Quake DeveLS - Low-light Vision (GL Mode ONLY for Multiplayer)

Author: Jonathan Benson (Hardware)
Difficulty: MEDIUM

OK well here is a quick test I put together to give the effect of low-light vision.  Unfortunately due to the (simple) little trick I use it is really only any good in multiplayer if in GL Mode.  You'll soon see what I mean if you run it in Software mode.  If ANYONE knows why the r_fullbright cvar has no effect whilst in multiplayer I'd appreciate them enlightening me via email.

Text in red = Quake II's code
Text in green = My changes

Alright, first up we need to add a few #defines and some variables that will be used to for the effect.  Open up p_view.c and find and modify the start of the file as follows:

#include "g_local.h"
#include "m_player.h"

// JDB: Define variables for lowlight vision effect 4/4/98
#define LLV_R 0.0
#define LLV_G 0.7
#define LLV_B 0.0
#define LLV_A 0.7

static  edict_t         *current_player;
static  gclient_t       *current_client;
These are the red, green, blue and alpha values that we will blend to the players vision to give the effect of looking through a low-light scope.  I've #defined them so I can tweak them if necessary.

Why didn't I do this in g_local.h in the appropriate section (ie the part refering to p_view.c)?  Simple, they are only used in p_view.c and if I'd included them in g_local.h then every time I change them I'd have to recompile all the objects, as g_local.h is included in most/all? source files.  This way only p_view.c need be recompiled when they are changed.

The values I have here are OK, but I'm sure this whole mod could do with a few improvements so this makes it simpler to modify later.

Next open up g_local.h and modify the following section towards the end of the gclient_s struct to give us a variable we can use to toggle the low-light vision on/off:

Alright now we have a variable we might as well make sure it is initialised, so open up p_client.c and modify the code as follows in the PutClientInServer function.  I'm not entirely sure this is necessary, but it's better to be safe than sorry, right?  This section also makes sure the gl_saturatelighting and r_fullbright part of the effect is turned off when the player is respawned (more on them later):
        VectorCopy (ent->s.angles, client->ps.viewangles);
        VectorCopy (ent->s.angles, client->v_angle);

        // JDB: init variable for lowlight and reset gl_saturatelighting 4/4/98
        ent->client->lowlight = 0;

        if (!KillBox (ent))
        {       // could't spawn in?
Next we need to add a command to toggle the effect on/off so open up g_cmds.c and first add the code that will call the appropriate function when we type the command: Then we need to add the function itself, so go back up a bit (still in g_cmds.c) and add in the rather simple command as follows: Some of you may be wondering what the if(ent->client->lowlight ^= 1) does, or perhaps how it does it's magic.  Well the ^= is an assignment operator which does an XOR of the current lowlight value with 1.  This gives the result of toggling it between 1 and 0.  Ie.  1 XOR 1 = 0 and 0 XOR 1 = 1

The gl_saturatelighting (in GL mode) and the r_fullbright (in Software mode) are both console variables that are used to make it appear as though all the lights in the level are fully on (although they can actually be off) when the low-light vision is enabled.  This effect will be most visible in a dark area or if you've used the Lights Out! mod by John Rittenhouse to turn out all the lights.  Here's a hint: try doing both these tutes then turning out the lights in single player and running around with the low light vision!!

I guess an explanation of the gi.cvar_forceset function is in order.  I've used cvar_forceset instead of just cvar_set as I'd been having troubles getting this working in multiplayer.  A quick and dirty explanation is that it is a Game Interface function (hence the gi.) that allows you to set a console variable, similar to typing "set gl_saturatelighting 1" at the console.  If you didn't know this I suggest you take a look at some of the earlier tutorials here and take a look through the 'functions provided by the main engine' (ie. the other game interface functions) in game.h

I've reduced the field-of-view by setting the fov variable for the client (ie the player) to give the effect of looking through a scope/goggles.  If you don't like it just comment out those two lines.

Finally we need to effect the players vision, to give the green tint, when the low light vision is enabled so open go back to p_view.c and modify SV_CalcBlend as follows:

        else if (contents & CONTENTS_WATER)
                SV_AddBlend (0.5, 0.3, 0.2, 0.4, ent->client->ps.blend);

        // JDB: lowlight vision effect 4/4/98
        if (ent->client->lowlight)
                SV_AddBlend (LLV_R, LLV_G, LLV_B, LLV_A, ent->client->ps.blend);

        // add for powerups
        if (ent->client->quad_framenum > level.framenum)
Without this everything would look too bright and washed out and of course it wouldn't have the green tint.  As it is many of the skins will get washed out, but as I said I'm more than open to suggestions of a better way to do this (ie rather than using gl_saturatelighting/r_fullbright).

OK we are done so compile it, fire up a map and find a dark area to try it out in (where you start in q2dm1 isn't a bad spot), or if you've already done the Lights Out! tute then just turn out the lights!  You can bind the command to a key if you like.  I used "bind \ lowlight".

Some suggestions for further development:

Anyway,  if you do any of the above then please let me know via e-mail.  Also let me know if you use this in a PC/TC and give credit where credit is due.

This site, and all content and graphics displayed on it,
are ©opyrighted to the Quake DeveLS team. All rights received.
Got a suggestion? Comment? Question? Hate mail? Send it to us!
Oh yeah, this site is best viewed in 16 Bit or higher, with the resolution on 800*600.
Thanks to Planet Quake for there great help and support with hosting.
Best viewed with Netscape 4