diff --git a/CREDITS-wolfcam.txt b/CREDITS-wolfcam.txt index 5ddce6ba..40db00c0 100644 --- a/CREDITS-wolfcam.txt +++ b/CREDITS-wolfcam.txt @@ -1,7 +1,7 @@ id software: releasing quake3 source ioquake3 Luigi Auriemma: quake live pk3 decryption -CaNaBiS, HMage, auri: q3mme (blur code, and obviously inspiration) +CaNaBiS, HMage, auri, ent: q3mme (blur code, q3mme camera code, and obviously inspiration) Cloud Wu: backtrace OpenArena: some content Cyberstorm: anim map change @@ -19,7 +19,7 @@ Adam Pyle: technical information regarding quake live Ed Bow: qldt Jonathan Young: quakelive offline -Maverick and quake live developers for information regarding dm 90 protocol changes +Maverick and quake live developers for information regarding dm90 and dm91 protocol changes Dmitry 'qrealka' Loginov: cpma pro-sound description Ravensoft: png output from Jedi Acadmey diff --git a/FIXME b/FIXME index e98507a3..ee0122c2 100644 --- a/FIXME +++ b/FIXME @@ -1566,7 +1566,6 @@ WARNING ShaderForShaderNum: using default shader for 'textures/common/weapclip' * /devmap powerup available needs to be broadcast * spec demo doesn't show ql hud * 44100 sound -* check CG_StartSound(NULL, MAX_GENTITIES - 1, cg_view for railgun freecam hack * something is still calling sound/feedback/fight.wav ? 2015-07-06-demos/CTF q3wcp9 cpma * still using red/blue flag returned? * flag capture/return sounds (not vo) for specs? @@ -1589,9 +1588,41 @@ WARNING ShaderForShaderNum: using default shader for 'textures/common/weapclip' - harvester capture - 1fctf (cap attack) -* unsigned long Width; //uint32_t Width; in tr_image_png.c * double check di.protocol == PROTOCOL_QL is also for 73 and now 91 2015-07-28 - +* protocol 91: utf8, scoreboards +* WARNING: unknown general shader parameter 'nodefault' in 'models/players/hunter/harpy_f' +* dir demos/ doesn't list ql ones +* ui_shared.c DC->cursorx -- horiz scrollbars +* spline angles acceleration, initial velocities in CG_CameraUpdateInfo() +* win32 console output also store output to file + +* hud support for q3mme camera +* camera: spline to interp what about roll? +* check spline angles and use previous +* camera masking like q3mme (done for q3mme types, need for others) +* check if add q3mme camera point checks for time and bypasses q3mme checks (can q3mme add cam points at same time?) +* q3mme and camera velocity and cg_drawSpeed +* q3mme camera: disable playing when new cam point added? +* why does cg_cameraRewindTime depend on cg_cameraQue ? +* camera: spline type for offsets? +* spamming errorpup in console when bad angle type is added in hud, find and test disabled spamming + + bad camera point 0 viewpoint but not followed by either viewpoint pass or viewpoint + +* fix angle accel for spline +* wolfcamql camera flags for other types besides q3mme ones +* wolfcamql missing linear origin interpolation from q3mme + +* last todo: + - wolfcamql disable hud roll for angles spline + x - q3mme camera hud + x - maybe com_idlesleep + - maybe also write stdout.txt for console output + - q3mme camera commands (shift, smooth, etc..) for wolfcamql camera + +* camera: accel initial values and camera masking flags +* check all uses of CursorX_Widescreen() +* linear angle interpolation from q3mme --------------------------- diff --git a/Makefile b/Makefile index 17ce588e..08fac8a2 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ COMPILE_PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]'|sed -e 's/\//_/g') -COMPILE_ARCH=$(shell uname -m | sed -e s/i.86/i386/) +COMPILE_ARCH=$(shell uname -m | sed -e s/i.86/i386/ | sed -e 's/^arm.*/arm/') ifeq ($(COMPILE_PLATFORM),sunos) # Solaris uname and GNU uname differ @@ -259,31 +259,20 @@ CGAME_LIBS = -lpthread ############################################################################# ## Defaults -LIB=lib - INSTALL=install MKDIR=mkdir +ifneq (,$(findstring "$(COMPILE_PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu")) + TOOLS_CFLAGS += -DARCH_STRING=\"$(COMPILE_ARCH)\" +endif + ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu")) ifeq ($(ARCH),axp) ARCH=alpha else ifeq ($(ARCH),x86_64) - LIB=lib64 LDFLAGS += -m64 - else - ifeq ($(ARCH),ppc64) - LIB=lib64 - else - ifeq ($(ARCH),s390x) - LIB=lib64 - else - ifeq ($(ARCH),aarch64) - LIB=lib64 - endif - endif - endif endif endif @@ -293,10 +282,10 @@ ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu") ifdef CGAME_HARD_LINKED BASE_CFLAGS = -p -g -rdynamic -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \ - -pipe -DUSE_ICON -D_FILE_OFFSET_BITS=64 -msse $(CGAME_HARD_LINKED) + -pipe -DUSE_ICON -DARCH_STRING=\\\"$(ARCH)\\\" -D_FILE_OFFSET_BITS=64 -msse $(CGAME_HARD_LINKED) else BASE_CFLAGS = -g -rdynamic -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \ - -pipe -DUSE_ICON -D_FILE_OFFSET_BITS=64 -msse + -pipe -DUSE_ICON -DARCH_STRING=\\\"$(ARCH)\\\" -D_FILE_OFFSET_BITS=64 -msse endif CLIENT_CFLAGS = $(SDL_CFLAGS) @@ -648,9 +637,10 @@ ifdef MINGW CLIENT_CFLAGS += -I$(SDLHDIR)/include CLIENT_LIBS += $(LIBSDIR)/win32/libSDLmain.a \ $(LIBSDIR)/win32/libSDL.dll.a + #CLIENT_LIBS += $(LIBSDIR)/win32/libSDL.dll.a else CLIENT_CFLAGS += $(SDL_CFLAGS) - CLIENT_LIBS += $(SDL_LIBS) + #CLIENT_LIBS += $(SDL_LIBS) endif BUILD_CLIENT_SMP = 0 @@ -831,7 +821,7 @@ else # ifeq netbsd ############################################################################# ifeq ($(PLATFORM),irix64) - + LIB=lib ARCH=mips CC = c99 @@ -1051,8 +1041,7 @@ endef define DO_CPP $(echo_cmd) "CPP $<" -#$(Q)$(CPP) -Wall -m32 -o $@ -c $< -$(CPP) -Wall -m32 -o $@ -c $< +$(Q)$(CPP) -Wall -m32 -o $@ -c $< endef define DO_SMP_CC @@ -1945,6 +1934,7 @@ Q3CGOBJHARDLINKED_ = \ $(B)/baseq3/cgame/bg_slidemove.o \ $(B)/baseq3/cgame/bg_lib.o \ $(B)/baseq3/cgame/bg_xmlparser.o \ + $(B)/baseq3/cgame/cg_camera.o \ $(B)/baseq3/cgame/cg_consolecmds.o \ $(B)/baseq3/cgame/cg_draw.o \ $(B)/baseq3/cgame/cg_drawdc.o \ @@ -1994,6 +1984,7 @@ Q3CGOBJ_ = \ $(B)/baseq3/cgame/bg_slidemove.o \ $(B)/baseq3/cgame/bg_xmlparser.o \ $(B)/baseq3/cgame/bg_lib.o \ + $(B)/baseq3/cgame/cg_camera.o \ $(B)/baseq3/cgame/cg_consolecmds.o \ $(B)/baseq3/cgame/cg_draw.o \ $(B)/baseq3/cgame/cg_drawdc.o \ diff --git a/Makefile.local b/Makefile.local index cdd9b70b..e74141eb 100644 --- a/Makefile.local +++ b/Makefile.local @@ -1,4 +1,4 @@ -VERSION=11.0test10 +VERSION=11.0test11 USE_CODEC_VORBIS=1 USE_FREETYPE=1 BUILD_MISSIONPACK=0 diff --git a/README-wolfcam.txt b/README-wolfcam.txt index 54da3243..fcc6421c 100644 --- a/README-wolfcam.txt +++ b/README-wolfcam.txt @@ -967,15 +967,16 @@ Edit all currently selected camera points <...> are required [...] are optional -/ecam type -/ecam fov [fov value] +/ecam type +/ecam fov [fov value] /ecam command /ecam numsplines -/ecam angles +/ecam angles the 'ent' option has additional parameter for the entity /ecam angles ent [entity number] /ecam offset [x offset] [y offset] [z offset] /ecam roll [roll value] +/ecam flags [origin | angles | fov | time] /ecam initialVelocity /ecam finalVelocity @@ -1025,10 +1026,18 @@ Origin types: jump: don't move at all towards next camera point, simply appear at the next one spline: a 'best fitting' curve is created for all the camera points. One of the disadvantages is that you are not likely to pass through the exact origin that you selected for a particular camera point. curve: every three points of this type define a quadratic curve. You can think of the first and last being the 'start' and 'end' points with the middle one controlling the steepness of the curve. This has the advantage over the spline type of being able to pass through exactly through the chosen origins for camera points. + splineBezier: (from q3mme, uses camera flags for masking) + splineCatmullRom: (from q3mme, uses camera flags for masking) + +Angle types: + interp: linear angle interpolation, roll is treated as a separate setting + spline: (from q3mme, uses camera flags for masking), camera roll is included in this interpolation Velocity: //FIXME + Note that spline fov uses the final fov values (ex: go from 60 -> 120 fov) instead of offset values which q3mme uses (ex: 10 -> 30 means go from currentFov + 10 to currentFov + 30). + cvar cg_draw2d 2 for use with camera editing default bind BACKSPACE "toggle cg_draw2d 0 1 2" @@ -1044,7 +1053,7 @@ Velocity: cg_cameraUpdateFreeCam transfers origin and angles to freecam state - cg_cameraDebugPath adds a model showing the camera path without updating freecam origin and angles, use r_drawworld 0 and r_fastsky 1 for a clearer view + cg_cameraDebugPath adds a model showing the camera path without updating freecam origin and angles. Use r_drawworld 0 and r_fastsky 1 for a clearer view. If both camera types are present (q3mme and wolfcamql) it will draw a model for each of them. -------------------------------------------------------------------------- @@ -1069,6 +1078,26 @@ Velocity: --------------------------------------------------------------------------- +* q3mme camera support: + /q3mmecamera (same as q3mme /camera command) + added flags subcommand to print or set camera flag values: + /q3mmecamera flags [origin | angles | fov | time] + + target sub command changed, you need to specify a target number (-1 means no target). Ex: /q3mmecamera target 9 + + additional commands: + + /playq3mmecamera + /stopq3mmecamera + /saveq3mmecamera + /loadq3mmecamera + + cg_q3mmeCameraSmoothPos is the same as mov_cameraSmoothPos in q3mme. + + FIXME target (Note: target selection isn't available) + +--------------------------------------------------------------------------- + * cg_inheritPowerupShader for multiple power-ups (ex: quad and medkit) do/don't apply the first power-up custom shader to the second * +chat and cg_chatHistoryLength @@ -1839,7 +1868,13 @@ You can use it in order to un-grab the mouse pointer without having to bring dow * cg_killBeep same as quake live -* fs_quakelivedir Default quake live install paths are checked in order to list demos, you can override with this cvar +* fs_quakelivedir Default quake live install paths are checked in order to list demos (steam and stand alone versions). You can override with this cvar. It should point to the directory that contains the 'baseq3' directory where demos are saved. Ex: + + # steam version + wolfcamql +set fs_quakelivedir "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Quake Live\\12345678901234567" + + # stand alone version + wolfcamql +set fs_quakelivedir "C:\\Users\user1\\Application Data\\LocalLow\\id Software\\quakelive\\home" * r_dynamicLight 1 fixes square lights, 2 original q3 code (sometimes textures have light added to the wrong side), 3 testing only determine if lighting applies in one place in the source code @@ -1873,8 +1908,6 @@ You can use it in order to un-grab the mouse pointer without having to bring dow The default widescreen value in menus appears to be '2' if it's never defined in a menuDef. - Note: this type of widescreen implementation can create problems with the ingame mouse cursor. An example is selectiong a name in the scoreboard. Use cg_scoreBoardCursorAreaWideScreen to set it to the same value used for 'widescreen' in the hud menu file. - Values: 0: original code q3 (and older quake live versions), with images stretched or shrunk horizontally @@ -2238,6 +2271,8 @@ automated scripting examples: playdemolist.py and recorddemolist.py * ability to filter out reward types to disable both the announcment and the display icon: cg_rewardCapture, cg_rewardImpressive, cg_rewardExcellent, cg_rewardHumiliation, cg_rewardDefend, cg_rewardAssist, cg_rewardComboKill, cg_rewardRampage, cg_rewardMidAir, cg_rewardRevenge, cg_rewardPerforated, cg_rewardHeadshot, cg_rewardAccuracy, cg_rewardQuadGod, cg_rewardFirstFrag, cg_rewardPerfect +* windows version can echo console messages in the command prompt if --console-output is used in the command line. This will also convert ansi colors. + ---------- brugal diff --git a/code/cgame/cg_camera.c b/code/cgame/cg_camera.c new file mode 100644 index 00000000..8a5783fe --- /dev/null +++ b/code/cgame/cg_camera.c @@ -0,0 +1,354 @@ +#include "cg_camera.h" +#include "cg_local.h" // cg. +//#include "cg_q3mme_math.h" +#include "cg_q3mme_camera.h" // CAM_ORIGIN, CAM_ANGLES + +// from q3mme +static void wolfcamCameraPointMatch (const cameraPoint_t *point, int mask, const cameraPoint_t *match[4]) +{ + const cameraPoint_t *p; + + p = point; + while (p && !(p->flags & mask)) + p = p->prev; + + if (!p) { + match[0] = 0; + match[1] = 0; + p = point; + while (p && !(p->flags & mask)) + p = p->next; + if (!p) { + match[2] = 0; + match[3] = 0; + return; + } + } else { + match[1] = p; + p = p->prev; + + while (p && !(p->flags & mask)) + p = p->prev; + + match[0] = p; + } + p = point->next; + while (p && !(p->flags & mask)) + p = p->next; + match[2] = p; + if (p) + p = p->next; + while (p && !(p->flags & mask)) + p = p->next; + match[3] = p; +} + +// from q3mme +static qboolean wolfcamCameraMatchOrigin (const cameraPoint_t *match[4], vec3_t origin[4]) +{ + if ( !match[1] ) + return qfalse; + + VectorCopy( match[1]->origin, origin[1] ); + + if (match[0]) + VectorCopy( match[0]->origin, origin[0] ); + else if (match[2]) + VectorSubDelta( match[1]->origin, match[2]->origin, origin[0] ); + else + VectorCopy( match[1]->origin, origin[0] ); + + if (match[2]) { + VectorCopy( match[2]->origin, origin[2] ); + if (match[3]) + VectorCopy( match[3]->origin, origin[3] ); + else + VectorAddDelta( match[1]->origin, match[2]->origin, origin[3] ); + } else if ( match[0] ) { + VectorAddDelta( match[0]->origin, match[1]->origin, origin[2] ); + VectorAddDelta( match[0]->origin, match[1]->origin, origin[3] ); + } else { + VectorCopy( match[1]->origin, origin[2] ); + VectorCopy( match[1]->origin, origin[3] ); + } + return qtrue; +} + +// from q3mme +//static void cameraMatchAt( int time, int mask, const demoCameraPoint_t *match[4] ) { +static void wolfcamCameraMatchAt (double ftime, int mask, const cameraPoint_t *match[4]) +{ + const cameraPoint_t *p; + + p = cg.cameraPointsPointer; + + match[0] = match[1] = 0; + while( p ) { + if (p->cgtime > ftime) + break; + if (p->flags & mask) { + match[0] = match[1]; + match[1] = p; + } + p = p->next; + } + + while (p && !(p->flags & mask)) + p = p->next; + + match[2] = p; + if (p) + p = p->next; + + while (p && !(p->flags & mask)) + p = p->next; + + match[3] = p; +} + +// from q3mme +static float wolfcamCameraPointLength (posInterpolate_t posType, cameraPoint_t *point) +{ + int i; + cameraPoint_t *match[4]; + vec3_t control[4]; + vec3_t lastOrigin, nextOrigin; + float len = 0, step = 0, addStep, distance, deltaDist = 0.01f; + + if (point->len >= 0) { + return point->len; + } + + //cameraPointMatch( point, CAM_ORIGIN, (const demoCameraPoint_t **)match ); + wolfcamCameraPointMatch(point, CAM_ORIGIN, (const cameraPoint_t **)match); + + + if (!wolfcamCameraMatchOrigin( (const cameraPoint_t **)match, control )) { + point->len = 0; + return 0; + } + +#if 0 //FIXME linear + if ( demo.camera.smoothPos == posLinear ) { + point->len = VectorDistance( control[1], control[2] ); + return point->len; + } +#endif + if (posType == posLinear) { + Com_Printf("^1wolfcamCameraPointLength pos is linear\n"); + posType = posBezier; + } + + posGet( 0, posType, (const vec3_t *)control, lastOrigin ); + if (cg_q3mmeCameraSmoothPos.value >= 1) + deltaDist = 0.01f / cg_q3mmeCameraSmoothPos.value; + while (step < 1) { + addStep = 1 - step; + if (addStep > 0.01f) + addStep = 0.01f; + for (i = 0; i < 10; i++) { + posGet( step+addStep, posType, (const vec3_t *)control, nextOrigin ); + distance = VectorDistanceSquared( lastOrigin, nextOrigin); + if ( distance <= deltaDist) + break; + addStep *= 0.7f; + } + step += addStep; + len += sqrt( distance ); + VectorCopy( nextOrigin, lastOrigin ); + if (!distance) + break; + } + point->len = len; + return point->len; +} + +// from q3mme +//qboolean CG_CameraSplineOriginAt (int time, float timeFraction, vec3_t origin) +qboolean CG_CameraSplineOriginAt (double ftime, posInterpolate_t posType, vec3_t origin) +{ + cameraPoint_t *match[4]; + float searchLen; + vec3_t dx, dy; + vec3_t control[4]; + vec3_t nextOrigin; + float len = 0, step = 0, addStep, distance, deltaDist = 0.01f; + int i; + + //cameraMatchAt( time, CAM_ORIGIN, (const demoCameraPoint_t **)match ); + wolfcamCameraMatchAt(ftime, CAM_ORIGIN, (const cameraPoint_t **)match); + + if (!match[1]) { + if (!match[2]) + return qfalse; + if (!match[3]) + return qfalse; + //wolfcamCameraPointMatch(match[2], CAM_ORIGIN, (const demoCameraPoint_t **)match ); + //FIXME mask + wolfcamCameraPointMatch(match[2], CAM_ORIGIN, (const cameraPoint_t **)match ); + searchLen = 0; + } else if (!match[2]) { + /* Only match[1] is valid, will be copied to all points */ + searchLen = 0; + } else { + dx[1] = match[2]->cgtime - match[1]->cgtime; + dy[1] = wolfcamCameraPointLength(posType, match[1]); + if (match[0]) { + dx[0] = match[1]->cgtime - match[0]->cgtime; + dy[0] = wolfcamCameraPointLength(posType, match[0]); + } else { + dx[0] = dx[1]; + dy[0] = dy[1]; + } + if (match[3]) { + dx[2] = match[3]->cgtime - match[2]->cgtime; + dy[2] = wolfcamCameraPointLength(posType, match[2]); + } else { + dx[2] = dx[1]; + dy[2] = dy[1]; + } + searchLen = dsplineCalc( (ftime - match[1]->cgtime), dx, dy, 0 ); + } + + if (!wolfcamCameraMatchOrigin( (const cameraPoint_t **)match, control )) + return qfalse; + +#if 0 //FIXME linear + //if ( demo.camera.smoothPos == posLinear ) { + if (posType == posLinear) { + float t = searchLen / match[1]->len ; + posGet( t, posType, (const vec3_t *)control, origin ); + return qtrue; + } +#endif + if (posType == posLinear) { + Com_Printf("^1posLinear specified\n"); + posType = posBezier; + } + + posGet( 0, posType, (const vec3_t *)control, origin ); + if (cg_q3mmeCameraSmoothPos.value >= 1) + deltaDist = 0.01f / cg_q3mmeCameraSmoothPos.value; + while (step < 1) { + addStep = 1 - step; + if (addStep > 0.01f) + addStep = 0.01f; + for (i = 0; i < 10; i++) { + posGet( step+addStep, posType, (const vec3_t *)control, nextOrigin ); + distance = VectorDistanceSquared( origin, nextOrigin); + if ( distance <= deltaDist) + break; + addStep *= 0.7f; + } + distance = sqrt( distance ); + if (len + distance > searchLen) + break; + len += distance; + step += addStep; + VectorCopy( nextOrigin, origin ); + //Com_Printf("nextorigin: %f %f %f\n", nextOrigin[0], nextOrigin[1], nextOrigin[2]); + } + return qtrue; +} + +// from q3mme +qboolean CG_CameraSplineAnglesAt (double ftime, vec3_t angles) +{ + cameraPoint_t *match[4]; + float lerp; + vec3_t tempAngles; + Quat_t q0, q1, q2, q3, qr; + //double timeFraction; + + //cameraMatchAt( time, CAM_ANGLES, (const demoCameraPoint_t **)match ); + wolfcamCameraMatchAt(ftime, CAM_ANGLES, (const cameraPoint_t **)match); + + if (!match[1]) { + if (match[2]) { + VectorCopy( match[2]->angles, angles ); + return qtrue; + } + return qfalse; + } + if (!match[2]) { + VectorCopy( match[1]->angles, angles ); + return qtrue; + } + + //timeFraction = ftime - match[1]->cgtime; + lerp = ((ftime - match[1]->cgtime) ) / (match[2]->cgtime - match[1]->cgtime); + + //Com_Printf("lerp: %f\n", lerp); + + // switch ( demo.camera.smoothAngles ) { + //case angleLinear: + // LerpAngles( match[1]->angles, match[2]->angles, angles, lerp ); + // break; + //default: + //case angleQuat: + QuatFromAngles( match[1]->angles, q1 ); + if ( match[0] ) { + QuatFromAnglesClosest( match[0]->angles, q1, q0 ); + } else { + VectorSubDelta( match[1]->angles, match[2]->angles, tempAngles ); + QuatFromAnglesClosest( tempAngles, q1, q0 ); + } + QuatFromAnglesClosest( match[2]->angles, q1, q2 ); + if (match[3]) { + QuatFromAnglesClosest( match[3]->angles, q2, q3 ); + } else { + VectorAddDelta( match[1]->angles, match[2]->angles, tempAngles ); + QuatFromAnglesClosest( tempAngles, q2, q3 ); + } + QuatSquad( lerp, q0, q1, q2, q3, qr ); + QuatToAngles( qr, angles ); + //} + return qtrue; +} + +// from q3mme +qboolean CG_CameraSplineFovAt (double ftime, float *fov) +{ + cameraPoint_t *match[4]; + float lerp; + float f[4]; + int t[4]; + + wolfcamCameraMatchAt( ftime, CAM_FOV, (const cameraPoint_t **)match ); + + if (!match[1]) { + if (match[2]) { + *fov = match[2]->fov; + return qtrue; + } + return qfalse; + } + if (!match[2]) { + *fov = match[1]->fov; + return qtrue; + } + + f[1] = match[1]->fov; + t[1] = match[1]->cgtime; + f[2] = match[2]->fov; + t[2] = match[2]->cgtime; + + if ( match[0] ) { + f[0] = match[0]->fov; + t[0] = match[0]->cgtime; + } else { + f[0] = f[1] - (f[2] - f[1]); + t[0] = t[1] - (t[2] - t[1]); + } + if (match[3]) { + f[3] = match[3]->fov; + t[3] = match[3]->cgtime; + } else { + f[3] = f[2] + (f[2] - f[1]); + t[3] = t[2] + (t[2] - t[1]); + } + lerp = (ftime - t[1] ) / (t[2] - t[1]); + VectorTimeSpline( lerp, t, (float*)f, fov, 1 ); + return qtrue; +} + diff --git a/code/cgame/cg_camera.h b/code/cgame/cg_camera.h index d87d98fa..cd97cc1a 100644 --- a/code/cgame/cg_camera.h +++ b/code/cgame/cg_camera.h @@ -2,8 +2,9 @@ #define camera_h_included #include "../qcommon/q_shared.h" +#include "cg_q3mme_math.h" // posInterpolate_t -#define WOLFCAM_CAMERA_VERSION 8 +#define WOLFCAM_CAMERA_VERSION 9 #define MAX_CAMERAPOINTS 256 #define MAX_SPLINEPOINTS (1024 * 10) //(1024 * 1024 * 3) #define DEFAULT_NUM_SPLINES 40 @@ -19,6 +20,7 @@ enum { CEF_CAMERA_TYPE, CEF_VIEW_TYPE, CEF_ROLL_TYPE, + CEF_FLAGS, CEF_NUMBER_OF_SPLINES, CEF_VIEWPOINT_ORIGIN, CEF_VIEW_ENT, @@ -56,6 +58,8 @@ enum { CAMERA_INTERP, CAMERA_JUMP, CAMERA_CURVE, + CAMERA_SPLINE_BEZIER, + CAMERA_SPLINE_CATMULLROM, CAMERA_ENUM_END, }; @@ -68,6 +72,7 @@ enum { CAMERA_ANGLES_VIEWPOINT_INTERP, CAMERA_ANGLES_VIEWPOINT_PASS, CAMERA_ANGLES_VIEWPOINT_FIXED, + CAMERA_ANGLES_SPLINE, CAMERA_ANGLES_ENUM_END, }; @@ -83,6 +88,7 @@ enum { CAMERA_FOV_INTERP, CAMERA_FOV_FIXED, CAMERA_FOV_PASS, + CAMERA_FOV_SPLINE, CAMERA_FOV_ENUM_END, }; @@ -99,7 +105,7 @@ enum { SPLINE_ENUM_END, }; -typedef struct { +typedef struct cameraPoint_s { int version; vec3_t origin; @@ -219,7 +225,15 @@ typedef struct { int curveCount; + // for q3mme camera functions + struct cameraPoint_s *next, *prev; // not stored in cam file + float len; // dynamic variable, not stored in cam file + int flags; } cameraPoint_t; +qboolean CG_CameraSplineAnglesAt (double ftime, vec3_t angles); +qboolean CG_CameraSplineOriginAt (double ftime, posInterpolate_t posType, vec3_t origin); +qboolean CG_CameraSplineFovAt (double ftime, float *fov); + #endif // camera_h_included diff --git a/code/cgame/cg_consolecmds.c b/code/cgame/cg_consolecmds.c index d83fa1f7..94b5b7a8 100644 --- a/code/cgame/cg_consolecmds.c +++ b/code/cgame/cg_consolecmds.c @@ -6,6 +6,7 @@ #include "cg_local.h" #include "../qcommon/q_shared.h" #include "../game/bg_public.h" +#include "../game/bg_xmlparser.h" #include "cg_consolecmds.h" #include "cg_draw.h" // cg_fade... @@ -972,13 +973,20 @@ static void CG_SeekClock_f (void) void CG_ErrorPopup (const char *s) { + qboolean messageRepeated = qfalse; + + if (!Q_stricmpn(cg.errorPopupString, s, strlen(s))) { + messageRepeated = qtrue; + } cg.errorPopupStartTime = cg.realTime; cg.errorPopupTime = 3000; //4000; //cg_errorPopupTime.integer; cg.errorPopupString[0] = '\0'; Q_strncpyz(cg.errorPopupString, s, sizeof(cg.errorPopupString)); Com_Printf("^1%s\n", cg.errorPopupString); - trap_SendConsoleCommand(va("play sound/weapons/noammo.ogg\n")); + if (!messageRepeated) { + trap_SendConsoleCommand(va("play sound/weapons/noammo.ogg\n")); + } } void CG_EchoPopup (const char *s, int x, int y) @@ -1729,6 +1737,11 @@ static void CG_PlayPath_f (void) return; } + if (cg.cameraQ3mmePlaying) { + Com_Printf("can't play path, q3mme camera is playing\n"); + return; + } + //cg.playPath = !cg.playPath; //cg.playPathStarted = qfalse; @@ -2026,17 +2039,23 @@ static void CG_AddCameraPoint_f (void) cp->type = CAMERA_JUMP; } else if (!Q_stricmp(type, "curve")) { cp->type = CAMERA_CURVE; + } else if (!Q_stricmp(type, "splinebezier")) { + cp->type = CAMERA_SPLINE_BEZIER; + } else if (!Q_stricmp(type, "splinecatmullrom")) { + cp->type = CAMERA_SPLINE_CATMULLROM; } else { - cp->type = CAMERA_CURVE; + cp->type = CAMERA_SPLINE_BEZIER; } - cp->viewType = CAMERA_ANGLES_INTERP; + cp->viewType = CAMERA_ANGLES_SPLINE; cp->rollType = CAMERA_ROLL_INTERP; cp->splineType = SPLINE_FIXED; cp->numSplines = DEFAULT_NUM_SPLINES; cp->viewEnt = -1; cp->fov = -1; + cp->fovType = CAMERA_FOV_USE_CURRENT; cp->timescale = -1; + cp->flags = CAM_ORIGIN | CAM_ANGLES; } cp->useOriginVelocity = qfalse; @@ -2179,11 +2198,13 @@ static void CG_AddCameraPoint_f (void) //Com_Printf("add camera point selected : %d\n", cg.selectedCameraPointMin); } +// not needed, /q3mmecamera add +#if 0 static void CG_AddQ3mmeCameraPoint_f (void) { demoCameraPoint_t *point; - //point = cameraPointAdd( demo.play.time, demo.camera.flags ); - point = cameraPointAdd(cg.time, CAM_ORIGIN | CAM_ANGLES | CAM_FOV | CAM_TIME); + //point = CG_Q3mmeCameraPointAdd( demo.play.time, demo.camera.flags ); + point = CG_Q3mmeCameraPointAdd(cg.time, CAM_ORIGIN | CAM_ANGLES | CAM_FOV | CAM_TIME); if (point) { //VectorCopy( demo.viewOrigin, point->origin ); //VectorCopy( demo.viewAngles, point->angles ); @@ -2193,12 +2214,13 @@ static void CG_AddQ3mmeCameraPoint_f (void) point->fov = 0; Com_Printf("^6added q3mme camera point\n"); // just to view the path and points - CG_AddCameraPoint_f(); + //CG_AddCameraPoint_f(); } else { Com_Printf("^1couldn't add q3mme camera point\n"); } } +#endif static void CG_ClearCameraPoints_f (void) { @@ -2207,6 +2229,7 @@ static void CG_ClearCameraPoints_f (void) cg.numCameraPoints = 0; cg.numSplinePoints = 0; + cg.cameraPointsPointer = NULL; cg.selectedCameraPointMin = 0; cg.selectedCameraPointMax = 0; } @@ -2224,6 +2247,8 @@ static void CG_PlayCamera_f (void) Com_Printf("can't play camera, need at least 2 camera points\n"); return; } + + //FIXME why this dependency ? if (cg_cameraQue.integer) { extraTime = 1000.0 * cg_cameraRewindTime.value; if (extraTime < 0) { @@ -2232,7 +2257,7 @@ static void CG_PlayCamera_f (void) trap_SendConsoleCommand(va("seekservertime %f\n", cg.cameraPoints[0].cgtime - extraTime)); } - cg.cameraQ3mme = qfalse; + //cg.cameraQ3mmePlaying = qfalse; cg.cameraPlaying = qtrue; cg.cameraPlayedLastFrame = qfalse; @@ -2254,7 +2279,7 @@ static void CG_WriteString (const char *s, qhandle_t file) static void CG_SaveCamera_f (void) { - qhandle_t f; + fileHandle_t f; const char *s; int i; const cameraPoint_t *cp; @@ -2287,7 +2312,7 @@ static void CG_SaveCamera_f (void) } if (!f) { - Com_Printf("^1couldn't open cameras/%s.cam%d\n", CG_Argv(1), WOLFCAM_CAMERA_VERSION); + Com_Printf("^1couldn't create %s.cam%d\n", CG_Argv(1), WOLFCAM_CAMERA_VERSION); return; } s = va("WolfcamCamera %d\n", WOLFCAM_CAMERA_VERSION); @@ -2302,6 +2327,7 @@ static void CG_SaveCamera_f (void) CG_WriteString(va("%d type\n", cp->type), f); CG_WriteString(va("%d viewType\n", cp->viewType), f); CG_WriteString(va("%d rollType\n", cp->rollType), f); + CG_WriteString(va("%d flags\n", cp->flags), f); CG_WriteString(va("%f cgtime\n", cp->cgtime), f); CG_WriteString(va("%d splineType\n", cp->splineType), f); CG_WriteString(va("%d numSplines\n", cp->numSplines), f); @@ -2348,7 +2374,6 @@ static void CG_SaveCamera_f (void) CG_WriteString(va("%d useRollVelocity\n", cp->useRollVelocity), f); CG_WriteString(va("%f rollInitialVelocity\n", cp->rollInitialVelocity), f); CG_WriteString(va("%f rollFinalVelocity\n", cp->rollFinalVelocity), f); - len = strlen(cp->command); CG_WriteString(va("%d commandStrLen\n", len), f); if (len) { @@ -2424,7 +2449,7 @@ static void CG_CamtraceSave_f (void) static void CG_LoadCamera_f (void) { - qhandle_t f; + fileHandle_t f; int len; int version; const char *s; @@ -2496,6 +2521,13 @@ static void CG_LoadCamera_f (void) s = CG_FS_ReadLine(f, &len); sscanf(s, "%d", &cp->rollType); + if (version > 8) { + s = CG_FS_ReadLine(f, &len); + sscanf(s, "%d", &cp->flags); + } else { + cp->flags = CAM_ORIGIN | CAM_ANGLES; + } + s = CG_FS_ReadLine(f, &len); sscanf(s, "%lf", &cp->cgtime); @@ -2681,7 +2713,7 @@ static void CG_SelectCameraPoint_f (void) static void CG_EditCameraPoint_f (void) { - qboolean gotoSplinePoint = qtrue; + qboolean gotoRealPoint = qtrue; int cameraPoint = cg.numCameraPoints - 1; const char *s; @@ -2708,9 +2740,8 @@ static void CG_EditCameraPoint_f (void) } if (CG_Argc() >= 3) { - //gotoSplinePoint = atoi(CG_Argv(2)); if (!Q_stricmp(CG_Argv(2), "real")) { - gotoSplinePoint = qfalse; + gotoRealPoint = qfalse; } } @@ -2719,8 +2750,8 @@ static void CG_EditCameraPoint_f (void) return; } - if (cg.numCameraPoints < 2 || cg.cameraPoints[cameraPoint].type != CAMERA_SPLINE) { - gotoSplinePoint = qfalse; + if (cg.numCameraPoints < 2 || (cg.cameraPoints[cameraPoint].type != CAMERA_SPLINE || cg.cameraPoints[cameraPoint].type != CAMERA_SPLINE_BEZIER || cg.cameraPoints[cameraPoint].type != CAMERA_SPLINE_CATMULLROM )) { + gotoRealPoint = qfalse; } //FIXME @@ -2728,16 +2759,29 @@ static void CG_EditCameraPoint_f (void) cg.selectedCameraPointMin = cameraPoint; cg.selectedCameraPointMax = cameraPoint; - if (gotoSplinePoint) { - VectorCopy(cg.splinePoints[cg.cameraPoints[cameraPoint].splineStart], cg.freecamPlayerState.origin); - VectorCopy(cg.splinePoints[cg.cameraPoints[cameraPoint].splineStart], cg.fpos); - VectorCopy(cg.cameraPoints[cameraPoint].angles, cg.freecamPlayerState.viewangles); - VectorCopy(cg.cameraPoints[cameraPoint].angles, cg.fang); - } else { + if (gotoRealPoint) { + if (cg.cameraPoints[cameraPoint].type == CAMERA_SPLINE) { + VectorCopy(cg.splinePoints[cg.cameraPoints[cameraPoint].splineStart], cg.freecamPlayerState.origin); + } else if (cg.cameraPoints[cameraPoint].type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(cg.cameraPoints[cameraPoint].cgtime, posBezier, cg.freecamPlayerState.origin); + } else if (cg.cameraPoints[cameraPoint].type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(cg.cameraPoints[cameraPoint].cgtime, posCatmullRom, cg.freecamPlayerState.origin); + } else { + VectorCopy(cg.cameraPoints[cameraPoint].origin, cg.freecamPlayerState.origin); + } + VectorCopy(cg.freecamPlayerState.origin, cg.fpos); + + if (cg.cameraPoints[cameraPoint].viewType == CAMERA_ANGLES_SPLINE) { + CG_CameraSplineAnglesAt(cg.cameraPoints[cameraPoint].cgtime, cg.freecamPlayerState.viewangles); + } else { + VectorCopy(cg.cameraPoints[cameraPoint].angles, cg.freecamPlayerState.viewangles); + } + VectorCopy(cg.freecamPlayerState.viewangles, cg.fang); + } else { // goto set values VectorCopy(cg.cameraPoints[cameraPoint].origin, cg.freecamPlayerState.origin); - VectorCopy(cg.cameraPoints[cameraPoint].origin, cg.fpos); + VectorCopy(cg.freecamPlayerState.origin, cg.fpos); VectorCopy(cg.cameraPoints[cameraPoint].angles, cg.freecamPlayerState.viewangles); - VectorCopy(cg.cameraPoints[cameraPoint].angles, cg.fang); + VectorCopy(cg.freecamPlayerState.viewangles, cg.fang); } cg.freecamPlayerState.origin[2] -= DEFAULT_VIEWHEIGHT; cg.fpos[2] -= DEFAULT_VIEWHEIGHT; @@ -2887,27 +2931,52 @@ static void CG_UpdateCameraInfo (void) cg.cameraPlayedLastFrame = qfalse; if (cg.numCameraPoints < 2) { + // update pointers for q3mme camera functions + if (cg.numCameraPoints == 0) { + cg.cameraPointsPointer = NULL; + } else { // 1 + cg.cameraPointsPointer = &cg.cameraPoints[0]; + cg.cameraPoints[0].prev = NULL; + cg.cameraPoints[0].next = NULL; + cg.cameraPoints[0].len = -1; + } + return; } + // there's at least 2 camera points now + + // update camera pointers for q3mme camera functions, needs to be done + // early since this functions calls q3mme cam functions + for (i = 0; i < cg.numCameraPoints; i++) { + if (i == 0) { + cg.cameraPoints[i].prev = NULL; + cg.cameraPoints[i].next = &cg.cameraPoints[i + 1]; + } else if (i == cg.numCameraPoints - 1) { + cg.cameraPoints[i].prev = &cg.cameraPoints[i - 1]; + cg.cameraPoints[i].next = NULL; + } else { + cg.cameraPoints[i].prev = &cg.cameraPoints[i - 1]; + cg.cameraPoints[i].next = &cg.cameraPoints[i + 1]; + } + + cg.cameraPoints[i].len = -1; + } + cg.cameraPointsPointer = &cg.cameraPoints[0]; + cg.numSplinePoints = 0; granularity = 0.025; //FIXME cvar - //granularity = 0.005; - //granularity = 0.2; - //granularity = 0.05; - //granularity = 0.8; -#if 1 VectorCopy(cg.cameraPoints[0].origin, bpoint0); VectorCopy(cg.cameraPoints[0].origin, bpoint1); VectorCopy(cg.cameraPoints[0].origin, bpoint2); - //VectorSubtract(cg.cameraPoints[1].origin, cg.cameraPoints[0].origin, dir); VectorSubtract(cg.cameraPoints[0].origin, cg.cameraPoints[1].origin, dir); dist = Distance(cg.cameraPoints[1].origin, cg.cameraPoints[0].origin); //Com_Printf("beg dist %f\n", dist); VectorNormalize(dir); + // hack to keep spline point 0 with camera point 0 VectorMA(bpoint0, (float)dist * 1.0 * 3.0, dir, bpoint0); VectorMA(bpoint1, (float)dist * 0.66 * 3.0, dir, bpoint1); VectorMA(bpoint2, (float)dist * 0.33 * 3.0, dir, bpoint2); @@ -2916,22 +2985,9 @@ static void CG_UpdateCameraInfo (void) VectorCopy(cg.cameraPoints[cg.numCameraPoints - 1].origin, point1); VectorCopy(cg.cameraPoints[cg.numCameraPoints - 1].origin, point2); - // ?????????????????????? -#if 1 VectorCopy(point0, cg.cameraPoints[cg.numCameraPoints + 0].origin); VectorCopy(point1, cg.cameraPoints[cg.numCameraPoints + 1].origin); VectorCopy(point2, cg.cameraPoints[cg.numCameraPoints + 2].origin); -#endif - -#if 0 - VectorSubtract(cg.cameraPoints[cg.numCameraPoints - 1].origin, cg.cameraPoints[cg.numCameraPoints - 2].origin, dir); - dist = Distance(cg.cameraPoints[cg.numCameraPoints - 1].origin, cg.cameraPoints[cg.numCameraPoints - 2].origin); - VectorNormalize(dir); - - VectorMA(point0, (float)dist * 1.0, dir, cg.cameraPoints[cg.numCameraPoints + 0].origin); - VectorMA(point0, (float)dist * 1.0, dir, cg.cameraPoints[cg.numCameraPoints + 1].origin); - VectorMA(point0, (float)dist * 1.0, dir, cg.cameraPoints[cg.numCameraPoints + 2].origin); -#endif for (i = 0; i < 3; i++) { cg.cameraPoints[cg.numCameraPoints + i].numSplines = cg.cameraPoints[cg.numCameraPoints - 1].numSplines; @@ -2983,6 +3039,7 @@ static void CG_UpdateCameraInfo (void) } VectorSet(cg.splinePoints[cg.numSplinePoints], x, y, z); cg.splinePointsCameraPoints[cg.numSplinePoints] = i; + //cg.splinePointsCameraPoints[cg.numSplinePoints] = i - 2; cg.numSplinePoints++; if (tension > 0.49) { if (!midPointHit) { @@ -2990,6 +3047,7 @@ static void CG_UpdateCameraInfo (void) } midPointHit = qtrue; } + //Com_Printf("%d (%d) %f %f %f\n", i, cg.numSplinePoints - 1, x, y, z); //Com_Printf(" pt %f %f %f\n", x, y, z); if (cg.numSplinePoints >= MAX_SPLINEPOINTS) { Com_Printf("cg.numSplinePoints >= MAX_SPLINEPOINTS\n"); @@ -3003,83 +3061,10 @@ static void CG_UpdateCameraInfo (void) } } } -#endif - -#if 0 - for (i = 0; i < cg.numCameraPoints; i++) { - cp = &cg.cameraPoints[i]; - - // some clean up - cp->viewPointPassStart = -1; - cp->viewPointPassEnd = -1; - cp->rollPassStart = -1; - cp->rollPassEnd = -1; - cp->fovPassStart = -1; - cp->fovPassEnd = -1; - cp->offsetPassStart = -1; - cp->offsetPassEnd = -1; - - //Com_Printf("camera point (%d): %f %f %f\n", i, cg.cameraPoints[i].origin[0], cg.cameraPoints[i].origin[1], cg.cameraPoints[i].origin[2]); - cg.cameraPoints[i].splineStart = cg.numSplinePoints; - - start = cg.numSplinePoints; - - granularity = 1.0 / (float)cg.cameraPoints[i].numSplines; - - midPointHit = qfalse; - - if (i == 0) { - for (tension = 0.0; tension < 0.999 /*1.001*/; tension += granularity) { - x = y = z = 0; - for (j = 0; j < 4; j++) { - vec3_t origin; - - VectorCopy(cg.cameraPoints[i].origin, origin); - - x += origin[0] * CG_CalcSpline(j, tension); - y += origin[1] * CG_CalcSpline(j, tension); - z += origin[2] * CG_CalcSpline(j, tension); - } - } - } - - for (tension = 0.0; tension < 0.999 /*1.001*/; tension += granularity) { - x = y = z = 0; - for (j = 0; j < 4; j++) { - vec3_t origin; - - VectorCopy(cg.cameraPoints[i].origin, origin); - - x += origin[0] * CG_CalcSpline(j, tension); - y += origin[1] * CG_CalcSpline(j, tension); - z += origin[2] * CG_CalcSpline(j, tension); - } - VectorSet(cg.splinePoints[cg.numSplinePoints], x, y, z); - cg.splinePointsCameraPoints[cg.numSplinePoints] = i; - cg.numSplinePoints++; - if (tension > 0.49) { - if (!midPointHit) { - //cg.cameraPoints[i - 2].splineStart = cg.numSplinePoints; - } - midPointHit = qtrue; - } - //Com_Printf(" pt %f %f %f\n", x, y, z); - if (cg.numSplinePoints >= MAX_SPLINEPOINTS) { - Com_Printf("cg.numSplinePoints >= MAX_SPLINEPOINTS\n"); - //return; - goto alldone; - } - } - if (SC_Cvar_Get_Int("debug_splines")) { - if (i < cg.numCameraPoints) { - Com_Printf("cam point %d %d splines granularity %f\n", i, cg.numSplinePoints - start, granularity); - } - } - } -#endif alldone: - cg.cameraPoints[cg.numCameraPoints - 1].splineStart = cg.numSplinePoints - 1; + // ugh.. this was already set + //cg.cameraPoints[cg.numCameraPoints - 1].splineStart = cg.numSplinePoints - 1; if (SC_Cvar_Get_Int("debug_splines")) { Com_Printf("UpdateCameraInfo(): CreateSplines %d spline points\n", cg.numSplinePoints); @@ -3127,6 +3112,10 @@ static void CG_UpdateCameraInfo (void) if (cpprev && cpprev->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[cp->splineStart], point0); + } else if (cpprev && cpprev->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(cp->cgtime, posBezier, point0); + } else if (cpprev && cpprev->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(cp->cgtime, posCatmullRom, point0); } else { VectorCopy(cp->origin, point0); } @@ -3137,6 +3126,10 @@ static void CG_UpdateCameraInfo (void) if (p3) { if (p3->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[p3->splineStart], point2); + } else if (p3->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(p3->cgtime, posBezier, point2); + } else if (p3->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(p3->cgtime, posCatmullRom, point2); } else { VectorCopy(p3->origin, point2); } @@ -3149,6 +3142,10 @@ static void CG_UpdateCameraInfo (void) if (p1 && cpprevprev && cpprevprev->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[p1->splineStart], point0); + } else if (p1 && cpprevprev && cpprevprev->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(p1->cgtime, posBezier, point0); + } else if (p1 && cpprevprev && cpprevprev->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(p1->cgtime, posCatmullRom, point0); } else { VectorCopy(p1->origin, point0); } @@ -3159,6 +3156,10 @@ static void CG_UpdateCameraInfo (void) if (p3) { if (p3->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[p3->splineStart], point2); + } else if (p3->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(p3->cgtime, posBezier, point2); + } else if (p3->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(p3->cgtime, posCatmullRom, point2); } else { VectorCopy(p3->origin, point2); } @@ -3185,6 +3186,7 @@ static void CG_UpdateCameraInfo (void) } cp->originDistance = 0; + if (cp->type == CAMERA_SPLINE) { for (j = cp->splineStart; j < cpnext->splineStart; j++) { cp->originDistance += Distance(cg.splinePoints[j], cg.splinePoints[j + 1]); @@ -3210,6 +3212,76 @@ static void CG_UpdateCameraInfo (void) } else { cp->originImmediateFinalVelocity = 0; } + } else if (cp->type == CAMERA_SPLINE_BEZIER || cp->type == CAMERA_SPLINE_CATMULLROM) { + posInterpolate_t posType = posBezier; + double cameraTime; + double startTime, endTime; + vec3_t start, end; + double timeSlice; + int numSplines; + + if (cp->type == CAMERA_SPLINE_CATMULLROM) { + posType = posCatmullRom; + } + + cameraTime = cpnext->cgtime - cp->cgtime; + if (cameraTime <= 0.0) { + Com_Printf("^1invalid camera times found during spline calculation: %f -> %f\n", cp->cgtime, cpnext->cgtime); + return; + } + + //FIXME DEFAULT_NUM_SPLINES + numSplines = DEFAULT_NUM_SPLINES; + if (numSplines <= 1) { + Com_Printf("^1invalid number of splines %d\n", numSplines); + } + + timeSlice = cameraTime / numSplines; + + for (j = 0; j < numSplines - 1; j++) { + startTime = ((double)(j + 0) * timeSlice) + cp->cgtime; + endTime = ((double)(j + 1) * timeSlice) + cp->cgtime; + + CG_CameraSplineOriginAt(startTime, posType, start); + CG_CameraSplineOriginAt(endTime, posType, end); + + cp->originDistance += Distance(start, end); + } + + cp->originAvgVelocity = cp->originDistance / (cpnext->cgtime - cp->cgtime) * 1000.0; + + startTime = cp->cgtime; + endTime = ((double)(1) * timeSlice) + cp->cgtime; + CG_CameraSplineOriginAt(startTime, posType, start); + CG_CameraSplineOriginAt(endTime, posType, end); + + cp->originImmediateInitialVelocity = Distance(start, end) / (endTime - startTime) * 1000.0; + + if (cp->originAvgVelocity > 0.001) { + if (cp->useOriginVelocity) { + if (cp->originInitialVelocity > 2.0 * cp->originAvgVelocity) { + cp->originInitialVelocity = 2.0 * cp->originAvgVelocity; + } + cp->originFinalVelocity = 2.0 * cp->originDistance / ((cpnext->cgtime - cp->cgtime) / 1000.0) - cp->originInitialVelocity; + cp->originImmediateInitialVelocity *= (cp->originInitialVelocity / cp->originAvgVelocity); + } + } else { + cp->originImmediateInitialVelocity = 0; + } + + startTime = ((double)(numSplines - 1) * timeSlice) + cp->cgtime; + endTime = ((double)(numSplines - 0) * timeSlice) + cp->cgtime; + CG_CameraSplineOriginAt(startTime, posType, start); + CG_CameraSplineOriginAt(endTime, posType, end); + + cp->originImmediateFinalVelocity = Distance(start, end) / (endTime - startTime) * 1000.0; + if (cp->originAvgVelocity > 0.001) { + if (cp->useOriginVelocity) { + cp->originImmediateFinalVelocity *= (cp->originFinalVelocity / cp->originAvgVelocity); + } + } else { + cp->originImmediateFinalVelocity = 0; + } } else if (cp->type == CAMERA_CURVE) { //double dd; @@ -3290,7 +3362,7 @@ static void CG_UpdateCameraInfo (void) } Com_Printf("%f approx %f %f\n", cp->originDistance, Distance(cp->origin, cpnext->origin), dd); #endif - } else { + } else { // not camera curve, or spline type cp->originDistance = Distance(cp->origin, cpnext->origin); cp->originAvgVelocity = cp->originDistance / (cpnext->cgtime - cp->cgtime) * 1000.0; cp->originImmediateInitialVelocity = cp->originDistance / ((cpnext->cgtime - cp->cgtime) / 1000.0); @@ -3315,12 +3387,18 @@ static void CG_UpdateCameraInfo (void) } } - //cp->originAvgVelocity = cp->originDistance / (cpnext->cgtime - cp->cgtime) * 1000.0; //Com_Printf("cam %d vel %f i %f -> f %f\n", i, cp->originAvgVelocity, cp->originImmediateInitialVelocity, cp->originImmediateFinalVelocity); + // now camera angle velocities + // prelim values, pass is handled below - VectorCopy(cp->angles, a0); - VectorCopy(cpnext->angles, a1); + if (cp->viewType == CAMERA_ANGLES_SPLINE) { + CG_CameraSplineAnglesAt(cp->cgtime, a0); + CG_CameraSplineAnglesAt(cpnext->cgtime, a1); + } else { + VectorCopy(cp->angles, a0); + VectorCopy(cpnext->angles, a1); + } a0[ROLL] = 0; a1[ROLL] = 0; //AnglesSubtract(a1, a0, cp->anglesDistance); @@ -3499,8 +3577,38 @@ static void CG_UpdateCameraInfo (void) Com_Printf("fov pass info set for %d\n", j); } } + } else if (cp->fovType == CAMERA_FOV_SPLINE) { + float startFov, endFov; + + if (!CG_CameraSplineFovAt(cp->cgtime, &startFov)) { + startFov = cg_fov.value; + } + if (!CG_CameraSplineFovAt(cpnext->cgtime, &endFov)) { + endFov = cg_fov.value; + } + cp->fovDistance = fabs(startFov - endFov); + cp->fovAvgVelocity = dist / (cpnext->cgtime - cp->cgtime) * 1000.0; + + } // cp->fovType + } + + + // debugging +#if 0 + for (i = 0; i < cg.numCameraPoints; i++) { + Com_Printf("W %d: %f %f %f\n", i, cg.cameraPoints[i].origin[0], cg.cameraPoints[i].origin[1], cg.cameraPoints[i].origin[2]); + } + + { + int count = 0; + demoCameraPoint_t *p = demo.camera.points; + while (p) { + Com_Printf("Q %d: %f %f %f\n", count, p->origin[0], p->origin[1], p->origin[2]); + count++; + p = p->next; } } +#endif //FIXME not here trap_SendConsoleCommand("savecamera wolfcam-autosave\n"); @@ -3540,15 +3648,16 @@ static const char *EcamHelpDoc = "\n" "<...> are required\n" "[...] are optional\n" "\n" -"/ecam type \n" -"/ecam fov [fov value]\n" +"/ecam type \n" +"/ecam fov [fov value]\n" "/ecam command \n" "/ecam numsplines \n" -"/ecam angles \n" +"/ecam angles \n" " the 'ent' option has additional parameter for the entity\n" " /ecam angles ent [entity number]\n" "/ecam offset [x offset] [y offset] [z offset]\n" "/ecam roll [roll value]\n" +"/ecam flags [origin | angles | fov | time]\n" "/ecam initialVelocity \n" "/ecam finalVelocity \n" "/ecam rebase [origin | angles | dir | dirna | time | timen ] ...\n" @@ -4294,8 +4403,13 @@ static void CG_ChangeSelectedCameraPoints_f (void) cp->type = CAMERA_JUMP; } else if (!Q_stricmp(s, "curve")) { cp->type = CAMERA_CURVE; + } else if (!Q_stricmp(s, "splinebezier")) { + cp->type = CAMERA_SPLINE_BEZIER; + } else if (!Q_stricmp(s, "splinecatmullrom")) { + cp->type = CAMERA_SPLINE_CATMULLROM; } else { - cp->type = CAMERA_SPLINE; + Com_Printf("unknown camera type\n"); + //cp->type = CAMERA_SPLINE_BEZIER; } } else if (!Q_stricmp(s, "fov")) { s = CG_Argv(j + 1); @@ -4312,6 +4426,8 @@ static void CG_ChangeSelectedCameraPoints_f (void) cp->fovType = CAMERA_FOV_FIXED; } else if (!Q_stricmp(s, "pass")) { cp->fovType = CAMERA_FOV_PASS; + } else if (!Q_stricmp(s, "spline")) { + cp->fovType = CAMERA_FOV_SPLINE; } else { Com_Printf("unknown fov type\n"); return; @@ -4344,6 +4460,7 @@ static void CG_ChangeSelectedCameraPoints_f (void) } } else if (!Q_stricmp(s, "command")) { cp->command[0] = '\0'; + //FIXME can you use j++? j++; while (CG_Argv(j)[0]) { Q_strcat(cp->command, sizeof(cp->command), va("%s ", CG_Argv(j))); @@ -4398,6 +4515,8 @@ static void CG_ChangeSelectedCameraPoints_f (void) cp->viewType = CAMERA_ANGLES_INTERP; //} else if (!Q_stricmp(s, "snaptospline")) { // VectorCopy(cg.splinePoints[cp->splineStart], cp->origin); + } else if (!Q_stricmp(s, "spline")) { + cp->viewType = CAMERA_ANGLES_SPLINE; } else if (!Q_stricmp(s, "interpuseprevious")) { cp->viewType = CAMERA_ANGLES_INTERP_USE_PREVIOUS; } else if (!Q_stricmp(s, "fixed")) { @@ -4428,6 +4547,38 @@ static void CG_ChangeSelectedCameraPoints_f (void) if (*s) { cp->angles[ROLL] = atof(s); } + } else if (!Q_stricmp(s, "flags")) { + int k; + + for (k = 2; k < CG_Argc(); k++) { + if (!Q_stricmp(CG_Argv(k), "origin")) { + cp->flags ^= CAM_ORIGIN; + } else if (!Q_stricmp(CG_Argv(k), "angles")) { + cp->flags ^= CAM_ANGLES; + } else if (!Q_stricmp(CG_Argv(k), "fov")) { + cp->flags ^= CAM_FOV; + } else if (!Q_stricmp(CG_Argv(k), "time")) { + cp->flags ^= CAM_TIME; + } else { + Com_Printf("unknown flag type: '%s'\n", CG_Argv(k)); + } + } + + // print flag values + Com_Printf("[%d] flags: ", i); + if (cp->flags & CAM_ORIGIN) { + Com_Printf("origin "); + } + if (cp->flags & CAM_ANGLES) { + Com_Printf("angles "); + } + if (cp->flags & CAM_FOV) { + Com_Printf("fov "); + } + if (cp->flags & CAM_TIME) { + Com_Printf("time "); + } + Com_Printf("\n"); } else if (!Q_stricmp(s, "offset")) { j++; s = CG_Argv(j); @@ -5090,6 +5241,8 @@ static void CG_ChangeSelectedField_f (void) if (cp->rollType >= CAMERA_ROLL_ENUM_END) { cp->rollType = CAMERA_ROLL_INTERP; } + } else if (n == CEF_FLAGS) { + CG_ErrorPopup("use /ecam flags"); } else if (n == CEF_NUMBER_OF_SPLINES) { CG_ErrorPopup("use /ecam numsplines "); } else if (n == CEF_VIEWPOINT_ORIGIN) { @@ -7090,23 +7243,24 @@ static void CG_PlayQ3mmeCamera_f (void) return; } -#if 0 - if (cg.numCameraPoints < 2) { - Com_Printf("can't play camera, need at least 2 camera points\n"); + if (!demo.camera.points || !(demo.camera.points->next)) { + Com_Printf("can't play q3mme camera, need at least 2 camera points\n"); return; } -#endif - if (cg_cameraQue.integer) { + + //FIXME cameraque ? + if (1) { //(cg_cameraQue.integer) { extraTime = 1000.0 * cg_cameraRewindTime.value; if (extraTime < 0) { extraTime = 0; } - trap_SendConsoleCommand(va("seekservertime %f\n", cg.cameraPoints[0].cgtime - extraTime)); + trap_SendConsoleCommandNow(va("seekservertime %f\n", demo.camera.points->time - extraTime)); } - cg.cameraQ3mme = qtrue; - cg.cameraPlaying = qtrue; - cg.cameraPlayedLastFrame = qfalse; + cg.cameraQ3mmePlaying = qtrue; + cg.playQ3mmeCameraCommandIssued = qtrue; + //cg.cameraPlaying = qtrue; + ///cg.cameraPlayedLastFrame = qfalse; cg.currentCameraPoint = 0; //cg.cameraWaitToSync = qfalse; //FIXME stupid @@ -7114,6 +7268,98 @@ static void CG_PlayQ3mmeCamera_f (void) } +static void CG_StopQ3mmeCamera_f (void) +{ + cg.cameraQ3mmePlaying = qfalse; + cg.playQ3mmeCameraCommandIssued = qfalse; + Com_Printf("stopping q3mme camera\n"); +} + +static void CG_SaveQ3mmeCamera_f (void) +{ + fileHandle_t f; + int i; + const char *fname; + qboolean useDefaultFolder = qtrue; + + if (CG_Argc() < 2) { + Com_Printf("usage: saveq3mmecamera \n"); + return; + } + + if (!demo.camera.points) { + Com_Printf("need at least one camera points\n"); + return; + } + + fname = CG_Argv(1); + for (i = 0; i < strlen(fname); i++) { + if (fname[i] == '/') { + useDefaultFolder = qfalse; + break; + } + } + + if (useDefaultFolder) { + trap_FS_FOpenFile(va("cameras/%s.q3mmeCam", CG_Argv(1)), &f, FS_WRITE); + } else { + trap_FS_FOpenFile(va("%s.q3mmeCam", fname), &f, FS_WRITE); + } + + if (!f) { + Com_Printf("^1couldn't create %s.q3mmeCam\n", CG_Argv(1)); + return; + } + + CG_Q3mmeCameraSave(f); + trap_FS_FCloseFile(f); +} + +static void CG_LoadQ3mmeCamera_f (void) +{ + qboolean useDefaultFolder = qtrue; + const char *fname; + int i; + BG_XMLParse_t xmlParse; + char filename[MAX_OSPATH]; + BG_XMLParseBlock_t loadBlock[] = { + { "camera", CG_Q3mmeCameraParse, 0 }, + { 0, 0, 0 }, + }; + + if (CG_Argc() < 2) { + Com_Printf("usage: loadq3mmecamera \n"); + return; + } + + fname = CG_Argv(1); + for (i = 0; i < strlen(fname); i++) { + if (fname[i] == '/') { + useDefaultFolder = qfalse; + break; + } + } + + if (useDefaultFolder) { + //trap_FS_FOpenFile(va("cameras/%s.q3mmeCam", CG_Argv(1)), &f, FS_READ); + //ret = BG_XMLOpen(&xmlParse, va("cameras/%s.q3mmeCam", CG_Argv(1))); + Com_sprintf(filename, sizeof(filename), "cameras/%s.q3mmeCam", CG_Argv(1)); + } else { + //trap_FS_FOpenFile(va("%s.q3mmeCam", fname), &f, FS_READ); + Com_sprintf(filename, sizeof(filename), "%s.q3mmeCam", CG_Argv(1)); + } + + if (!BG_XMLOpen(&xmlParse, filename)) { + Com_Printf("^1couldn't open %s\n", CG_Argv(1)); + return; + } + + if (!BG_XMLParse(&xmlParse, 0, loadBlock, 0)) { + Com_Printf("^1Errors while loading q3mme camera\n"); + return; + } +} + typedef struct { const char *cmd; void (*function)(void); @@ -7296,9 +7542,13 @@ static consoleCommand_t commands[] = { { "printtime", CG_PrintTime_f }, { "killcountreset", CG_KillCountReset_f }, { "printentitydistance", CG_PrintEntityDistance_f }, + { "q3mmecamera", CG_Q3mmeDemoCameraCommand_f }, //{ "addq3mmecamerapoint", CG_AddQ3mmeCameraPoint_f }, - //{ "playq3mmecamera", CG_PlayQ3mmeCamera_f }, - //{ "q3mmecamera", CG_Q3mmeDemoCameraCommand_f }, + { "playq3mmecamera", CG_PlayQ3mmeCamera_f }, + { "stopq3mmecamera", CG_StopQ3mmeCamera_f }, + { "saveq3mmecamera", CG_SaveQ3mmeCamera_f }, + { "loadq3mmecamera", CG_LoadQ3mmeCamera_f }, + }; diff --git a/code/cgame/cg_draw.c b/code/cgame/cg_draw.c index 6dbe078c..15dcf677 100644 --- a/code/cgame/cg_draw.c +++ b/code/cgame/cg_draw.c @@ -15,6 +15,7 @@ #include "cg_main.h" #include "cg_players.h" // color from string #include "cg_predict.h" +#include "cg_q3mme_camera.h" #include "cg_scoreboard.h" #include "cg_sound.h" #include "cg_syscalls.h" @@ -43,13 +44,6 @@ char systemChat[256]; char teamChat1[256]; char teamChat2[256]; -/* -//FIXME hack for ql widescreen -//FIXME needed? -static int QLWideScreenOrig = 0; -#define saveWidescreen(x) QLWideScreen = x -#define resetWidescreen() QLWideScreen = QLWideScreenOrig -*/ //FIXME move #define MAX_HUD_ITEMS 100 @@ -141,8 +135,8 @@ static void CG_DrawCameraPointInfo (void) return; } - QLWideScreen = 1; - + QLWideScreen = WIDESCREEN_LEFT; + align = cg_drawCameraPointInfoAlign.integer; scale = cg_drawCameraPointInfoScale.value; style = cg_drawCameraPointInfoStyle.integer; @@ -206,6 +200,7 @@ static void CG_DrawCameraPointInfo (void) if (cpprev && cg.selectedCameraPointMin != (cg.numCameraPoints - 1)) { double a1, a2; + //FIXME does this apply to spline origins? //if ((cp->originAvgVelocity * 2.0) > cpprev->originAvgVelocity) { if ((cp->originImmediateInitialVelocity * cg_cameraSmoothFactor.value) < cpprev->originImmediateFinalVelocity) { badOrigin = qtrue; @@ -228,14 +223,14 @@ static void CG_DrawCameraPointInfo (void) } } - if (badOrigin) { + if (badOrigin && (cp->type != CAMERA_SPLINE_BEZIER || cp->type != CAMERA_SPLINE_CATMULLROM)) { s = va("origin: %d %d %d ^1(not smooth)", (int)cp->origin[0], (int)cp->origin[1], (int)cp->origin[2]); } else { s = va("origin: %d %d %d", (int)cp->origin[0], (int)cp->origin[1], (int)cp->origin[2]); } CG_SPrint(s); - if (badAngles) { + if (badAngles && (cp->viewType != CAMERA_ANGLES_SPLINE)) { s = va("angles: %d %d %d ^1(not smooth)", (int)cp->angles[0], (int)cp->angles[1], (int)cp->angles[2]); } else { s = va("angles: %d %d %d", (int)cp->angles[0], (int)cp->angles[1], (int)cp->angles[2]); @@ -250,6 +245,10 @@ static void CG_DrawCameraPointInfo (void) s = va("camera type: jump"); } else if (cp->type == CAMERA_CURVE) { s = va("camera type: curve"); + } else if (cp->type == CAMERA_SPLINE_BEZIER) { + s = va("camera type: splineBezier"); + } else if (cp->type == CAMERA_SPLINE_CATMULLROM) { + s = va("camera type: splineCatmullRom"); } else { s = va("camera type: ???"); } @@ -257,6 +256,8 @@ static void CG_DrawCameraPointInfo (void) if (cp->viewType == CAMERA_ANGLES_INTERP) { s = va("angles type: interp"); + } else if (cp->viewType == CAMERA_ANGLES_SPLINE) { + s = va("angles type: spline"); } else if (cp->viewType == CAMERA_ANGLES_ENT) { s = va("angles type: view entity"); } else if (cp->viewType == CAMERA_ANGLES_VIEWPOINT_INTERP) { @@ -276,6 +277,7 @@ static void CG_DrawCameraPointInfo (void) } CG_SPrint(s); + //FIXME show disable for angles type spline if (cp->rollType == CAMERA_ROLL_INTERP) { s = va("camera roll: interp"); } else if (cp->rollType == CAMERA_ROLL_FIXED) { @@ -286,6 +288,10 @@ static void CG_DrawCameraPointInfo (void) s = va("camera roll: ???"); } CG_SPrint(s); + + // flags + CG_SPrint(va("flags: %s%s%s%s", cp->flags & CAM_ORIGIN ? "origin " : "", cp->flags & CAM_ANGLES ? "angles " : "", cp->flags & CAM_FOV ? "fov " : "", cp->flags & CAM_TIME ? "time " : "")); + CG_SPrint(va("number of splines: %d", cp->numSplines)); CG_SPrint(va("view point: %d %d %d", (int)cp->viewPointOrigin[0], (int)cp->viewPointOrigin[1], (int)cp->viewPointOrigin[2])); @@ -321,6 +327,8 @@ static void CG_DrawCameraPointInfo (void) CG_SPrint("fov type: fixed"); } else if (cp->fovType == CAMERA_FOV_PASS) { CG_SPrint("fov type: pass"); + } else if (cp->fovType == CAMERA_FOV_SPLINE) { + CG_SPrint("fov type: spline"); } else { CG_SPrint("fov type: ???"); } @@ -2467,7 +2475,7 @@ static void CG_DrawStatusBar( void ) { if ( cg_drawStatus.integer == 0 ) { return; } - QLWideScreen = 2; + QLWideScreen = WIDESCREEN_CENTER; // draw the team background if (wolfcam_following) { @@ -3486,7 +3494,7 @@ static void CG_DrawClientItemTimer (void) static void CG_DrawFxDebugEntities (void) { - QLWideScreen = 1; + QLWideScreen = WIDESCREEN_LEFT; CG_DrawSmallString(5, 480 - 70, va("local entities: %d", cg.numLocalEntities), 6.0); } @@ -3595,7 +3603,7 @@ static float CG_DrawTimer( float y ) { s = va( "%i:%i%i", mins, tens, seconds ); } - QLWideScreen = 3; + QLWideScreen = WIDESCREEN_RIGHT; w = CG_DrawStrlen( s, &cgs.media.bigchar ); CG_DrawBigString( 635 - w, y + 2, s, 1.0F); @@ -4103,7 +4111,7 @@ static float CG_DrawTeamOverlay (float y, qboolean right, qboolean upper) item = BG_FindItemForPowerup( j ); // 2010-08-08 new ql, spawn protectin powerup - if (item && !(ci->powerups & PW_SPAWNPROTECTION)) { + if (item && !(ci->powerups & PWEX_SPAWNPROTECTION)) { //CG_DrawPic( xx, y, TINYCHAR_WIDTH, TINYCHAR_HEIGHT, trap_R_RegisterShader( item->icon ) ); CG_DrawPic( xx, y - cwidth / 1, cwidth, cheight, trap_R_RegisterShader( item->icon ) ); if (right) { @@ -4205,7 +4213,7 @@ static float CG_DrawPlayersLeft( float y ) { return y; } - QLWideScreen = 3; + QLWideScreen = WIDESCREEN_RIGHT; s1 = cgs.redPlayersLeft; //cgs.scores1; s2 = cgs.bluePlayersLeft; //cgs.scores2; @@ -4383,7 +4391,7 @@ static float CG_DrawScores( float y ) { return y; } - QLWideScreen = 3; + QLWideScreen = WIDESCREEN_RIGHT; if (wolfcam_following) { ourTeam = cgs.clientinfo[wcg.clientNum].team; @@ -4595,7 +4603,7 @@ static float CG_DrawPowerups( float y ) { return y; } - QLWideScreen = 3; + QLWideScreen = WIDESCREEN_RIGHT; ps = &cg.snap->ps; //ci = &cgs.clientinfo[ps->clientNum]; @@ -4638,7 +4646,7 @@ static float CG_DrawPowerups( float y ) { item = BG_FindItemForPowerup( sorted[i] ); // item 0 is ql spawn protection - if (item && sorted[i] != 0) { //!(ci->powerups & PW_SPAWNPROTECTION)) { + if (item && sorted[i] != 0) { //!(ci->powerups & PWEX_SPAWNPROTECTION)) { color = 1; @@ -4956,7 +4964,7 @@ static void CG_DrawTeamInfo( void ) { #define CHATLOC_Y 420 // bottom end #define CHATLOC_X 0 - QLWideScreen = 1; + QLWideScreen = WIDESCREEN_LEFT; if (cg_teamChatHeight.integer < TEAMCHAT_HEIGHT) chatHeight = cg_teamChatHeight.integer; @@ -5030,7 +5038,7 @@ static void CG_DrawHoldableItem( void ) { return; } - QLWideScreen = 3; + QLWideScreen = WIDESCREEN_RIGHT; value = cg.snap->ps.stats[STAT_HOLDABLE_ITEM]; if ( value ) { @@ -5051,7 +5059,7 @@ CG_DrawPersistantPowerup static void CG_DrawPersistantPowerup( void ) { int value; - QLWideScreen = 3; + QLWideScreen = WIDESCREEN_RIGHT; value = cg.snap->ps.stats[STAT_PERSISTANT_POWERUP]; if ( value ) { @@ -5483,7 +5491,7 @@ static void CG_DrawDisconnect( void ) { // also add text in center of screen s = "Connection Interrupted"; // bk 010215 - FIXME - QLWideScreen = 2; + QLWideScreen = WIDESCREEN_CENTER; w = CG_DrawStrlen( s, &cgs.media.bigchar ); CG_DrawBigString( 320 - w/2, 100, s, 1.0F); @@ -7097,7 +7105,7 @@ static void Wolfcam_DrawCrosshair (void) y = cg_crosshairY.integer; //QLWideScreen = cg_crosshairWideScreen.integer; //FIXME change? - QLWideScreen = 0; + QLWideScreen = WIDESCREEN_NONE; CG_AdjustFrom640( &x, &y, &w, &h ); @@ -7377,7 +7385,7 @@ static void CG_DrawCrosshair(void) { y = cg_crosshairY.integer; //QLWideScreen = cg_crosshairWideScreen.integer; //FIXME change? - QLWideScreen = 0; + QLWideScreen = WIDESCREEN_NONE; CG_AdjustFrom640( &x, &y, &w, &h ); @@ -7813,7 +7821,7 @@ static void CG_DrawKeyPress (void) } //FIXME widescreen - QLWideScreen = 2; + QLWideScreen = WIDESCREEN_CENTER; //VectorCopy(cg.snap->ps.velocity, velocity); VectorCopy(cg.prevSnap->ps.velocity, velocity); @@ -7943,7 +7951,7 @@ static void CG_DrawSpectator(void) { return; } - QLWideScreen = 2; + QLWideScreen = WIDESCREEN_CENTER; CG_DrawBigString(320 - 9 * 8, 440, "SPECTATOR", 1.0F); if ( cgs.gametype == GT_TOURNAMENT ) { @@ -8359,11 +8367,28 @@ static void CG_DrawScoreboardMenuCursor (void) float x = cgs.cursorX - 16; float y = cgs.cursorY - 16; - // widescreen needs to match the setting in the scoreboard huds - //FIXME can this be handled in ui/* ? - QLWideScreen = cg_scoreBoardCursorAreaWideScreen.integer; + QLWideScreen = WIDESCREEN_NONE; //cg_scoreBoardCursorAreaWideScreen.integer; + // don't stretch the cursor in widescreen mode + if (cg_wideScreen.integer == 5) { + float aspect; + float width43; + float newXScale; + + //FIXME duplicate code + //FIXME store calculations + aspect = (float)cgs.glconfig.vidWidth / (float)cgs.glconfig.vidHeight; + if (aspect > 1.25f) { + width43 = 4.0f * (cgs.glconfig.vidHeight / 3.0); + newXScale = width43 / (float)cgs.glconfig.vidWidth; + w *= newXScale; + } + } CG_DrawPic(x, y, w, h, cgs.media.selectCursor); + + // testing + //QLWideScreen = WIDESCREEN_CENTER; + //CG_DrawPic(x, y, w, h, cgs.media.plasmaBallShader); } /* @@ -9043,7 +9068,7 @@ static void CG_DrawErrorPopup (void) //FIXME cvars to control - QLWideScreen = 1; + QLWideScreen = WIDESCREEN_LEFT; scale = 0.3; //cg.echoPopupScale; x = 0; //cg.echoPopupX; @@ -9266,7 +9291,7 @@ static void CG_DrawCtfsRoundScoreboard (void) //align = ITEM_ALIGN_CENTER; style = ITEM_TEXTSTYLE_SHADOWED; - QLWideScreen = 2; + QLWideScreen = WIDESCREEN_CENTER; x = 200; y = 152 + 20; @@ -9381,7 +9406,7 @@ static void CG_Draw2D( void ) { } if (cg.testMenu) { - QLWideScreen = 2; + QLWideScreen = WIDESCREEN_CENTER; Menu_Paint(cg.testMenu, qtrue); CG_DrawPic(cgs.cursorX - 16, cgs.cursorY - 16, 32, 32, cgs.media.selectCursor); return; @@ -9402,8 +9427,32 @@ static void CG_Draw2D( void ) { } if (cg_draw2D.integer == 2) { - QLWideScreen = 1; - CG_Text_Paint(2, 16, 0.2, colorRed, "Camera Edit Hud (cg_draw2d 1 to disable)", 0, 0, 1, &cgs.media.qlfont16); + QLWideScreen = WIDESCREEN_LEFT; + CG_Text_Paint(2, 16, 0.2, colorRed, "Camera Edit Hud (set cg_draw2d 1 to disable)", 0, 0, 1, &cgs.media.qlfont16); + + + if (cg.numCameraPoints > 0) { + if (cg.cameraPlaying) { + CG_Text_Paint(2, 32, 0.2, colorWhite, "^5Camera view is ^3locked ^5(camera is playing, use /stopcamera to allow changing origin and angles)", 0, 0, 1, &cgs.media.qlfont16); + } else { + if (cg_cameraQue.integer) { + CG_Text_Paint(2, 32, 0.2, colorWhite, "^5Camera view is ^3locked ^5(set cg_cameraQue 0 to allow changing origin and angles)", 0, 0, 1, &cgs.media.qlfont16); + } else { + CG_Text_Paint(2, 32, 0.2, colorWhite, "^5Camera view is ^7unlocked ^5(set cg_cameraQue 1 to lock and follow camera view)", 0, 0, 1, &cgs.media.qlfont16); + } + } + } else if (demo.camera.points) { + // q3mme camera points present + if (cg.cameraQ3mmePlaying) { + CG_Text_Paint(2, 32, 0.2, colorWhite, "^6Q3mme Camera view is ^3locked ^6(camera is playing, use /stopq3mmecamera to allow changing origin and angles)", 0, 0, 1, &cgs.media.qlfont16); + } else { + if (cg_cameraQue.integer) { + CG_Text_Paint(2, 32, 0.2, colorWhite, "^6Q3mme Camera view is ^3locked ^6(set cg_cameraQue 0 to allow changing origin and angles)", 0, 0, 1, &cgs.media.qlfont16); + } else { + CG_Text_Paint(2, 32, 0.2, colorWhite, "^6Q3mme Camera view is ^7unlocked ^6(set cg_cameraQue 1 to lock and follow camera view)", 0, 0, 1, &cgs.media.qlfont16); + } + } + } CG_DrawFPS(10.0); Wolfcam_DrawSpeed(30.0); @@ -9636,7 +9685,7 @@ static void CG_Draw2D( void ) { char buf[1024]; Q_strncpyz(buf, "01234567890abcdefghijklmnop\nqrstuvwxyzABCDEFGHIJKLMN\nOPQRSTUVWXYZ\n~!@#$%^&*()_-+=\\]}[{'\";:/?.>,<\n", sizeof(buf)); - QLWideScreen = 2; + QLWideScreen = WIDESCREEN_CENTER; //FIXME testing CG_CenterPrint( buf, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); //CG_CenterPrint("qrstuvwxyzABCDEFGHIJK", SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH); diff --git a/code/cgame/cg_drawtools.c b/code/cgame/cg_drawtools.c index 91278156..7e876c5c 100644 --- a/code/cgame/cg_drawtools.c +++ b/code/cgame/cg_drawtools.c @@ -37,13 +37,11 @@ CG_AdjustFrom640 Adjusted for resolution and screen aspect ratio ================ */ -void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) { +void CG_AdjustFrom640 (float *x, float *y, float *w, float *h) +{ float aspect; qboolean square = qfalse; - float origWidth = *w; - float origX = *x; - if (*w == *h) { square = qtrue; } @@ -57,9 +55,11 @@ void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) { // ql widescreen if (cg_wideScreen.integer == 5) { - if (MenuWidescreen != QLWideScreen && QLWideScreen != 0) { - //Com_Printf("^3m %d i %d\n", MenuWidescreen, QLWideScreen); - } + float width43; + float diff; + float newXScale; + rectDef_t menuRect; + if ((float)cgs.glconfig.vidWidth / (float)cgs.glconfig.vidHeight < 1.25f) { // stretched vertically, just use original scaling @@ -71,131 +71,65 @@ void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) { return; } - - if (1) { //(MenuWidescreen || QLWideScreen) { - //FIXME duplicate code - float width43; - float diff; - float newXScale; - rectDef_t menuRect; - float newX = 0; - - menuRect = MenuRect; - menuRect.x *= cgs.screenXScale; - menuRect.y *= cgs.screenYScale; - menuRect.w *= cgs.screenXScale; - menuRect.h *= cgs.screenYScale; + //FIXME duplicate code + menuRect = MenuRect; + menuRect.x *= cgs.screenXScale; + menuRect.y *= cgs.screenYScale; + menuRect.w *= cgs.screenXScale; + menuRect.h *= cgs.screenYScale; - width43 = 4.0 * (cgs.glconfig.vidHeight / 3.0); - diff = (float)cgs.glconfig.vidWidth - width43; + width43 = 4.0 * (cgs.glconfig.vidHeight / 3.0); + diff = (float)cgs.glconfig.vidWidth - width43; - newXScale = width43 / 640.0; + newXScale = width43 / 640.0; + if (QLWideScreen == WIDESCREEN_NONE) { + //FIXME - //*x *= newXScale; - - - - //FIXME - if (QLWideScreen == 0) { - //FIXME + if (MenuWidescreen) { + Com_Printf("^3FIXME ql QLWideScreen 0 menu %d\n", MenuWidescreen); + } + //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 1, 0, 0, 0.1); + *x *= cgs.screenXScale; + *y *= cgs.screenYScale; + *w *= cgs.screenXScale; + *h *= cgs.screenYScale; - if (MenuWidescreen) { - Com_Printf("^3FIXME ql QLWideScreen 0 menu %d\n", MenuWidescreen); - } - //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 1, 0, 0, 0.1); - *x *= cgs.screenXScale; - *y *= cgs.screenYScale; - *w *= cgs.screenXScale; - *h *= cgs.screenYScale; - - } else if (QLWideScreen == 1) { - //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 0, 0, 1, 0.1); - //*x *= cgs.screenXScale; - //*x = menuRect.x; - - //*x = 0; //FIXME testing - - *y *= cgs.screenYScale; - *w *= newXScale; - *h *= cgs.screenYScale; - - - *x *= newXScale; - } else if (QLWideScreen == 2) { - rectDef_t itemRect; - - //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 0, 1, 0, 0.1); - - *y *= cgs.screenYScale; - *w *= newXScale; - *h *= cgs.screenYScale; - - - itemRect.x = *x - MenuRect.x; - //FIXME - //*x = 0; - //*x = 40; - - //*x = (menuRect.x + (menuRect.w / 2) - (*w / 2)); - - //*x += itemRect.x * cgs.screenXScale / 2; - //*x += itemRect.x * newXScale / 2; - //*x += itemRect.x; - //*x = 0; - //*x = menuRect.x; - //*y += 30; - //*x *= cgs.screenXScale; - - //diff = (origWidth * cgs.screenXScale) - (origWidth * newXScale); - ////*x *= cgs.screenXScale; - - /* this is it */ - *x *= newXScale; - *x += diff / 2; - - //*x += diff / 2; - //*x += diff; - - if (origX <= 320) { - //*x += diff; - - } else { - //*x -= diff; - } - - } else if (QLWideScreen == 3) { - //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 1, 0.5, 0.8, 0.1); + } else if (QLWideScreen == WIDESCREEN_LEFT) { + //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 0, 0, 1, 0.1); + *y *= cgs.screenYScale; + *w *= newXScale; + *h *= cgs.screenYScale; - *y *= cgs.screenYScale; - *w *= newXScale; - *h *= cgs.screenYScale; + *x *= newXScale; + } else if (QLWideScreen == WIDESCREEN_CENTER) { + //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 0, 1, 0, 0.1); - //*x += (diff / 2.0); - //*x = 6666; - //*x = (menuRect.x + menuRect.w) - *w; + *y *= cgs.screenYScale; + *w *= newXScale; + *h *= cgs.screenYScale; - //*x = 0; //FIXME testing - - *x *= newXScale; - *x += diff; + *x *= newXScale; + *x += diff / 2; - } else { - *x *= cgs.screenXScale; - *y *= cgs.screenYScale; - *w *= cgs.screenXScale; - *h *= cgs.screenYScale; + } else if (QLWideScreen == WIDESCREEN_RIGHT) { + //debug_rect(menuRect.x, menuRect.y, menuRect.w, menuRect.h, qfalse, 1, 0.5, 0.8, 0.1); - Com_Printf("^3invalid widescreen value: %d\n", QLWideScreen); - } + *y *= cgs.screenYScale; + *w *= newXScale; + *h *= cgs.screenYScale; + *x *= newXScale; + *x += diff; } else { *x *= cgs.screenXScale; *y *= cgs.screenYScale; *w *= cgs.screenXScale; *h *= cgs.screenYScale; + + Com_Printf("^3invalid widescreen value: %d\n", QLWideScreen); } return; @@ -211,8 +145,6 @@ void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) { } #endif - // scale for screen sizes - if (cg.scoreBoardShowing) { //Com_Printf("scoreboard\n"); if (cg_wideScreenScoreBoardHack.integer == 1) { @@ -226,8 +158,6 @@ void CG_AdjustFrom640( float *x, float *y, float *w, float *h ) { newXScale = width43 / 640.0; - //*x += (diff / 2.0); - *x *= newXScale; *y *= cgs.screenYScale; *w *= newXScale; diff --git a/code/cgame/cg_effects.c b/code/cgame/cg_effects.c index 5b825eaa..fc81827b 100644 --- a/code/cgame/cg_effects.c +++ b/code/cgame/cg_effects.c @@ -654,7 +654,7 @@ void CG_ImpactSparks( int weapon, const vec3_t origin, const vec3_t dir, int ent //Com_Printf("imp %d\n", entityNum); //FIXME hack for 2010-08-08 new ql spawn invuln - if (cg_entities[entityNum].currentState.powerups & PW_SPAWNPROTECTION) { + if (cg_entities[entityNum].currentState.powerups & PWEX_SPAWNPROTECTION) { //Com_Printf("invul %d %s\n", entityNum, cgs.clientinfo[entityNum].name); //CG_PlayerFloatSprite(&cg_entities[entityNum], cgs.media.connectionShader); if (entityNum >= 0 && entityNum < MAX_CLIENTS) { diff --git a/code/cgame/cg_ents.c b/code/cgame/cg_ents.c index e74df1d1..79cc3c31 100644 --- a/code/cgame/cg_ents.c +++ b/code/cgame/cg_ents.c @@ -1467,37 +1467,28 @@ static void CG_DrawPowerupAvailable (const centity_t *cent) ent.renderfx |= RF_DEPTHHACK; - switch (item->giTag) { - case PW_QUAD: + if (item->giTag == PW_QUAD) { shader = cgs.media.quadAvailable; - break; - case PW_BATTLESUIT: + } else if (item->giTag == PW_BATTLESUIT) { shader = cgs.media.bsAvailable; - break; - case PW_HASTE: + } else if (item->giTag == PW_HASTE) { shader = cgs.media.hasteAvailable; - break; - case PW_INVIS: + } else if (item->giTag == PW_INVIS) { shader = cgs.media.invisAvailable; - break; - case PW_REGEN: + } else if (item->giTag == PW_REGEN) { shader = cgs.media.regenAvailable; - break; - case PW_FLIGHT: + } else if (item->giTag == PW_FLIGHT) { //FIXME not in ql, draw something // 2015-07-16 no, looks bad in demos, will make it look like // the powerup is right in front of you, draw own icon or skip //shader = cg_items[es->modelindex].icon; return; - break; - - default: + } else { // icon shader looks bad //shader = cg_items[es->modelindex].icon; return; - break; } ent.customShader = shader; diff --git a/code/cgame/cg_event.c b/code/cgame/cg_event.c index 743012a9..dbc82613 100644 --- a/code/cgame/cg_event.c +++ b/code/cgame/cg_event.c @@ -1004,23 +1004,28 @@ Returns waterlevel for entity origin static int CG_WaterLevel(const centity_t *cent) { vec3_t point; int contents, sample1, sample2, anim, waterlevel; + int viewheight; - // get waterlevel, accounting for ducking - waterlevel = 0; - VectorCopy(cent->lerpOrigin, point); - point[2] += MINS_Z + 1; anim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT; if (anim == LEGS_WALKCR || anim == LEGS_IDLECR) { - point[2] += CROUCH_VIEWHEIGHT; + viewheight = CROUCH_VIEWHEIGHT; } else { - point[2] += DEFAULT_VIEWHEIGHT; + viewheight = DEFAULT_VIEWHEIGHT; } + // + // get waterlevel, accounting for ducking + // + waterlevel = 0; + + point[0] = cent->lerpOrigin[0]; + point[1] = cent->lerpOrigin[1]; + point[2] = cent->lerpOrigin[2] + MINS_Z + 1; contents = CG_PointContents(point, -1); if (contents & MASK_WATER) { - sample2 = point[2] - MINS_Z; + sample2 = viewheight - MINS_Z; sample1 = sample2 / 2; waterlevel = 1; point[2] = cent->lerpOrigin[2] + MINS_Z + sample1; @@ -1080,7 +1085,7 @@ void CG_PainEvent( centity_t *cent, int health ) { } // play a gurp sound instead of a normal pain sound - if (0) { //(CG_WaterLevel(cent) >= 1) { + if (0) { //(CG_WaterLevel(cent) == 3) { if (rand()&1) { CG_StartSound(NULL, cent->currentState.number, CHAN_VOICE, CG_CustomSound(cent->currentState.number, "sound/player/gurp1.wav")); } else { @@ -1831,35 +1836,25 @@ void CG_EntityEvent( centity_t *cent, const vec3_t position ) { play = qfalse; } -#if 1 //def MPACK - switch (item->giTag ) { - case PW_SCOUT: + if (item->giTag == PW_SCOUT) { if (play) { CG_StartSound (NULL, clientNum, CHAN_ANNOUNCER, cgs.media.scoutSound ); } - break; - case PW_GUARD: + } else if (item->giTag == PW_GUARD) { if (play) { CG_StartSound (NULL, clientNum, CHAN_ANNOUNCER, cgs.media.guardSound ); } - break; - case PW_DOUBLER: + } else if (item->giTag == PW_DOUBLER) { if (play) { CG_StartSound (NULL, clientNum, CHAN_ANNOUNCER, cgs.media.doublerSound ); } - break; - case PW_ARMORREGEN: + } else if (item->giTag == PW_ARMORREGEN) { if (play) { CG_StartSound (NULL, clientNum, CHAN_ANNOUNCER, cgs.media.armorRegenSound ); } - break; - case PW_KEY: + } else if (item->giTag == PWEX_KEY) { CG_StartSound(NULL, clientNum, CHAN_AUTO, trap_S_RegisterSound(item->pickup_sound, qfalse)); - break; - default: - break; } -#endif } else { CG_StartSound (NULL, clientNum, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); } @@ -3239,7 +3234,7 @@ void CG_EntityEvent( centity_t *cent, const vec3_t position ) { //CG_PrintEntityStatep(es); - if (cgs.protocol == PROTOCOL_Q3 && CG_WaterLevel(&cg_entities[clientNum])) { + if (cgs.protocol == PROTOCOL_Q3 && CG_WaterLevel(&cg_entities[clientNum]) == 3) { CG_StartSound(NULL, clientNum, CHAN_VOICE, CG_CustomSound(clientNum, "*drown.wav")); } else { CG_StartSound( NULL, clientNum, CHAN_VOICE, diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h index 183057e1..c29c54c2 100644 --- a/code/cgame/cg_local.h +++ b/code/cgame/cg_local.h @@ -1352,25 +1352,27 @@ typedef struct { //cameraPathKeyPoint_t cameraPoints[MAX_CAMERAPOINTS]; cameraPoint_t cameraPoints[MAX_CAMERAPOINTS]; + cameraPoint_t *cameraPointsPointer; vec3_t splinePoints[MAX_SPLINEPOINTS]; int splinePointsCameraPoints[MAX_SPLINEPOINTS]; int numSplinePoints; int numCameraPoints; - int numQ3mmeCameraPoints; + int numQ3mmeCameraPoints; int selectedCameraPointMin; int selectedCameraPointMax; int selectedCameraPointField; qboolean cameraPlaying; - qboolean cameraQ3mme; + qboolean cameraQ3mmePlaying; qboolean cameraPlayedLastFrame; int currentCameraPoint; qboolean atCameraPoint; qboolean cameraWaitToSync; qboolean cameraJustStarted; qboolean playCameraCommandIssued; + qboolean playQ3mmeCameraCommandIssued; double cameraPointCommandTime; vec3_t cameraLastOrigin; vec3_t cameraVelocity; @@ -2905,7 +2907,7 @@ extern vmCvar_t cg_scoreBoardAtIntermission; extern vmCvar_t cg_scoreBoardWarmup; extern vmCvar_t cg_scoreBoardOld; extern vmCvar_t cg_scoreBoardOldWideScreen; -extern vmCvar_t cg_scoreBoardCursorAreaWideScreen; +//extern vmCvar_t cg_scoreBoardCursorAreaWideScreen; extern vmCvar_t cg_hitBeep; diff --git a/code/cgame/cg_localents.c b/code/cgame/cg_localents.c index 6ede500f..00a87c97 100644 --- a/code/cgame/cg_localents.c +++ b/code/cgame/cg_localents.c @@ -1530,7 +1530,9 @@ static void CG_AddDamagePlum (localEntity_t *le) { refEntity_t *re; vec3_t origin, ourOrig, ourViewAngles, dir; - vec3_t forward, right, up = {0, 0, 1}; + //vec3_t forward; + vec3_t right; + //vec3_t up = {0, 0, 1}; float c; int i, score, digits[10], numdigits, negative; trajectory_t trajectory; @@ -2093,7 +2095,7 @@ static void CG_Add_FX_Emitted (localEntity_t *le) float newZ; float sinkTime; vec3_t mins, maxs; - int i; + //int i; #if 0 // force // add external forces @@ -2220,7 +2222,7 @@ static void CG_Add_FX_Emitted (localEntity_t *le) } else if (ScriptVars.hasMoveBounce || ScriptVars.hasMoveGravity) { vec3_t oldVelocity; - int i; + //int i; #if 0 // force // add external forces diff --git a/code/cgame/cg_main.c b/code/cgame/cg_main.c index dfd42c1b..df435dd6 100644 --- a/code/cgame/cg_main.c +++ b/code/cgame/cg_main.c @@ -13,6 +13,7 @@ #include "cg_marks.h" #include "cg_newdraw.h" #include "cg_players.h" +#include "cg_q3mme_camera.h" #include "cg_q3mme_scripts.h" #include "cg_servercmds.h" #include "cg_snapshot.h" @@ -645,7 +646,7 @@ vmCvar_t cg_scoreBoardAtIntermission; vmCvar_t cg_scoreBoardWarmup; vmCvar_t cg_scoreBoardOld; vmCvar_t cg_scoreBoardOldWideScreen; -vmCvar_t cg_scoreBoardCursorAreaWideScreen; +//vmCvar_t cg_scoreBoardCursorAreaWideScreen; vmCvar_t cg_hitBeep; @@ -1676,7 +1677,7 @@ static cvarTable_t cvarTable[] = { // bk001129 { &cg_scoreBoardWarmup, "cg_scoreBoardWarmup", "1", CVAR_ARCHIVE }, { &cg_scoreBoardOld, "cg_scoreBoardOld", "0", CVAR_ARCHIVE }, { cvp(cg_scoreBoardOld), "2", CVAR_ARCHIVE }, - { cvp(cg_scoreBoardCursorAreaWideScreen), "2", CVAR_ARCHIVE }, + //{ cvp(cg_scoreBoardCursorAreaWideScreen), "2", CVAR_ARCHIVE }, { &cg_hitBeep, "cg_hitBeep", "2", CVAR_ARCHIVE }, @@ -2037,7 +2038,7 @@ static cvarTable_t cvarTable[] = { // bk001129 { &cg_cameraQue, "cg_cameraQue", "1", CVAR_ARCHIVE }, { &cg_cameraUpdateFreeCam, "cg_cameraUpdateFreeCam", "1", CVAR_ARCHIVE }, { &cg_cameraAddUsePreviousValues, "cg_cameraAddUsePreviousValues", "1", CVAR_ARCHIVE }, - { &cg_cameraDefaultOriginType, "cg_cameraDefaultOriginType", "curve", CVAR_ARCHIVE }, + { &cg_cameraDefaultOriginType, "cg_cameraDefaultOriginType", "splineBezier", CVAR_ARCHIVE }, { &cg_cameraDebugPath, "cg_cameraDebugPath", "0", CVAR_ARCHIVE }, { &cg_cameraSmoothFactor, "cg_cameraSmoothFactor", "1.5", CVAR_ARCHIVE }, { cvp(cg_q3mmeCameraSmoothPos), "0", CVAR_ARCHIVE }, @@ -6988,6 +6989,27 @@ static void CG_Init (int serverMessageNum, int serverCommandSequence, int client //Com_Printf("^3ctfs %d\n", GT_CTFS); + if (cgs.realProtocol == 91) { + PW_NONE = PW91_NONE; + //PW_SPAWNARMOR = PW91_SPAWNARMOR; + PW_QUAD = PW91_QUAD; + PW_BATTLESUIT = PW91_BATTLESUIT; + PW_HASTE = PW91_HASTE; + PW_INVIS = PW91_INVIS; + PW_REGEN = PW91_REGEN; + PW_FLIGHT = PW91_FLIGHT; + PW_REDFLAG = PW91_REDFLAG; + PW_BLUEFLAG = PW91_BLUEFLAG; + PW_NEUTRALFLAG = PW91_NEUTRALFLAG; + PW_INVULNERABILITY = PW91_INVULNERABILITY; + PW_SCOUT = PW91_SCOUT; + PW_GUARD = PW91_GUARD; + PW_DOUBLER = PW91_DOUBLER; + PW_ARMORREGEN = PW91_ARMORREGEN; + PW_FROZEN = PW91_FROZEN; + PW_NUM_POWERUPS = PW91_NUM_POWERUPS; + } + if (cgs.protocol == PROTOCOL_Q3) { //FIXME hack // start as baseq3 memcpy(&bg_itemlist, &bg_itemlistQ3, sizeof(gitem_t) * bg_numItemsQ3); @@ -7109,7 +7131,8 @@ static void CG_Init (int serverMessageNum, int serverCommandSequence, int client trap_GetGlconfig( &cgs.glconfig ); cgs.screenXScale = cgs.glconfig.vidWidth / 640.0; cgs.screenYScale = cgs.glconfig.vidHeight / 480.0; - + memcpy(&cgDC.glconfig, &cgs.glconfig, sizeof(glconfig_t)); + cgDC.widescreen = cg_wideScreen.integer; trap_SendConsoleCommandNow("exec cgameinit.cfg\n"); @@ -7145,7 +7168,11 @@ static void CG_Init (int serverMessageNum, int serverCommandSequence, int client WP_NUM_WEAPONS = 14; // no hmg //Com_Printf("^5setting item list to ql dm 73\n"); + } else if (cgs.realProtocol == 91) { + memcpy(&bg_itemlist, &bg_itemlistQldm91, sizeof(gitem_t) * bg_numItemsQldm91); + bg_numItems = bg_numItemsQldm91; } + if (cgs.defrag) { Com_Printf("^5defrag\n"); } @@ -7444,6 +7471,12 @@ static void CG_Init (int serverMessageNum, int serverCommandSequence, int client if (cg.demoPlayback) { trap_Get_Demo_Timeouts(&cgs.numTimeouts, cgs.timeOuts); } + + // q3mme camera + demo.camera.flags = CAM_ORIGIN | CAM_ANGLES; + demo.camera.smoothPos = posBezier; + demo.camera.smoothAngles = angleQuat; + demo.camera.target = -1; } void CG_LoadDefaultMenus (void) diff --git a/code/cgame/cg_players.c b/code/cgame/cg_players.c index 2da22b2b..e316fd27 100644 --- a/code/cgame/cg_players.c +++ b/code/cgame/cg_players.c @@ -2993,7 +2993,7 @@ static void CG_PlayerPowerups( centity_t *cent, const refEntity_t *torso ) { CG_UpdatePositionData(cent, ¢->hastePositionData); } - if (powerups & PW_SPAWNPROTECTION) { // 2010-08-08 new ql invuln + if (powerups & PWEX_SPAWNPROTECTION) { // 2010-08-08 new ql invuln //CG_PlayerFloatSprite(cent, cgs.media.connectionShader); if (cg.time - cent->spawnArmorTime < cg_spawnArmorTime.integer) { //CG_PlayerFloatSprite(cent, cgs.media.connectionShader); @@ -3364,14 +3364,14 @@ Float sprites over the player's head =============== */ static void CG_PlayerSprites( centity_t *cent ) { - int team; + //int team; qhandle_t s; const clientInfo_t *ci; qboolean flagIconDrawn; ci = &cgs.clientinfo[cent->currentState.clientNum]; - team = ci->team; + //team = ci->team; if (cg_drawPlayerNames.integer) { CG_PlayerFloatSpriteNameExt(cent, cgs.clientNameImage[cent->currentState.clientNum], 0); diff --git a/code/cgame/cg_q3mme_camera.c b/code/cgame/cg_q3mme_camera.c index e216b0e9..6da48aa1 100644 --- a/code/cgame/cg_q3mme_camera.c +++ b/code/cgame/cg_q3mme_camera.c @@ -1,19 +1,41 @@ -#if 1 - #include "cg_local.h" #include "cg_main.h" #include "cg_mem.h" #include "cg_q3mme_camera.h" +#include "cg_syscalls.h" // trap_Print, trap_FS_Write +#include "../game/bg_xmlparser.h" - -//FIXME demoMain_t demo; // mov_smoothCamPos renamed to cg_q3mmeCameraSmoothPos +static void CG_DemosAddLog (const char *fmt, ...) +{ + va_list args; + char text[MAX_PRINT_MSG]; + + va_start(args, fmt); + Q_vsnprintf(text, sizeof(text), fmt, args); + va_end(args); + + trap_Print(va("^6q3mme camera: ^7%s\n", text)); +} + +static void demoSaveLine (fileHandle_t fileHandle, const char *fmt, ...) +{ + va_list args; + char buf[1024]; + int len; + + va_start(args, fmt); + len = Q_vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + + trap_FS_Write(buf, len, fileHandle); +} -void cameraPointMatch( const demoCameraPoint_t *point, int mask, const demoCameraPoint_t *match[4] ) { +static void cameraPointMatch( const demoCameraPoint_t *point, int mask, const demoCameraPoint_t *match[4] ) { const demoCameraPoint_t *p; p = point; @@ -49,7 +71,7 @@ void cameraPointMatch( const demoCameraPoint_t *point, int mask, const demoCamer match[3] = p; } -void cameraMatchAt( int time, int mask, const demoCameraPoint_t *match[4] ) { +static void cameraMatchAt( int time, int mask, const demoCameraPoint_t *match[4] ) { const demoCameraPoint_t *p; p = demo.camera.points; @@ -113,7 +135,7 @@ static float cameraPointLength( demoCameraPoint_t *point ) { return point->len; cameraPointMatch( point, CAM_ORIGIN, (const demoCameraPoint_t **)match ); - + if (!cameraMatchOrigin( (const demoCameraPoint_t **)match, control )) { point->len = 0; return 0; @@ -146,7 +168,7 @@ static float cameraPointLength( demoCameraPoint_t *point ) { return point->len; } -qboolean cameraOriginAt( int time, float timeFraction, vec3_t origin ) +qboolean CG_Q3mmeCameraOriginAt (int time, float timeFraction, vec3_t origin) { demoCameraPoint_t *match[4]; float searchLen; @@ -220,7 +242,7 @@ qboolean cameraOriginAt( int time, float timeFraction, vec3_t origin ) return qtrue; } -qboolean cameraAnglesAt( int time, float timeFraction, vec3_t angles) +qboolean CG_Q3mmeCameraAnglesAt (int time, float timeFraction, vec3_t angles) { demoCameraPoint_t *match[4]; float lerp; @@ -263,13 +285,14 @@ qboolean cameraAnglesAt( int time, float timeFraction, vec3_t angles) VectorAddDelta( match[1]->angles, match[2]->angles, tempAngles ); QuatFromAnglesClosest( tempAngles, q2, q3 ); } - QuatSquad( lerp, q0, q1, q2, q3, qr ); + QuatSquad( lerp, q0, q1, q2, q3, qr ); QuatToAngles( qr, angles ); } return qtrue; } -static qboolean cameraFovAt( int time, float timeFraction, float *fov ) { +qboolean CG_Q3mmeCameraFovAt (int time, float timeFraction, float *fov) +{ demoCameraPoint_t *match[4]; float lerp; float f[4]; @@ -336,7 +359,8 @@ static void cameraPointReset( demoCameraPoint_t *point ) { } -void cameraDrawPath( demoCameraPoint_t *point, const vec4_t color) { +void CG_Q3mmeCameraDrawPath (demoCameraPoint_t *point, const vec4_t color) +{ int i; polyVert_t verts[4]; qboolean skipFirst = qtrue; @@ -372,7 +396,7 @@ void cameraDrawPath( demoCameraPoint_t *point, const vec4_t color) { } } -demoCameraPoint_t *cameraPointSynch( int time ) { +static demoCameraPoint_t *cameraPointSynch( int time ) { demoCameraPoint_t *point = demo.camera.points; if (!point) return 0; @@ -398,7 +422,8 @@ static void cameraPointFree(demoCameraPoint_t *point) { CG_FreeMem(point); } -demoCameraPoint_t *cameraPointAdd( int time, int flags ) { +demoCameraPoint_t *CG_Q3mmeCameraPointAdd (int time, int flags) +{ demoCameraPoint_t *point = cameraPointSynch( time ); demoCameraPoint_t *newPoint; if (!point || point->time > time) { @@ -454,7 +479,6 @@ static void cameraClear( void ) { cg.numQ3mmeCameraPoints = 0; } -#if 0 // wolfcamql static int cameraPointShift( int shift ) { demoCameraPoint_t *startPoint, *endPoint; if ( demo.camera.start != demo.camera.end ) { @@ -518,22 +542,26 @@ static int cameraPointShift( int shift ) { } return shift; } -#endif - -void cameraUpdate( int time, float timeFraction ) { - //FIXME wolfcamql add - //centity_t *targetCent; +#if 0 // wolfcamql unused +static void cameraUpdate( int time, float timeFraction ) { + centity_t *targetCent; - if (!demo.camera.locked || !demo.camera.points ) { + if (!cg_cameraQue.integer || !demo.camera.points ) { } else { - cameraOriginAt( time, timeFraction, demo.camera.origin ); - cameraAnglesAt( time, timeFraction, demo.camera.angles ); - if (!cameraFovAt( time, timeFraction, &demo.camera.fov )) + CG_Q3mmeCameraOriginAt( time, timeFraction, demo.camera.origin ); + CG_Q3mmeCameraAnglesAt( time, timeFraction, demo.camera.angles ); + if (!CG_Q3mmeCameraFovAt( time, timeFraction, &demo.camera.fov )) { demo.camera.fov = 0; + } else { + cg_fov.value = demo.camera.fov; + //FIXME trap_Cvar_Set? + trap_Cvar_Set("cg_fov", va("%f", cg_fov.value)); + } + } -#if 0 // wolfcamql + /* Optionally look at a target */ targetCent = demoTargetEntity( demo.camera.target ); if ( targetCent ) { @@ -545,12 +573,12 @@ void cameraUpdate( int time, float timeFraction ) { demo.camera.angles[PITCH] = targetAngles[PITCH]; } else { } -#endif } +#endif -#if 0 // wolfcamql -void cameraMoveDirect(void) { - if (demo.camera.locked) +#if 0 // wolfcamql unused +static void cameraMoveDirect(void) { + if (cg_cameraQue.integer) return; /* First clear some related values */ if (!(demo.oldcmd.buttons & BUTTON_ATTACK)) { @@ -561,7 +589,7 @@ void cameraMoveDirect(void) { demoMovePoint( demo.camera.origin, demo.camera.velocity, demo.camera.angles ); } -void cameraMove(void) { +static void cameraMove(void) { vec3_t moveAngles; float *origin; float *angles; @@ -569,7 +597,7 @@ void cameraMove(void) { demoCameraPoint_t *point; - if (!demo.camera.locked) { + if (!cg_cameraQue.integer) { angles = demo.camera.angles; VectorCopy( angles, moveAngles ); origin = demo.camera.origin; @@ -579,7 +607,7 @@ void cameraMove(void) { point = cameraPointSynch( demo.play.time ); if (!point || point->time != demo.play.time || demo.play.fraction ) return; - if (!cameraAnglesAt( point->time, 0, moveAngles )) + if (!CG_Q3mmeCameraAnglesAt( point->time, 0, moveAngles )) return; angles = point->angles; origin = point->origin; @@ -633,7 +661,6 @@ typedef struct { int flags; } parseCameraPoint_t; -#if 0 // wolfcamql static qboolean cameraParseTime( BG_XMLParse_t *parse,const char *line, void *data) { parseCameraPoint_t *point= (parseCameraPoint_t *)data; @@ -642,7 +669,8 @@ static qboolean cameraParseTime( BG_XMLParse_t *parse,const char *line, void *da return qtrue; } static qboolean cameraParseTarget( BG_XMLParse_t *parse,const char *line, void *data) { - parseCameraPoint_t *point= (parseCameraPoint_t *)data; + //FIXME unused + //parseCameraPoint_t *point= (parseCameraPoint_t *)data; demo.camera.target = atoi( line ); return qtrue; @@ -686,14 +714,15 @@ static qboolean cameraParsePoint( BG_XMLParse_t *parse,const struct BG_XMLParseB if (! (pointLoad.flags & CAM_TIME) ) return BG_XMLError(parse, "Camera point has no time"); - point = cameraPointAdd( pointLoad.time, pointLoad.flags ); + point = CG_Q3mmeCameraPointAdd( pointLoad.time, pointLoad.flags ); VectorCopy( pointLoad.origin, point->origin ); VectorCopy( pointLoad.angles, point->angles ); point->fov = pointLoad.fov; return qtrue; } static qboolean cameraParseLocked( BG_XMLParse_t *parse,const char *line, void *data) { - demo.camera.locked = atoi( line ); + //demo.camera.locked = atoi( line ); + trap_Cvar_Set("cg_cameraQue", line); return qtrue; } static qboolean cameraParseSmoothPos(BG_XMLParse_t *parse,const char *line, void *data) { @@ -705,7 +734,8 @@ static qboolean cameraParseSmoothAngles(BG_XMLParse_t *parse,const char *line, v return qtrue; } -qboolean cameraParse( BG_XMLParse_t *parse, const struct BG_XMLParseBlock_s *fromBlock, void *data) { +qboolean CG_Q3mmeCameraParse (BG_XMLParse_t *parse, const struct BG_XMLParseBlock_s *fromBlock, void *data) +{ static BG_XMLParseBlock_t cameraParseBlock[] = { {"point", cameraParsePoint, 0 }, {"locked", 0, cameraParseLocked }, @@ -721,17 +751,16 @@ qboolean cameraParse( BG_XMLParse_t *parse, const struct BG_XMLParseBlock_s *fro return qtrue; } -#endif -#if 0 // wolfcamql -void cameraSave( fileHandle_t fileHandle ) { +void CG_Q3mmeCameraSave (fileHandle_t fileHandle) +{ demoCameraPoint_t *point; point = demo.camera.points; demoSaveLine( fileHandle, "\n" ); demoSaveLine( fileHandle, "\t%d\n", demo.camera.smoothPos ); demoSaveLine( fileHandle, "\t%d\n", demo.camera.smoothAngles ); - demoSaveLine( fileHandle, "\t%d\n", demo.camera.locked ); + demoSaveLine( fileHandle, "\t%d\n", cg_cameraQue.integer ); demoSaveLine( fileHandle, "\t%d\n", demo.camera.target ); while (point) { demoSaveLine( fileHandle, "\t\n"); @@ -747,12 +776,11 @@ void cameraSave( fileHandle_t fileHandle ) { } demoSaveLine( fileHandle, "\n" ); } -#endif -void cameraDraw( int time, float timeFraction ) { +#if 0 // wolfcamql unused +static void cameraDraw( int time, float timeFraction ) { demoCameraPoint_t *point; - //FIXME wolfcamql add - //centity_t *targetCent; + centity_t *targetCent; vec3_t origin, angles, forward; point = cameraPointSynch( time - 10000 ); if (!point) @@ -761,17 +789,16 @@ void cameraDraw( int time, float timeFraction ) { point = point->next; while (point && point->time < (time + 10000)) { /* Draw the splines */ - cameraDrawPath( point, colorRed ); + CG_Q3mmeCameraDrawPath( point, colorRed ); demoDrawCross( point->origin, colorRed ); point = point->next; } /* Draw current line */ - if ( cameraOriginAt( time, timeFraction, origin) && cameraAnglesAt( time, timeFraction, angles )) { + if ( CG_Q3mmeCameraOriginAt( time, timeFraction, origin) && CG_Q3mmeCameraAnglesAt( time, timeFraction, angles )) { AngleVectors( angles, forward, 0, 0); VectorMA( origin, 80, forward, angles ); demoDrawLine( origin, angles, colorWhite ); } -#if 0 // wolfcamql /* Draw a box around an optional target */ targetCent = demoTargetEntity( demo.camera.target ); if (targetCent) { @@ -779,10 +806,10 @@ void cameraDraw( int time, float timeFraction ) { demoCentityBoxSize( targetCent, container ); demoDrawBox( targetCent->lerpOrigin, container, colorWhite ); } -#endif } +#endif -void cameraSmooth( void ) { +static void cameraSmooth( void ) { demoCameraPoint_t *startPoint, *endPoint; demoCameraPoint_t *point; @@ -833,7 +860,7 @@ void cameraSmooth( void ) { static void cameraMoveAll( const vec3_t move ) { demoCameraPoint_t *point; - + point = demo.camera.points; while (point) { @@ -861,7 +888,7 @@ static void cameraRotateAll( const vec3_t origin, const vec3_t angles ) { } } -// from q3mm3: game/bg_demos.c +// from q3mme: game/bg_demos.c static void demoCommandValue( const char *cmd, float * oldVal ) { if (!cmd[0]) @@ -888,14 +915,13 @@ void CG_Q3mmeDemoCameraCommand_f (void) demo.play.time = cg.time; demo.play.fraction = (float)cg.foverf; - demo.camera.flags = CAM_ORIGIN | CAM_ANGLES | CAM_FOV | CAM_TIME; demo.serverTime = cg.snap->serverTime; if (!Q_stricmp(cmd, "smooth")) { cameraSmooth( ); } else if (!Q_stricmp(cmd, "add")) { demoCameraPoint_t *point; - point = cameraPointAdd( demo.play.time, demo.camera.flags ); + point = CG_Q3mmeCameraPointAdd( demo.play.time, demo.camera.flags ); if (point) { VectorCopy( demo.viewOrigin, point->origin ); VectorCopy( demo.viewAngles, point->angles ); @@ -928,34 +954,73 @@ void CG_Q3mmeDemoCameraCommand_f (void) CG_DemosAddLog( "Camera selection end at %d.%03d", demo.camera.end / 1000, demo.camera.end % 1000 ); } else if (!Q_stricmp(cmd, "next")) { demoCameraPoint_t *point = cameraPointSynch( demo.play.time ); - if (!point) + if (!point) { + Com_Printf("^3q3mmecamera next: no point found\n"); return; + } if (point->next) point = point->next; - demo.play.time = point->time; - demo.play.fraction = 0; + + //demo.play.time = point->time; + //demo.play.fraction = 0; + cg.cameraQ3mmePlaying = qfalse; + //cg.q3mmeCameraPlaying = qfalse; + cg.cameraPlayedLastFrame = qfalse; + VectorCopy(point->origin, cg.freecamPlayerState.origin); + VectorCopy(point->origin, cg.fpos); + VectorCopy(point->angles, cg.freecamPlayerState.viewangles); + VectorCopy(point->angles, cg.fang); + trap_Cvar_Set("cl_freezeDemo", "1"); + trap_SendConsoleCommandNow(va("seekservertime %f\n", (float)point->time)); + //FIXME bad hack + cg.atCameraPoint = qtrue; + } else if (!Q_stricmp(cmd, "prev")) { demoCameraPoint_t *point = cameraPointSynch( demo.play.time ); - if (!point) + if (!point) { + Com_Printf("^3q3mmecamera prev: no point found\n"); return; + } if (point->prev) point = point->prev; - demo.play.time = point->time; - demo.play.fraction = 0; + + //demo.play.time = point->time; + //demo.play.fraction = 0; + + cg.cameraQ3mmePlaying = qfalse; + //cg.q3mmeCameraPlaying = qfalse; + cg.cameraPlayedLastFrame = qfalse; + VectorCopy(point->origin, cg.freecamPlayerState.origin); + VectorCopy(point->origin, cg.fpos); + VectorCopy(point->angles, cg.freecamPlayerState.viewangles); + VectorCopy(point->angles, cg.fang); + trap_Cvar_Set("cl_freezeDemo", "1"); + trap_SendConsoleCommandNow(va("seekservertime %f\n", (float)point->time)); + //FIXME bad hack + cg.atCameraPoint = qtrue; + } else if (!Q_stricmp(cmd, "lock")) { - demo.camera.locked = !demo.camera.locked; - if (demo.camera.locked) + qboolean cameraLockedOld = cg_cameraQue.integer; + qboolean cameraLockedNew = !cameraLockedOld; + //demo.camera.locked = !demo.camera.locked; + + trap_Cvar_Set("cg_cameraQue", va("%d", cameraLockedNew)); + + if (cameraLockedNew) { CG_DemosAddLog("Camera view locked"); - else + } else { CG_DemosAddLog("Camera view unlocked"); + } + + cg.cameraQ3mmePlaying = qfalse; } else if (!Q_stricmp(cmd, "target")) { - Com_Printf("^3FIXME target not implemented\n"); + //Com_Printf("^3FIXME target not implemented\n"); #if 0 // wolfcamql - if ( demo.camera.locked ) { + if ( cg_cameraQue.integer ) { CG_DemosAddLog("Can't target while locked" ); } if ( demo.cmd.buttons & BUTTON_ATTACK ) { - if (demo.camera.target>=0) { + if (demo.camera.target>=0) { CG_DemosAddLog("Cleared target %d", demo.camera.target ); demo.camera.target = -1; } else { @@ -974,50 +1039,56 @@ void CG_Q3mmeDemoCameraCommand_f (void) CG_DemosAddLog("Camera view synched"); } #endif + if (CG_Argc() < 3) { + Com_Printf("current target: %d\n", demo.camera.target); + } else { + demo.camera.target = atoi(CG_Argv(2)); + Com_Printf("target %d selected\n", demo.camera.target); + } } else if (!Q_stricmp(cmd, "shift")) { - - - Com_Printf("^3FIXME shift not implemented\n"); -#if 0 // wolfcamql int shift = 1000 * atof(CG_Argv(2)); demo.camera.shiftWarn = 0; if (cameraPointShift( shift )) { CG_DemosAddLog( "Shifted %d.%03d seconds", shift / 1000, shift % 1000); } -#endif } else if (!Q_stricmp(cmd, "clear")) { cameraClear( ); CG_DemosAddLog( "Camera points cleared" ); } else if (!Q_stricmp(cmd, "pos")) { float *oldOrigin; - if (demo.camera.locked) { + //if (demo.camera.locked) { + if (cg_cameraQue.integer) { demoCameraPoint_t *point = cameraPointSynch( demo.play.time ); - if (!point || point->time != demo.play.time || demo.play.fraction ) { + //if (!point || point->time != demo.play.time || demo.play.fraction ) { + if (!point || point->time != cg.time) { Com_Printf("Can't change position when not synched to a point\n"); return; } oldOrigin = point->origin; } else { - oldOrigin = demo.camera.origin; + //oldOrigin = cg.fpos; //demo.camera.origin; + oldOrigin = cg.freecamPlayerState.origin; } -#if 1 // wolfcamql + //Com_Printf("old origin: %f %f %f\n", oldOrigin[0], oldOrigin[1], oldOrigin[2]); demoCommandValue( CG_Argv(2), oldOrigin ); demoCommandValue( CG_Argv(3), oldOrigin+1 ); demoCommandValue( CG_Argv(4), oldOrigin+2 ); -#endif - //FIXME - Com_Printf("^3FIXME q3mme camera 'pos'\n"); + + //Com_Printf("new origin: %f %f %f\n", oldOrigin[0], oldOrigin[1], oldOrigin[2]); } else if (!Q_stricmp(cmd, "angles")) { float *oldAngles; - if (demo.camera.locked) { + //if (demo.camera.locked) { + if (cg_cameraQue.integer) { demoCameraPoint_t *point = cameraPointSynch( demo.play.time ); - if (!point || point->time != demo.play.time || demo.play.fraction ) { + //if (!point || point->time != demo.play.time || demo.play.fraction ) { + if (!point || point->time != cg.ftime) { Com_Printf("Can't change angles when not synched to a point\n"); return; } oldAngles = point->angles; } else { - oldAngles = demo.camera.angles; + //oldAngles = demo.camera.angles; + oldAngles = cg.freecamPlayerState.viewangles; } demoCommandValue( CG_Argv(2), oldAngles ); demoCommandValue( CG_Argv(3), oldAngles+1 ); @@ -1026,15 +1097,26 @@ void CG_Q3mmeDemoCameraCommand_f (void) } else if (!Q_stricmp(cmd, "fov")) { float *oldFov; - if (demo.camera.locked) { + //if (demo.camera.locked) { + if (cg_cameraQue.integer) { demoCameraPoint_t *point = cameraPointSynch( demo.play.time ); - if (!point || point->time != demo.play.time || demo.play.fraction ) { + //if (!point || point->time != demo.play.time || demo.play.fraction ) { + if (!point || point->time != cg.ftime) { Com_Printf("Can't change fov when not synched to a point\n"); return; } oldFov = &point->fov; } else { - oldFov = &demo.camera.fov; + //FIXME wolfcamql shouldn't really set cg_fov +#if 0 + //oldFov = &demo.camera.fov; + oldFov = &cg_fov.value; + // hack + demoCommandValue( CG_Argv(2), oldFov ); + trap_Cvar_Set("cg_fov", va("%f", cg_fov.value)); +#endif + Com_Printf("Camera is unlocked, fov not set\n"); + return; } demoCommandValue( CG_Argv(2), oldFov ); } else if (!Q_stricmp(cmd, "smoothPos")) { @@ -1079,9 +1161,10 @@ void CG_Q3mmeDemoCameraCommand_f (void) } Com_Printf( " interpolation\n" ); } else if (!Q_stricmp(cmd, "toggle")) { - if (demo.camera.locked) { + //if (demo.camera.locked) { + if (cg_cameraQue.integer) { demoCameraPoint_t *point = cameraPointSynch( demo.play.time ); - if (!point || point->time != demo.play.time || demo.play.fraction ) { + if (!point || point->time != cg.ftime) { Com_Printf("Can't toggle flags when not synched to a point\n"); return; } @@ -1093,13 +1176,13 @@ void CG_Q3mmeDemoCameraCommand_f (void) vec3_t v; if (!Q_stricmp(CG_Argv(2), "here" )) { - cameraOriginAt( demo.play.time, demo.play.fraction, v ); + CG_Q3mmeCameraOriginAt( demo.play.time, demo.play.fraction, v ); VectorSubtract( demo.viewOrigin, v, v ); } else { v[0] = atof( CG_Argv(2) ); v[1] = atof( CG_Argv(3) ); v[2] = atof( CG_Argv(4) ); - } + } cameraMoveAll( v ); Com_Printf("moving all points %.2f %.2f %.2f\n", v[0], v[1], v[2] ); } else if (!Q_stricmp(cmd, "rotate")) { @@ -1111,6 +1194,48 @@ void CG_Q3mmeDemoCameraCommand_f (void) cameraRotateAll( demo.viewOrigin, v ); Com_Printf("Rotate all points %.2f %.2f %.2f\n", v[0], v[1], v[2] ); + } else if (!Q_stricmp(cmd, "flags")) { + if (cg_cameraQue.integer) { + int i; + demoCameraPoint_t *point = cameraPointSynch( demo.play.time ); + if (!point || point->time != cg.ftime) { + Com_Printf("Can't change mask when not synched to a point\n"); + return; + } + for (i = 2; i < CG_Argc(); i++) { + if (!Q_stricmp(CG_Argv(i), "origin")) { + point->flags ^= CAM_ORIGIN; + } else if (!Q_stricmp(CG_Argv(i), "angles")) { + point->flags ^= CAM_ANGLES; + } else if (!Q_stricmp(CG_Argv(i), "fov")) { + point->flags ^= CAM_FOV; + } else if (!Q_stricmp(CG_Argv(i), "time")) { + point->flags ^= CAM_TIME; + } else { + Com_Printf("unknown flag type: '%s'\n", CG_Argv(i)); + } + } + + // print flag values + Com_Printf("flags: "); + if (point->flags & CAM_ORIGIN) { + Com_Printf("origin "); + } + if (point->flags & CAM_ANGLES) { + Com_Printf("angles "); + } + if (point->flags & CAM_FOV) { + Com_Printf("fov "); + } + if (point->flags & CAM_TIME) { + Com_Printf("time "); + } + Com_Printf("\n"); + + } else { + Com_Printf("Camera is unlocked, can't edit mask\n"); + return; + } } else { Com_Printf("camera usage:\n" ); Com_Printf("camera add/del, add/del a camera point at current viewpoint and time.\n" ); @@ -1131,5 +1256,3 @@ void CG_Q3mmeDemoCameraCommand_f (void) } } - -#endif diff --git a/code/cgame/cg_q3mme_camera.h b/code/cgame/cg_q3mme_camera.h index 5420fa0d..3abea9e4 100644 --- a/code/cgame/cg_q3mme_camera.h +++ b/code/cgame/cg_q3mme_camera.h @@ -2,6 +2,7 @@ #define cg_q3mme_camera_h_included #include "../qcommon/q_shared.h" +#include "../game/bg_xmlparser.h" #include "cg_local.h" #include "cg_q3mme_math.h" @@ -12,9 +13,6 @@ #define CAM_TIME 0x100 -//FIXME wolfcamql -#define CG_DemosAddLog CG_Printf - typedef struct demoCameraPoint_s { struct demoCameraPoint_s *next, *prev; vec3_t origin, angles; @@ -27,12 +25,14 @@ typedef struct demoMain_s { int serverTime; struct { + // selects start and end points for /q3mmecamera shift int start, end; int target, flags; int shiftWarn; float timeShift; float fov; - qboolean locked; + // wolfcamql this is lke cg_cameraQue + // qboolean locked; vec3_t angles, origin, velocity; demoCameraPoint_t *points; posInterpolate_t smoothPos; @@ -48,7 +48,7 @@ typedef struct demoMain_s { vec3_t viewAngles; //vec3_t viewFov; float viewFov; - + } demoMain_t; extern demoMain_t demo; @@ -57,10 +57,15 @@ extern demoMain_t demo; //qboolean cameraAnglesAt (int time, float timeFraction, vec3_t angles); //qboolean cameraFovAt (int time, float timeFraction, float *fov); -extern demoCameraPoint_t *cameraPointAdd( int time, int flags ); -extern qboolean cameraOriginAt( int time, float timeFraction, vec3_t origin ); -extern qboolean cameraAnglesAt( int time, float timeFraction, vec3_t angles); +extern demoCameraPoint_t *CG_Q3mmeCameraPointAdd (int time, int flags); +extern qboolean CG_Q3mmeCameraOriginAt (int time, float timeFraction, vec3_t origin); +extern qboolean CG_Q3mmeCameraAnglesAt (int time, float timeFraction, vec3_t angles); +extern qboolean CG_Q3mmeCameraFovAt (int time, float timeFraction, float *fov); +extern void CG_Q3mmeCameraDrawPath (demoCameraPoint_t *point, const vec4_t color); + extern void CG_Q3mmeDemoCameraCommand_f (void); +extern void CG_Q3mmeCameraSave (fileHandle_t fileHandle); +extern qboolean CG_Q3mmeCameraParse (BG_XMLParse_t *parse, const struct BG_XMLParseBlock_s *fromBlock, void *data); #endif // cg_q3mme_camera_h_included diff --git a/code/cgame/cg_q3mme_math.c b/code/cgame/cg_q3mme_math.c index f6a98dc8..d22c95e7 100644 --- a/code/cgame/cg_q3mme_math.c +++ b/code/cgame/cg_q3mme_math.c @@ -21,15 +21,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ //#include "../game/bg_demos.h" -//#include "cg_demos.h" +//#include "cg_demos.h" //#include #include "../qcommon/q_shared.h" + #define __Q3_VM_Q3MME_MATH 1 // inlines only present here in qvm #include "cg_q3mme_math.h" +#include "cg_local.h" // cg., after cg_q3mme_math.h for qvm + #include "cg_syscalls.h" #ifdef _MSC_VER diff --git a/code/cgame/cg_q3mme_math.h b/code/cgame/cg_q3mme_math.h index 5cf02631..490fe732 100644 --- a/code/cgame/cg_q3mme_math.h +++ b/code/cgame/cg_q3mme_math.h @@ -23,7 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ifndef cg_q3mme_math_h_included #define cg_q3mme_math_h_included -#include "cg_local.h" +//#include "cg_local.h" +#include "../renderer/tr_types.h" // polyVert_t typedef enum { posLinear, diff --git a/code/cgame/cg_sound.c b/code/cgame/cg_sound.c index ef14120b..7603542c 100644 --- a/code/cgame/cg_sound.c +++ b/code/cgame/cg_sound.c @@ -24,11 +24,6 @@ static qboolean CG_CheckCanPlaySound (const vec3_t origin, int entityNum, sfxHan } if (origin == NULL) { - if (entityNum == (MAX_GENTITIES - 1)) { - //FIXME hack for freecam rail - Com_Printf("^3FIXME cpma sound, hack for freecam rail\n"); - return qtrue; - } if (entityNum == ENTITYNUM_WORLD) { Com_Printf("^3WARNING cpma sound WORLD entity and null origin\n"); return qtrue; diff --git a/code/cgame/cg_spawn.c b/code/cgame/cg_spawn.c index 63d54c8e..e272d2cf 100644 --- a/code/cgame/cg_spawn.c +++ b/code/cgame/cg_spawn.c @@ -211,6 +211,10 @@ qboolean CG_ParseSpawnVars( void ) { blueSpawn = qfalse; initial = qfalse; deathmatch = qfalse; + portal = qfalse; + portalHasTarget = qfalse; + startTimer = qfalse; + stopTimer = qfalse; gotOrigin = qfalse; // get the rest diff --git a/code/cgame/cg_view.c b/code/cgame/cg_view.c index 83b2d97e..49e18cfc 100644 --- a/code/cgame/cg_view.c +++ b/code/cgame/cg_view.c @@ -4,6 +4,7 @@ // for a 3D rendering #include "cg_local.h" +#include "cg_camera.h" #include "cg_consolecmds.h" // popup() #include "cg_draw.h" // CG_Fade() #include "cg_effects.h" @@ -2072,6 +2073,232 @@ static float LerpAngle2 (float from, float to, float frac) } #endif +// from q3mme +static centity_t *demoTargetEntity( int num ) { + if (num <0 || num >= (MAX_GENTITIES -1) ) + return 0; + if (num == cg.snap->ps.clientNum) + return &cg.predictedPlayerEntity; + if (cg_entities[num].currentValid) + return &cg_entities[num]; + return 0; +} + +// from q3mme +static void chaseEntityOrigin( centity_t *cent, vec3_t origin ) { + VectorCopy( cent->lerpOrigin, origin ); + switch(cent->currentState.eType) { + case ET_PLAYER: + origin[2] += DEFAULT_VIEWHEIGHT; + break; + } +} + +static qboolean CG_PlayQ3mmeCamera (void) +{ + //int i; + vec3_t refOriginOrig, refAnglesOrig; + float refFovxOrig; + float refFovyOrig; + vec3_t velocityOrig; + demoCameraPoint_t *last, *next; + //int time; + //float timeFraction; + qboolean cameraDebugPath; + float fov; + centity_t *targetCent; + + last = demo.camera.points; + + if (!last) { + return qfalse; + } + + while (last->next) { + next = last->next; + last = next; + } + + if (cg_cameraDebugPath.integer) { + cameraDebugPath = qtrue; + } else { + cameraDebugPath = qfalse; + } + + //Com_Printf("cg.cameraQ3mmePlaying %d\n", cg.cameraQ3mmePlaying); + + //FIXME right place for cameraque ? + //if (cg.cameraQ3mme && cg_cameraQue.integer) { + if (cg.cameraQ3mmePlaying || (cg_cameraQue.integer && cg.time <= last->time)) { + int time; + float timeFraction; + + // ahahhh, seek hasn't taken effect yet so this will always be set so cg.time might be greater + + if (cg.playQ3mmeCameraCommandIssued) { +#if 0 + // race, they got deleted + if (!demo.camera.points) { + cg.playQ3mmeCameraCommandIssued = qfalse; + cg.cameraQ3mmePlaying = qfalse; + return qfalse; + } + + if (cg.time > demo.camera.points->time) { + // still not synced + //Com_Printf("waiting to sync q3mme camera %d -> %d\n", cg.time, demo.camera.points->time); + return qfalse; + } else { + // no synced + cg.playQ3mmeCameraCommandIssued = qfalse; + } +#endif + + //Com_Printf("waiting for seek\n"); + cg.playQ3mmeCameraCommandIssued = qfalse; + return qfalse; + } + if (cg.time > last->time) { + //Com_Printf("q3mme camera cg.time > last->time\n"); + cg.cameraQ3mmePlaying = qfalse; + return qfalse; + } + + if (cameraDebugPath) { + VectorCopy(cg.refdef.vieworg, refOriginOrig); + VectorCopy(cg.refdefViewAngles, refAnglesOrig); + refFovxOrig = cg.refdef.fov_x; + refFovyOrig = cg.refdef.fov_y; + VectorCopy(cg.freecamPlayerState.velocity, velocityOrig); + } + + //time = floor(cg.time); + //timeFraction = cg.time - time; + time = cg.time; + timeFraction = (float)cg.foverf; + + CG_Q3mmeCameraOriginAt(time, timeFraction, cg.refdef.vieworg); + CG_Q3mmeCameraAnglesAt(time, timeFraction, cg.refdefViewAngles); + + targetCent = demoTargetEntity(demo.camera.target); + if (targetCent) { + vec3_t targetOrigin, targetAngles; + chaseEntityOrigin(targetCent, targetOrigin); + VectorSubtract(targetOrigin, cg.refdef.vieworg, targetOrigin); + vectoangles(targetOrigin, targetAngles); + //demo.camera.angles[YAW] = targetAngles[YAW]; + //demo.camera.angles[PITCH] = targetAngles[PITCH]; + cg.refdefViewAngles[YAW] = targetAngles[YAW]; + cg.refdefViewAngles[PITCH] = targetAngles[PITCH]; + } + + AnglesToAxis(cg.refdefViewAngles, cg.refdef.viewaxis); + //Com_Printf("angles: %f %f %f\n", cg.refdefViewAngles[0], cg.refdefViewAngles[1], cg.refdefViewAngles[2]); + + fov = cg_fov.value; + if (!CG_Q3mmeCameraFovAt(time, timeFraction, &demo.camera.fov)) { + demo.camera.fov = 0; + } else { + fov += demo.camera.fov; + } + + cg.refdef.fov_x = fov; + if (cg.refdef.fov_x < 1) { + cg.refdef.fov_x = 1; + } + + CG_AdjustedFov(cg.refdef.fov_x, &cg.refdef.fov_x, &cg.refdef.fov_y); + + //Com_Printf("q3mme camera %f %f %f\n", cg.refdef.vieworg[0], cg.refdef.vieworg[1], cg.refdef.vieworg[2]); + + trap_S_Respatialize(MAX_GENTITIES - 1, cg.refdef.vieworg, cg.refdef.viewaxis, qfalse); + + + if (cg_cameraUpdateFreeCam.integer && !cg_cameraDebugPath.integer) { + cg.fMoveTime = 0; + VectorCopy(cg.refdef.vieworg, cg.fpos); + cg.fpos[2] -= DEFAULT_VIEWHEIGHT; + VectorCopy(cg.refdefViewAngles, cg.fang); + cg.freecamSet = qtrue; + //Com_Printf("xxx %f %f %f\n", cg.refdef.vieworg[0], cg.refdef.vieworg[1], cg.refdef.vieworg[2]); + +#if 0 //FIXME + if (cg.ftime >= lastPoint->cgtime) { + VectorClear(cg.freecamPlayerState.velocity); + } else if (cg.ftime > cg.positionSetTime) { + for (i = 0; i < 3; i++) { + cg.freecamPlayerState.velocity[i] = (cg.refdef.vieworg[i] - cg.cameraLastOrigin[i]) / ((cg.ftime - cg.positionSetTime) / 1000.0); + } + } else if (cg.ftime < cg.positionSetTime) { + VectorSet(cg.freecamPlayerState.velocity, 0, 0, 0); + } +#endif + } + +#if 0 //FIXME + if (cg.ftime >= lastPoint->cgtime) { + VectorClear(cg.cameraVelocity); + } else if (cg.ftime > cg.positionSetTime) { + for (i = 0; i < 3; i++) { + cg.cameraVelocity[i] = (cg.refdef.vieworg[i] - cg.cameraLastOrigin[i]) / ((cg.ftime - cg.positionSetTime) / 1000.0); + } + } else if (cg.ftime < cg.positionSetTime) { + VectorSet(cg.cameraVelocity, 0, 0, 0); + } +#endif + +#if 0 //FIXME + if (cg.ftime != cg.positionSetTime) { + cg.positionSetTime = cg.ftime; + VectorCopy(cg.refdef.vieworg, cg.cameraLastOrigin); + } +#endif + + if (cameraDebugPath) { + refEntity_t ent; + byte color[4] = { 255, 0, 0, 255 }; + vec3_t dir; + vec3_t origin; + + memset(&ent, 0, sizeof(ent)); + VectorCopy(cg.refdef.vieworg, ent.origin); + ent.reType = RT_MODEL; + ent.hModel = cgs.media.teleportEffectModel; + //ent.hModel = trap_R_RegisterModel("models/powerups/health/large_sphere.md3"); + //ent.hModel = trap_R_RegisterModel("models/powerups/health/mega_sphere.md3"); + AxisClear(ent.axis); + //ent.origin[2] += 16; + ent.radius = 300; + ent.customShader = 0; + ent.shaderRGBA[0] = 255; + ent.shaderRGBA[1] = 0; + ent.shaderRGBA[2] = 0; + ent.shaderRGBA[3] = 255; + ent.renderfx = RF_DEPTHHACK; + + CG_AddRefEntity(&ent); + + AngleVectors(cg.refdefViewAngles, dir, NULL, NULL); + VectorCopy(ent.origin, origin); + VectorMA(origin, 300, dir, origin); + CG_SimpleRailTrail(ent.origin, origin, cg_railTrailTime.value, color); + + VectorCopy(refOriginOrig, cg.refdef.vieworg); + VectorCopy(refAnglesOrig, cg.refdefViewAngles); + AnglesToAxis(cg.refdefViewAngles, cg.refdef.viewaxis); + cg.refdef.fov_x = refFovxOrig; + cg.refdef.fov_y = refFovyOrig; + VectorCopy(velocityOrig, cg.freecamPlayerState.velocity); + + cg.freecamSet = qtrue; + } // cameraDebugPath + return qtrue; + } // q3mme camera playing + + return qfalse; +} + + static qboolean CG_PlayCamera (void) { cameraPoint_t *cp; @@ -2103,41 +2330,14 @@ static qboolean CG_PlayCamera (void) vec3_t velocityOrig; qboolean cameraDebugPath = qfalse; -#if 0 // works - //FIXME testing q3mme camera - if (!cg.cameraPlaying) { - return qfalse; - } else if (cg.cameraQ3mme) { - int time; - float timeFraction; - - //time = floor(cg.time); - //timeFraction = cg.time - time; - time = cg.time; - timeFraction = (float)cg.foverf; - - //cameraOriginAt( time, timeFraction, demo.camera.origin ); - //cameraAnglesAt( time, timeFraction, demo.camera.angles ); - demo.camera.smoothPos = posBezier; - demo.camera.smoothAngles = angleQuat; - - cameraOriginAt(time, timeFraction, cg.refdef.vieworg); - cameraAnglesAt(time, timeFraction, cg.refdefViewAngles); - AnglesToAxis(cg.refdefViewAngles, cg.refdef.viewaxis); - //Com_Printf("angles: %f %f %f\n", cg.refdefViewAngles[0], cg.refdefViewAngles[1], cg.refdefViewAngles[2]); -#if 0 //FIXME q3mme camera - if (!cameraFovAt( time, timeFraction, &demo.camera.fov )) - demo.camera.fov = 0; -#endif + CG_PlayQ3mmeCamera(); - Com_Printf("q3mme camera...\n"); + if (cg.cameraQ3mmePlaying && !cg_cameraDebugPath.integer) { return qtrue; } else { - // pass .. wolfcamql camera + // Keep going and also play regular camera if available. This is + // to allow debugging of both at the same time. } -#endif - - //Com_Printf("wolfcamql camera...\n"); if (cg.numCameraPoints < 2) { cg.cameraPlaying = qfalse; @@ -2165,7 +2365,13 @@ static qboolean CG_PlayCamera (void) refFovyOrig = cg.refdef.fov_y; VectorCopy(cg.freecamPlayerState.velocity, velocityOrig); } else { - //refFovxOrig = 0; + // silence gcc warnings that they may be used unintialized, the + // warning seems invalid and is triggered by the long function + VectorSet(refOriginOrig, 0, 0, 0); + VectorSet(refAnglesOrig, 0, 0, 0); + refFovxOrig = 0; + refFovyOrig = 0; + VectorSet(velocityOrig, 0, 0, 0); } //#if 1 // gcc warning @@ -2360,12 +2566,20 @@ static qboolean CG_PlayCamera (void) if (cpprev && cpprev->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[cp->splineStart], o); + } else if (cpprev && cpprev->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(cp->cgtime, posBezier, o); + } else if (cpprev && cpprev->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(cp->cgtime, posCatmullRom, o); } else { VectorCopy(cp->origin, o); } if (cpnext->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[cpnext->splineStart], no); + } else if (cpnext->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(cpnext->cgtime, posBezier, no); + } else if (cpnext->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(cpnext->cgtime, posCatmullRom, no); } else { VectorCopy(cpnext->origin, no); } @@ -2438,6 +2652,38 @@ static qboolean CG_PlayCamera (void) cg.refdef.vieworg[0] = o[0] + f * (no[0] - o[0]); cg.refdef.vieworg[1] = o[1] + f * (no[1] - o[1]); cg.refdef.vieworg[2] = o[2] + f * (no[2] - o[2]); + } else if (cp->type == CAMERA_SPLINE_BEZIER || cp->type == CAMERA_SPLINE_CATMULLROM) { + posInterpolate_t posType; + + posType = posBezier; + if (cp->type == CAMERA_SPLINE_CATMULLROM) { + posType = posCatmullRom; + } + + if (cp->useOriginVelocity) { + totalDist = cp->originDistance; + totalTime = (double)(cpnext->cgtime - cp->cgtime) / 1000.0; + accel = (cp->originFinalVelocity - cp->originInitialVelocity) / totalTime; + t = (double)(cg.ftime - cp->cgtime) / 1000.0; + dist = (cp->originInitialVelocity * t) + 0.5 * accel * t * t; + f = dist / totalDist; + if (f > 1.0) { + f = 1; + } + + //CG_CameraSplineOriginAt(cg.ftime, posBezier, cg.refdef.vieworg); + CG_CameraSplineOriginAt(cp->cgtime + f * (cpnext->cgtime - cp->cgtime), posType, cg.refdef.vieworg); + } else { + f = -1; +#if 0 + if (cg.ftime < cpnext->cgtime) { + snumf = (cg.ftime - cp->cgtime) / singleTime; + } else { + snumf = (cpnext->cgtime - cp->cgtime) / singleTime; + } +#endif + CG_CameraSplineOriginAt(cg.ftime, posType, cg.refdef.vieworg); + } } else if (cp->type == CAMERA_CURVE) { f = (cg.ftime - cp->cgtime) / (cpnext->cgtime - cp->cgtime); if (f > 1.0) { @@ -2550,12 +2796,21 @@ static qboolean CG_PlayCamera (void) if (cpprev && cpprev->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[cp->splineStart], o); + } else if (cpprev && cpprev->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(cp->cgtime, posBezier, o); + } else if (cpprev && cpprev->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(cp->cgtime, posCatmullRom, o); + } else { VectorCopy(cp->origin, o); } if (cpnext->type == CAMERA_SPLINE) { VectorCopy(cg.splinePoints[cpnext->splineStart], no); + } else if (cpnext->type == CAMERA_SPLINE_BEZIER) { + CG_CameraSplineOriginAt(cpnext->cgtime, posBezier, no); + } else if (cpnext->type == CAMERA_SPLINE_CATMULLROM) { + CG_CameraSplineOriginAt(cpnext->cgtime, posCatmullRom, no); } else { VectorCopy(cpnext->origin, no); } @@ -2587,6 +2842,8 @@ static qboolean CG_PlayCamera (void) //#if 1 // gcc warning + // now angles + if (cp->viewType == CAMERA_ANGLES_INTERP || cp->viewType == CAMERA_ANGLES_INTERP_USE_PREVIOUS) { f = (cg.ftime - cp->cgtime) / (cpnext->cgtime - cp->cgtime); @@ -2602,6 +2859,9 @@ static qboolean CG_PlayCamera (void) return qfalse; } VectorCopy(cpprev->lastAngles, a); + } else if (cpprev && cpprev->viewType == CAMERA_ANGLES_SPLINE) { + CG_CameraSplineAnglesAt(cp->cgtime, a); + //FIXME roll } else { VectorCopy(cp->angles, a); } @@ -2653,6 +2913,9 @@ static qboolean CG_PlayCamera (void) VectorSubtract(o, cg.refdef.vieworg, dir); vectoangles(dir, na); pointNext = cpnext; + } else if (cpnext->viewType == CAMERA_ANGLES_SPLINE) { + CG_CameraSplineAnglesAt(cpnext->cgtime, na); + pointNext = cpnext; } else { CG_ErrorPopup("invalid view type state"); cg.cameraPlaying = qfalse; @@ -2901,6 +3164,25 @@ static qboolean CG_PlayCamera (void) } else if (cp->viewType == CAMERA_ANGLES_VIEWPOINT_FIXED) { VectorSubtract(cp->viewPointOrigin, cg.refdef.vieworg, dir); vectoangles(dir, cg.refdefViewAngles); + } else if (cp->viewType == CAMERA_ANGLES_SPLINE) { + if (cp->useAnglesVelocity) { + CG_CameraSplineAnglesAt(cp->cgtime, a); + CG_CameraSplineAnglesAt(cpnext->cgtime, na); + + totalDist = CameraAngleDistance(a, na); + totalTime = (double)(cpnext->cgtime - cp->cgtime) / 1000.0; + accel = (cp->anglesFinalVelocity - cp->anglesInitialVelocity) / totalTime; + t = (cg.ftime - cp->cgtime) / 1000.0; + dist = (cp->anglesInitialVelocity * t) + 0.5 * accel * t * t; + f = dist / totalDist; + if (f > 1.0) { + f = 1; + } + + CG_CameraSplineAnglesAt(cp->cgtime + f * (cpnext->cgtime - cp->cgtime), cg.refdefViewAngles); + } else { + CG_CameraSplineAnglesAt(cg.ftime, cg.refdefViewAngles); + } } else { // unknown cp->viewType CG_ErrorPopup(va("bad camera point %d unknown view type", cg.currentCameraPoint)); @@ -2912,7 +3194,11 @@ static qboolean CG_PlayCamera (void) #if 1 // gcc warning // up to here // roll - if (cp->rollType == CAMERA_ROLL_INTERP) { + + // skip roll for q3mme spline angles + if (cp->viewType == CAMERA_ANGLES_SPLINE) { + // pass + } else if (cp->rollType == CAMERA_ROLL_INTERP) { //roll = nroll = 0; // silence compiler warning if (cpnext->rollType == CAMERA_ROLL_INTERP || cpnext->rollType == CAMERA_ROLL_FIXED) { // @@ -3007,13 +3293,37 @@ static qboolean CG_PlayCamera (void) return qfalse; } - //FIXME testing q3mme camera just angles - //cameraAnglesAt(floor(cg.time), cg.time - floor(cg.time), cg.refdefViewAngles); VectorCopy(cg.refdefViewAngles, cp->lastAngles); AnglesToAxis(cg.refdefViewAngles, cg.refdef.viewaxis); if (cp->fovType == CAMERA_FOV_USE_CURRENT) { fov = cg_fov.value; + } else if (cp->fovType == CAMERA_FOV_SPLINE) { + float cfov; + + if (cp->useFovVelocity) { + totalDist = cp->fovDistance; + totalTime = (double)(cpnext->cgtime - cp->cgtime) / 1000.0; + accel = (cp->fovFinalVelocity - cp->fovInitialVelocity) / totalTime; + t = (cg.ftime - cp->cgtime) / 1000.0; + dist = (cp->fovInitialVelocity * t) + 0.5 * accel * t * t; + f = dist / totalDist; + if (f > 1.0) { + f = 1; + } + + if (!CG_CameraSplineFovAt(cp->cgtime + f * (cpnext->cgtime - cp->cgtime), &cfov)) { + fov = cg_fov.value; + } else { + fov = cfov; + } + } else { + if (!CG_CameraSplineFovAt(cg.ftime, &cfov)) { + fov = cg_fov.value; + } else { + fov = cfov; + } + } } else if (cp->fovType == CAMERA_FOV_INTERP) { if (cpnext->fovType == CAMERA_FOV_INTERP || cpnext->fovType == CAMERA_FOV_FIXED) { fov = cp->fov; @@ -3222,107 +3532,6 @@ static qboolean CG_PlayCamera (void) cg.freecamSet = qtrue; } - if (cg.cameraQ3mme) { - int time; - float timeFraction; - - //time = floor(cg.time); - //timeFraction = cg.time - time; - time = cg.time; - timeFraction = (float)cg.foverf; - - //cameraOriginAt( time, timeFraction, demo.camera.origin ); - //cameraAnglesAt( time, timeFraction, demo.camera.angles ); - demo.camera.smoothPos = posBezier; - demo.camera.smoothAngles = angleQuat; - - cameraOriginAt(time, timeFraction, cg.refdef.vieworg); - cameraAnglesAt(time, timeFraction, cg.refdefViewAngles); - AnglesToAxis(cg.refdefViewAngles, cg.refdef.viewaxis); - //Com_Printf("angles: %f %f %f\n", cg.refdefViewAngles[0], cg.refdefViewAngles[1], cg.refdefViewAngles[2]); -#if 0 //FIXME q3mme camera - if (!cameraFovAt( time, timeFraction, &demo.camera.fov )) - demo.camera.fov = 0; -#endif - - Com_Printf("q3mme camera...\n"); - - trap_S_Respatialize(MAX_GENTITIES - 1, cg.refdef.vieworg, cg.refdef.viewaxis, qfalse); - - - if (cg_cameraUpdateFreeCam.integer && !cg_cameraDebugPath.integer) { - cg.fMoveTime = 0; //cg.realTime; //cg.time; - //cg.fMoveTime = cg.realTime - 10; - //cg.mousex = cg.mousey = 0; - VectorCopy(cg.refdef.vieworg, cg.fpos); - cg.fpos[2] -= DEFAULT_VIEWHEIGHT; - VectorCopy(cg.refdefViewAngles, cg.fang); - cg.freecamSet = qtrue; - //Com_Printf("xxx %f %f %f\n", cg.refdef.vieworg[0], cg.refdef.vieworg[1], cg.refdef.vieworg[2]); - if (cg.ftime >= lastPoint->cgtime) { - VectorClear(cg.freecamPlayerState.velocity); - } else if (cg.ftime > cg.positionSetTime) { - for (i = 0; i < 3; i++) { - cg.freecamPlayerState.velocity[i] = (cg.refdef.vieworg[i] - cg.cameraLastOrigin[i]) / ((cg.ftime - cg.positionSetTime) / 1000.0); - } - } else if (cg.ftime < cg.positionSetTime) { - VectorSet(cg.freecamPlayerState.velocity, 0, 0, 0); - } - } - - if (cg.ftime >= lastPoint->cgtime) { - VectorClear(cg.cameraVelocity); - } else if (cg.ftime > cg.positionSetTime) { - for (i = 0; i < 3; i++) { - cg.cameraVelocity[i] = (cg.refdef.vieworg[i] - cg.cameraLastOrigin[i]) / ((cg.ftime - cg.positionSetTime) / 1000.0); - } - } else if (cg.ftime < cg.positionSetTime) { - VectorSet(cg.cameraVelocity, 0, 0, 0); - } - - if (cg.ftime != cg.positionSetTime) { - cg.positionSetTime = cg.ftime; - VectorCopy(cg.refdef.vieworg, cg.cameraLastOrigin); - } - - if (cameraDebugPath) { //cg_cameraDebugPath.integer) { //(1) { - refEntity_t ent; - byte color[4] = { 255, 0, 0, 255 }; - - memset(&ent, 0, sizeof(ent)); - VectorCopy(cg.refdef.vieworg, ent.origin); - ent.reType = RT_MODEL; - ent.hModel = cgs.media.teleportEffectModel; - //ent.hModel = trap_R_RegisterModel("models/powerups/health/large_sphere.md3"); - //ent.hModel = trap_R_RegisterModel("models/powerups/health/mega_sphere.md3"); - AxisClear(ent.axis); - //ent.origin[2] += 16; - ent.radius = 300; - ent.customShader = 0; - ent.shaderRGBA[0] = 255; - ent.shaderRGBA[1] = 0; - ent.shaderRGBA[2] = 0; - ent.shaderRGBA[3] = 255; - ent.renderfx = RF_DEPTHHACK; - - CG_AddRefEntity(&ent); - - AngleVectors(cg.refdefViewAngles, dir, NULL, NULL); - VectorCopy(ent.origin, origin); - VectorMA(origin, 300, dir, origin); - CG_SimpleRailTrail(ent.origin, origin, cg_railTrailTime.value, color); - - VectorCopy(refOriginOrig, cg.refdef.vieworg); - VectorCopy(refAnglesOrig, cg.refdefViewAngles); - AnglesToAxis(cg.refdefViewAngles, cg.refdef.viewaxis); - cg.refdef.fov_x = refFovxOrig; - cg.refdef.fov_y = refFovyOrig; - VectorCopy(velocityOrig, cg.freecamPlayerState.velocity); - - cg.freecamSet = qtrue; - } - return qtrue; - } return qtrue; } @@ -3724,8 +3933,7 @@ static void CG_FreeCam (void) VectorMA(muzzle, 8, right, muzzle); //CG_SimpleRailTrail(muzzle, end, color); CG_SimpleRailTrail(muzzle, tr.endpos, cg_railTrailTime.value, color); - // entity number is a hack - CG_StartSound(NULL, MAX_GENTITIES - 1, CHAN_WEAPON, cg_weapons[WP_RAILGUN].flashSound[0]); + CG_StartSound(cg.refdef.vieworg, ENTITYNUM_WORLD, CHAN_WEAPON, cg_weapons[WP_RAILGUN].flashSound[0]); if (tr.entityNum < MAX_CLIENTS && tr.entityNum >= 0) { CG_GibPlayer(&cg_entities[tr.entityNum]); } else { @@ -3847,6 +4055,23 @@ static void CG_DrawRawCameraPathKeyPoints (void) } } +static void CG_Q3mmeDrawCross (const vec3_t origin, const vec4_t color) +{ + unsigned int i; + vec3_t start, end; + polyVert_t verts[4]; + + demoDrawSetupVerts( verts, color ); + /* Create a few lines indicating the point */ + for(i = 0; i < 3; i++) { + VectorCopy(origin, start); + VectorCopy(origin, end ); + start[i] -= 10; + end[i] += 10; + demoDrawRawLine( start, end, 0.6f, verts ); + } +} + static vec4_t SplineColor; static int SplineNumPoints; @@ -3868,6 +4093,30 @@ static void CG_DrawSplinePoints (void) return; } + //FIXME + // q3mme camera + if (cg.numQ3mmeCameraPoints > 0) { + demoCameraPoint_t *next, *point; + int count; + vec3_t origin; + + MAKERGBA(color, 255, 165, 9, 255); + point = demo.camera.points; + count = 0; + while (point) { + next = point->next; + + VectorCopy(point->origin, origin); + // draw cross like q3mme + CG_Q3mmeDrawCross(origin, colorWhite); + CG_Q3mmeCameraDrawPath(point, colorRed); + origin[2] += 4; + CG_FloatNumber(count, origin, RF_DEPTHHACK, color, 1.0); + point = next; + count++; + } + } + if (cg.numCameraPoints < 2) { SplineNumPoints = 0; trap_SetPathLines(&cg.numCameraPoints, cg.cameraPoints, &SplineNumPoints, cg.splinePoints, SplineColor); @@ -4439,6 +4688,8 @@ void CG_DrawActiveFrame (int serverTime, stereoFrame_t stereoView, qboolean demo cgs.screenXScale = cgs.glconfig.vidWidth / 640.0; cgs.screenYScale = cgs.glconfig.vidHeight / 480.0; //Com_Printf("w %d h %d\n", cgs.glconfig.vidWidth, cgs.glconfig.vidHeight); + memcpy(&cgDC.glconfig, &cgs.glconfig, sizeof(glconfig_t)); + cgDC.widescreen = cg_wideScreen.integer; //CG_Printf ("CG_DrawActiveFrame: serverTime:%d\n", serverTime); #if 0 @@ -4998,7 +5249,7 @@ void CG_DrawActiveFrame (int serverTime, stereoFrame_t stereoView, qboolean demo CG_VibrateCamera(); } - if (cg.cameraPlaying || cg_cameraQue.integer) { + if (cg.cameraPlaying || cg.cameraQ3mmePlaying || cg_cameraQue.integer) { CG_PlayCamera(); cg.refdef.time = cg.time; if (cg.freecam) { diff --git a/code/cgame/cg_weapons.c b/code/cgame/cg_weapons.c index c606facf..9b5343bc 100644 --- a/code/cgame/cg_weapons.c +++ b/code/cgame/cg_weapons.c @@ -1111,8 +1111,8 @@ void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi ) { clientInfo_t *ci; int clientNum; int cgtime; - centity_t *playerCent; - vec3_t end; + //centity_t *playerCent; + //vec3_t end; //Com_Printf("%f grapple trail\n", cg.ftime); @@ -1132,7 +1132,7 @@ void CG_GrappleTrail( centity_t *ent, const weaponInfo_t *wi ) { clientNum = 0; } ci = &cgs.clientinfo[clientNum]; - playerCent = &cg_entities[clientNum]; + //playerCent = &cg_entities[clientNum]; memset( &beam, 0, sizeof( beam ) ); //FIXME adjust for muzzle position diff --git a/code/client/cl_cgame.c b/code/client/cl_cgame.c index 6a23c661..c0610f42 100644 --- a/code/client/cl_cgame.c +++ b/code/client/cl_cgame.c @@ -277,7 +277,7 @@ qboolean CL_PeekSnapshot (int snapshotNumber, snapshot_t *snapshot) int i, count; int origPosition; int cmd; - char *s; + //char *s; char buffer[16]; qboolean success = qfalse; int r; @@ -409,7 +409,8 @@ qboolean CL_PeekSnapshot (int snapshotNumber, snapshot_t *snapshot) case svc_serverCommand: //CL_ParseCommandString( msg ); MSG_ReadLong(&buf); // seq - s = MSG_ReadString(&buf); + //s = MSG_ReadString(&buf); + MSG_ReadString(&buf); break; case svc_gamestate: //CL_ParseGamestate( msg ); diff --git a/code/client/cl_curl.c b/code/client/cl_curl.c index 9f263cbd..bcdd7d04 100644 --- a/code/client/cl_curl.c +++ b/code/client/cl_curl.c @@ -193,12 +193,20 @@ void CL_cURL_Shutdown( void ) void CL_cURL_Cleanup(void) { if(clc.downloadCURLM) { + CURLMcode result; + if(clc.downloadCURL) { - qcurl_multi_remove_handle(clc.downloadCURLM, + result = qcurl_multi_remove_handle(clc.downloadCURLM, clc.downloadCURL); + if(result != CURLM_OK) { + Com_DPrintf("qcurl_multi_remove_handle failed: %s\n", qcurl_multi_strerror(result)); + } qcurl_easy_cleanup(clc.downloadCURL); } - qcurl_multi_cleanup(clc.downloadCURLM); + result = qcurl_multi_cleanup(clc.downloadCURLM); + if(result != CURLM_OK) { + Com_DPrintf("CL_cURL_Cleanup: qcurl_multi_cleanup failed: %s\n", qcurl_multi_strerror(result)); + } clc.downloadCURLM = NULL; clc.downloadCURL = NULL; } @@ -225,8 +233,25 @@ static size_t CL_cURL_CallbackWrite(const void *buffer, size_t size, size_t nmem return size*nmemb; } +CURLcode qcurl_easy_setopt_warn(CURL *curl, CURLoption option, ...) +{ + CURLcode result; + va_list args; + + va_start(args, option); + result = qcurl_easy_setopt(curl, option, args); + va_end(args); + if(result != CURLE_OK) { + Com_DPrintf("qcurl_easy_setopt failed: %s\n", qcurl_easy_strerror(result)); + } + + return result; +} + void CL_cURL_BeginDownload( const char *localName, const char *remoteURL ) { + CURLMcode result; + clc.cURLUsed = qtrue; Com_Printf("URL: %s\n", remoteURL); Com_DPrintf("***** CL_cURL_BeginDownload *****\n" @@ -261,23 +286,23 @@ void CL_cURL_BeginDownload( const char *localName, const char *remoteURL ) return; } if(com_developer->integer) - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_VERBOSE, 1); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_URL, clc.downloadURL); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_TRANSFERTEXT, 0); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_REFERER, va("ioQ3://%s", + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_VERBOSE, 1); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_URL, clc.downloadURL); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_TRANSFERTEXT, 0); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_REFERER, va("ioQ3://%s", NET_AdrToString(clc.serverAddress))); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_USERAGENT, va("%s %s", + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_USERAGENT, va("%s %s", Q3_VERSION, qcurl_version())); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEFUNCTION, + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_WRITEFUNCTION, CL_cURL_CallbackWrite); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, &clc.download); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_NOPROGRESS, 0); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSFUNCTION, + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_WRITEDATA, &clc.download); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_NOPROGRESS, 0); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_PROGRESSFUNCTION, CL_cURL_CallbackProgress); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSDATA, NULL); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FAILONERROR, 1); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FOLLOWLOCATION, 1); - qcurl_easy_setopt(clc.downloadCURL, CURLOPT_MAXREDIRS, 5); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_PROGRESSDATA, NULL); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_FAILONERROR, 1); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_FOLLOWLOCATION, 1); + qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_MAXREDIRS, 5); clc.downloadCURLM = qcurl_multi_init(); if(!clc.downloadCURLM) { qcurl_easy_cleanup(clc.downloadCURL); @@ -286,7 +311,13 @@ void CL_cURL_BeginDownload( const char *localName, const char *remoteURL ) "failed"); return; } - qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL); + result = qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL); + if(result != CURLM_OK) { + qcurl_easy_cleanup(clc.downloadCURL); + clc.downloadCURL = NULL; + Com_Error(ERR_DROP,"CL_cURL_BeginDownload: qcurl_multi_add_handle() failed: %s", qcurl_multi_strerror(result)); + return; + } if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) && !clc.cURLDisconnected) { diff --git a/code/client/cl_main.c b/code/client/cl_main.c index f0d7c27c..5a842ab5 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -1864,10 +1864,15 @@ static qhandle_t CL_OpenDemoFile (const char *arg) } if (!Q_stricmpn(arg, "ql:", strlen("ql:"))) { - Com_sprintf(name, sizeof(name), "%s/home/baseq3/%s", Sys_QuakeLiveDir(), arg + 3); - //Com_Printf("trying ql demo %s\n", name); + // try steam quake live directory first + Com_sprintf(name, sizeof(name), "%s/baseq3/%s", Sys_QuakeLiveDir(), arg + 3); FS_FOpenSysFileRead(name, &file); + if (!file) { // try stand alone directory + Com_sprintf(name, sizeof(name), "%s/home/baseq3/%s", Sys_QuakeLiveDir(), arg + 3); + FS_FOpenSysFileRead(name, &file); + } + if (!file) { Com_Error(ERR_DROP, "couldn't open '%s' in quake live directory", arg + 3); return 0; @@ -1908,10 +1913,43 @@ static qhandle_t CL_OpenDemoFile (const char *arg) } } - // check quakelive dir + // check steam quakelive dir + if (!file) { + Com_sprintf(name, sizeof(name), "%s/baseq3/%s", Sys_QuakeLiveDir(), demoPathName); + FS_FOpenSysFileRead(name, &file); + if (file) { + goto done; + } + + // check to see if name was given without protocol extension + + for (i = 0; i < ARRAY_LEN(demo_protocols) && !file; i++) { + Com_sprintf(name, sizeof(name), "%s/baseq3/%s.dm_%d", Sys_QuakeLiveDir(), demoPathName, demo_protocols[i]); + FS_FOpenSysFileRead(name, &file); + if (!file) { + Com_sprintf(name, sizeof(name), "%s/baseq3/%s.DM_%d", Sys_QuakeLiveDir(), demoPathName, demo_protocols[i]); + FS_FOpenSysFileRead(name, &file); + if (!file) { + // :/ + Com_sprintf(name, sizeof(name), "%s/baseq3/%s.dM_%d", Sys_QuakeLiveDir(), demoPathName, demo_protocols[i]); + FS_FOpenSysFileRead(name, &file); + if (!file) { + // :{ :/ + Com_sprintf(name, sizeof(name), "%s/baseq3/%s.Dm_%d", Sys_QuakeLiveDir(), demoPathName, demo_protocols[i]); + FS_FOpenSysFileRead(name, &file); + } + } + } + } // end protocol list + } + + // check stand alone quakelive dir if (!file) { Com_sprintf(name, sizeof(name), "%s/home/baseq3/%s", Sys_QuakeLiveDir(), demoPathName); FS_FOpenSysFileRead(name, &file); + if (file) { + goto done; + } // check to see if name was given without protocol extension @@ -2391,7 +2429,7 @@ void CL_Disconnect( qboolean showMainMenu ) { CL_UpdateGUID( NULL, 0 ); CL_ShutdownCGame(); - Cvar_Set("protocol", va("%d", PROTOCOL_QL)); + Cvar_Set("protocol", va("%i", SERVER_PROTOCOL)); } diff --git a/code/client/cl_parse.c b/code/client/cl_parse.c index 822ebfc4..07761cf7 100644 --- a/code/client/cl_parse.c +++ b/code/client/cl_parse.c @@ -716,7 +716,7 @@ CL_ParseServerInfo static void CL_ParseServerInfo(void) { const char *serverInfo; - const char *value; + //const char *value; serverInfo = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SERVERINFO ]; @@ -735,11 +735,11 @@ static void CL_ParseExtraGamestate (demoFile_t *df, msg_t *msg) int newnum; entityState_t nullstate; int cmd; - char *s; - int serverCommandSequence; + //char *s; + //int serverCommandSequence; entityState_t tmpEntity; - int clientNum; - int checksumFeed; + //int clientNum; + //int checksumFeed; //clc.connectPacketCount = 0; @@ -747,7 +747,8 @@ static void CL_ParseExtraGamestate (demoFile_t *df, msg_t *msg) //CL_ClearState(); // a gamestate always marks a server command sequence - serverCommandSequence = MSG_ReadLong( msg ); + //serverCommandSequence = MSG_ReadLong( msg ); + MSG_ReadLong(msg); // parse all the configstrings and baselines //cl.gameState.dataCount = 1; // leave a 0 at the beginning for uninitialized configstrings @@ -772,7 +773,8 @@ static void CL_ParseExtraGamestate (demoFile_t *df, msg_t *msg) Com_Printf("^1CL_ParseExtraGamestate configstring(%d) > MAX_CONFIGSTRINGS(%d) demoFile %d\n", i, MAX_CONFIGSTRINGS, df->f); return; } - s = MSG_ReadBigString( msg ); + //s = MSG_ReadBigString( msg ); + MSG_ReadBigString(msg); //len = strlen( s ); #if 0 @@ -808,10 +810,13 @@ static void CL_ParseExtraGamestate (demoFile_t *df, msg_t *msg) } //clc.clientNum = MSG_ReadLong(msg); - clientNum = MSG_ReadLong(msg); + //clientNum = MSG_ReadLong(msg); + MSG_ReadLong(msg); + // read the checksum feed //clc.checksumFeed = MSG_ReadLong( msg ); - checksumFeed = MSG_ReadLong(msg); + //checksumFeed = MSG_ReadLong(msg); + MSG_ReadLong(msg); // parse useful values out of CS_SERVERINFO //CL_ParseServerInfo(); @@ -1665,7 +1670,7 @@ void CL_ParseServerMessage( msg_t *msg ) { void CL_ParseExtraServerMessage (demoFile_t *df, msg_t *msg) { int cmd; - int reliableAcknowledge; + //int reliableAcknowledge; if ( cl_shownet->integer == 1 ) { Com_Printf ("%i ",msg->cursize); @@ -1676,7 +1681,8 @@ void CL_ParseExtraServerMessage (demoFile_t *df, msg_t *msg) MSG_Bitstream(msg); // get the reliable sequence acknowledge number - reliableAcknowledge = MSG_ReadLong( msg ); + //reliableAcknowledge = MSG_ReadLong( msg ); + MSG_ReadLong(msg); #if 0 // diff --git a/code/game/bg_misc.c b/code/game/bg_misc.c index ef5a21b2..9b9dcbf9 100644 --- a/code/game/bg_misc.c +++ b/code/game/bg_misc.c @@ -77,27 +77,1038 @@ int PERS_ATTACKEE_ARMOR = 14; int WP_NUM_WEAPONS = 15; // quakelive dm_90 with hmg +int PW_NONE = PWOLD_NONE; +//int PW_SPAWNARMOR = PWOLD_SPAWNARMOR; +int PW_QUAD = PWOLD_QUAD; +int PW_BATTLESUIT = PWOLD_BATTLESUIT; +int PW_HASTE = PWOLD_HASTE; +int PW_INVIS = PWOLD_INVIS; +int PW_REGEN = PWOLD_REGEN; +int PW_FLIGHT = PWOLD_FLIGHT; +int PW_REDFLAG = PWOLD_REDFLAG; +int PW_BLUEFLAG = PWOLD_BLUEFLAG; +int PW_NEUTRALFLAG = PWOLD_NEUTRALFLAG; +int PW_INVULNERABILITY = PWOLD_INVULNERABILITY; +int PW_SCOUT = PWOLD_SCOUT; +int PW_GUARD = PWOLD_GUARD; +int PW_DOUBLER = PWOLD_DOUBLER; +int PW_ARMORREGEN = PWOLD_ARMORREGEN; +int PW_FROZEN = PWOLD_FROZEN; +int PW_NUM_POWERUPS = PWOLD_NUM_POWERUPS; + const vec3_t bg_playerMins = { -15, -15, -24 }; const vec3_t bg_playerMaxs = { 15, 15, 32 }; -/*QUAKED item_***** ( 0 0 0 ) (-16 -16 -16) (16 16 16) suspended -DO NOT USE THIS CLASS, IT JUST HOLDS GENERAL INFORMATION. -The suspended flag will allow items to hang in the air, otherwise they are dropped to the next surface. +/*QUAKED item_***** ( 0 0 0 ) (-16 -16 -16) (16 16 16) suspended +DO NOT USE THIS CLASS, IT JUST HOLDS GENERAL INFORMATION. +The suspended flag will allow items to hang in the air, otherwise they are dropped to the next surface. + +If an item is the target of another entity, it will not spawn in until fired. + +An item fires all of its targets when it is picked up. If the toucher can't carry it, the targets won't be fired. + +"notfree" if set to 1, don't spawn in free for all games +"notteam" if set to 1, don't spawn in team games +"notsingle" if set to 1, don't spawn in single player games +"wait" override the default wait before respawning. -1 = never respawn automatically, which can be used with targeted spawning. +"random" random number of plus or minus seconds varied from the respawn time +"count" override quantity or duration on most items. +*/ + +// ql dm 90 +gitem_t bg_itemlist[] = +{ + { + NULL, + NULL, + { NULL, + NULL, + 0, 0} , +/* icon */ NULL, +/* pickup */ NULL, + 0, + 0, + 0, +/* precache */ "", +/* sounds */ "" + }, // leave index 0 alone + + // + // ARMOR + // + +/*QUAKED item_armor_shard (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_armor_shard", + "sound/misc/ar1_pkup.wav", + { "models/powerups/armor/shard.md3", + "models/powerups/armor/shard_sphere.md3", + 0, 0} , +/* icon */ "icons/iconr_shard", +/* pickup */ "Armor Shard", + 5, + IT_ARMOR, + 0, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_armor_combat (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_armor_combat", + "sound/misc/ar2_pkup.wav", + { "models/powerups/armor/armor_yel.md3", + 0, 0, 0}, +/* icon */ "icons/iconr_yellow", + /* pickup */ "Yellow Armor", // "Yellow Armor" + 50, + IT_ARMOR, + 0, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_armor_body", + "sound/misc/ar2_pkup.wav", + { "models/powerups/armor/armor_red.md3", + 0, 0, 0}, +/* icon */ "icons/iconr_red", + /* pickup */ "Red Armor", // "Red Armor" + 100, + IT_ARMOR, + 0, +/* precache */ "", +/* sounds */ "" + }, +/*QUAKED item_armor_body (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_armor_jacket", + "sound/misc/ar2_pkup.wav", + { "models/powerups/armor/armor_grn.md3", + 0, 0, 0}, +/* icon */ "icons/iconr_green", + /* pickup */ "Green Armor", + 25, //FIXME + IT_ARMOR, + 0, +/* precache */ "", +/* sounds */ "" + }, + + // + // health + // +/*QUAKED item_health_small (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_health_small", + "sound/items/s_health.wav", + { "models/powerups/health/small_cross.md3", + "models/powerups/health/small_sphere.md3", + 0, 0 }, +/* icon */ "icons/iconh_green", +/* pickup */ "5 Health", + 5, + IT_HEALTH, + 0, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_health (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_health", + "sound/items/n_health.wav", + { "models/powerups/health/medium_cross.md3", + "models/powerups/health/medium_sphere.md3", + 0, 0 }, +/* icon */ "icons/iconh_yellow", +/* pickup */ "25 Health", + 25, + IT_HEALTH, + 0, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_health_large (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_health_large", + "sound/items/l_health.wav", + { "models/powerups/health/large_cross.md3", + "models/powerups/health/large_sphere.md3", + 0, 0 }, +/* icon */ "icons/iconh_red", +/* pickup */ "50 Health", + 50, + IT_HEALTH, + 0, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_health_mega (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_health_mega", + "sound/items/m_health.wav", + { "models/powerups/health/mega_cross.md3", + "models/powerups/health/mega_sphere.md3", + 0, 0 }, +/* icon */ "icons/iconh_mega", +/* pickup */ "Mega Health", + 100, + IT_HEALTH, + 0, +/* precache */ "", +/* sounds */ "" + }, + + + // + // WEAPONS + // + +/*QUAKED weapon_gauntlet (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_gauntlet", + "sound/misc/w_pkup.wav", + { "models/weapons2/gauntlet/gauntlet.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_gauntlet", +/* pickup */ "Gauntlet", + 0, + IT_WEAPON, + WP_GAUNTLET, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_shotgun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_shotgun", + "sound/misc/w_pkup.wav", + { "models/weapons2/shotgun/shotgun.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_shotgun", +/* pickup */ "Shotgun", + 10, + IT_WEAPON, + WP_SHOTGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_machinegun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_machinegun", + "sound/misc/w_pkup.wav", + { "models/weapons2/machinegun/machinegun.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_machinegun", +/* pickup */ "Machinegun", + 40, + IT_WEAPON, + WP_MACHINEGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_grenadelauncher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_grenadelauncher", + "sound/misc/w_pkup.wav", + { "models/weapons2/grenadel/grenadel.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_grenade", +/* pickup */ "Grenade Launcher", + 10, + IT_WEAPON, + WP_GRENADE_LAUNCHER, +/* precache */ "", +/* sounds */ "sound/weapons/grenade/hgrenb1a.wav sound/weapons/grenade/hgrenb2a.wav" + }, + +/*QUAKED weapon_rocketlauncher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_rocketlauncher", + "sound/misc/w_pkup.wav", + { "models/weapons2/rocketl/rocketl.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_rocket", +/* pickup */ "Rocket Launcher", + 10, + IT_WEAPON, + WP_ROCKET_LAUNCHER, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_lightning (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_lightning", + "sound/misc/w_pkup.wav", + { "models/weapons2/lightning/lightning.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_lightning", +/* pickup */ "Lightning Gun", + 100, + IT_WEAPON, + WP_LIGHTNING, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_railgun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_railgun", + "sound/misc/w_pkup.wav", + { "models/weapons2/railgun/railgun.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_railgun", +/* pickup */ "Railgun", + 10, + IT_WEAPON, + WP_RAILGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_plasmagun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_plasmagun", + "sound/misc/w_pkup.wav", + { "models/weapons2/plasma/plasma.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_plasma", +/* pickup */ "Plasma Gun", + 50, + IT_WEAPON, + WP_PLASMAGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_bfg", + "sound/misc/w_pkup.wav", + { "models/weapons2/bfg/bfg.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_bfg", +/* pickup */ "BFG10K", + 20, + IT_WEAPON, + WP_BFG, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED weapon_grapplinghook (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_grapplinghook", + "sound/misc/w_pkup.wav", + { "models/weapons2/grapple/grapple.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_grapple", +/* pickup */ "Grappling Hook", + 0, + IT_WEAPON, + WP_GRAPPLING_HOOK, +/* precache */ "", +/* sounds */ "" + }, + + // + // AMMO ITEMS + // + +/*QUAKED ammo_shells (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_shells", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/shotgunam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_shotgun", +/* pickup */ "Shells", + 10, + IT_AMMO, + WP_SHOTGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_bullets (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_bullets", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/machinegunam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_machinegun", +/* pickup */ "Bullets", + 50, + IT_AMMO, + WP_MACHINEGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_grenades (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_grenades", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/grenadeam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_grenade", +/* pickup */ "Grenades", + 5, + IT_AMMO, + WP_GRENADE_LAUNCHER, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_cells (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_cells", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/plasmaam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_plasma", +/* pickup */ "Cells", + 30, + IT_AMMO, + WP_PLASMAGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_lightning (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_lightning", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/lightningam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_lightning", +/* pickup */ "Lightning", + 60, + IT_AMMO, + WP_LIGHTNING, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_rockets (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_rockets", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/rocketam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_rocket", +/* pickup */ "Rockets", + 5, + IT_AMMO, + WP_ROCKET_LAUNCHER, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_slugs (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_slugs", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/railgunam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_railgun", +/* pickup */ "Slugs", + 10, + IT_AMMO, + WP_RAILGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_bfg (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_bfg", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/bfgam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_bfg", +/* pickup */ "Bfg Ammo", + 15, + IT_AMMO, + WP_BFG, +/* precache */ "", +/* sounds */ "" + }, + + // + // HOLDABLE ITEMS + // +/*QUAKED holdable_teleporter (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "holdable_teleporter", + "sound/items/holdable.wav", + { "models/powerups/holdable/teleporter.md3", + 0, 0, 0}, +/* icon */ "icons/teleporter", +/* pickup */ "Personal Teleporter", + 60, + IT_HOLDABLE, + HI_TELEPORTER, +/* precache */ "", +/* sounds */ "" + }, +/*QUAKED holdable_medkit (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "holdable_medkit", + "sound/items/holdable.wav", + { + "models/powerups/holdable/medkit.md3", + "models/powerups/holdable/medkit_sphere.md3", + 0, 0}, +/* icon */ "icons/medkit", +/* pickup */ "Medkit", + 60, + IT_HOLDABLE, + HI_MEDKIT, +/* precache */ "", +/* sounds */ "sound/items/use_medkit.wav" + }, + + // + // POWERUP ITEMS + // +/*QUAKED item_quad (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_quad", + "sound/vo/quad_damage.wav", + { "models/powerups/instant/quad.md3", + "models/powerups/instant/quad_ring.md3", + 0, 0 }, +/* icon */ "icons/quad", +/* pickup */ "Quad Damage", + 30, + IT_POWERUP, + PWOLD_QUAD, +/* precache */ "", +/* sounds */ "sound/items/damage3.wav" + }, + +/*QUAKED item_enviro (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_enviro", + "sound/vo/battlesuit.ogg", + { "models/powerups/instant/enviro.md3", + "models/powerups/instant/enviro_ring.md3", + 0, 0 }, +/* icon */ "icons/envirosuit", +/* pickup */ "Battle Suit", + 30, + IT_POWERUP, + PWOLD_BATTLESUIT, +/* precache */ "", +/* sounds */ "sound/items/protect3.wav" + }, + +/*QUAKED item_haste (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_haste", + "sound/vo/haste.wav", + { "models/powerups/instant/haste.md3", + "models/powerups/instant/haste_ring.md3", + 0, 0 }, +/* icon */ "icons/haste", +/* pickup */ "Haste", + 30, + IT_POWERUP, + PWOLD_HASTE, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_invis (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_invis", + "sound/vo/invisibility.wav", + { "models/powerups/instant/invis.md3", + "models/powerups/instant/invis_ring.md3", + 0, 0 }, +/* icon */ "icons/invis", +/* pickup */ "Invisibility", + 30, + IT_POWERUP, + PWOLD_INVIS, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_regen (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_regen", + "sound/vo/regeneration.wav", + { "models/powerups/instant/regen.md3", + "models/powerups/instant/regen_ring.md3", + 0, 0 }, +/* icon */ "icons/regen", +/* pickup */ "Regeneration", + 30, + IT_POWERUP, + PWOLD_REGEN, +/* precache */ "", +/* sounds */ "sound/items/regen.wav" + }, + +/*QUAKED item_flight (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "item_flight", + "sound/items/flight.wav", + { "models/powerups/instant/flight.md3", + "models/powerups/instant/flight_ring.md3", + 0, 0 }, +/* icon */ "icons/flight", +/* pickup */ "Flight", + 60, + IT_POWERUP, + PWOLD_FLIGHT, +/* precache */ "", +/* sounds */ "sound/items/flight.wav" + }, + +/*QUAKED team_CTF_redflag (1 0 0) (-16 -16 -16) (16 16 16) +Only in CTF games +*/ + { + "team_CTF_redflag", + NULL, + { "models/flags/r_flag.md3", "models/flag3/r_flag3.md3", + 0, 0 }, +/* icon */ "icons/iconf_red1", +/* pickup */ "Red Flag", + 0, + IT_TEAM, + PWOLD_REDFLAG, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED team_CTF_blueflag (0 0 1) (-16 -16 -16) (16 16 16) +Only in CTF games +*/ + { + "team_CTF_blueflag", + NULL, + { "models/flags/b_flag.md3", "models/flag3/b_flag3.md3", + 0, 0 }, +/* icon */ "icons/iconf_blu1", +/* pickup */ "Blue Flag", + 0, + IT_TEAM, + PWOLD_BLUEFLAG, +/* precache */ "", +/* sounds */ "" + }, + +#if 1 //def MPACK +/*QUAKED holdable_kamikaze (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "holdable_kamikaze", + "sound/items/holdable.wav", + { "models/powerups/kamikazi.md3", + 0, 0, 0}, +/* icon */ "icons/kamikaze", +/* pickup */ "Kamikaze", + 60, + IT_HOLDABLE, + HI_KAMIKAZE, +/* precache */ "", +/* sounds */ "sound/items/kamikazerespawn.wav" + }, + +/*QUAKED holdable_portal (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "holdable_portal", + "sound/items/holdable.wav", + { "models/powerups/holdable/porter.md3", + 0, 0, 0}, +/* icon */ "icons/portal", +/* pickup */ "Portal", + 60, + IT_HOLDABLE, + HI_PORTAL, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED holdable_invulnerability (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "holdable_invulnerability", + "sound/items/holdable.wav", + { "models/powerups/holdable/invulnerability.md3", + 0, 0, 0}, +/* icon */ "icons/invulnerability", +/* pickup */ "Invulnerability", + 60, + IT_HOLDABLE, + HI_INVULNERABILITY, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_nails (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_nails", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/nailgunam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_nailgun", +/* pickup */ "Nails", + 20, + IT_AMMO, + WP_NAILGUN, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_mines (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_mines", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/proxmineam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_proxlauncher", +/* pickup */ "Proximity Mines", + 10, + IT_AMMO, + WP_PROX_LAUNCHER, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED ammo_belt (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "ammo_belt", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/chaingunam.md3", + 0, 0, 0}, +/* icon */ "icons/icona_chaingun", +/* pickup */ "Chaingun Belt", + 100, + IT_AMMO, + WP_CHAINGUN, +/* precache */ "", +/* sounds */ "" + }, + + // + // PERSISTANT POWERUP ITEMS + // +/*QUAKED item_scout (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam +*/ + { + "item_scout", + "sound/items/cl_scout.wav", + { "models/powerups/scout.md3", + 0, 0, 0 }, +/* icon */ "icons/scout", +/* pickup */ "Scout", + 30, + IT_PERSISTANT_POWERUP, + PWOLD_SCOUT, +/* precache */ "", +/* sounds */ "" + }, + +/*QUAKED item_guard (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam +*/ + { + "item_guard", + "sound/items/cl_guard.wav", + { "models/powerups/guard.md3", + 0, 0, 0 }, +/* icon */ "icons/guard", +/* pickup */ "Guard", + 30, + IT_PERSISTANT_POWERUP, + PWOLD_GUARD, +/* precache */ "", +/* sounds */ "" + }, -If an item is the target of another entity, it will not spawn in until fired. +/*QUAKED item_doubler (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam +*/ + { + "item_doubler", + //"sound/items/cl_doubler.wav", + "sound/items/cl_damage.ogg", + { "models/powerups/doubler.md3", + 0, 0, 0 }, +/* icon */ "icons/doubler", +/* pickup */ "Doubler", + 30, + IT_PERSISTANT_POWERUP, + PWOLD_DOUBLER, +/* precache */ "", +/* sounds */ "" + }, -An item fires all of its targets when it is picked up. If the toucher can't carry it, the targets won't be fired. +/*QUAKED item_doubler (.3 .3 1) (-16 -16 -16) (16 16 16) suspended redTeam blueTeam +*/ + { + "item_ammoregen", //FIXME double check + "sound/items/cl_armorregen.wav", + { "models/powerups/ammo.md3", + 0, 0, 0 }, +/* icon */ "icons/armor_regen", +/* pickup */ "Armor Regen", + 30, + IT_PERSISTANT_POWERUP, + PWOLD_ARMORREGEN, +/* precache */ "", +/* sounds */ "" + }, -"notfree" if set to 1, don't spawn in free for all games -"notteam" if set to 1, don't spawn in team games -"notsingle" if set to 1, don't spawn in single player games -"wait" override the default wait before respawning. -1 = never respawn automatically, which can be used with targeted spawning. -"random" random number of plus or minus seconds varied from the respawn time -"count" override quantity or duration on most items. + /*QUAKED team_CTF_neutralflag (0 0 1) (-16 -16 -16) (16 16 16) +Only in One Flag CTF games +*/ + { + "team_CTF_neutralflag", + NULL, + { "models/flags/n_flag.md3", "models/flag3/n_flag3.md3", + 0, 0 }, +/* icon */ "icons/iconf_neutral1", +/* pickup */ "Neutral Flag", + 0, + IT_TEAM, + PWOLD_NEUTRALFLAG, +/* precache */ "", +/* sounds */ "" + }, + + { + "item_redcube", + "sound/misc/am_pkup.wav", + { "models/powerups/orb/r_orb.md3", + 0, 0, 0 }, +/* icon */ "icons/iconh_rorb", +/* pickup */ "Red Skull", + 0, + IT_TEAM, + 0, +/* precache */ "", +/* sounds */ "" + }, + + { + "item_bluecube", + "sound/misc/am_pkup.wav", + { "models/powerups/orb/b_orb.md3", + 0, 0, 0 }, +/* icon */ "icons/iconh_borb", +/* pickup */ "Blue Skull", + 0, + IT_TEAM, + 0, +/* precache */ "", +/* sounds */ "" + }, +/*QUAKED weapon_nailgun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended */ + { + "weapon_nailgun", + "sound/misc/w_pkup.wav", + { "models/weapons/nailgun/nailgun.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_nailgun", +/* pickup */ "Nailgun", + 10, + IT_WEAPON, + WP_NAILGUN, +/* precache */ "", +/* sounds */ "" + }, -// ql dm 90 -gitem_t bg_itemlist[] = +/*QUAKED weapon_prox_launcher (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_prox_launcher", + "sound/misc/w_pkup.wav", + { "models/weapons/proxmine/proxmine.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_proxlauncher", +/* pickup */ "Prox Launcher", + 5, + IT_WEAPON, + WP_PROX_LAUNCHER, +/* precache */ "", +/* sounds */ "sound/weapons/proxmine/wstbtick.wav " + "sound/weapons/proxmine/wstbactv.wav " + "sound/weapons/proxmine/wstbimpl.wav " + "sound/weapons/proxmine/wstbimpm.wav " + "sound/weapons/proxmine/wstbimpd.wav " + "sound/weapons/proxmine/wstbactv.wav" + }, + +/*QUAKED weapon_chaingun (.3 .3 1) (-16 -16 -16) (16 16 16) suspended +*/ + { + "weapon_chaingun", + "sound/misc/w_pkup.wav", + { "models/weapons/vulcan/vulcan.md3", + 0, 0, 0}, +/* icon */ "icons/iconw_chaingun", +/* pickup */ "Chaingun", + 80, + IT_WEAPON, + WP_CHAINGUN, +/* precache */ "", +/* sounds */ "sound/weapons/vulcan/wvulwind.wav" + }, +#endif + +#if 1 + { + "item_spawnarmor", + "", //FIXME + { 0, 0, 0, 0 }, + "icons/spawnarmor", + "Spawn Armor", + 0, + 0, // IT_ ?? + 0, // ? + "", + "" + }, +#endif + + { + "weap_hmg", + "sound/misc/w_pkup.wav", + { "models/weapons3/hmg/hmg.md3", 0, 0, 0 }, + "icons/weap_hmg", + "Heavy Machinegun", + 0, //FIXME + IT_WEAPON, + WP_HEAVY_MACHINEGUN, + "", //FIXME + "" //FIXME + }, + + { + "ammo_hmg", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/hmgam.md3", 0, 0, 0 }, + "icons/ammo_hmg", + "Heavy Bllets", + 0, //FIXME + IT_AMMO, + WP_HEAVY_MACHINEGUN, + "", //FIXME + "" //FIXME + }, + + // ammo pack + { + "ammo_pack", + "sound/misc/am_pkup.wav", + { "models/powerups/ammo/ammopack.md3", 0, 0, 0 }, + "icons/ammo_pack", + "Ammo Pack", + 0, //FIXME + IT_AMMO, + 0, //FIXME + "", //FIXME + "" //FIXME + }, + + // keys + { + "item_key_silver", + "sound/items/key_silver.wav", + { "models/powerups/keys/key_silver.md3", 0, 0, 0 }, + "icons/key_silver", + "Silver Key", + 0, //FIXME + IT_PERSISTANT_POWERUP, + PWEX_KEY, //FIXME PW_QUAD .. PW_SILVER_KEY + "", //FIXME + "" //FIXME + }, + + { + "item_key_gold", + "sound/items/key_gold.wav", + { "models/powerups/keys/key_gold.md3", 0, 0, 0 }, + "icons/key_gold", + "Gold Key", + 0, //FIXME + IT_PERSISTANT_POWERUP, + PWEX_KEY, //FIXME PW_QUAD .. PW_SILVER_KEY + "", //FIXME + "" //FIXME + }, + + { + "item_key_master", + "sound/items/key_master.wav", + { "models/powerups/keys/key_master.md3", 0, 0, 0 }, + "icons/key_master", + "Master Key", + 0, //FIXME + IT_PERSISTANT_POWERUP, + PWEX_KEY, //FIXME PW_QUAD .. PW_SILVER_KEY + "", //FIXME + "" //FIXME + }, + + + // end of list marker + {NULL} +}; + +//FIXME 2015-07-30 just using qldm90 list since ql with protocol 91 isn't released yet, just need to update powerup indexes +const gitem_t bg_itemlistQldm91[] = { { NULL, @@ -601,7 +1612,7 @@ gitem_t bg_itemlist[] = /* pickup */ "Quad Damage", 30, IT_POWERUP, - PW_QUAD, + PW91_QUAD, /* precache */ "", /* sounds */ "sound/items/damage3.wav" }, @@ -618,7 +1629,7 @@ gitem_t bg_itemlist[] = /* pickup */ "Battle Suit", 30, IT_POWERUP, - PW_BATTLESUIT, + PW91_BATTLESUIT, /* precache */ "", /* sounds */ "sound/items/protect3.wav" }, @@ -635,7 +1646,7 @@ gitem_t bg_itemlist[] = /* pickup */ "Haste", 30, IT_POWERUP, - PW_HASTE, + PW91_HASTE, /* precache */ "", /* sounds */ "" }, @@ -652,7 +1663,7 @@ gitem_t bg_itemlist[] = /* pickup */ "Invisibility", 30, IT_POWERUP, - PW_INVIS, + PW91_INVIS, /* precache */ "", /* sounds */ "" }, @@ -669,7 +1680,7 @@ gitem_t bg_itemlist[] = /* pickup */ "Regeneration", 30, IT_POWERUP, - PW_REGEN, + PW91_REGEN, /* precache */ "", /* sounds */ "sound/items/regen.wav" }, @@ -686,7 +1697,7 @@ gitem_t bg_itemlist[] = /* pickup */ "Flight", 60, IT_POWERUP, - PW_FLIGHT, + PW91_FLIGHT, /* precache */ "", /* sounds */ "sound/items/flight.wav" }, @@ -703,7 +1714,7 @@ Only in CTF games /* pickup */ "Red Flag", 0, IT_TEAM, - PW_REDFLAG, + PW91_REDFLAG, /* precache */ "", /* sounds */ "" }, @@ -720,7 +1731,7 @@ Only in CTF games /* pickup */ "Blue Flag", 0, IT_TEAM, - PW_BLUEFLAG, + PW91_BLUEFLAG, /* precache */ "", /* sounds */ "" }, @@ -836,7 +1847,7 @@ Only in CTF games /* pickup */ "Scout", 30, IT_PERSISTANT_POWERUP, - PW_SCOUT, + PW91_SCOUT, /* precache */ "", /* sounds */ "" }, @@ -852,7 +1863,7 @@ Only in CTF games /* pickup */ "Guard", 30, IT_PERSISTANT_POWERUP, - PW_GUARD, + PW91_GUARD, /* precache */ "", /* sounds */ "" }, @@ -869,7 +1880,7 @@ Only in CTF games /* pickup */ "Doubler", 30, IT_PERSISTANT_POWERUP, - PW_DOUBLER, + PW91_DOUBLER, /* precache */ "", /* sounds */ "" }, @@ -885,7 +1896,7 @@ Only in CTF games /* pickup */ "Armor Regen", 30, IT_PERSISTANT_POWERUP, - PW_ARMORREGEN, + PW91_ARMORREGEN, /* precache */ "", /* sounds */ "" }, @@ -902,7 +1913,7 @@ Only in One Flag CTF games /* pickup */ "Neutral Flag", 0, IT_TEAM, - PW_NEUTRALFLAG, + PW91_NEUTRALFLAG, /* precache */ "", /* sounds */ "" }, @@ -1052,7 +2063,7 @@ Only in One Flag CTF games "Silver Key", 0, //FIXME IT_PERSISTANT_POWERUP, - PW_KEY, //FIXME PW_QUAD .. PW_SILVER_KEY + PWEX_KEY, //FIXME PW91_QUAD .. PW_SILVER_KEY "", //FIXME "" //FIXME }, @@ -1065,7 +2076,7 @@ Only in One Flag CTF games "Gold Key", 0, //FIXME IT_PERSISTANT_POWERUP, - PW_KEY, //FIXME PW_QUAD .. PW_SILVER_KEY + PWEX_KEY, //FIXME PW91_QUAD .. PW_SILVER_KEY "", //FIXME "" //FIXME }, @@ -1078,7 +2089,7 @@ Only in One Flag CTF games "Master Key", 0, //FIXME IT_PERSISTANT_POWERUP, - PW_KEY, //FIXME PW_QUAD .. PW_SILVER_KEY + PWEX_KEY, //FIXME PW91_QUAD .. PW_SILVER_KEY "", //FIXME "" //FIXME }, @@ -1593,7 +2604,7 @@ const gitem_t bg_itemlistQldm73[] = /* pickup */ "Quad Damage", 30, IT_POWERUP, - PW_QUAD, + PWOLD_QUAD, /* precache */ "", /* sounds */ "sound/items/damage3.wav" }, @@ -1610,7 +2621,7 @@ const gitem_t bg_itemlistQldm73[] = /* pickup */ "Battle Suit", 30, IT_POWERUP, - PW_BATTLESUIT, + PWOLD_BATTLESUIT, /* precache */ "", /* sounds */ "sound/items/protect3.wav" }, @@ -1627,7 +2638,7 @@ const gitem_t bg_itemlistQldm73[] = /* pickup */ "Haste", 30, IT_POWERUP, - PW_HASTE, + PWOLD_HASTE, /* precache */ "", /* sounds */ "" }, @@ -1644,7 +2655,7 @@ const gitem_t bg_itemlistQldm73[] = /* pickup */ "Invisibility", 30, IT_POWERUP, - PW_INVIS, + PWOLD_INVIS, /* precache */ "", /* sounds */ "" }, @@ -1661,7 +2672,7 @@ const gitem_t bg_itemlistQldm73[] = /* pickup */ "Regeneration", 30, IT_POWERUP, - PW_REGEN, + PWOLD_REGEN, /* precache */ "", /* sounds */ "sound/items/regen.wav" }, @@ -1678,7 +2689,7 @@ const gitem_t bg_itemlistQldm73[] = /* pickup */ "Flight", 60, IT_POWERUP, - PW_FLIGHT, + PWOLD_FLIGHT, /* precache */ "", /* sounds */ "sound/items/flight.wav" }, @@ -1695,7 +2706,7 @@ Only in CTF games /* pickup */ "Red Flag", 0, IT_TEAM, - PW_REDFLAG, + PWOLD_REDFLAG, /* precache */ "", /* sounds */ "" }, @@ -1712,7 +2723,7 @@ Only in CTF games /* pickup */ "Blue Flag", 0, IT_TEAM, - PW_BLUEFLAG, + PWOLD_BLUEFLAG, /* precache */ "", /* sounds */ "" }, @@ -1828,7 +2839,7 @@ Only in CTF games /* pickup */ "Scout", 30, IT_PERSISTANT_POWERUP, - PW_SCOUT, + PWOLD_SCOUT, /* precache */ "", /* sounds */ "" }, @@ -1844,7 +2855,7 @@ Only in CTF games /* pickup */ "Guard", 30, IT_PERSISTANT_POWERUP, - PW_GUARD, + PWOLD_GUARD, /* precache */ "", /* sounds */ "" }, @@ -1861,7 +2872,7 @@ Only in CTF games /* pickup */ "Doubler", 30, IT_PERSISTANT_POWERUP, - PW_DOUBLER, + PWOLD_DOUBLER, /* precache */ "", /* sounds */ "" }, @@ -1877,7 +2888,7 @@ Only in CTF games /* pickup */ "Armor Regen", 30, IT_PERSISTANT_POWERUP, - PW_ARMORREGEN, + PWOLD_ARMORREGEN, /* precache */ "", /* sounds */ "" }, @@ -1894,7 +2905,7 @@ Only in One Flag CTF games /* pickup */ "Neutral Flag", 0, IT_TEAM, - PW_NEUTRALFLAG, + PWOLD_NEUTRALFLAG, /* precache */ "", /* sounds */ "" }, @@ -2490,7 +3501,7 @@ const gitem_t bg_itemlistQ3[] = /* pickup */ "Quad Damage", 30, IT_POWERUP, - PW_QUAD, + PWOLD_QUAD, /* precache */ "", /* sounds */ "sound/items/damage3.wav" }, @@ -2507,7 +3518,7 @@ const gitem_t bg_itemlistQ3[] = /* pickup */ "Battle Suit", 30, IT_POWERUP, - PW_BATTLESUIT, + PWOLD_BATTLESUIT, /* precache */ "", /* sounds */ "sound/items/protect3.wav" }, @@ -2524,7 +3535,7 @@ const gitem_t bg_itemlistQ3[] = /* pickup */ "Haste", 30, IT_POWERUP, - PW_HASTE, + PWOLD_HASTE, /* precache */ "", /* sounds */ "" }, @@ -2541,7 +3552,7 @@ const gitem_t bg_itemlistQ3[] = /* pickup */ "Invisibility", 30, IT_POWERUP, - PW_INVIS, + PWOLD_INVIS, /* precache */ "", /* sounds */ "" }, @@ -2558,7 +3569,7 @@ const gitem_t bg_itemlistQ3[] = /* pickup */ "Regeneration", 30, IT_POWERUP, - PW_REGEN, + PWOLD_REGEN, /* precache */ "", /* sounds */ "sound/items/regen.wav" }, @@ -2575,7 +3586,7 @@ const gitem_t bg_itemlistQ3[] = /* pickup */ "Flight", 60, IT_POWERUP, - PW_FLIGHT, + PWOLD_FLIGHT, /* precache */ "", /* sounds */ "sound/items/flight.wav" }, @@ -2592,7 +3603,7 @@ Only in CTF games /* pickup */ "Red Flag", 0, IT_TEAM, - PW_REDFLAG, + PWOLD_REDFLAG, /* precache */ "", /* sounds */ "" }, @@ -2609,7 +3620,7 @@ Only in CTF games /* pickup */ "Blue Flag", 0, IT_TEAM, - PW_BLUEFLAG, + PWOLD_BLUEFLAG, /* precache */ "", /* sounds */ "" }, @@ -2725,7 +3736,7 @@ Only in CTF games /* pickup */ "Scout", 30, IT_PERSISTANT_POWERUP, - PW_SCOUT, + PWOLD_SCOUT, /* precache */ "", /* sounds */ "" }, @@ -2741,7 +3752,7 @@ Only in CTF games /* pickup */ "Guard", 30, IT_PERSISTANT_POWERUP, - PW_GUARD, + PWOLD_GUARD, /* precache */ "", /* sounds */ "" }, @@ -2757,7 +3768,7 @@ Only in CTF games /* pickup */ "Doubler", 30, IT_PERSISTANT_POWERUP, - PW_DOUBLER, + PWOLD_DOUBLER, /* precache */ "", /* sounds */ "" }, @@ -2773,7 +3784,7 @@ Only in CTF games /* pickup */ "Ammo Regen", 30, IT_PERSISTANT_POWERUP, - PW_AMMOREGEN, + PWOLD_AMMOREGEN, /* precache */ "", /* sounds */ "" }, @@ -2790,7 +3801,7 @@ Only in One Flag CTF games /* pickup */ "Neutral Flag", 0, IT_TEAM, - PW_NEUTRALFLAG, + PWOLD_NEUTRALFLAG, /* precache */ "", /* sounds */ "" }, @@ -3370,7 +4381,7 @@ const gitem_t bg_itemlistCpma[] = /* pickup */ "Quad Damage", 30, IT_POWERUP, - PW_QUAD, + PWOLD_QUAD, /* precache */ "", /* sounds */ "sound/items/damage3.wav" }, @@ -3387,7 +4398,7 @@ const gitem_t bg_itemlistCpma[] = /* pickup */ "Battle Suit", 30, IT_POWERUP, - PW_BATTLESUIT, + PWOLD_BATTLESUIT, /* precache */ "", /* sounds */ "sound/items/protect3.wav" }, @@ -3404,7 +4415,7 @@ const gitem_t bg_itemlistCpma[] = /* pickup */ "Haste", 30, IT_POWERUP, - PW_HASTE, + PWOLD_HASTE, /* precache */ "", /* sounds */ "" }, @@ -3421,7 +4432,7 @@ const gitem_t bg_itemlistCpma[] = /* pickup */ "Invisibility", 30, IT_POWERUP, - PW_INVIS, + PWOLD_INVIS, /* precache */ "", /* sounds */ "" }, @@ -3438,7 +4449,7 @@ const gitem_t bg_itemlistCpma[] = /* pickup */ "Regeneration", 30, IT_POWERUP, - PW_REGEN, + PWOLD_REGEN, /* precache */ "", /* sounds */ "sound/items/regen.wav" }, @@ -3455,7 +4466,7 @@ const gitem_t bg_itemlistCpma[] = /* pickup */ "Flight", 60, IT_POWERUP, - PW_FLIGHT, + PWOLD_FLIGHT, /* precache */ "", /* sounds */ "sound/items/flight.wav" }, @@ -3472,7 +4483,7 @@ Only in CTF games /* pickup */ "Red Flag", 0, IT_TEAM, - PW_REDFLAG, + PWOLD_REDFLAG, /* precache */ "", /* sounds */ "" }, @@ -3489,7 +4500,7 @@ Only in CTF games /* pickup */ "Blue Flag", 0, IT_TEAM, - PW_BLUEFLAG, + PWOLD_BLUEFLAG, /* precache */ "", /* sounds */ "" }, @@ -3605,7 +4616,7 @@ Only in CTF games /* pickup */ "Scout", 30, IT_PERSISTANT_POWERUP, - PW_SCOUT, + PWOLD_SCOUT, /* precache */ "", /* sounds */ "" }, @@ -3621,7 +4632,7 @@ Only in CTF games /* pickup */ "Guard", 30, IT_PERSISTANT_POWERUP, - PW_GUARD, + PWOLD_GUARD, /* precache */ "", /* sounds */ "" }, @@ -3637,7 +4648,7 @@ Only in CTF games /* pickup */ "Doubler", 30, IT_PERSISTANT_POWERUP, - PW_DOUBLER, + PWOLD_DOUBLER, /* precache */ "", /* sounds */ "" }, @@ -3653,7 +4664,7 @@ Only in CTF games /* pickup */ "Ammo Regen", 30, IT_PERSISTANT_POWERUP, - PW_AMMOREGEN, + PWOLD_AMMOREGEN, /* precache */ "", /* sounds */ "" }, @@ -3670,7 +4681,7 @@ Only in One Flag CTF games /* pickup */ "Neutral Flag", 0, IT_TEAM, - PW_NEUTRALFLAG, + PWOLD_NEUTRALFLAG, /* precache */ "", /* sounds */ "" }, @@ -3779,7 +4790,7 @@ Only in One Flag CTF games /* pickup */ "Backpack", 0, IT_TEAM, - PW_NEUTRALFLAG, + PWOLD_NEUTRALFLAG, /* precache */ "", /* sounds */ "" }, @@ -3793,7 +4804,7 @@ Only in One Flag CTF games /* pickup */ "Neutral Flag", 0, IT_TEAM, - PW_NEUTRALFLAG, + PWOLD_NEUTRALFLAG, /* precache */ "", /* sounds */ "" }, @@ -3808,7 +4819,7 @@ int bg_numItems = ARRAY_LEN(bg_itemlist) - 1; int bg_numItemsQ3 = ARRAY_LEN(bg_itemlistQ3) - 1; int bg_numItemsCpma = ARRAY_LEN(bg_itemlistCpma) - 1; int bg_numItemsQldm73 = ARRAY_LEN(bg_itemlistQldm73) - 1; - +int bg_numItemsQldm91 = ARRAY_LEN(bg_itemlistQldm91) - 1; /* ============== diff --git a/code/game/bg_pmove.c b/code/game/bg_pmove.c index 6501109c..b90ba5b3 100644 --- a/code/game/bg_pmove.c +++ b/code/game/bg_pmove.c @@ -487,13 +487,15 @@ static void PM_WaterMove( void ) { PM_WaterJumpMove(); return; } + +//FIXME 2015-08-06 test now that there have been fixes (ioq3) #if 0 // jump = head for surface if ( pm->cmd.upmove >= 10 ) { if (pm->ps->velocity[2] > -300) { - if ( pm->watertype == CONTENTS_WATER ) { + if ( pm->watertype & CONTENTS_WATER ) { pm->ps->velocity[2] = 100; - } else if (pm->watertype == CONTENTS_SLIME) { + } else if ( pm->watertype & CONTENTS_SLIME) { pm->ps->velocity[2] = 80; } else { pm->ps->velocity[2] = 50; diff --git a/code/game/bg_public.h b/code/game/bg_public.h index a90e1c13..fd8edd5b 100644 --- a/code/game/bg_public.h +++ b/code/game/bg_public.h @@ -563,31 +563,74 @@ extern int PERS_ATTACKEE_ARMOR; // NOTE: may not have more than 16 typedef enum { - PW_NONE, - PW_QUAD, - PW_BATTLESUIT, - PW_HASTE, - PW_INVIS, - - PW_REGEN, - PW_FLIGHT, - PW_REDFLAG, - PW_BLUEFLAG, - PW_NEUTRALFLAG, - - PW_INVULNERABILITY, - PW_SCOUT, - PW_GUARD, - PW_DOUBLER, - //PW_AMMOREGEN, - PW_ARMORREGEN, - - PW_FROZEN, - PW_NUM_POWERUPS, + PWOLD_NONE, + PWOLD_QUAD, + PWOLD_BATTLESUIT, + PWOLD_HASTE, + PWOLD_INVIS, + + PWOLD_REGEN, + PWOLD_FLIGHT, + PWOLD_REDFLAG, + PWOLD_BLUEFLAG, + PWOLD_NEUTRALFLAG, + + PWOLD_INVULNERABILITY, + PWOLD_SCOUT, + PWOLD_GUARD, + PWOLD_DOUBLER, + PWOLD_ARMORREGEN, + + PWOLD_FROZEN, + PWOLD_NUM_POWERUPS, } powerup_t; -#define PW_SPAWNPROTECTION 1 // hack -#define PW_KEY 601 // hack to use PW_ for keys +typedef enum { + PW91_NONE, + PW91_SPAWNARMOR = PW91_NONE, + + PW91_REDFLAG, + PW91_BLUEFLAG, + PW91_NEUTRALFLAG, + PW91_QUAD, + PW91_BATTLESUIT, + PW91_HASTE, + PW91_INVIS, + PW91_REGEN, + PW91_FLIGHT, + PW91_INVULNERABILITY, + + PW91_SCOUT, + PW91_GUARD, + PW91_DOUBLER, + PW91_ARMORREGEN, + + PW91_FROZEN, + + PW91_NUM_POWERUPS +} powerupQldm91_t; + +#define PWEX_SPAWNPROTECTION 1 // hack +#define PWEX_KEY 601 // hack to use PW_ for keys + +extern int PW_NONE; +//extern int PW_SPAWNARMOR; +extern int PW_QUAD; +extern int PW_BATTLESUIT; +extern int PW_HASTE; +extern int PW_INVIS; +extern int PW_REGEN; +extern int PW_FLIGHT; +extern int PW_REDFLAG; +extern int PW_BLUEFLAG; +extern int PW_NEUTRALFLAG; +extern int PW_INVULNERABILITY; +extern int PW_SCOUT; +extern int PW_GUARD; +extern int PW_DOUBLER; +extern int PW_ARMORREGEN; +extern int PW_FROZEN; +extern int PW_NUM_POWERUPS; typedef enum { HI_NONE, @@ -1134,10 +1177,12 @@ extern gitem_t bg_itemlist[]; // ql dm 90 extern const gitem_t bg_itemlistQ3[]; extern const gitem_t bg_itemlistCpma[]; extern const gitem_t bg_itemlistQldm73[]; +extern const gitem_t bg_itemlistQldm91[]; extern int bg_numItems; extern int bg_numItemsQ3; extern int bg_numItemsCpma; extern int bg_numItemsQldm73; +extern int bg_numItemsQldm91; gitem_t *BG_FindItem( const char *pickupName ); gitem_t *BG_FindItemForWeapon( const weapon_t weapon ); diff --git a/code/game/g_items.c b/code/game/g_items.c index efb02117..c1fde743 100644 --- a/code/game/g_items.c +++ b/code/game/g_items.c @@ -127,8 +127,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { other->client->ps.stats[STAT_PERSISTANT_POWERUP] = ent->item - bg_itemlist; other->client->persistantPowerup = ent; - switch( ent->item->giTag ) { - case PW_GUARD: + if (ent->item->giTag == PW_GUARD) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); @@ -142,10 +141,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { other->client->ps.stats[STAT_MAX_HEALTH] = max; other->client->ps.stats[STAT_ARMOR] = max; other->client->pers.maxHealth = max; - - break; - - case PW_SCOUT: + } else if (ent->item->giTag == PW_SCOUT) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); @@ -154,9 +150,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { } other->client->pers.maxHealth = handicap; other->client->ps.stats[STAT_ARMOR] = 0; - break; - - case PW_DOUBLER: + } else if (ent->item->giTag == PW_DOUBLER) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); @@ -164,8 +158,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { handicap = 100.0f; } other->client->pers.maxHealth = handicap; - break; - case PW_ARMORREGEN: + } else if (ent->item->giTag == PW_ARMORREGEN) { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); @@ -174,8 +167,7 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { } other->client->pers.maxHealth = handicap; memset(other->client->ammoTimes, 0, sizeof(other->client->ammoTimes)); - break; - default: + } else { clientNum = other->client->ps.clientNum; trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); handicap = atof( Info_ValueForKey( userinfo, "handicap" ) ); @@ -183,7 +175,6 @@ int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) { handicap = 100.0f; } other->client->pers.maxHealth = handicap; - break; } return -1; diff --git a/code/game/g_main.c b/code/game/g_main.c index 851c3cb5..f4d54fee 100644 --- a/code/game/g_main.c +++ b/code/game/g_main.c @@ -418,6 +418,8 @@ G_InitGame */ void G_InitGame( int levelTime, int randomSeed, int restart ) { int i; + int protocol; + char buffer[256]; G_Printf ("------- Game Initialization -------\n"); G_Printf ("gamename: %s\n", GAMEVERSION); @@ -432,6 +434,38 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) { G_InitMemory(); + trap_Cvar_VariableStringBuffer("protocol", buffer, sizeof(buffer)); + protocol = atoi(buffer); + G_Printf("protocol %d\n", protocol); + + if (protocol == 91) { + // defaults to protocol 91 + PW_NONE = PW91_NONE; + //PW_SPAWNARMOR = PW91_SPAWNARMOR; + PW_QUAD = PW91_QUAD; + PW_BATTLESUIT = PW91_BATTLESUIT; + PW_HASTE = PW91_HASTE; + PW_INVIS = PW91_INVIS; + PW_REGEN = PW91_REGEN; + PW_FLIGHT = PW91_FLIGHT; + PW_REDFLAG = PW91_REDFLAG; + PW_BLUEFLAG = PW91_BLUEFLAG; + PW_NEUTRALFLAG = PW91_NEUTRALFLAG; + PW_INVULNERABILITY = PW91_INVULNERABILITY; + PW_SCOUT = PW91_SCOUT; + PW_GUARD = PW91_GUARD; + PW_DOUBLER = PW91_DOUBLER; + PW_ARMORREGEN = PW91_ARMORREGEN; + PW_FROZEN = PW91_FROZEN; + PW_NUM_POWERUPS = PW91_NUM_POWERUPS; + + memcpy(&bg_itemlist, &bg_itemlistQldm91, sizeof(gitem_t) * bg_numItemsQldm91); + bg_numItems = bg_numItemsQldm91; + } else { + //FIXME + G_Printf("^3FIXME: game unsupported protocol %d\n", protocol); + } + // set some level globals memset( &level, 0, sizeof( level ) ); level.time = levelTime; diff --git a/code/q3_ui/ui_demo2.c b/code/q3_ui/ui_demo2.c index 2daeb69b..9ad3af7e 100644 --- a/code/q3_ui/ui_demo2.c +++ b/code/q3_ui/ui_demo2.c @@ -330,6 +330,8 @@ static void Demos_MenuInit (const char *dirName) s_demos.list.itemnames = (const char **)s_demos.demolist; s_demos.list.columns = 1; + //Com_Printf("numitems: %d\n", s_demos.list.numitems); + if (!s_demos.list.numitems) { //strcpy( s_demos.names, "No Demos Found." ); Q_strncpyz(s_demos.names, "../", sizeof(s_demos.names)); diff --git a/code/qcommon/cm_patch.c b/code/qcommon/cm_patch.c index e1f48d34..14328091 100644 --- a/code/qcommon/cm_patch.c +++ b/code/qcommon/cm_patch.c @@ -876,7 +876,10 @@ void CM_AddFacetBevels( facet_t *facet ) { } if ( i == facet->numBorders ) { - if (facet->numBorders > 4 + 6 + 16) Com_Printf("ERROR: too many bevels\n"); + if (facet->numBorders >= 4 + 6 + 16) { + Com_Printf("ERROR: too many bevels\n"); + continue; + } facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped); facet->borderNoAdjust[facet->numBorders] = 0; facet->borderInward[facet->numBorders] = flipped; @@ -938,7 +941,10 @@ void CM_AddFacetBevels( facet_t *facet ) { } if ( i == facet->numBorders ) { - if (facet->numBorders > 4 + 6 + 16) Com_Printf("ERROR: too many bevels\n"); + if (facet->numBorders >= 4 + 6 + 16) { + Com_Printf("ERROR: too many bevels\n"); + continue; + } facet->borderPlanes[facet->numBorders] = CM_FindPlane2(plane, &flipped); for ( k = 0 ; k < facet->numBorders ; k++ ) { @@ -976,6 +982,10 @@ void CM_AddFacetBevels( facet_t *facet ) { #ifndef BSPC //add opposite plane + if ( facet->numBorders >= 4 + 6 + 16 ) { + Com_Printf( "ERROR: too many bevels\n" ); + return; + } facet->borderPlanes[facet->numBorders] = facet->surfacePlane; facet->borderNoAdjust[facet->numBorders] = 0; facet->borderInward[facet->numBorders] = qtrue; diff --git a/code/qcommon/files.c b/code/qcommon/files.c index 33a438ac..8b1f490c 100644 --- a/code/qcommon/files.c +++ b/code/qcommon/files.c @@ -507,7 +507,9 @@ qboolean FS_CreatePath (char *OSPath) { // Skip creation of the root directory as it will always be there ofs = strchr( path, PATH_SEP ); - ofs++; + if ( ofs != NULL ) { + ofs++; + } for (; ofs != NULL && *ofs ; ofs++) { if (*ofs == PATH_SEP) { @@ -2175,14 +2177,17 @@ char **FS_ListFilteredFiles( const char *path, const char *extension, char *filt char *name; char ospath[MAX_OSPATH]; - //Com_Printf("want quake live dir\n"); - Com_sprintf(ospath, sizeof(ospath), "%s/home/baseq3/%s", Sys_QuakeLiveDir(), path + 3); + // steam quakelive directory + Com_sprintf(ospath, sizeof(ospath), "%s/baseq3/%s", Sys_QuakeLiveDir(), path + 3); FS_ReplaceSeparators(ospath); + //Com_Printf("dir listing: '%s'\n", ospath); + nfiles = 0; - sysFiles = Sys_ListFiles(ospath, extension, filter, &numSysFiles, qfalse ); + sysFiles = Sys_ListFiles(ospath, extension, filter, &numSysFiles, qfalse); for ( i = 0 ; i < numSysFiles ; i++ ) { // unique the match name = sysFiles[i]; + //Com_Printf("adding '%s'\n", name); nfiles = FS_AddFileToList( name, list, nfiles ); } Sys_FreeFileList( sysFiles ); diff --git a/code/qcommon/msg.c b/code/qcommon/msg.c index 30f9acba..eaa8f876 100644 --- a/code/qcommon/msg.c +++ b/code/qcommon/msg.c @@ -816,9 +816,7 @@ netField_t entityStateFieldsQldm91[] = { NETF(apos.trBase[1]), 0 }, { NETF(pos.trDelta[2]), 0 }, { NETF(apos.trBase[0]), 0 }, -//#ifdef QUAKELIVE_PROTOCOL -{ NETF(pos.gravity), 32 }, //// -//#endif +{ NETF(pos.gravity), 32 }, { NETF(event), 10 }, { NETF(angles2[1]), 0 }, { NETF(eType), 8 }, @@ -855,29 +853,20 @@ netField_t entityStateFieldsQldm91[] = { NETF(apos.trDelta[0]), 0 }, { NETF(apos.trDelta[1]), 0 }, { NETF(apos.trDelta[2]), 0 }, - -//#ifdef QUAKELIVE_PROTOCOL -//FIXME is this new? or did i screw up? -{ NETF(apos.gravity), 32 }, //// -//#endif +{ NETF(apos.gravity), 32 }, { NETF(time2), 32 }, -//{ NETF(apos.gravity), 0 }, { NETF(angles[2]), 0 }, { NETF(angles2[0]), 0 }, { NETF(angles2[2]), 0 }, { NETF(constantLight), 32 }, { NETF(frame), 16 }, { NETF(jumpTime), 32 }, -{ NETF(unknown1), 32 }, // crouch time? -{ NETF(unknown2), 16 }, // health -// armor, location, ... command time -//{ NETF(unknown3), 32 }, // ??? -{ NETF(unknown4), 16 }, // armor -{ NETF(unknown5), 8 }, // location { NETF(doubleJumped), 1 }, -//{ NETF(unknown6), 32 }, // ?? +{ NETF(health), 16 }, +{ NETF(armor), 16 }, +{ NETF(location), 8 }, // location }; @@ -1456,41 +1445,26 @@ netField_t playerStateFieldsQldm91[] = { PSF(eventParms[1]), 8 }, { PSF(clientNum), 8 }, { PSF(weapon), 5 }, -// weaponPrimary -//{ PSF(unknown9), 5 }, + +{ PSF(weaponPrimary), 8 }, { PSF(viewangles[2]), 0 }, { PSF(grapplePoint[0]), 0 }, { PSF(grapplePoint[1]), 0 }, { PSF(grapplePoint[2]), 0 }, - - +{ PSF(jumppad_ent), 10 } , // GENTITYNUM_BITS { PSF(loopSound), 16 }, -{ PSF(jumppad_ent), 10 } , //GENTITYNUM_BITS }, -{ PSF(doubleJumped), 1 }, -{ PSF(jumpTime), 32 }, -//{ PSF(crouchTime), 32 }, - -// crouchSlideTime -// jumpTime:697465 crouchTime:697702 location:22 fov:93 forwardmove:127 rightmove:127 upmove:0 (1811 bits) - - -{ PSF(unknown1), 1 }, // ?? skipped crouchSlideTime? -{ PSF(unknown2), 32 }, // crouchTime -{ PSF(unknown3), 8 }, // ?? -{ PSF(unknown4), 8 }, // location -// crouchSlide time -//{ PSF(unknown11), 32 }, - -{ PSF(unknown5), 8 }, // fov -{ PSF(unknown6), 8 }, // forwardmove -{ PSF(unknown7), 8 }, // rightmove - -{ PSF(unknown8), 8 }, // upmove - -//{ PSF(unknown9), 1 }, // 58 -//{ PSF(unknown10), 1 }, +{ PSF(jumpTime), 32 }, +{ PSF(doubleJumped), 1 }, +{ PSF(crouchTime), 32 }, +{ PSF(crouchSlideTime), 32 }, + +{ PSF(location), 8 }, +{ PSF(fov), 8 }, +{ PSF(forwardmove), 8 }, +{ PSF(rightmove), 8 }, +{ PSF(upmove), 8 }, }; diff --git a/code/qcommon/q_platform.h b/code/qcommon/q_platform.h index 06bc9f99..dc7ed02e 100644 --- a/code/qcommon/q_platform.h +++ b/code/qcommon/q_platform.h @@ -189,38 +189,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define PATH_SEP '/' -#if defined __i386__ -#define ARCH_STRING "i386" -#elif defined __x86_64__ +#if !defined(ARCH_STRING) +# error ARCH_STRING should be defined by the Makefile +#endif + +#if defined __x86_64__ #undef idx64 #define idx64 1 -#define ARCH_STRING "x86_64" -#elif defined __powerpc64__ -#define ARCH_STRING "ppc64" -#elif defined __powerpc__ -#define ARCH_STRING "ppc" -#elif defined __s390__ -#define ARCH_STRING "s390" -#elif defined __s390x__ -#define ARCH_STRING "s390x" -#elif defined __ia64__ -#define ARCH_STRING "ia64" -#elif defined __alpha__ -#define ARCH_STRING "alpha" -#elif defined __sparc__ -#define ARCH_STRING "sparc" -#elif defined __arm__ -#define ARCH_STRING "arm" -#elif defined __aarch64__ -#define ARCH_STRING "aarch64" -#elif defined __cris__ -#define ARCH_STRING "cris" -#elif defined __hppa__ -#define ARCH_STRING "hppa" -#elif defined __mips__ -#define ARCH_STRING "mips" -#elif defined __sh__ -#define ARCH_STRING "sh" #endif #if __FLOAT_WORD_ORDER == __BIG_ENDIAN diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index cce5bca0..08f27f80 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define PROTOCOL_Q3 68 #define PROTOCOL_QL 91 // latest ql protocol +#define SERVER_PROTOCOL 90 // devmap #ifdef STANDALONE #define PRODUCT_NAME "iofoo3" @@ -1228,6 +1229,18 @@ typedef struct playerState_s { // ql protocol 90 qboolean doubleJumped; int jumpTime; + + // ql protocol 91 + int crouchTime; + int crouchSlideTime; + int location; + int fov; + int forwardmove; + int rightmove; + int upmove; + int weaponPrimary; + +#if 0 int unknown1; int unknown2; int unknown3; @@ -1239,7 +1252,7 @@ typedef struct playerState_s { int unknown9; int unknown10; int unknown11; - +#endif } playerState_t; @@ -1359,11 +1372,18 @@ typedef struct entityState_s { int jumpTime; qboolean doubleJumped; + // ql protocol 91 + int health; + int armor; + int location; + +#if 0 int unknown1; int unknown2; int unknown3; int unknown4; int unknown5; +#endif } entityState_t; diff --git a/code/qcommon/vm_x86.c b/code/qcommon/vm_x86.c index bd3fae43..3fcf108c 100644 --- a/code/qcommon/vm_x86.c +++ b/code/qcommon/vm_x86.c @@ -203,19 +203,25 @@ static void EmitRexString(byte rex, const char *string) #define MASK_REG(modrm, mask) \ - EmitString("81"); \ - EmitString((modrm)); \ - Emit4((mask)) + do { \ + EmitString("81"); \ + EmitString((modrm)); \ + Emit4((mask)); \ + } while(0) // add bl, bytes #define STACK_PUSH(bytes) \ - EmitString("80 C3"); \ - Emit1(bytes) + do { \ + EmitString("80 C3"); \ + Emit1(bytes); \ + } while(0) // sub bl, bytes #define STACK_POP(bytes) \ - EmitString("80 EB"); \ - Emit1(bytes) + do { \ + EmitString("80 EB"); \ + Emit1(bytes); \ + } while(0) static void EmitCommand(ELastCommand command) { diff --git a/code/renderer/tr_backend.c b/code/renderer/tr_backend.c index 5dc42b70..e1284c24 100644 --- a/code/renderer/tr_backend.c +++ b/code/renderer/tr_backend.c @@ -597,7 +597,7 @@ static void RE_DrawPathLines (void) for (i = 0; i < *PLnumCameraPoints - 1; i++) { cp = &PLcameraPoints[i]; cpnext = &PLcameraPoints[i + 1]; - if (cp->type == CAMERA_SPLINE) { + if (cp->type == CAMERA_SPLINE || cp->type == CAMERA_SPLINE_BEZIER || cp->type == CAMERA_SPLINE_CATMULLROM) { qglColor3f(PLcolor[0], PLcolor[1], PLcolor[2]); for (j = cp->splineStart; j < PLcameraPoints[i + 1].splineStart; j++) { qglVertex3fv(PLsplinePoints[j]); diff --git a/code/renderer/tr_image.c b/code/renderer/tr_image.c index f15a8e2d..42223047 100644 --- a/code/renderer/tr_image.c +++ b/code/renderer/tr_image.c @@ -2066,7 +2066,7 @@ qhandle_t RE_RegisterSkin( const char *name ) { // If not a .skin file, load as a single shader if ( strcmp( iname + strlen( iname ) - 5, ".skin" ) ) { skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof(skin->surfaces[0]), h_low ); + skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); skin->surfaces[0]->shader = R_FindShader( iname, LIGHTMAP_NONE, qtrue ); return hSkin; } @@ -2137,7 +2137,7 @@ void R_InitSkins( void ) { skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low ); Q_strncpyz( skin->name, "", sizeof( skin->name ) ); skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces ), h_low ); + skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); skin->surfaces[0]->shader = tr.defaultShader; } diff --git a/code/renderer/tr_init.c b/code/renderer/tr_init.c index d7926d42..15320f66 100644 --- a/code/renderer/tr_init.c +++ b/code/renderer/tr_init.c @@ -2476,7 +2476,7 @@ void R_Register( void ) r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_overBrightBitsValue = ri.Cvar_Get("r_overBrightBitsValue", "1.0", CVAR_ARCHIVE | CVAR_LATCH); r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH); - r_mode = ri.Cvar_Get( "r_mode", "4", CVAR_ARCHIVE | CVAR_LATCH ); + r_mode = ri.Cvar_Get( "r_mode", "11", CVAR_ARCHIVE | CVAR_LATCH ); r_fullscreen = ri.Cvar_Get( "r_fullscreen", "0", CVAR_ARCHIVE ); r_noborder = Cvar_Get("r_noborder", "0", CVAR_ARCHIVE | CVAR_LATCH); r_customwidth = ri.Cvar_Get( "r_customwidth", "1600", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/code/renderer/tr_light.c b/code/renderer/tr_light.c index 36d78e9c..842cd89b 100644 --- a/code/renderer/tr_light.c +++ b/code/renderer/tr_light.c @@ -151,7 +151,7 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { frac[i] = v - pos[i]; if ( pos[i] < 0 ) { pos[i] = 0; - } else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) { + } else if ( pos[i] > tr.world->lightGridBounds[i] - 1 ) { pos[i] = tr.world->lightGridBounds[i] - 1; } } @@ -182,6 +182,9 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { data = gridData; for ( j = 0 ; j < 3 ; j++ ) { if ( i & (1< tr.world->lightGridBounds[j] - 1 ) { + break; // ignore values outside lightgrid + } factor *= frac[j]; data += gridStep[j]; } else { @@ -189,6 +192,10 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { } } + if ( j != 3 ) { + continue; + } + if ( !(data[0]+data[1]+data[2]) ) { continue; // ignore samples in walls } diff --git a/code/renderer/tr_main.c b/code/renderer/tr_main.c index 3244b878..34de9970 100644 --- a/code/renderer/tr_main.c +++ b/code/renderer/tr_main.c @@ -1033,6 +1033,10 @@ int R_SpriteFogNum( trRefEntity_t *ent ) { return 0; } + if ( ent->ePtr->renderfx & RF_CROSSHAIR ) { + return 0; + } + for ( i = 1 ; i < tr.world->numfogs ; i++ ) { fog = &tr.world->fogs[i]; for ( j = 0 ; j < 3 ; j++ ) { diff --git a/code/renderer/tr_shader.c b/code/renderer/tr_shader.c index 6e1f141a..a72fd65d 100644 --- a/code/renderer/tr_shader.c +++ b/code/renderer/tr_shader.c @@ -1630,6 +1630,23 @@ static qboolean ParseShader( char **text ) return qfalse; } + if ( r_greyscale->integer ) + { + float luminance; + + luminance = LUMA( shader.fogParms.color[0], shader.fogParms.color[1], shader.fogParms.color[2] ); + VectorSet( shader.fogParms.color, luminance, luminance, luminance ); + } + else if ( r_greyscale->value ) + { + float luminance; + + luminance = LUMA( shader.fogParms.color[0], shader.fogParms.color[1], shader.fogParms.color[2] ); + shader.fogParms.color[0] = LERP( shader.fogParms.color[0], luminance, r_greyscale->value ); + shader.fogParms.color[1] = LERP( shader.fogParms.color[1], luminance, r_greyscale->value ); + shader.fogParms.color[2] = LERP( shader.fogParms.color[2], luminance, r_greyscale->value ); + } + token = COM_ParseExt( text, qfalse ); if ( !token[0] ) { diff --git a/code/sdl/sdl_glimp.c b/code/sdl/sdl_glimp.c index 9322b205..0914230b 100644 --- a/code/sdl/sdl_glimp.c +++ b/code/sdl/sdl_glimp.c @@ -566,7 +566,7 @@ static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qbool { char driverName[ 64 ]; - if (SDL_Init(SDL_INIT_VIDEO) == -1) + if (SDL_Init(SDL_INIT_VIDEO) != 0) { ri.Printf( PRINT_ALL, "SDL_Init( SDL_INIT_VIDEO ) FAILED (%s)\n", SDL_GetError()); diff --git a/code/sdl/sdl_input.c b/code/sdl/sdl_input.c index e7aea18d..0c65695f 100644 --- a/code/sdl/sdl_input.c +++ b/code/sdl/sdl_input.c @@ -591,7 +591,7 @@ static void IN_InitJoystick( void ) if (!SDL_WasInit(SDL_INIT_JOYSTICK)) { Com_DPrintf("Calling SDL_Init(SDL_INIT_JOYSTICK)...\n"); - if (SDL_Init(SDL_INIT_JOYSTICK) == -1) + if (SDL_Init(SDL_INIT_JOYSTICK) != 0) { Com_DPrintf("SDL_Init(SDL_INIT_JOYSTICK) failed: %s\n", SDL_GetError()); return; diff --git a/code/sdl/sdl_snd.c b/code/sdl/sdl_snd.c index f312c9bf..9bfcc3ae 100644 --- a/code/sdl/sdl_snd.c +++ b/code/sdl/sdl_snd.c @@ -176,7 +176,7 @@ qboolean SNDDMA_Init(void) if (!SDL_WasInit(SDL_INIT_AUDIO)) { - if (SDL_Init(SDL_INIT_AUDIO) == -1) + if (SDL_Init(SDL_INIT_AUDIO) != 0) { Com_Printf( "FAILED (%s)\n", SDL_GetError( ) ); return qfalse; diff --git a/code/server/sv_ccmds.c b/code/server/sv_ccmds.c index 3caf5725..edf52be2 100644 --- a/code/server/sv_ccmds.c +++ b/code/server/sv_ccmds.c @@ -166,7 +166,7 @@ static void SV_Map_f( void ) { } #endif - Cvar_Set("protocol", va("%i", PROTOCOL_QL)); + Cvar_Set("protocol", va("%i", SERVER_PROTOCOL)); map = Cmd_Argv(1); if ( !map ) { diff --git a/code/sys/sys_local.h b/code/sys/sys_local.h index f63480c5..c64ab692 100644 --- a/code/sys/sys_local.h +++ b/code/sys/sys_local.h @@ -51,9 +51,10 @@ char *Sys_StripAppBundle( char *pwd ); void Sys_GLimpSafeInit( void ); void Sys_GLimpInit( void ); -void Sys_PlatformInit (qboolean useBacktrace); +void Sys_PlatformInit (qboolean useBacktrace, qboolean useConsoleOutput); void Sys_PlatformExit (void); void Sys_SigHandler( int signal ); void Sys_ErrorDialog( const char *error ); void Sys_AnsiColorPrint( const char *msg ); void Sys_Backtrace_f (void); +qboolean Sys_FileIsDirectory (char *path); diff --git a/code/sys/sys_main.c b/code/sys/sys_main.c index 03d4c110..e6f8c982 100644 --- a/code/sys/sys_main.c +++ b/code/sys/sys_main.c @@ -204,74 +204,7 @@ void Sys_Init(void) Cvar_Set( "username", Sys_GetCurrentUser( ) ); } -/* -================= -Sys_AnsiColorPrint - -Transform Q3 colour codes to ANSI escape sequences -================= -*/ -void Sys_AnsiColorPrint( const char *msg ) -{ - static char buffer[ MAX_PRINT_MSG ]; - int length = 0; - static int q3ToAnsi[ 8 ] = - { - 30, // COLOR_BLACK - 31, // COLOR_RED - 32, // COLOR_GREEN - 33, // COLOR_YELLOW - 34, // COLOR_BLUE - 36, // COLOR_CYAN - 35, // COLOR_MAGENTA - 0 // COLOR_WHITE - }; - - while( *msg ) - { - if( Q_IsColorString( msg ) || *msg == '\n' ) - { - // First empty the buffer - if( length > 0 ) - { - buffer[ length ] = '\0'; - fputs( buffer, stderr ); - length = 0; - } - - if( *msg == '\n' ) - { - // Issue a reset and then the newline - fputs( "\033[0m\n", stderr ); - msg++; - } - else - { - // Print the color code - Com_sprintf( buffer, sizeof( buffer ), "\033[%dm", - q3ToAnsi[ ColorIndex( *( msg + 1 ) ) ] ); - fputs( buffer, stderr ); - msg += 2; - } - } - else - { - if( length >= MAX_PRINT_MSG - 1 ) - break; - buffer[ length ] = *msg; - length++; - msg++; - } - } - - // Empty anything still left in the buffer - if( length > 0 ) - { - buffer[ length ] = '\0'; - fputs( buffer, stderr ); - } -} /* ================= @@ -339,6 +272,22 @@ int Sys_FileTime( char *path ) return buf.st_mtime; } +qboolean Sys_FileIsDirectory (char *path) +{ + struct stat buf; + + if (stat(path, &buf) != 0) { + Com_Printf("WARNING: couldn't stat file '%s'\n", path); + return qfalse; + } + + if (buf.st_mode & S_IFDIR) { + return qtrue; + } + + return qfalse; +} + /* ================= Sys_UnloadDll @@ -511,6 +460,7 @@ int main( int argc, char **argv ) int i; char commandLine[ MAX_STRING_CHARS ] = { 0 }; qboolean useBacktrace; + qboolean useConsoleOutput; #ifndef DEDICATED // SDL version check @@ -540,12 +490,16 @@ int main( int argc, char **argv ) StartTime = Sys_Milliseconds(); useBacktrace = qtrue; + useConsoleOutput = qfalse; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--nobacktrace")) { useBacktrace = qfalse; + } else if (!strcmp(argv[i], "--console-output")) { + useConsoleOutput = qtrue; } + } - Sys_PlatformInit(useBacktrace); + Sys_PlatformInit(useBacktrace, useConsoleOutput); // Set the initial time base //Sys_Milliseconds( ); diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c index 562821bc..1c90913b 100644 --- a/code/sys/sys_unix.c +++ b/code/sys/sys_unix.c @@ -21,7 +21,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #define __USE_GNU -#define _GNU_SOURCE +#ifndef _GNU_SOURCE + #define _GNU_SOURCE +#endif #include "../qcommon/q_shared.h" @@ -95,6 +97,10 @@ char *Sys_QuakeLiveDir (void) const char *p; const char *override = NULL; const char *user = getenv("USER"); + char searchPath[MAX_OSPATH]; + char subPath[MAX_OSPATH]; + DIR *d; + struct dirent *dir; if (!*QuakeLivePath) { override = Cvar_VariableString("fs_quakelivedir"); @@ -106,20 +112,58 @@ char *Sys_QuakeLiveDir (void) if ((p = getenv("HOME")) != NULL) { if (user && *user) { - Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s/.wine/drive_c/users/%s/Application Data/id Software/quakelive/", p, user); + struct stat st; + int count; + + // check for quake live steam + count = 0; + while (count < 2) { + //const char *tag; + + if (count == 0) { + Com_sprintf(searchPath, sizeof(searchPath), "%s/.wine/drive_c/Program Files (x86)/Steam/steamapps/common/Quake Live", p); + //tag = "64-bit"; + } else { + Com_sprintf(searchPath, sizeof(searchPath), "%s/.wine/drive_c/Program Files/Steam/steamapps/common/Quake Live", p); + //tag = "32-bit"; + } + + d = opendir(searchPath); + if (d) { + while ((dir = readdir(d)) != NULL) { + //printf("%s: '%s'\n", tag, dir->d_name); + if (dir->d_name[0] == '.') { + continue; + } + Com_sprintf(subPath, sizeof(subPath), "%s/%s/baseq3", searchPath, dir->d_name); + if (stat(subPath, &st) == 0) { + // got it + Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s/%s", searchPath, dir->d_name); + goto done; + } + } + } + + count++; + } // while (count < 2) + + // didn't find wine steam quake live, try wine stand alone + Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s/.wine/drive_c/users/%s/Application Data/id Software/quakelive/home", p, user); } else { // try old quakelive native linux/mac support #ifdef MACOS_X //FIXME not sure // /Library/Application\ Support/Quakelive/ - Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s/Library/Application Support/Quakelive/", p); + Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s/Library/Application Support/Quakelive/home/", p); #else - Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s/.quakelive/quakelive/", p); + Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s/.quakelive/quakelive/home", p); #endif } } } +done: + return QuakeLivePath; } @@ -891,7 +935,7 @@ static void signal_crash (int signum, siginfo_t *info, void *ptr) #endif -void Sys_PlatformInit (qboolean useBacktrace) +void Sys_PlatformInit (qboolean useBacktrace, qboolean useConsoleOutput) { struct sigaction action; const char *term = getenv("TERM"); @@ -1022,6 +1066,75 @@ void Sys_SetEnv(const char *name, const char *value) unsetenv(name); } +/* +================= +Sys_AnsiColorPrint + +Transform Q3 colour codes to ANSI escape sequences +================= +*/ +void Sys_AnsiColorPrint( const char *msg ) +{ + static char buffer[ MAX_PRINT_MSG ]; + int length = 0; + static int q3ToAnsi[ 8 ] = + { + 30, // COLOR_BLACK + 31, // COLOR_RED + 32, // COLOR_GREEN + 33, // COLOR_YELLOW + 34, // COLOR_BLUE + 36, // COLOR_CYAN + 35, // COLOR_MAGENTA + 0 // COLOR_WHITE + }; + + while( *msg ) + { + if( Q_IsColorString( msg ) || *msg == '\n' ) + { + // First empty the buffer + if( length > 0 ) + { + buffer[ length ] = '\0'; + fputs( buffer, stderr ); + length = 0; + } + + if( *msg == '\n' ) + { + // Issue a reset and then the newline + fputs( "\033[0m\n", stderr ); + msg++; + } + else + { + // Print the color code + Com_sprintf( buffer, sizeof( buffer ), "\033[%dm", + q3ToAnsi[ ColorIndex( *( msg + 1 ) ) ] ); + fputs( buffer, stderr ); + msg += 2; + } + } + else + { + if( length >= MAX_PRINT_MSG - 1 ) + break; + + buffer[ length ] = *msg; + length++; + msg++; + } + } + + // Empty anything still left in the buffer + if( length > 0 ) + { + buffer[ length ] = '\0'; + fputs( buffer, stderr ); + } +} + void Sys_Backtrace_f (void) { print_gdb_trace(); diff --git a/code/sys/sys_win32.c b/code/sys/sys_win32.c index fa0531ac..7a5134fc 100644 --- a/code/sys/sys_win32.c +++ b/code/sys/sys_win32.c @@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include + // Used to determine where to store user-specific files static char homePath[ MAX_OSPATH ] = { 0 }; static char QuakeLivePath[MAX_OSPATH] = { 0 }; @@ -96,10 +97,16 @@ char *Sys_QuakeLiveDir (void) FARPROC qSHGetFolderPath; HMODULE shfolder; const char *override = NULL; - //const char *win7vista = "LocalLow\\id Software\\quakelive\\home\\baseq3"; - const char *win7Vista = "LocalLow\\id Software\\quakelive"; - //const char *xp = "id Software\\quakelive\\home\\baseq3"; - const char *xp = "id Software\\quakelive"; + // "LocalLow\\id Software\\quakelive\\home\\baseq3"; + // "id Software\\quakelive\\home\\baseq3"; + const char *win7Vista = "LocalLow\\id Software\\quakelive\\home"; + const char *xp = "id Software\\quakelive\\home"; + const char *steamPath = "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Quake Live"; + const char *steamPath32bit = "C:\\Program Files\\Steam\\steamapps\\common\\Quake Live"; + HANDLE hFind; + WIN32_FIND_DATA FindData; + char searchString[MAX_OSPATH]; + int count; if (!*QuakeLivePath) { override = Cvar_VariableString("fs_quakelivedir"); @@ -108,6 +115,48 @@ char *Sys_QuakeLiveDir (void) //FS_ReplaceSeparators(QuakeLivePath); return QuakeLivePath; } + + // check steam first + // C:\\Program Files (x86)\\Steam\\steamapps\\common\\Quake Live\\12345678901234567\\baseq3 + + count = 0; + while (count < 2) { + const char *spath = steamPath; + + if (count == 1) { + spath = steamPath32bit; + } + + Com_sprintf(searchString, sizeof(searchString), "%s\\*", spath); + + //Com_Printf("searching for '%s'\n", searchString); + hFind = FindFirstFile(searchString, &FindData); + if (hFind != INVALID_HANDLE_VALUE) { + + do { + if (FindData.cFileName[0] == '.') { // skip . and .. + continue; + } + Com_sprintf(searchString, sizeof(searchString), "%s\\%s\\baseq3", spath, FindData.cFileName); + //Com_Printf("checking '%s'\n", searchString); + if (Sys_FileIsDirectory(searchString)) { + // got it + //Com_Printf("found steam directory '%s'\n", FindData.cFileName); + Com_sprintf(QuakeLivePath, sizeof(QuakeLivePath), "%s\\%s", spath, FindData.cFileName); + FindClose(hFind); + return QuakeLivePath; + } else { + //Com_Printf("found steam file '%s' but it is not a directory\n", FindData.cFileName); + } + + } while(FindNextFile(hFind, &FindData)); + } + FindClose(hFind); + //Com_Printf("(%s) didn't find steam directory...\n", count == 0 ? "64-bit" : "32-bit"); + count++; + } // while (count < 2) + + // try old quake live stand alone directory shfolder = LoadLibrary("shfolder.dll"); if(shfolder == NULL) @@ -457,6 +506,7 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter int flag; int i; qboolean wantDirs; + int extLen; if (filter) { @@ -497,6 +547,8 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter flag = _A_SUBDIR; } + extLen = strlen( extension ); + Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension ); // search @@ -510,6 +562,14 @@ char **Sys_ListFiles( const char *directory, const char *extension, char *filter do { if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) || wantDirs ) { + if (*extension) { + if ( strlen( findinfo.name ) < extLen || + Q_stricmp( + findinfo.name + strlen( findinfo.name ) - extLen, + extension ) ) { + continue; // didn't match + } + } if ( nfiles == MAX_FOUND_FILES - 1 ) { break; } @@ -698,6 +758,10 @@ void Sys_GLimpInit( void ) #endif } +static HANDLE HStdout = INVALID_HANDLE_VALUE; +static CONSOLE_SCREEN_BUFFER_INFO ScreenBufferInfo; +static qboolean GotHandle = qfalse; + /* ============== Sys_PlatformInit @@ -705,7 +769,7 @@ Sys_PlatformInit Windows specific initialisation ============== */ -void Sys_PlatformInit (qboolean useBacktrace) +void Sys_PlatformInit (qboolean useBacktrace, qboolean useConsoleOutput) { HMODULE bt; OSVERSIONINFO vi; @@ -717,6 +781,35 @@ void Sys_PlatformInit (qboolean useBacktrace) const char *SDL_VIDEODRIVER; #endif + // sdl redirects output, steal it back + if (useConsoleOutput) { + BOOL b = AttachConsole(ATTACH_PARENT_PROCESS); + if (b) { + freopen("conin$", "r", stdin); + freopen("conout$", "w", stdout); + freopen("conout$", "w", stderr); + + HStdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (HStdout != INVALID_HANDLE_VALUE) { + + if (GetConsoleScreenBufferInfo(HStdout, &ScreenBufferInfo) != 0) { + SetConsoleTextAttribute(HStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + fputs("\r\n", stderr); + Com_Printf("win32: using console output\n"); + GotHandle = qtrue; + } else { + Com_Printf("win32: couldn't get screen buffer information for console output, error %ld\n", GetLastError()); + HStdout = INVALID_HANDLE_VALUE; + GotHandle = qfalse; + } + } else { + Com_Printf("win32: couldn't get output handle for console output, error %ld\n", GetLastError()); + GotHandle = qfalse; + } + } else { + Com_Printf("win32: couldn't get parent console for console output, error %ld\n", GetLastError()); + } + } if (useBacktrace) { bt = LoadLibraryA("backtrace.dll"); Com_Printf("backtrace: %d\n", (int)bt); @@ -916,10 +1009,16 @@ Windows specific initialisation ============== */ + void Sys_PlatformExit (void) { if (timerResolution) timeEndPeriod(timerResolution); + + if (GotHandle && HStdout != INVALID_HANDLE_VALUE) { + SetConsoleTextAttribute(HStdout, ScreenBufferInfo.wAttributes); + fputs("\r\n", stderr); + } } /* @@ -998,3 +1097,71 @@ int Sys_DirnameCmp (const char *pathName1, const char *pathName2) { return Q_stricmp(pathName1, pathName2); } + + +void Sys_AnsiColorPrint( const char *msg ) +{ + static char buffer[ MAX_PRINT_MSG ]; + int length = 0; + static int q3ToAnsi[ 8 ] = + { + FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // COLOR_BLACK, using bright white so it's visible + FOREGROUND_INTENSITY | FOREGROUND_RED, // COLOR_RED + FOREGROUND_INTENSITY | FOREGROUND_GREEN, // COLOR_GREEN + FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN, // COLOR_YELLOW + FOREGROUND_INTENSITY | FOREGROUND_BLUE, // COLOR_BLUE + FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE, // COLOR_CYAN + FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE, // COLOR_MAGENTA + //FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // COLOR_WHITE + FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // COLOR_WHITE, using default gray foreground color is ms-dos prompt + }; + + if (!GotHandle || HStdout == INVALID_HANDLE_VALUE) { + fputs(msg, stderr); + return; + } + + while( *msg ) + { + if( Q_IsColorString( msg ) || *msg == '\n' ) + { + // First empty the buffer + if( length > 0 ) + { + buffer[ length ] = '\0'; + fputs( buffer, stderr ); + length = 0; + } + + if( *msg == '\n' ) + { + // Issue a reset and then the newline + SetConsoleTextAttribute(HStdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + fputs("\r\n", stderr); + msg++; + } + else + { + // Print the color code + SetConsoleTextAttribute(HStdout, q3ToAnsi[ ColorIndex( *( msg + 1 ) ) ]); + msg += 2; + } + } + else + { + if( length >= MAX_PRINT_MSG - 1 ) + break; + + buffer[ length ] = *msg; + length++; + msg++; + } + } + + // Empty anything still left in the buffer + if( length > 0 ) + { + buffer[ length ] = '\0'; + fputs( buffer, stderr ); + } +} diff --git a/code/ui/ui_main.c b/code/ui/ui_main.c index 768d3963..b32a0904 100644 --- a/code/ui/ui_main.c +++ b/code/ui/ui_main.c @@ -4508,6 +4508,11 @@ static qboolean Team_Parse(char **p) { } if (token[0] == '{') { + if (uiInfo.teamCount == MAX_TEAMS) { + uiInfo.teamCount--; + Com_Printf("Too many teams, last team replaced!\n"); + } + // seven tokens per line, team name and icon, and 5 team member names if (!String_Parse(p, &uiInfo.teamList[uiInfo.teamCount].teamName) || !String_Parse(p, &tempStr)) { return qfalse; @@ -4529,11 +4534,8 @@ static qboolean Team_Parse(char **p) { } Com_Printf("Loaded team %s with team icon %s.\n", uiInfo.teamList[uiInfo.teamCount].teamName, tempStr); - if (uiInfo.teamCount < MAX_TEAMS) { - uiInfo.teamCount++; - } else { - Com_Printf("Too many teams, last team replaced!\n"); - } + uiInfo.teamCount++; + token = COM_ParseExt(p, qtrue); if (token[0] != '}') { return qfalse; diff --git a/code/ui/ui_shared.c b/code/ui/ui_shared.c index 20208cbc..ec49ae16 100644 --- a/code/ui/ui_shared.c +++ b/code/ui/ui_shared.c @@ -1232,7 +1232,8 @@ static qboolean IsVisible(int flags) { return (flags & WINDOW_VISIBLE && !(flags & WINDOW_FADINGOUT)); } -static qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y) { +static qboolean Rect_ContainsPoint (const rectDef_t *rect, float x, float y) +{ if (rect) { if (x > rect->x && x < rect->x + rect->w && y > rect->y && y < rect->y + rect->h) { return qtrue; @@ -1241,13 +1242,142 @@ static qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y) { return qfalse; } +#if 0 +static qboolean Item_ContainsPoint (const itemDef_t *item, float x, float y) +{ + rectDef_t rect; + float aspect; + float width43; + float diff; + float diff640; + float newXScale; + + if (!item) { + Com_Printf("^1Item_ContainsPoint item == NULL\n"); + return qfalse; + } + + memcpy(&rect, &item->window.rect, sizeof(rectDef_t)); + //FIXME get cg_wideScreen value + + //FIXME store calculations + aspect = (float)DC->glconfig.vidWidth / (float)DC->glconfig.vidHeight; + + width43 = 4.0f * (DC->glconfig.vidHeight / 3.0); + diff = (float)DC->glconfig.vidWidth - width43; + + diff640 = 640.0f * diff / (float)DC->glconfig.vidWidth; + newXScale = width43 / (float)DC->glconfig.vidWidth; + + // already scaled to 640x480, reverse and apply new + + if (item->widescreen == WIDESCREEN_NONE || aspect <= 1.25f) { + //use regular scaling, don't alter rect values + } else if (item->widescreen == WIDESCREEN_LEFT) { + rect.w *= newXScale; + } else if (item->widescreen == WIDESCREEN_CENTER) { + rect.w *= newXScale; + rect.x *= newXScale; + rect.x += diff640 / 2; + } else if (item->widescreen == WIDESCREEN_RIGHT) { + rect.w *= newXScale; + rect.x += diff640; + } + + return Rect_ContainsPoint(&rect, x, y); +} +#endif + +static qboolean Rect_ContainsWidescreenPoint (const rectDef_t *rectIn, float x, float y, int widescreen) +{ + rectDef_t rect; + float aspect; + float width43; + float diff; + float diff640; + float newXScale; + + if (!rectIn) { + Com_Printf("^1Rect_ContainsWidescreenPoint item == NULL\n"); + return qfalse; + } + + memcpy(&rect, rectIn, sizeof(rectDef_t)); + + //FIXME store calculations + aspect = (float)DC->glconfig.vidWidth / (float)DC->glconfig.vidHeight; + + width43 = 4.0f * (DC->glconfig.vidHeight / 3.0); + diff = (float)DC->glconfig.vidWidth - width43; + + diff640 = 640.0f * diff / (float)DC->glconfig.vidWidth; + newXScale = width43 / (float)DC->glconfig.vidWidth; + + // already scaled to 640x480, reverse and apply new + + if (widescreen == WIDESCREEN_NONE || aspect <= 1.25f || DC->widescreen != 5) { + //use regular scaling, don't alter rect values + } else if (widescreen == WIDESCREEN_LEFT) { + rect.w *= newXScale; + } else if (widescreen == WIDESCREEN_CENTER) { + rect.w *= newXScale; + rect.x *= newXScale; + rect.x += diff640 / 2; + } else if (widescreen == WIDESCREEN_RIGHT) { + rect.w *= newXScale; + rect.x += diff640; + } + + return Rect_ContainsPoint(&rect, x, y); +} + +// assumes cursor is being drawn fullscreen (widescreen == WIDESCREEN_NONE), +// and the item uses widescreen values so translate the realx value to +// the one that would be scaled by widescreen +static float CursorX_Widescreen (int widescreen) +{ + float aspect; + float width43; + float diff; + float diff640; + float newXScale; + float x; + + x = DC->cursorx; + + //FIXME store calculations + aspect = (float)DC->glconfig.vidWidth / (float)DC->glconfig.vidHeight; + width43 = 4.0 * (DC->glconfig.vidHeight / 3.0); + diff = (float)DC->glconfig.vidWidth - width43; + + diff640 = 640.0f * diff / (float)DC->glconfig.vidWidth; + //newXScale = width43 / (float)DC->glconfig.vidWidth; + + //newXScale = width43 / 640.0f; + newXScale = (float)DC->glconfig.vidWidth / 640.0f; + + if (widescreen == WIDESCREEN_NONE || aspect <= 1.25f) { + //use regular scaling, don't chage x + } else if (widescreen == WIDESCREEN_LEFT) { + x *= newXScale; + } else if (widescreen == WIDESCREEN_CENTER) { + x -= diff640 / 2; + x *= newXScale; + } else if (widescreen == WIDESCREEN_RIGHT) { + x -= diff640; + x *= newXScale; + } + + return x; +} + static int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name) { int i; int count = 0; for (i = 0; i < menu->itemCount; i++) { if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0)) { count++; - } + } } return count; } @@ -1838,7 +1968,7 @@ static qboolean Item_SetFocus(itemDef_t *item, float x, float y) { rectDef_t r; r = item->textRect; r.y -= r.h; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { item->window.flags |= WINDOW_HASFOCUS; if (item->focusSound) { sfx = &item->focusSound; @@ -1933,8 +2063,10 @@ static int Item_ListBox_ThumbDrawPosition(itemDef_t *item) { if (item->window.flags & WINDOW_HORIZONTAL) { min = item->window.rect.x + SCROLLBAR_SIZE + 1; max = item->window.rect.x + item->window.rect.w - 2*SCROLLBAR_SIZE - 1; - if (DC->cursorx >= min + SCROLLBAR_SIZE/2 && DC->cursorx <= max + SCROLLBAR_SIZE/2) { - return DC->cursorx - SCROLLBAR_SIZE/2; + //Com_Printf("checking cursor x\n"); + //if (DC->cursorx >= min + SCROLLBAR_SIZE/2 && DC->cursorx <= max + SCROLLBAR_SIZE/2) { + if (CursorX_Widescreen(item->widescreen) >= min + SCROLLBAR_SIZE/2 && CursorX_Widescreen(item->widescreen) <= max + SCROLLBAR_SIZE/2) { + return CursorX_Widescreen(item->widescreen) - SCROLLBAR_SIZE/2; } else { return Item_ListBox_ThumbPosition(item); @@ -1992,12 +2124,17 @@ static float Item_Slider_ThumbPosition(itemDef_t *item) { static int Item_Slider_OverSlider(itemDef_t *item, float x, float y) { rectDef_t r; + if (!item) { + Com_Printf("^1Item_SlideOverSlide item == NULL\n"); + return 0; + } + r.x = Item_Slider_ThumbPosition(item) - (SLIDER_THUMB_WIDTH / 2); r.y = item->window.rect.y - 2; r.w = SLIDER_THUMB_WIDTH; r.h = SLIDER_THUMB_HEIGHT; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_THUMB; } return 0; @@ -2009,6 +2146,10 @@ static int Item_ListBox_OverLB(itemDef_t *item, float x, float y) { int thumbstart; //int count; + if (!item) { + Com_Printf("^1Item_ListBox_OverLB item == NULL\n"); + } + //count = DC->feederCount(item->special); //listPtr = (listBoxDef_t*)item->typeData; if (item->window.flags & WINDOW_HORIZONTAL) { @@ -2016,54 +2157,54 @@ static int Item_ListBox_OverLB(itemDef_t *item, float x, float y) { r.x = item->window.rect.x; r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; r.h = r.w = SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_LEFTARROW; } // check if on right arrow r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_RIGHTARROW; } // check if on thumb thumbstart = Item_ListBox_ThumbPosition(item); r.x = thumbstart; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_THUMB; } r.x = item->window.rect.x + SCROLLBAR_SIZE; r.w = thumbstart - r.x; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_PGUP; } r.x = thumbstart + SCROLLBAR_SIZE; r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_PGDN; } } else { r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; r.y = item->window.rect.y; r.h = r.w = SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_LEFTARROW; } r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_RIGHTARROW; } thumbstart = Item_ListBox_ThumbPosition(item); r.y = thumbstart; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_THUMB; } r.y = item->window.rect.y + SCROLLBAR_SIZE; r.h = thumbstart - r.y; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_PGUP; } r.y = thumbstart + SCROLLBAR_SIZE; r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { return WINDOW_LB_PGDN; } } @@ -2089,7 +2230,7 @@ static void Item_ListBox_MouseEnter(itemDef_t *item, float x, float y) r.y = item->window.rect.y; r.h = item->window.rect.h - SCROLLBAR_SIZE; r.w = item->window.rect.w - listPtr->drawPadding; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { listPtr->cursorPos = (int)((x - r.x) / listPtr->elementWidth) + listPtr->startPos; if (listPtr->cursorPos >= listPtr->endPos) { listPtr->cursorPos = listPtr->endPos; @@ -2104,7 +2245,7 @@ static void Item_ListBox_MouseEnter(itemDef_t *item, float x, float y) r.y = item->window.rect.y; r.w = item->window.rect.w - SCROLLBAR_SIZE; r.h = item->window.rect.h - listPtr->drawPadding; - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { listPtr->cursorPos = (int)((y - 2 - r.y) / listPtr->elementHeight) + listPtr->startPos; if (listPtr->cursorPos > listPtr->endPos) { listPtr->cursorPos = listPtr->endPos; @@ -2129,7 +2270,7 @@ static void Item_MouseEnter(itemDef_t *item, float x, float y) { return; } - if (Rect_ContainsPoint(&r, x, y)) { + if (Rect_ContainsWidescreenPoint(&r, x, y, item->widescreen)) { if (!(item->window.flags & WINDOW_MOUSEOVERTEXT)) { Item_RunScript(item, item->mouseEnterText); item->window.flags |= WINDOW_MOUSEOVERTEXT; @@ -2174,9 +2315,9 @@ static void Item_MouseLeave(itemDef_t *item) { static itemDef_t *Menu_HitTest(menuDef_t *menu, float x, float y) { int i; for (i = 0; i < menu->itemCount; i++) { - if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { - return menu->items[i]; - } + if (Rect_ContainsWidescreenPoint(&menu->items[i]->window.rect, x, y, menu->items[i]->widescreen)) { + return menu->items[i]; + } } return NULL; } @@ -2205,7 +2346,7 @@ static qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, int count = DC->feederCount(item->special); int max, viewmax; - if (force || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS)) { + if (force || (Rect_ContainsWidescreenPoint(&item->window.rect, DC->cursorx, DC->cursory, item->widescreen) && item->window.flags & WINDOW_HASFOCUS)) { max = Item_ListBox_MaxScroll(item); if (item->window.flags & WINDOW_HORIZONTAL) { viewmax = (item->window.rect.w / listPtr->elementWidth); @@ -2412,7 +2553,7 @@ static qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, static qboolean Item_YesNo_HandleKey(itemDef_t *item, int key) { - if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) { + if (Rect_ContainsWidescreenPoint(&item->window.rect, DC->cursorx, DC->cursory, item->widescreen) && item->window.flags & WINDOW_HASFOCUS && item->cvar) { if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) { DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar))); return qtrue; @@ -2486,7 +2627,7 @@ static const char *Item_Multi_Setting(itemDef_t *item) { static qboolean Item_Multi_HandleKey(itemDef_t *item, int key) { multiDef_t *multiPtr = (multiDef_t*)item->typeData; if (multiPtr) { - if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) { + if (Rect_ContainsWidescreenPoint(&item->window.rect, DC->cursorx, DC->cursory, item->widescreen) && item->window.flags & WINDOW_HASFOCUS && item->cvar) { if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) { int current = Item_Multi_FindCvarByValue(item) + 1; int max = Item_Multi_CountSettings(item); @@ -2680,7 +2821,7 @@ static void Scroll_ListBox_ThumbFunc(void *p) { listBoxDef_t *listPtr = (listBoxDef_t*)si->item->typeData; if (si->item->window.flags & WINDOW_HORIZONTAL) { - if (DC->cursorx == si->xStart) { + if (CursorX_Widescreen(si->item->widescreen) == si->xStart) { return; } r.x = si->item->window.rect.x + SCROLLBAR_SIZE + 1; @@ -2689,7 +2830,7 @@ static void Scroll_ListBox_ThumbFunc(void *p) { r.w = si->item->window.rect.w - (SCROLLBAR_SIZE*2) - 2; max = Item_ListBox_MaxScroll(si->item); // - pos = (DC->cursorx - r.x - SCROLLBAR_SIZE/2) * max / (r.w - SCROLLBAR_SIZE); + pos = (CursorX_Widescreen(si->item->widescreen) - r.x - SCROLLBAR_SIZE/2) * max / (r.w - SCROLLBAR_SIZE); if (pos < 0) { pos = 0; } @@ -2697,7 +2838,7 @@ static void Scroll_ListBox_ThumbFunc(void *p) { pos = max; } listPtr->startPos = pos; - si->xStart = DC->cursorx; + si->xStart = CursorX_Widescreen(si->item->widescreen); } else if (DC->cursory != si->yStart) { @@ -2745,7 +2886,7 @@ static void Scroll_Slider_ThumbFunc(void *p) { x = si->item->window.rect.x; } - cursorx = DC->cursorx; + cursorx = CursorX_Widescreen(si->item->widescreen); //DC->cursorx; if (cursorx < x) { cursorx = x; @@ -2781,7 +2922,7 @@ static void Item_StartCapture(itemDef_t *item, int key) { } else if (flags & WINDOW_LB_THUMB) { scrollInfo.scrollKey = key; scrollInfo.item = item; - scrollInfo.xStart = DC->cursorx; + scrollInfo.xStart = CursorX_Widescreen(scrollInfo.item->widescreen); //DC->cursorx; scrollInfo.yStart = DC->cursory; captureData = &scrollInfo; captureFunc = &Scroll_ListBox_ThumbFunc; @@ -2797,7 +2938,7 @@ static void Item_StartCapture(itemDef_t *item, int key) { if (flags & WINDOW_LB_THUMB) { scrollInfo.scrollKey = key; scrollInfo.item = item; - scrollInfo.xStart = DC->cursorx; + scrollInfo.xStart = CursorX_Widescreen(scrollInfo.item->widescreen); //DC->cursorx; scrollInfo.yStart = DC->cursory; captureData = &scrollInfo; captureFunc = &Scroll_Slider_ThumbFunc; @@ -2816,7 +2957,7 @@ static qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) { float x, value, width, work; //DC->Print("slider handle key\n"); - if (item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) { + if (item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsWidescreenPoint(&item->window.rect, DC->cursorx, DC->cursory, item->widescreen)) { if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) { editFieldDef_t *editDef = item->typeData; if (editDef) { @@ -2835,8 +2976,8 @@ static qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) { //DC->Print("slider x: %f\n", testRect.x); testRect.w = (SLIDER_WIDTH + (float)SLIDER_THUMB_WIDTH / 2); //DC->Print("slider w: %f\n", testRect.w); - if (Rect_ContainsPoint(&testRect, DC->cursorx, DC->cursory)) { - work = DC->cursorx - x; + if (Rect_ContainsWidescreenPoint(&testRect, DC->cursorx, DC->cursory, item->widescreen)) { + work = CursorX_Widescreen(item->widescreen) - x; value = work / width; value *= (editDef->maxVal - editDef->minVal); // vm fuckage @@ -3121,7 +3262,7 @@ void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) { } // see if the mouse is within the window bounds and if so is this a mouse click - if (down && !(menu->window.flags & WINDOW_POPUP) && !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory)) { + if (down && !(menu->window.flags & WINDOW_POPUP) && !Rect_ContainsWidescreenPoint(&menu->window.rect, DC->cursorx, DC->cursory, menu->widescreen)) { static qboolean inHandleKey = qfalse; if (!inHandleKey && ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3 ) ) { inHandleKey = qtrue; @@ -3204,18 +3345,18 @@ void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) { case K_MOUSE2: if (item) { if (item->type == ITEM_TYPE_TEXT) { - if (Rect_ContainsPoint(Item_CorrectedTextRect(item), DC->cursorx, DC->cursory)) { + if (Rect_ContainsWidescreenPoint(Item_CorrectedTextRect(item), DC->cursorx, DC->cursory, item->widescreen)) { Item_Action(item); } } else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) { - if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) { + if (Rect_ContainsWidescreenPoint(&item->window.rect, DC->cursorx, DC->cursory, item->widescreen)) { item->cursorPos = 0; g_editingField = qtrue; g_editItem = item; DC->setOverstrikeMode(qtrue); } } else { - if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) { + if (Rect_ContainsWidescreenPoint(&item->window.rect, DC->cursorx, DC->cursory, item->widescreen)) { Item_Action(item); } } @@ -4019,7 +4160,7 @@ static qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down) { int id; int i; - if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && !g_waitingForKey) + if (Rect_ContainsWidescreenPoint(&item->window.rect, DC->cursorx, DC->cursory, item->widescreen) && !g_waitingForKey) { if (down && (key == K_MOUSE1 || key == K_ENTER)) { g_waitingForKey = qtrue; @@ -4852,11 +4993,13 @@ void Menu_HandleMouseMove(menuDef_t *menu, float x, float y) { - if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { + //if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { + //if (Item_ContainsPoint(menu->items[i], x, y)) { + if (Rect_ContainsWidescreenPoint(&menu->items[i]->window.rect, x, y, menu->items[i]->widescreen)) { if (pass == 1) { overItem = menu->items[i]; if (overItem->type == ITEM_TYPE_TEXT && overItem->text) { - if (!Rect_ContainsPoint(Item_CorrectedTextRect(overItem), x, y)) { + if (!Rect_ContainsWidescreenPoint(Item_CorrectedTextRect(overItem), x, y, overItem->widescreen)) { continue; } } @@ -7758,7 +7901,7 @@ void *Display_CaptureItem(int x, int y) { for (i = 0; i < menuCount; i++) { // turn off focus each item // menu->items[i].window.flags &= ~WINDOW_HASFOCUS; - if (Rect_ContainsPoint(&Menus[i].window.rect, x, y)) { + if (Rect_ContainsWidescreenPoint(&Menus[i].window.rect, x, y, Menus[i].widescreen)) { return &Menus[i]; } } @@ -7798,7 +7941,7 @@ int Display_CursorType(int x, int y) { r2.x = Menus[i].window.rect.x - 3; r2.y = Menus[i].window.rect.y - 3; r2.w = r2.h = 7; - if (Rect_ContainsPoint(&r2, x, y)) { + if (Rect_ContainsWidescreenPoint(&r2, x, y, Menus[i].widescreen)) { return CURSOR_SIZER; } } @@ -7859,7 +8002,7 @@ void Display_CacheAll(void) { static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y) { if (menu && menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)) { - if (Rect_ContainsPoint(&menu->window.rect, x, y)) { + if (Rect_ContainsWidescreenPoint(&menu->window.rect, x, y, menu->widescreen)) { int i; for (i = 0; i < menu->itemCount; i++) { // turn off focus each item @@ -7873,10 +8016,10 @@ static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y) { continue; } - if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { + if (Rect_ContainsWidescreenPoint(&menu->items[i]->window.rect, x, y, menu->items[i]->widescreen)) { itemDef_t *overItem = menu->items[i]; if (overItem->type == ITEM_TYPE_TEXT && overItem->text) { - if (Rect_ContainsPoint(Item_CorrectedTextRect(overItem), x, y)) { + if (Rect_ContainsWidescreenPoint(Item_CorrectedTextRect(overItem), x, y, overItem->widescreen)) { return qtrue; } else { continue; diff --git a/code/ui/ui_shared.h b/code/ui/ui_shared.h index 8ddb26ba..42824814 100644 --- a/code/ui/ui_shared.h +++ b/code/ui/ui_shared.h @@ -113,6 +113,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define SLIDER_THUMB_HEIGHT 20.0 #define NUM_CROSSHAIRS 30 // there are 29 in ql but have space for 0 (none) +#define WIDESCREEN_NONE 0 +#define WIDESCREEN_LEFT 1 +#define WIDESCREEN_CENTER 2 +#define WIDESCREEN_RIGHT 3 + // unused /* typedef struct { @@ -415,6 +420,7 @@ typedef struct { qhandle_t gradientImage; qhandle_t cursor; float FPS; + int widescreen; } displayContextDef_t; diff --git a/track-ioq3.txt b/track-ioq3.txt index d9280b6f..e18699ae 100644 --- a/track-ioq3.txt +++ b/track-ioq3.txt @@ -1618,3 +1618,73 @@ Remove unnecessary localhost check from reconnect command. 2015-06-30-02 skip: Merge pull request #128 from tbm/master 2015-06-30-03 Merge pull request #4 from smcv/hurd Add support for the GNU/Hurd architecture +2015-07-04-01 Fix CG_WaterLevel() checks for waterlevel 2 and 3 +2015-07-04-02 Fix CGame CG_WaterLevel() comparisons +2015-07-04-03 Apply greyscaling to fog blocks +2015-07-04-04 Don't fog 3D crosshair sprite +2015-07-04-05 Fix Windows file list extension check + +2015-07-06-01 skip: server_compile.sh & start_server.sh for Linux ioq3 sysadmins +2015-07-06-02 skip: Fix server_compile.sh to exit after completed + +2015-07-09-01 skip (depends on previous skipped patch): Remove unused fpucw from snapvector.asm +2015-07-09-02 part (gl1): Fix OpenGL2 ignoring last light grid point on each axis + +2015-07-12-01 Backport ignoring values outside lightgrid to OpenGL1 +2015-07-12-02 Fix range checks for numBorders in CM_AddFacetBevels +2015-07-12-03 Make more vm_x86 macros use braces so they work with if blah run macro +2015-07-12-04 Don't segfault in FS_CreatePath when there are no path seperators +2015-07-12-05 skip (rend2): Remove logically dead code in R_CheckFBO +2015-07-12-06 Fix alloc size for default skin and single shader skin +2015-07-12-07 skip (different): Fix cgs.teamVoteString buffer overflow in CG_ConfigStringModified +2015-07-12-08 skip (not really dead code): Remove logically dead code from CL_GetServerStatus + +2015-07-13-01 Fix handling too many teams in Team Arena UI + +2015-07-14-01 Makefile: confine $(LIB) to the one platform that needs it, namely irix64 +2015-07-14-02 build: canonicalize all ARM variants to "arm", matching q_platform.h +2015-07-14-03 build: define ARCH_STRING in Makefile on Linux and other GNU platforms + +2015-07-15-01 skip: Merge pull request #129 from smcv/generic-platform + +2015-07-22-01 skip (code is different): build: if tput fails, fall back to a reasonable text width +2015-07-22-02 skip: Merge pull request #131 from smcv/tput + +2015-07-24-01 SDL_Init zero check + +2015-07-25-01 skip: Merge pull request #132 from Pan7/SDL_Init +2015-07-25-02 skip (sdl2): SDL_FALSE/TRUE for SDL_SetWindowGrab +2015-07-25-03 skip (sdl2): SDL_SetWindowGammaRamp check + +2015-07-26-01 skip (sdl2): SDL_GetWindowDisplayIndex check +2015-07-26-02 skip (sdl2): SDL_CreateWindow NULL check +2015-07-26-03 skip (sdl2): Added SDL_GetError() +2015-07-26-04 skip (sdl2): Added SDL_GetError() +2015-07-26-05 skip: Merge pull request #133 from Pan7/SDL_bool +2015-07-26-06 skip: Merge pull request #134 from Pan7/GammaCheck +2015-07-26-07 skip: Merge pull request #135 from Pan7/SDL_Index +2015-07-26-08 skip: Merge pull request #136 from Pan7/SDL_NULL +2015-07-26-09 skip (sdl2): SDL_GetWindowDisplayIndex() check2 +2015-07-26-10 skip (sdl2): SDL_GL_SetSwapInterval() check +2015-07-26-11 skip: Merge pull request #92 from Pan7/curl_error +2015-07-26-12 skip: Merge pull request #137 from Pan7/SDL_display +2015-07-26-13 skip: Merge pull request #138 from Pan7/SDL_Swap +2015-07-26-14 skip (missing file): Fix 'Invalid architecture' message in make-macosx-app.sh + +2015-07-27-01 qcurl_multi_remove_handle check +2015-07-27-02 qcurl_multi_strerror not curl_multi_strerror + +2015-07-28-01 skip: Merge pull request #140 from Pan7/qcurl_remove +2015-07-28-01 qcurl_easy_setopt dev warning + +2015-07-29-01 qcurl_multi_cleanup check +2015-07-29-02 skip: Merge pull request #142 from Pan7/qcurl_warn +2015-07-29-03 skip: Merge pull request #143 from Pan7/qcurl_cleanup +2015-07-29-04 Return the result from qcurl_easy_setopt_warn +2015-07-29-05 Add missing qcurl handle cleanup +2015-07-29-06 skip: Merge pull request #144 from Pan7/qurl_handle2 + +2015-07-30-01 Fix va_list warning +2015-07-30-01 skip: Merge pull request #145 from Pan7/va_list +2015-07-30-02 Fix (unused) watertype checks in PM_WaterMove + diff --git a/version b/version index b5e45b2d..c646d737 100644 --- a/version +++ b/version @@ -1,11 +1,11 @@ -11.0test10 +11.0test11 * hud: quake3 single player gametype is cg_gametype 16 * bug fix: quake3 single player demos would show hud elements from quake live 'race' gametype * bug fix: incorrect player shown in cpma duel scoreboard * bug fix: additional quake live weapons registered even if protocol didn't support them -* default quake live linux and mac os x directory changed to $HOME/.wine/drive_c/users/$USER/Application Data/id Software/quakelive +* default quake live linux and mac os x directory is checked with wine versions (either steam or standalone). Ex: $HOME/.wine/drive_c/users/$USER/Application Data/id Software/quakelive * cl_demoFileCheckSystem check for demo file in the local file system as well as wolfcam and quake live directories. (0: no check, 1: check local directory before wolfcam or quakelive directories, 2: (default) check if not found in wolfcam or quake live directories) ex: wolfcamql.exe +set cl_demoFileCheckSystem 1 +demo c:\tmp\dem6.dm_90 @@ -53,8 +53,6 @@ Widescreen cvars for hud elements not controlled through menus: cg_drawSpeedWideScreen, cg_drawJumpSpeedWideScreen, cg_drawJumpSpeedsTimeWideScreen, cg_drawFollowingWideScreen, cg_drawAttackerWideScreen, cg_drawSnapshotWideScreen, cg_drawFPSWideScreen.integer, cg_drawClientItemTimerWideScreen, cg_drawOriginWideScreen, cg_drawItemPickupsWideScreen, cg_drawRewardsWideScreen, cg_lagometerWideScreen, cg_drawCenterPrintWideScreen, cg_drawFragMessageWideScreen, cg_drawCrosshairNamesWideScreen, cg_drawCrosshairTeammateHealthWideScreen, cg_drawVoteWideScreen, cg_drawTeamVoteWideScreen, cg_scoreBoardOldWideScreen, cg_drawFollowingWideScreen, cg_drawAmmoWarningWideScreen, cg_drawProxWarningWideScreen, cg_drawWaitingForPlayersWideScreen, cg_accWideScreen, cg_drawDominationPointStatusWideScreen, cg_weaponBarWideScreen, cg_drawWarmupStringWideScreen, cg_echoPopupWideScreen - FIXME cursor / mouse uses widescreen 0 - - damage indicators (cg_damagePlum, cg_damagePlumColorStyle, cg_damagePlumTarget, cg_damagePlumTime, cg_damagePlumBounce, cg_damagePlumGravity, cg_damagePlumRandomVelocity, cg_damagePlumFont, cg_damagePlumFontStyle, cg_damagePlumPointSize, cg_damagePlumScale, cg_damagePlumColor, cg_damagePlumAlpha) - freezetag scoreboard change @@ -141,9 +139,36 @@ * png option for videos and screenshots: /video png /screenshotPNG r_pngCompressionFast * bug fix: inconsistent use of either 'cg_helpIcon 0' or 'cg_helpIconStyle 0' to disable ingame help icons. Setting either to 0 will disable them. * ability to filter out reward types: cg_rewardHumiliation, cg_rewardQuadGod, etc.. disables both announcement and icon display -*FIXME q3mme camera -* preliminary support for demo protocol 91 +* camera: spline angle type (from q3mme) available. This is now the default angle type. +* camera: splineBezier and splineCatmullRom camera origin type (from q3mme) available. splineBezier is now the default origin type. +* camera: fov spline interpolation type from q3mme +* camera: camera flags incorporated from q3mme. These are used with spline angle type, splineBezier origin type, splineCatmullRom origin type, and spline fov type. + Can be set with /ecam flags [origin | angles | fov | time] +* q3mme camera support: + /q3mmecamera (same as q3mme /camera command) + added flags subcommand to print or set camera flag values: + /q3mmecamera flags [origin | angles | fov | time] + + target sub command changed, you need to specify a target number (-1 means no target). Ex: /q3mmecamera target 9 + + additional commands: + /playq3mmecamera + /stopq3mmecamera + /saveq3mmecamera + /loadq3mmecamera + + cg_q3mmeCameraSmoothPos is the same as mov_cameraSmoothPos in q3mme. + +* preliminary support for demo protocol 91 +* r_mode default changed to 11 (856x480) +* steam quake live directory also checked for demos +* fs_quakelivedir changed to also support steam version and needs to point to the parent of the 'baseq3' directory. Ex: wolfcamql +set fs_quakelivedir "C:\\Program Files (x86)\\Steam\\steamapps\\common\\Quake Live\\12345678901234567" +* bug fix: last camera origin spline point was set incorrectly +* windows version can echo console messages in the command prompt if --console-output is used in the command line. This will also output using q3 colors. +* camera: editing hud indicates if the camera view is locked +* bug fix: error popup message doesn't spam error sound if the same message is repeated +* camera bug fix: /ecam didn't report unknown camera types ------------------------------------ 10.3 2013-11-16