Reformat the client

This commit is contained in:
Yamagi Burmeister 2012-07-22 15:34:45 +02:00
parent 7bbfa01a87
commit b52336850f
21 changed files with 10161 additions and 6787 deletions

View file

@ -27,42 +27,45 @@
#include "header/client.h" #include "header/client.h"
typedef struct { typedef struct
byte *data; {
int count; byte *data;
int count;
} cblock_t; } cblock_t;
typedef struct { typedef struct
qboolean restart_sound; {
int s_rate; qboolean restart_sound;
int s_width; int s_rate;
int s_channels; int s_width;
int s_channels;
int width; int width;
int height; int height;
byte *pic; byte *pic;
byte *pic_pending; byte *pic_pending;
/* order 1 huffman stuff */ /* order 1 huffman stuff */
int *hnodes1; int *hnodes1;
/* [256][256][2]; */ /* [256][256][2]; */
int numhnodes1[256]; int numhnodes1[256];
int h_used[512]; int h_used[512];
int h_count[512]; int h_count[512];
} cinematics_t; } cinematics_t;
cinematics_t cin; cinematics_t cin;
void void
SCR_LoadPCX(char *filename, byte ** pic, byte ** palette, int *width, int *height) { SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height)
byte *raw; {
pcx_t *pcx; byte *raw;
int x, y; pcx_t *pcx;
int len; int x, y;
int dataByte, runLength; int len;
byte *out, *pix; int dataByte, runLength;
byte *out, *pix;
*pic = NULL; *pic = NULL;
@ -70,18 +73,21 @@ SCR_LoadPCX(char *filename, byte ** pic, byte ** palette, int *width, int *heigh
len = FS_LoadFile(filename, (void **)&raw); len = FS_LoadFile(filename, (void **)&raw);
if (!raw) if (!raw)
{
return; return;
}
/* parse the PCX file */ /* parse the PCX file */
pcx = (pcx_t *) raw; pcx = (pcx_t *)raw;
raw = &pcx->data; raw = &pcx->data;
if (pcx->manufacturer != 0x0a if ((pcx->manufacturer != 0x0a) ||
|| pcx->version != 5 (pcx->version != 5) ||
|| pcx->encoding != 1 (pcx->encoding != 1) ||
|| pcx->bits_per_pixel != 8 (pcx->bits_per_pixel != 8) ||
|| pcx->xmax >= 640 (pcx->xmax >= 640) ||
|| pcx->ymax >= 480) { (pcx->ymax >= 480))
{
Com_Printf("Bad pcx file %s\n", filename); Com_Printf("Bad pcx file %s\n", filename);
return; return;
} }
@ -92,35 +98,47 @@ SCR_LoadPCX(char *filename, byte ** pic, byte ** palette, int *width, int *heigh
pix = out; pix = out;
if (palette) { if (palette)
{
*palette = Z_Malloc(768); *palette = Z_Malloc(768);
memcpy(*palette, (byte *) pcx + len - 768, 768); memcpy(*palette, (byte *)pcx + len - 768, 768);
} }
if (width) if (width)
{
*width = pcx->xmax + 1; *width = pcx->xmax + 1;
if (height)
*height = pcx->ymax + 1;
for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1) {
for (x = 0; x <= pcx->xmax;) {
dataByte = *raw++;
if ((dataByte & 0xC0) == 0xC0) {
runLength = dataByte & 0x3F;
dataByte = *raw++;
} else
runLength = 1;
while (runLength-- > 0)
pix[x++] = dataByte;
}
} }
if (raw - (byte *) pcx > len) { if (height)
{
*height = pcx->ymax + 1;
}
for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1)
{
for (x = 0; x <= pcx->xmax; )
{
dataByte = *raw++;
if ((dataByte & 0xC0) == 0xC0)
{
runLength = dataByte & 0x3F;
dataByte = *raw++;
}
else
{
runLength = 1;
}
while (runLength-- > 0)
{
pix[x++] = dataByte;
}
}
}
if (raw - (byte *)pcx > len)
{
Com_Printf("PCX file %s was malformed", filename); Com_Printf("PCX file %s was malformed", filename);
Z_Free(*pic); Z_Free(*pic);
*pic = NULL; *pic = NULL;
@ -130,71 +148,88 @@ SCR_LoadPCX(char *filename, byte ** pic, byte ** palette, int *width, int *heigh
} }
void void
SCR_StopCinematic(void) { SCR_StopCinematic(void)
{
cl.cinematictime = 0; /* done */ cl.cinematictime = 0; /* done */
if (cin.pic) { if (cin.pic)
{
Z_Free(cin.pic); Z_Free(cin.pic);
cin.pic = NULL; cin.pic = NULL;
} }
if (cin.pic_pending) { if (cin.pic_pending)
{
Z_Free(cin.pic_pending); Z_Free(cin.pic_pending);
cin.pic_pending = NULL; cin.pic_pending = NULL;
} }
if (cl.cinematicpalette_active) { if (cl.cinematicpalette_active)
{
re.CinematicSetPalette(NULL); re.CinematicSetPalette(NULL);
cl.cinematicpalette_active = false; cl.cinematicpalette_active = false;
} }
if (cl.cinematic_file) { if (cl.cinematic_file)
{
FS_FCloseFile((size_t)cl.cinematic_file); FS_FCloseFile((size_t)cl.cinematic_file);
cl.cinematic_file = 0; cl.cinematic_file = 0;
} }
if (cin.hnodes1) { if (cin.hnodes1)
{
Z_Free(cin.hnodes1); Z_Free(cin.hnodes1);
cin.hnodes1 = NULL; cin.hnodes1 = NULL;
} }
/* switch back down to 11 khz sound if necessary */ /* switch back down to 11 khz sound if necessary */
if (cin.restart_sound) { if (cin.restart_sound)
{
cin.restart_sound = false; cin.restart_sound = false;
CL_Snd_Restart_f(); CL_Snd_Restart_f();
} }
} }
void void
SCR_FinishCinematic(void) { SCR_FinishCinematic(void)
{
/* tell the server to advance to the next map / cinematic */ /* tell the server to advance to the next map / cinematic */
MSG_WriteByte(&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
SZ_Print(&cls.netchan.message, va("nextserver %i\n", cl.servercount)); SZ_Print(&cls.netchan.message, va("nextserver %i\n", cl.servercount));
} }
int int
SmallestNode1(int numhnodes) { SmallestNode1(int numhnodes)
int i; {
int best, bestnode; int i;
int best, bestnode;
best = 99999999; best = 99999999;
bestnode = -1; bestnode = -1;
for (i = 0; i < numhnodes; i++) { for (i = 0; i < numhnodes; i++)
{
if (cin.h_used[i]) if (cin.h_used[i])
{
continue; continue;
}
if (!cin.h_count[i]) if (!cin.h_count[i])
{
continue; continue;
}
if (cin.h_count[i] < best) { if (cin.h_count[i] < best)
{
best = cin.h_count[i]; best = cin.h_count[i];
bestnode = i; bestnode = i;
} }
} }
if (bestnode == -1) if (bestnode == -1)
{
return -1; return -1;
}
cin.h_used[bestnode] = true; cin.h_used[bestnode] = true;
return bestnode; return bestnode;
@ -204,17 +239,19 @@ SmallestNode1(int numhnodes) {
* Reads the 64k counts table and initializes the node trees * Reads the 64k counts table and initializes the node trees
*/ */
void void
Huff1TableInit(void) { Huff1TableInit(void)
int prev; {
int j; int prev;
int *node, *nodebase; int j;
byte counts[256]; int *node, *nodebase;
int numhnodes; byte counts[256];
int numhnodes;
cin.hnodes1 = Z_Malloc(256 * 256 * 2 * 4); cin.hnodes1 = Z_Malloc(256 * 256 * 2 * 4);
memset(cin.hnodes1, 0, 256 * 256 * 2 * 4); memset(cin.hnodes1, 0, 256 * 256 * 2 * 4);
for (prev = 0; prev < 256; prev++) { for (prev = 0; prev < 256; prev++)
{
memset(cin.h_count, 0, sizeof(cin.h_count)); memset(cin.h_count, 0, sizeof(cin.h_count));
memset(cin.h_used, 0, sizeof(cin.h_used)); memset(cin.h_used, 0, sizeof(cin.h_used));
@ -222,27 +259,35 @@ Huff1TableInit(void) {
FS_Read(counts, sizeof(counts), (size_t)cl.cinematic_file); FS_Read(counts, sizeof(counts), (size_t)cl.cinematic_file);
for (j = 0; j < 256; j++) for (j = 0; j < 256; j++)
{
cin.h_count[j] = counts[j]; cin.h_count[j] = counts[j];
}
/* build the nodes */ /* build the nodes */
numhnodes = 256; numhnodes = 256;
nodebase = cin.hnodes1 + prev * 256 * 2; nodebase = cin.hnodes1 + prev * 256 * 2;
while (numhnodes != 511) { while (numhnodes != 511)
{
node = nodebase + (numhnodes - 256) * 2; node = nodebase + (numhnodes - 256) * 2;
/* pick two lowest counts */ /* pick two lowest counts */
node[0] = SmallestNode1(numhnodes); node[0] = SmallestNode1(numhnodes);
if (node[0] == -1) if (node[0] == -1)
break; /* no more counts */ {
break; /* no more counts */
}
node[1] = SmallestNode1(numhnodes); node[1] = SmallestNode1(numhnodes);
if (node[1] == -1) if (node[1] == -1)
{
break; break;
}
cin.h_count[numhnodes] = cin.h_count[node[0]] + cin.h_count[node[1]]; cin.h_count[numhnodes] = cin.h_count[node[0]] +
cin.h_count[node[1]];
numhnodes++; numhnodes++;
} }
@ -251,49 +296,56 @@ Huff1TableInit(void) {
} }
cblock_t cblock_t
Huff1Decompress(cblock_t in) { Huff1Decompress(cblock_t in)
byte *input; {
byte *out_p; byte *input;
int nodenum; byte *out_p;
int count; int nodenum;
cblock_t out; int count;
int inbyte; cblock_t out;
int *hnodes, *hnodesbase; int inbyte;
int *hnodes, *hnodesbase;
/* get decompressed count */ /* get decompressed count */
count = in.data[0] + (in.data[1] << 8) + (in.data[2] << 16) + (in.data[3] << 24); count = in.data[0] +
(in.data[1] << 8) + (in.data[2] << 16) + (in.data[3] << 24);
input = in.data + 4; input = in.data + 4;
out_p = out.data = Z_Malloc(count); out_p = out.data = Z_Malloc(count);
/* read bits */ /* read bits */
hnodesbase = cin.hnodes1 - 256 * 2; /* nodes 0-255 aren't stored */ hnodesbase = cin.hnodes1 - 256 * 2; /* nodes 0-255 aren't stored */
hnodes = hnodesbase; hnodes = hnodesbase;
nodenum = cin.numhnodes1[0]; nodenum = cin.numhnodes1[0];
while (count) { while (count)
{
inbyte = *input++; inbyte = *input++;
int i = 0; int i = 0;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++)
if (nodenum < 256) { {
if (nodenum < 256)
{
hnodes = hnodesbase + (nodenum << 9); hnodes = hnodesbase + (nodenum << 9);
*out_p++ = nodenum; *out_p++ = nodenum;
if (!--count) if (!--count)
{
break; break;
}
nodenum = cin.numhnodes1[nodenum]; nodenum = cin.numhnodes1[nodenum];
} }
nodenum = hnodes[nodenum * 2 + (inbyte & 1)]; nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
inbyte >>= 1; inbyte >>= 1;
} }
} }
if (input - in.data != in.count && input - in.data != in.count + 1) { if ((input - in.data != in.count) && (input - in.data != in.count + 1))
{
Com_Printf("Decompression overread by %i", (input - in.data) - in.count); Com_Printf("Decompression overread by %i", (input - in.data) - in.count);
} }
@ -303,34 +355,43 @@ Huff1Decompress(cblock_t in) {
} }
byte * byte *
SCR_ReadNextFrame(void) { SCR_ReadNextFrame(void)
int r; {
int command; int r;
byte samples[22050 / 14 * 4]; int command;
byte compressed[0x20000]; byte samples[22050 / 14 * 4];
int size; byte compressed[0x20000];
byte *pic; int size;
cblock_t in, huf1; byte *pic;
int start, end, count; cblock_t in, huf1;
int start, end, count;
/* read the next frame */ /* read the next frame */
r = FS_FRead(&command, 4, 1, (size_t)cl.cinematic_file); r = FS_FRead(&command, 4, 1, (size_t)cl.cinematic_file);
if (r == 0) if (r == 0)
{
/* we'll give it one more chance */ /* we'll give it one more chance */
r = FS_FRead(&command, 4, 1, (size_t)cl.cinematic_file); r = FS_FRead(&command, 4, 1, (size_t)cl.cinematic_file);
}
if (r != 4) if (r != 4)
{
return NULL; return NULL;
}
command = LittleLong(command); command = LittleLong(command);
if (command == 2) if (command == 2)
{
return NULL; /* last frame marker */ return NULL; /* last frame marker */
}
if (command == 1) { if (command == 1)
{
/* read palette */ /* read palette */
FS_Read(cl.cinematicpalette, sizeof(cl.cinematicpalette), (size_t)cl.cinematic_file); FS_Read(cl.cinematicpalette, sizeof(cl.cinematicpalette),
(size_t)cl.cinematic_file);
cl.cinematicpalette_active = 0; cl.cinematicpalette_active = 0;
} }
@ -338,8 +399,10 @@ SCR_ReadNextFrame(void) {
FS_Read(&size, 4, (size_t)cl.cinematic_file); FS_Read(&size, 4, (size_t)cl.cinematic_file);
size = LittleLong(size); size = LittleLong(size);
if ((unsigned long)size > sizeof(compressed) || size < 1) if (((unsigned long)size > sizeof(compressed)) || (size < 1))
{
Com_Error(ERR_DROP, "Bad compressed frame size"); Com_Error(ERR_DROP, "Bad compressed frame size");
}
FS_Read(compressed, size, (size_t)cl.cinematic_file); FS_Read(compressed, size, (size_t)cl.cinematic_file);
@ -348,14 +411,19 @@ SCR_ReadNextFrame(void) {
end = (cl.cinematicframe + 1) * cin.s_rate / 14; end = (cl.cinematicframe + 1) * cin.s_rate / 14;
count = end - start; count = end - start;
FS_Read(samples, count * cin.s_width * cin.s_channels, (size_t)cl.cinematic_file); FS_Read(samples, count * cin.s_width * cin.s_channels,
(size_t)cl.cinematic_file);
if (cin.s_width == 2) { if (cin.s_width == 2)
{
for (r = 0; r < count * cin.s_channels; r++) for (r = 0; r < count * cin.s_channels; r++)
((short *) samples)[r] = LittleShort( ((short *) samples)[r] ); {
((short *)samples)[r] = LittleShort(((short *)samples)[r]);
}
} }
S_RawSamples(count, cin.s_rate, cin.s_width, cin.s_channels, samples, Cvar_VariableValue("s_volume")); S_RawSamples(count, cin.s_rate, cin.s_width, cin.s_channels,
samples, Cvar_VariableValue("s_volume"));
in.data = compressed; in.data = compressed;
in.count = size; in.count = size;
@ -370,18 +438,23 @@ SCR_ReadNextFrame(void) {
} }
void void
SCR_RunCinematic(void) { SCR_RunCinematic(void)
int frame; {
int frame;
if (cl.cinematictime <= 0) { if (cl.cinematictime <= 0)
{
SCR_StopCinematic(); SCR_StopCinematic();
return; return;
} }
if (cl.cinematicframe == -1) if (cl.cinematicframe == -1)
{
return; /* static image */ return; /* static image */
}
if (cls.key_dest != key_game) { if (cls.key_dest != key_game)
{
/* pause if menu or console is up */ /* pause if menu or console is up */
cl.cinematictime = cls.realtime - cl.cinematicframe * 1000 / 14; cl.cinematictime = cls.realtime - cl.cinematicframe * 1000 / 14;
return; return;
@ -390,21 +463,27 @@ SCR_RunCinematic(void) {
frame = (cls.realtime - cl.cinematictime) * 14.0 / 1000; frame = (cls.realtime - cl.cinematictime) * 14.0 / 1000;
if (frame <= cl.cinematicframe) if (frame <= cl.cinematicframe)
{
return; return;
}
if (frame > cl.cinematicframe + 1) { if (frame > cl.cinematicframe + 1)
{
Com_Printf("Dropped frame: %i > %i\n", frame, cl.cinematicframe + 1); Com_Printf("Dropped frame: %i > %i\n", frame, cl.cinematicframe + 1);
cl.cinematictime = cls.realtime - cl.cinematicframe * 1000 / 14; cl.cinematictime = cls.realtime - cl.cinematicframe * 1000 / 14;
} }
if (cin.pic) if (cin.pic)
{
Z_Free(cin.pic); Z_Free(cin.pic);
}
cin.pic = cin.pic_pending; cin.pic = cin.pic_pending;
cin.pic_pending = NULL; cin.pic_pending = NULL;
cin.pic_pending = SCR_ReadNextFrame(); cin.pic_pending = SCR_ReadNextFrame();
if (!cin.pic_pending) { if (!cin.pic_pending)
{
SCR_StopCinematic(); SCR_StopCinematic();
SCR_FinishCinematic(); SCR_FinishCinematic();
cl.cinematictime = 1; /* the black screen behind loading */ cl.cinematictime = 1; /* the black screen behind loading */
@ -419,37 +498,44 @@ SCR_RunCinematic(void) {
* view rendering should be skipped * view rendering should be skipped
*/ */
qboolean qboolean
SCR_DrawCinematic(void) { SCR_DrawCinematic(void)
if (cl.cinematictime <= 0) { {
if (cl.cinematictime <= 0)
{
return false; return false;
} }
/* blank screen and pause if menu is up */ /* blank screen and pause if menu is up */
if (cls.key_dest == key_menu) { if (cls.key_dest == key_menu)
{
re.CinematicSetPalette(NULL); re.CinematicSetPalette(NULL);
cl.cinematicpalette_active = false; cl.cinematicpalette_active = false;
return true; return true;
} }
if (!cl.cinematicpalette_active) { if (!cl.cinematicpalette_active)
{
re.CinematicSetPalette(cl.cinematicpalette); re.CinematicSetPalette(cl.cinematicpalette);
cl.cinematicpalette_active = true; cl.cinematicpalette_active = true;
} }
if (!cin.pic) if (!cin.pic)
{
return true; return true;
}
re.DrawStretchRaw(0, 0, viddef.width, viddef.height, re.DrawStretchRaw(0, 0, viddef.width, viddef.height,
cin.width, cin.height, cin.pic); cin.width, cin.height, cin.pic);
return true; return true;
} }
void void
SCR_PlayCinematic(char *arg) { SCR_PlayCinematic(char *arg)
int width, height; {
byte *palette; int width, height;
char name[MAX_OSPATH], *dot; byte *palette;
char name[MAX_OSPATH], *dot;
/* make sure background music is not playing */ /* make sure background music is not playing */
#ifdef CDA #ifdef CDA
@ -463,7 +549,8 @@ SCR_PlayCinematic(char *arg) {
dot = strstr(arg, "."); dot = strstr(arg, ".");
/* static pcx image */ /* static pcx image */
if (dot && !strcmp(dot, ".pcx")) { if (dot && !strcmp(dot, ".pcx"))
{
Com_sprintf(name, sizeof(name), "pics/%s", arg); Com_sprintf(name, sizeof(name), "pics/%s", arg);
SCR_LoadPCX(name, &cin.pic, &palette, &cin.width, &cin.height); SCR_LoadPCX(name, &cin.pic, &palette, &cin.width, &cin.height);
cl.cinematicframe = -1; cl.cinematicframe = -1;
@ -471,11 +558,13 @@ SCR_PlayCinematic(char *arg) {
SCR_EndLoadingPlaque(); SCR_EndLoadingPlaque();
cls.state = ca_active; cls.state = ca_active;
if (!cin.pic) { if (!cin.pic)
{
Com_Printf("%s not found.\n", name); Com_Printf("%s not found.\n", name);
cl.cinematictime = 0; cl.cinematictime = 0;
}
} else { else
{
memcpy(cl.cinematicpalette, palette, sizeof(cl.cinematicpalette)); memcpy(cl.cinematicpalette, palette, sizeof(cl.cinematicpalette));
Z_Free(palette); Z_Free(palette);
} }
@ -484,9 +573,10 @@ SCR_PlayCinematic(char *arg) {
} }
Com_sprintf(name, sizeof(name), "video/%s", arg); Com_sprintf(name, sizeof(name), "video/%s", arg);
FS_FOpenFile(name, (fileHandle_t *) &cl.cinematic_file, FS_READ); FS_FOpenFile(name, (fileHandle_t *)&cl.cinematic_file, FS_READ);
if (!cl.cinematic_file) { if (!cl.cinematic_file)
{
SCR_FinishCinematic(); SCR_FinishCinematic();
cl.cinematictime = 0; /* done */ cl.cinematictime = 0; /* done */
return; return;
@ -514,3 +604,4 @@ SCR_PlayCinematic(char *arg) {
cin.pic = SCR_ReadNextFrame(); cin.pic = SCR_ReadNextFrame();
cl.cinematictime = Sys_Milliseconds(); cl.cinematictime = Sys_Milliseconds();
} }

View file

@ -27,168 +27,220 @@
#include "header/client.h" #include "header/client.h"
#include <time.h> #include <time.h>
console_t con; console_t con;
cvar_t *con_notifytime; cvar_t *con_notifytime;
#define MAXCMDLINE 256 #define MAXCMDLINE 256
extern char key_lines[32][MAXCMDLINE]; extern char key_lines[32][MAXCMDLINE];
extern int edit_line; extern int edit_line;
extern int key_linepos; extern int key_linepos;
void DrawString (int x, int y, char *s) { void
while (*s) { DrawString(int x, int y, char *s)
re.DrawChar (x, y, *s); {
x+=8; while (*s)
{
re.DrawChar(x, y, *s);
x += 8;
s++; s++;
} }
} }
void DrawAltString (int x, int y, char *s) { void
while (*s) { DrawAltString(int x, int y, char *s)
re.DrawChar (x, y, *s ^ 0x80); {
x+=8; while (*s)
{
re.DrawChar(x, y, *s ^ 0x80);
x += 8;
s++; s++;
} }
} }
void Key_ClearTyping (void) { void
Key_ClearTyping(void)
{
key_lines[edit_line][1] = 0; /* clear any typing */ key_lines[edit_line][1] = 0; /* clear any typing */
key_linepos = 1; key_linepos = 1;
} }
void Con_ToggleConsole_f (void) { void
SCR_EndLoadingPlaque (); /* get rid of loading plaque */ Con_ToggleConsole_f(void)
{
SCR_EndLoadingPlaque(); /* get rid of loading plaque */
if (cl.attractloop) { if (cl.attractloop)
{
Cvar_SetValue("windowed_mouse", 0); Cvar_SetValue("windowed_mouse", 0);
Cbuf_AddText("killserver\n"); Cbuf_AddText("killserver\n");
return; return;
} }
if (cls.state == ca_disconnected) { if (cls.state == ca_disconnected)
{
/* start the demo loop again */ /* start the demo loop again */
Cvar_SetValue("windowed_mouse", 1); Cvar_SetValue("windowed_mouse", 1);
Cbuf_AddText ("d1\n"); Cbuf_AddText("d1\n");
return; return;
} }
Key_ClearTyping (); Key_ClearTyping();
Con_ClearNotify (); Con_ClearNotify();
if (cls.key_dest == key_console) { if (cls.key_dest == key_console)
M_ForceMenuOff (); {
Cvar_Set ("paused", "0"); M_ForceMenuOff();
Cvar_Set("paused", "0");
} else { }
M_ForceMenuOff (); else
{
M_ForceMenuOff();
cls.key_dest = key_console; cls.key_dest = key_console;
if (Cvar_VariableValue ("maxclients") == 1 if ((Cvar_VariableValue("maxclients") == 1) &&
&& Com_ServerState ()) Com_ServerState())
Cvar_Set ("paused", "1"); {
Cvar_Set("paused", "1");
}
} }
} }
void Con_ToggleChat_f (void) { void
Key_ClearTyping (); Con_ToggleChat_f(void)
{
Key_ClearTyping();
if (cls.key_dest == key_console) { if (cls.key_dest == key_console)
if (cls.state == ca_active) { {
M_ForceMenuOff (); if (cls.state == ca_active)
{
M_ForceMenuOff();
cls.key_dest = key_game; cls.key_dest = key_game;
} }
}
} else else
{
cls.key_dest = key_console; cls.key_dest = key_console;
}
Con_ClearNotify (); Con_ClearNotify();
} }
void Con_Clear_f (void) { void
memset (con.text, ' ', CON_TEXTSIZE); Con_Clear_f(void)
{
memset(con.text, ' ', CON_TEXTSIZE);
} }
/* /*
* Save the console contents out to a file * Save the console contents out to a file
*/ */
void Con_Dump_f (void) { void
int l, x; Con_Dump_f(void)
char *line; {
FILE *f; int l, x;
char buffer[1024]; char *line;
char name[MAX_OSPATH]; FILE *f;
char buffer[1024];
char name[MAX_OSPATH];
if (Cmd_Argc() != 2) { if (Cmd_Argc() != 2)
Com_Printf ("usage: condump <filename>\n"); {
Com_Printf("usage: condump <filename>\n");
return; return;
} }
if (con.linewidth > 1024) { if (con.linewidth > 1024)
Com_Printf ("con.linewidth too large!\n"); {
Com_Printf("con.linewidth too large!\n");
return; return;
} }
Com_sprintf (name, sizeof(name), "%s/%s.txt", FS_Gamedir(), Cmd_Argv(1)); Com_sprintf(name, sizeof(name), "%s/%s.txt", FS_Gamedir(), Cmd_Argv(1));
Com_Printf ("Dumped console text to %s.\n", name); Com_Printf("Dumped console text to %s.\n", name);
FS_CreatePath (name); FS_CreatePath(name);
f = fopen (name, "w"); f = fopen(name, "w");
if (!f) { if (!f)
Com_Printf ("ERROR: couldn't open.\n"); {
Com_Printf("ERROR: couldn't open.\n");
return; return;
} }
/* skip empty lines */ /* skip empty lines */
for (l = con.current - con.totallines + 1 ; l <= con.current ; l++) { for (l = con.current - con.totallines + 1; l <= con.current; l++)
line = con.text + (l%con.totallines)*con.linewidth; {
line = con.text + (l % con.totallines) * con.linewidth;
for (x=0 ; x<con.linewidth ; x++) for (x = 0; x < con.linewidth; x++)
{
if (line[x] != ' ') if (line[x] != ' ')
{
break; break;
}
}
if (x != con.linewidth) if (x != con.linewidth)
{
break; break;
}
} }
/* write the remaining lines */ /* write the remaining lines */
buffer[con.linewidth] = 0; buffer[con.linewidth] = 0;
for ( ; l <= con.current ; l++) { for ( ; l <= con.current; l++)
line = con.text + (l%con.totallines)*con.linewidth; {
strncpy (buffer, line, con.linewidth); line = con.text + (l % con.totallines) * con.linewidth;
strncpy(buffer, line, con.linewidth);
for (x=con.linewidth-1 ; x>=0 ; x--) { for (x = con.linewidth - 1; x >= 0; x--)
{
if (buffer[x] == ' ') if (buffer[x] == ' ')
{
buffer[x] = 0; buffer[x] = 0;
}
else else
{
break; break;
}
} }
for (x=0; buffer[x]; x++) for (x = 0; buffer[x]; x++)
{
buffer[x] &= 0x7f; buffer[x] &= 0x7f;
}
fprintf (f, "%s\n", buffer); fprintf(f, "%s\n", buffer);
} }
fclose (f); fclose(f);
} }
void Con_ClearNotify (void) { void
int i; Con_ClearNotify(void)
{
int i;
for (i=0 ; i<NUM_CON_TIMES ; i++) for (i = 0; i < NUM_CON_TIMES; i++)
{
con.times[i] = 0; con.times[i] = 0;
}
} }
void Con_MessageMode_f (void) { void
Con_MessageMode_f(void)
{
chat_team = false; chat_team = false;
cls.key_dest = key_message; cls.key_dest = key_message;
} }
void Con_MessageMode2_f (void) { void
Con_MessageMode2_f(void)
{
chat_team = true; chat_team = true;
cls.key_dest = key_message; cls.key_dest = key_message;
} }
@ -196,23 +248,29 @@ void Con_MessageMode2_f (void) {
/* /*
* If the line width has changed, reformat the buffer. * If the line width has changed, reformat the buffer.
*/ */
void Con_CheckResize (void) { void
int i, j, width, oldwidth, oldtotallines, numlines, numchars; Con_CheckResize(void)
char tbuf[CON_TEXTSIZE]; {
int i, j, width, oldwidth, oldtotallines, numlines, numchars;
char tbuf[CON_TEXTSIZE];
width = (viddef.width >> 3) - 2; width = (viddef.width >> 3) - 2;
if (width == con.linewidth) if (width == con.linewidth)
{
return; return;
}
/* video hasn't been initialized yet */ /* video hasn't been initialized yet */
if (width < 1) { if (width < 1)
{
width = 38; width = 38;
con.linewidth = width; con.linewidth = width;
con.totallines = CON_TEXTSIZE / con.linewidth; con.totallines = CON_TEXTSIZE / con.linewidth;
memset (con.text, ' ', CON_TEXTSIZE); memset(con.text, ' ', CON_TEXTSIZE);
}
} else { else
{
oldwidth = con.linewidth; oldwidth = con.linewidth;
con.linewidth = width; con.linewidth = width;
oldtotallines = con.totallines; oldtotallines = con.totallines;
@ -220,59 +278,71 @@ void Con_CheckResize (void) {
numlines = oldtotallines; numlines = oldtotallines;
if (con.totallines < numlines) if (con.totallines < numlines)
{
numlines = con.totallines; numlines = con.totallines;
}
numchars = oldwidth; numchars = oldwidth;
if (con.linewidth < numchars) if (con.linewidth < numchars)
{
numchars = con.linewidth; numchars = con.linewidth;
}
memcpy (tbuf, con.text, CON_TEXTSIZE); memcpy(tbuf, con.text, CON_TEXTSIZE);
memset (con.text, ' ', CON_TEXTSIZE); memset(con.text, ' ', CON_TEXTSIZE);
for (i=0 ; i<numlines ; i++) { for (i = 0; i < numlines; i++)
for (j=0 ; j<numchars ; j++) { {
for (j = 0; j < numchars; j++)
{
con.text[(con.totallines - 1 - i) * con.linewidth + j] = con.text[(con.totallines - 1 - i) * con.linewidth + j] =
tbuf[((con.current - i + oldtotallines) % tbuf[((con.current - i + oldtotallines) %
oldtotallines) * oldwidth + j]; oldtotallines) * oldwidth + j];
} }
} }
Con_ClearNotify (); Con_ClearNotify();
} }
con.current = con.totallines - 1; con.current = con.totallines - 1;
con.display = con.current; con.display = con.current;
} }
void Con_Init (void) { void
Con_Init(void)
{
con.linewidth = -1; con.linewidth = -1;
Con_CheckResize (); Con_CheckResize();
Com_Printf ("Console initialized.\n"); Com_Printf("Console initialized.\n");
/* register our commands */ /* register our commands */
con_notifytime = Cvar_Get ("con_notifytime", "3", 0); con_notifytime = Cvar_Get("con_notifytime", "3", 0);
Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f); Cmd_AddCommand("toggleconsole", Con_ToggleConsole_f);
Cmd_AddCommand ("togglechat", Con_ToggleChat_f); Cmd_AddCommand("togglechat", Con_ToggleChat_f);
Cmd_AddCommand ("messagemode", Con_MessageMode_f); Cmd_AddCommand("messagemode", Con_MessageMode_f);
Cmd_AddCommand ("messagemode2", Con_MessageMode2_f); Cmd_AddCommand("messagemode2", Con_MessageMode2_f);
Cmd_AddCommand ("clear", Con_Clear_f); Cmd_AddCommand("clear", Con_Clear_f);
Cmd_AddCommand ("condump", Con_Dump_f); Cmd_AddCommand("condump", Con_Dump_f);
con.initialized = true; con.initialized = true;
} }
void Con_Linefeed (void) { void
Con_Linefeed(void)
{
con.x = 0; con.x = 0;
if (con.display == con.current) if (con.display == con.current)
{
con.display++; con.display++;
}
con.current++; con.current++;
memset (&con.text[(con.current%con.totallines)*con.linewidth] memset(&con.text[(con.current % con.totallines) * con.linewidth],
, ' ', con.linewidth); ' ', con.linewidth);
} }
/* /*
@ -280,50 +350,67 @@ void Con_Linefeed (void) {
* must go through this in order to be logged to disk If no console is * must go through this in order to be logged to disk If no console is
* visible, the text will appear at the top of the game window * visible, the text will appear at the top of the game window
*/ */
void Con_Print (char *txt) { void
int y; Con_Print(char *txt)
int c, l; {
static int cr; int y;
int mask; int c, l;
static int cr;
int mask;
if (!con.initialized) if (!con.initialized)
{
return; return;
}
if (txt[0] == 1 || txt[0] == 2) { if ((txt[0] == 1) || (txt[0] == 2))
mask = 128; /* go to colored text */ {
mask = 128; /* go to colored text */
txt++; txt++;
}
} else else
{
mask = 0; mask = 0;
}
while ((c = *txt))
while ( (c = *txt) ) { {
/* count word length */ /* count word length */
for (l=0 ; l< con.linewidth ; l++) for (l = 0; l < con.linewidth; l++)
if ( txt[l] <= ' ') {
if (txt[l] <= ' ')
{
break; break;
}
}
/* word wrap */ /* word wrap */
if (l != con.linewidth && (con.x + l > con.linewidth) ) if ((l != con.linewidth) && (con.x + l > con.linewidth))
{
con.x = 0; con.x = 0;
}
txt++; txt++;
if (cr) { if (cr)
{
con.current--; con.current--;
cr = false; cr = false;
} }
if (!con.x)
if (!con.x) { {
Con_Linefeed (); Con_Linefeed();
/* mark time for transparent overlay */ /* mark time for transparent overlay */
if (con.current >= 0) if (con.current >= 0)
{
con.times[con.current % NUM_CON_TIMES] = cls.realtime; con.times[con.current % NUM_CON_TIMES] = cls.realtime;
}
} }
switch (c) { switch (c)
{
case '\n': case '\n':
con.x = 0; con.x = 0;
break; break;
@ -335,193 +422,241 @@ void Con_Print (char *txt) {
default: /* display character and advance */ default: /* display character and advance */
y = con.current % con.totallines; y = con.current % con.totallines;
con.text[y*con.linewidth+con.x] = c | mask | con.ormask; con.text[y * con.linewidth + con.x] = c | mask | con.ormask;
con.x++; con.x++;
if (con.x >= con.linewidth) if (con.x >= con.linewidth)
{
con.x = 0; con.x = 0;
}
break; break;
} }
} }
} }
void Con_CenteredPrint (char *text) { void
int l; Con_CenteredPrint(char *text)
char buffer[1024]; {
int l;
char buffer[1024];
l = strlen(text); l = strlen(text);
l = (con.linewidth-l)/2; l = (con.linewidth - l) / 2;
if (l < 0) if (l < 0)
{
l = 0; l = 0;
}
memset (buffer, ' ', l); memset(buffer, ' ', l);
strcpy (buffer+l, text); strcpy(buffer + l, text);
strcat (buffer, "\n"); strcat(buffer, "\n");
Con_Print (buffer); Con_Print(buffer);
} }
/* /*
* The input line scrolls horizontally if * The input line scrolls horizontally if
* typing goes beyond the right edge * typing goes beyond the right edge
*/ */
void Con_DrawInput (void) { void
int i; Con_DrawInput(void)
char *text; {
int i;
char *text;
if (cls.key_dest == key_menu) if (cls.key_dest == key_menu)
{
return; return;
}
/* don't draw anything (always draw if not active) */ /* don't draw anything (always draw if not active) */
if (cls.key_dest != key_console && cls.state == ca_active) if ((cls.key_dest != key_console) && (cls.state == ca_active))
{
return; return;
}
text = key_lines[edit_line]; text = key_lines[edit_line];
/* add the cursor frame */ /* add the cursor frame */
text[key_linepos] = 10+((int)(cls.realtime>>8)&1); text[key_linepos] = 10 + ((int)(cls.realtime >> 8) & 1);
/* fill out remainder with spaces */ /* fill out remainder with spaces */
for (i=key_linepos+1 ; i< con.linewidth ; i++) for (i = key_linepos + 1; i < con.linewidth; i++)
{
text[i] = ' '; text[i] = ' ';
}
/* prestep if horizontally scrolling */ /* prestep if horizontally scrolling */
if (key_linepos >= con.linewidth) if (key_linepos >= con.linewidth)
{
text += 1 + key_linepos - con.linewidth; text += 1 + key_linepos - con.linewidth;
}
for (i=0 ; i<con.linewidth ; i++) for (i = 0; i < con.linewidth; i++)
re.DrawChar ( (i+1)<<3, con.vislines - 22, text[i]); {
re.DrawChar((i + 1) << 3, con.vislines - 22, text[i]);
}
/* remove cursor */ /* remove cursor */
key_lines[edit_line][key_linepos] = 0; key_lines[edit_line][key_linepos] = 0;
} }
/* /*
* Draws the last few lines of output transparently over the game top * Draws the last few lines of output transparently over the game top
*/ */
void Con_DrawNotify (void) { void
int x, v; Con_DrawNotify(void)
char *text; {
int i; int x, v;
int time; char *text;
char *s; int i;
int skip; int time;
char *s;
int skip;
v = 0; v = 0;
for (i= con.current-NUM_CON_TIMES+1 ; i<=con.current ; i++) { for (i = con.current - NUM_CON_TIMES + 1; i <= con.current; i++)
{
if (i < 0) if (i < 0)
{
continue; continue;
}
time = con.times[i % NUM_CON_TIMES]; time = con.times[i % NUM_CON_TIMES];
if (time == 0) if (time == 0)
{
continue; continue;
}
time = cls.realtime - time; time = cls.realtime - time;
if (time > con_notifytime->value*1000) if (time > con_notifytime->value * 1000)
{
continue; continue;
}
text = con.text + (i % con.totallines)*con.linewidth; text = con.text + (i % con.totallines) * con.linewidth;
for (x = 0 ; x < con.linewidth ; x++) for (x = 0; x < con.linewidth; x++)
re.DrawChar ( (x+1)<<3, v, text[x]); {
re.DrawChar((x + 1) << 3, v, text[x]);
}
v += 8; v += 8;
} }
if (cls.key_dest == key_message) { if (cls.key_dest == key_message)
if (chat_team) { {
DrawString (8, v, "say_team:"); if (chat_team)
{
DrawString(8, v, "say_team:");
skip = 11; skip = 11;
}
} else { else
DrawString (8, v, "say:"); {
DrawString(8, v, "say:");
skip = 5; skip = 5;
} }
s = chat_buffer; s = chat_buffer;
if (chat_bufferlen > (viddef.width>>3)-(skip+1)) if (chat_bufferlen > (viddef.width >> 3) - (skip + 1))
s += chat_bufferlen - ((viddef.width>>3)-(skip+1)); {
s += chat_bufferlen - ((viddef.width >> 3) - (skip + 1));
}
x = 0; x = 0;
while(s[x]) { while (s[x])
re.DrawChar ( (x+skip)<<3, v, s[x]); {
re.DrawChar((x + skip) << 3, v, s[x]);
x++; x++;
} }
re.DrawChar ( (x+skip)<<3, v, 10+((cls.realtime>>8)&1)); re.DrawChar((x + skip) << 3, v, 10 + ((cls.realtime >> 8) & 1));
v += 8; v += 8;
} }
if (v) { if (v)
SCR_AddDirtyPoint (0,0); {
SCR_AddDirtyPoint (viddef.width-1, v); SCR_AddDirtyPoint(0, 0);
SCR_AddDirtyPoint(viddef.width - 1, v);
} }
} }
/* /*
* Draws the console with the solid background * Draws the console with the solid background
*/ */
void Con_DrawConsole (float frac) { void
int i, j, x, y, n; Con_DrawConsole(float frac)
int rows; {
char *text; int i, j, x, y, n;
int row; int rows;
int lines; char *text;
char version[48]; int row;
char dlbar[1024]; int lines;
char timebuf[48]; char version[48];
char tmpbuf[48]; char dlbar[1024];
char timebuf[48];
char tmpbuf[48];
time_t t; time_t t;
struct tm *today; struct tm *today;
lines = viddef.height * frac; lines = viddef.height * frac;
if (lines <= 0) if (lines <= 0)
{
return; return;
}
if (lines > viddef.height) if (lines > viddef.height)
{
lines = viddef.height; lines = viddef.height;
}
/* draw the background */ /* draw the background */
re.DrawStretchPic (0, -viddef.height+lines, viddef.width, viddef.height, "conback"); re.DrawStretchPic(0, -viddef.height + lines, viddef.width,
SCR_AddDirtyPoint (0,0); viddef.height, "conback");
SCR_AddDirtyPoint (viddef.width-1,lines-1); SCR_AddDirtyPoint(0, 0);
SCR_AddDirtyPoint(viddef.width - 1, lines - 1);
Com_sprintf (version, sizeof(version), "Yamagi Quake II v%4.2f",VERSION); Com_sprintf(version, sizeof(version), "Yamagi Quake II v%4.2f", VERSION);
for (x=0 ; x<21 ; x++) for (x = 0; x < 21; x++)
re.DrawChar (viddef.width-173+x*8, lines-35, 128 + version[x] ); {
re.DrawChar(viddef.width - 173 + x * 8, lines - 35, 128 + version[x]);
}
t = time(NULL); t = time(NULL);
today = localtime(&t); today = localtime(&t);
strftime (timebuf, sizeof(timebuf), "%H:%M:%S - %m/%d/%Y", today); strftime(timebuf, sizeof(timebuf), "%H:%M:%S - %m/%d/%Y", today);
Com_sprintf (tmpbuf, sizeof(tmpbuf), "%s",timebuf); Com_sprintf(tmpbuf, sizeof(tmpbuf), "%s", timebuf);
for (x=0 ; x<21 ; x++) for (x = 0; x < 21; x++)
re.DrawChar (viddef.width-173+x*8, lines-25, 128 + tmpbuf[x] ); {
re.DrawChar(viddef.width - 173 + x * 8, lines - 25, 128 + tmpbuf[x]);
}
/* draw the text */ /* draw the text */
con.vislines = lines; con.vislines = lines;
rows = (lines-22)>>3; /* rows of text to draw */ rows = (lines - 22) >> 3; /* rows of text to draw */
y = lines - 30; y = lines - 30;
/* draw from the bottom up */ /* draw from the bottom up */
if (con.display != con.current) { if (con.display != con.current)
{
/* draw arrows to show the buffer is backscrolled */ /* draw arrows to show the buffer is backscrolled */
for (x=0 ; x<con.linewidth ; x+=4) for (x = 0; x < con.linewidth; x += 4)
re.DrawChar ( (x+1)<<3, y, '^'); {
re.DrawChar((x + 1) << 3, y, '^');
}
y -= 8; y -= 8;
rows--; rows--;
@ -529,39 +664,54 @@ void Con_DrawConsole (float frac) {
row = con.display; row = con.display;
for (i=0 ; i<rows ; i++, y-=8, row--) { for (i = 0; i < rows; i++, y -= 8, row--)
{
if (row < 0) if (row < 0)
{
break; break;
}
if (con.current - row >= con.totallines) if (con.current - row >= con.totallines)
{
break; /* past scrollback wrap point */ break; /* past scrollback wrap point */
}
text = con.text + (row % con.totallines)*con.linewidth; text = con.text + (row % con.totallines) * con.linewidth;
for (x=0 ; x<con.linewidth ; x++) for (x = 0; x < con.linewidth; x++)
re.DrawChar ( (x+1)<<3, y, text[x]); {
re.DrawChar((x + 1) << 3, y, text[x]);
}
} }
/* draw the download bar, figure out width */ /* draw the download bar, figure out width */
if (cls.download) { if (cls.download)
{
if ((text = strrchr(cls.downloadname, '/')) != NULL) if ((text = strrchr(cls.downloadname, '/')) != NULL)
{
text++; text++;
}
else else
{
text = cls.downloadname; text = cls.downloadname;
}
x = con.linewidth - ((con.linewidth * 7) / 40); x = con.linewidth - ((con.linewidth * 7) / 40);
y = x - strlen(text) - 8; y = x - strlen(text) - 8;
i = con.linewidth/3; i = con.linewidth / 3;
if (strlen(text) > i) { if (strlen(text) > i)
{
y = x - i - 11; y = x - i - 11;
strncpy(dlbar, text, i); strncpy(dlbar, text, i);
dlbar[i] = 0; dlbar[i] = 0;
strcat(dlbar, "..."); strcat(dlbar, "...");
}
} else else
{
strcpy(dlbar, text); strcpy(dlbar, text);
}
strcat(dlbar, ": "); strcat(dlbar, ": ");
i = strlen(dlbar); i = strlen(dlbar);
@ -569,17 +719,27 @@ void Con_DrawConsole (float frac) {
/* where's the dot gone? */ /* where's the dot gone? */
if (cls.downloadpercent == 0) if (cls.downloadpercent == 0)
{
n = 0; n = 0;
}
else else
{
n = y * cls.downloadpercent / 100; n = y * cls.downloadpercent / 100;
}
for (j = 0; j < y; j++) for (j = 0; j < y; j++)
{
if (j == n) if (j == n)
{
dlbar[i++] = '\x83'; dlbar[i++] = '\x83';
}
else else
{
dlbar[i++] = '\x81'; dlbar[i++] = '\x81';
}
}
dlbar[i++] = '\x82'; dlbar[i++] = '\x82';
dlbar[i] = 0; dlbar[i] = 0;
@ -587,12 +747,15 @@ void Con_DrawConsole (float frac) {
sprintf(dlbar + strlen(dlbar), " %02d%%", cls.downloadpercent); sprintf(dlbar + strlen(dlbar), " %02d%%", cls.downloadpercent);
/* draw it */ /* draw it */
y = con.vislines-12; y = con.vislines - 12;
for (i = 0; i < strlen(dlbar); i++) for (i = 0; i < strlen(dlbar); i++)
re.DrawChar ( (i+1)<<3, y, dlbar[i]); {
re.DrawChar((i + 1) << 3, y, dlbar[i]);
}
} }
/* draw the input prompt, user text, and cursor if desired */ /* draw the input prompt, user text, and cursor if desired */
Con_DrawInput (); Con_DrawInput();
} }

View file

@ -26,18 +26,18 @@
#include "header/client.h" #include "header/client.h"
extern cvar_t *allow_download; extern cvar_t *allow_download;
extern cvar_t *allow_download_players; extern cvar_t *allow_download_players;
extern cvar_t *allow_download_models; extern cvar_t *allow_download_models;
extern cvar_t *allow_download_sounds; extern cvar_t *allow_download_sounds;
extern cvar_t *allow_download_maps; extern cvar_t *allow_download_maps;
extern int precache_check; extern int precache_check;
extern int precache_spawncount; extern int precache_spawncount;
extern int precache_tex; extern int precache_tex;
extern int precache_model_skin; extern int precache_model_skin;
extern byte *precache_model; extern byte *precache_model;
static const char *env_suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; static const char *env_suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
@ -45,38 +45,48 @@ static const char *env_suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
/* ENV_CNT is map load, ENV_CNT+1 is first env map */ /* ENV_CNT is map load, ENV_CNT+1 is first env map */
#define ENV_CNT (CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) #define ENV_CNT (CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
#define TEXTURE_CNT (ENV_CNT+13) #define TEXTURE_CNT (ENV_CNT + 13)
void CL_RequestNextDownload (void) void
CL_RequestNextDownload(void)
{ {
unsigned int map_checksum; /* for detecting cheater maps */ unsigned int map_checksum; /* for detecting cheater maps */
char fn[MAX_OSPATH]; char fn[MAX_OSPATH];
dmdl_t *pheader; dmdl_t *pheader;
if (cls.state != ca_connected) if (cls.state != ca_connected)
{
return; return;
}
if (!allow_download->value && precache_check < ENV_CNT) if (!allow_download->value && (precache_check < ENV_CNT))
{
precache_check = ENV_CNT; precache_check = ENV_CNT;
}
if (precache_check == CS_MODELS) if (precache_check == CS_MODELS)
{ {
precache_check = CS_MODELS+2; precache_check = CS_MODELS + 2;
if (allow_download_maps->value) if (allow_download_maps->value)
if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1])) {
if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS + 1]))
{
return; /* started a download */ return; /* started a download */
}
}
} }
if (precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS) if ((precache_check >= CS_MODELS) &&
(precache_check < CS_MODELS + MAX_MODELS))
{ {
if (allow_download_models->value) if (allow_download_models->value)
{ {
while (precache_check < CS_MODELS+MAX_MODELS && while (precache_check < CS_MODELS + MAX_MODELS &&
cl.configstrings[precache_check][0]) cl.configstrings[precache_check][0])
{ {
if (cl.configstrings[precache_check][0] == '*' || if ((cl.configstrings[precache_check][0] == '*') ||
cl.configstrings[precache_check][0] == '#') (cl.configstrings[precache_check][0] == '#'))
{ {
precache_check++; precache_check++;
continue; continue;
@ -94,11 +104,10 @@ void CL_RequestNextDownload (void)
} }
/* checking for skins in the model */ /* checking for skins in the model */
if (!precache_model) if (!precache_model)
{ {
FS_LoadFile(cl.configstrings[precache_check],
FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model); (void **)&precache_model);
if (!precache_model) if (!precache_model)
{ {
@ -107,7 +116,8 @@ void CL_RequestNextDownload (void)
continue; /* couldn't load it */ continue; /* couldn't load it */
} }
if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER) if (LittleLong(*(unsigned *)precache_model) !=
IDALIASHEADER)
{ {
/* not an alias model */ /* not an alias model */
FS_FreeFile(precache_model); FS_FreeFile(precache_model);
@ -119,7 +129,7 @@ void CL_RequestNextDownload (void)
pheader = (dmdl_t *)precache_model; pheader = (dmdl_t *)precache_model;
if (LittleLong (pheader->version) != ALIAS_VERSION) if (LittleLong(pheader->version) != ALIAS_VERSION)
{ {
precache_check++; precache_check++;
precache_model_skin = 0; precache_model_skin = 0;
@ -132,8 +142,8 @@ void CL_RequestNextDownload (void)
while (precache_model_skin - 1 < LittleLong(pheader->num_skins)) while (precache_model_skin - 1 < LittleLong(pheader->num_skins))
{ {
if (!CL_CheckOrDownloadFile((char *)precache_model + if (!CL_CheckOrDownloadFile((char *)precache_model +
LittleLong(pheader->ofs_skins) + LittleLong(pheader->ofs_skins) +
(precache_model_skin - 1)*MAX_SKINNAME)) (precache_model_skin - 1) * MAX_SKINNAME))
{ {
precache_model_skin++; precache_model_skin++;
return; /* started a download */ return; /* started a download */
@ -157,15 +167,18 @@ void CL_RequestNextDownload (void)
precache_check = CS_SOUNDS; precache_check = CS_SOUNDS;
} }
if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS) if ((precache_check >= CS_SOUNDS) &&
(precache_check < CS_SOUNDS + MAX_SOUNDS))
{ {
if (allow_download_sounds->value) if (allow_download_sounds->value)
{ {
if (precache_check == CS_SOUNDS) if (precache_check == CS_SOUNDS)
{
precache_check++; precache_check++;
}
while (precache_check < CS_SOUNDS+MAX_SOUNDS && while (precache_check < CS_SOUNDS + MAX_SOUNDS &&
cl.configstrings[precache_check][0]) cl.configstrings[precache_check][0])
{ {
if (cl.configstrings[precache_check][0] == '*') if (cl.configstrings[precache_check][0] == '*')
{ {
@ -173,36 +186,47 @@ void CL_RequestNextDownload (void)
continue; continue;
} }
Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]); Com_sprintf(fn, sizeof(fn), "sound/%s",
cl.configstrings[precache_check++]);
if (!CL_CheckOrDownloadFile(fn)) if (!CL_CheckOrDownloadFile(fn))
{
return; /* started a download */ return; /* started a download */
}
} }
} }
precache_check = CS_IMAGES; precache_check = CS_IMAGES;
} }
if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES+MAX_IMAGES) if ((precache_check >= CS_IMAGES) &&
(precache_check < CS_IMAGES + MAX_IMAGES))
{ {
if (precache_check == CS_IMAGES) if (precache_check == CS_IMAGES)
precache_check++;
while (precache_check < CS_IMAGES+MAX_IMAGES &&
cl.configstrings[precache_check][0])
{ {
Com_sprintf(fn, sizeof(fn), "pics/%s.pcx", cl.configstrings[precache_check++]); precache_check++;
}
while (precache_check < CS_IMAGES + MAX_IMAGES &&
cl.configstrings[precache_check][0])
{
Com_sprintf(fn, sizeof(fn), "pics/%s.pcx",
cl.configstrings[precache_check++]);
if (!CL_CheckOrDownloadFile(fn)) if (!CL_CheckOrDownloadFile(fn))
return; // started a download {
return; /* started a download */
}
} }
precache_check = CS_PLAYERSKINS; precache_check = CS_PLAYERSKINS;
} }
/* skins are special, since a player has three things to download: /* skins are special, since a player has three
model, weapon model and skin so precache_check is now *3 */ things to download: model, weapon model and
if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) skin so precache_check is now *3 */
if ((precache_check >= CS_PLAYERSKINS) &&
(precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT))
{ {
if (allow_download_players->value) if (allow_download_players->value)
{ {
@ -211,26 +235,32 @@ void CL_RequestNextDownload (void)
int i, n; int i, n;
char model[MAX_QPATH], skin[MAX_QPATH], *p; char model[MAX_QPATH], skin[MAX_QPATH], *p;
i = (precache_check - CS_PLAYERSKINS)/PLAYER_MULT; i = (precache_check - CS_PLAYERSKINS) / PLAYER_MULT;
n = (precache_check - CS_PLAYERSKINS)%PLAYER_MULT; n = (precache_check - CS_PLAYERSKINS) % PLAYER_MULT;
if (!cl.configstrings[CS_PLAYERSKINS+i][0]) if (!cl.configstrings[CS_PLAYERSKINS + i][0])
{ {
precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT; precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
continue; continue;
} }
if ((p = strchr(cl.configstrings[CS_PLAYERSKINS+i], '\\')) != NULL) if ((p = strchr(cl.configstrings[CS_PLAYERSKINS + i], '\\')) != NULL)
{
p++; p++;
}
else else
p = cl.configstrings[CS_PLAYERSKINS+i]; {
p = cl.configstrings[CS_PLAYERSKINS + i];
}
strcpy(model, p); strcpy(model, p);
p = strchr(model, '/'); p = strchr(model, '/');
if (!p) if (!p)
{
p = strchr(model, '\\'); p = strchr(model, '\\');
}
if (p) if (p)
{ {
@ -239,11 +269,12 @@ void CL_RequestNextDownload (void)
} }
else else
{
*skin = 0; *skin = 0;
}
switch (n) switch (n)
{ {
case 0: /* model */ case 0: /* model */
Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model); Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model);
@ -294,7 +325,7 @@ void CL_RequestNextDownload (void)
if (!CL_CheckOrDownloadFile(fn)) if (!CL_CheckOrDownloadFile(fn))
{ {
precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5; precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5;
return; // started a download return; /* started a download */
} }
/* move on to next model */ /* move on to next model */
@ -311,17 +342,17 @@ void CL_RequestNextDownload (void)
{ {
precache_check = ENV_CNT + 1; precache_check = ENV_CNT + 1;
CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum); CM_LoadMap(cl.configstrings[CS_MODELS + 1], true, &map_checksum);
if (map_checksum != (int)strtol(cl.configstrings[CS_MAPCHECKSUM], (char **)NULL, 10)) if (map_checksum != (int)strtol(cl.configstrings[CS_MAPCHECKSUM], (char **)NULL, 10))
{ {
Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n", Com_Error(ERR_DROP, "Local map version differs from server: %i != '%s'\n",
map_checksum, cl.configstrings[CS_MAPCHECKSUM]); map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
return; return;
} }
} }
if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT) if ((precache_check > ENV_CNT) && (precache_check < TEXTURE_CNT))
{ {
if (allow_download->value && allow_download_maps->value) if (allow_download->value && allow_download_maps->value)
{ {
@ -330,14 +361,20 @@ void CL_RequestNextDownload (void)
int n = precache_check++ - ENV_CNT - 1; int n = precache_check++ - ENV_CNT - 1;
if (n & 1) if (n & 1)
{
Com_sprintf(fn, sizeof(fn), "env/%s%s.pcx", Com_sprintf(fn, sizeof(fn), "env/%s%s.pcx",
cl.configstrings[CS_SKY], env_suf[n/2]); cl.configstrings[CS_SKY], env_suf[n / 2]);
}
else else
{
Com_sprintf(fn, sizeof(fn), "env/%s%s.tga", Com_sprintf(fn, sizeof(fn), "env/%s%s.tga",
cl.configstrings[CS_SKY], env_suf[n/2]); cl.configstrings[CS_SKY], env_suf[n / 2]);
}
if (!CL_CheckOrDownloadFile(fn)) if (!CL_CheckOrDownloadFile(fn))
{
return; return;
}
} }
} }
@ -346,15 +383,15 @@ void CL_RequestNextDownload (void)
if (precache_check == TEXTURE_CNT) if (precache_check == TEXTURE_CNT)
{ {
precache_check = TEXTURE_CNT+1; precache_check = TEXTURE_CNT + 1;
precache_tex = 0; precache_tex = 0;
} }
/* confirm existance of textures, download any that don't exist */ /* confirm existance of textures, download any that don't exist */
if (precache_check == TEXTURE_CNT+1) if (precache_check == TEXTURE_CNT + 1)
{ {
extern int numtexinfo; extern int numtexinfo;
extern mapsurface_t map_surfaces[]; extern mapsurface_t map_surfaces[];
if (allow_download->value && allow_download_maps->value) if (allow_download->value && allow_download_maps->value)
{ {
@ -362,71 +399,87 @@ void CL_RequestNextDownload (void)
{ {
char fn[MAX_OSPATH]; char fn[MAX_OSPATH];
sprintf(fn, "textures/%s.wal", map_surfaces[precache_tex++].rname); sprintf(fn, "textures/%s.wal",
map_surfaces[precache_tex++].rname);
if (!CL_CheckOrDownloadFile(fn)) if (!CL_CheckOrDownloadFile(fn))
{
return; /* started a download */ return; /* started a download */
}
} }
} }
precache_check = TEXTURE_CNT+999; precache_check = TEXTURE_CNT + 999;
} }
CL_RegisterSounds (); CL_RegisterSounds();
CL_PrepRefresh (); CL_PrepRefresh();
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("begin %i\n", precache_spawncount) ); MSG_WriteString(&cls.netchan.message, va("begin %i\n", precache_spawncount));
} }
void CL_DownloadFileName(char *dest, int destlen, char *fn) { void
CL_DownloadFileName(char *dest, int destlen, char *fn)
{
if (strncmp(fn, "players", 7) == 0) if (strncmp(fn, "players", 7) == 0)
Com_sprintf (dest, destlen, "%s/%s", BASEDIRNAME, fn); {
Com_sprintf(dest, destlen, "%s/%s", BASEDIRNAME, fn);
}
else else
Com_sprintf (dest, destlen, "%s/%s", FS_Gamedir(), fn); {
Com_sprintf(dest, destlen, "%s/%s", FS_Gamedir(), fn);
}
} }
/* /*
* Returns true if the file exists, otherwise it attempts * Returns true if the file exists, otherwise it attempts
* to start a download from the server. * to start a download from the server.
*/ */
qboolean CL_CheckOrDownloadFile (char *filename) { qboolean
FILE *fp; CL_CheckOrDownloadFile(char *filename)
char name[MAX_OSPATH]; {
char *ptr; FILE *fp;
char name[MAX_OSPATH];
char *ptr;
if (strstr (filename, "..")) { if (strstr(filename, ".."))
Com_Printf ("Refusing to download a path with ..\n"); {
Com_Printf("Refusing to download a path with ..\n");
return true; return true;
} }
/* fix backslashes - this is mostly für UNIX comaptiblity */ /* fix backslashes - this is mostly für UNIX comaptiblity */
while ((ptr=strchr(filename,'\\'))) { while ((ptr = strchr(filename, '\\')))
{
*ptr = '/'; *ptr = '/';
} }
if (FS_LoadFile (filename, NULL) != -1) { if (FS_LoadFile(filename, NULL) != -1)
{
/* it exists, no need to download */ /* it exists, no need to download */
return true; return true;
} }
strcpy (cls.downloadname, filename); strcpy(cls.downloadname, filename);
/* download to a temp name, and only rename /* download to a temp name, and only rename
to the real name when done, so if interrupted to the real name when done, so if interrupted
a runt file wont be left */ a runt file wont be left */
COM_StripExtension (cls.downloadname, cls.downloadtempname); COM_StripExtension(cls.downloadname, cls.downloadtempname);
strcat (cls.downloadtempname, ".tmp"); strcat(cls.downloadtempname, ".tmp");
/* check to see if we already have a tmp for this file, if so, try to resume /* check to see if we already have a tmp for this
and open the file if not opened yet */ file, if so, try to resume and open the file if
not opened yet */
CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);
fp = fopen (name, "r+b"); fp = fopen(name, "r+b");
if (fp) { if (fp)
{
/* it exists */ /* it exists */
int len; int len;
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
@ -435,16 +488,15 @@ qboolean CL_CheckOrDownloadFile (char *filename) {
cls.download = fp; cls.download = fp;
/* give the server an offset to start the download */ /* give the server an offset to start the download */
Com_Printf ("Resuming %s\n", cls.downloadname); Com_Printf("Resuming %s\n", cls.downloadname);
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, MSG_WriteString(&cls.netchan.message, va("download %s %i", cls.downloadname, len));
va("download %s %i", cls.downloadname, len)); }
else
} else { {
Com_Printf ("Downloading %s\n", cls.downloadname); Com_Printf("Downloading %s\n", cls.downloadname);
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, MSG_WriteString(&cls.netchan.message, va("download %s", cls.downloadname));
va("download %s", cls.downloadname));
} }
cls.downloadnumber++; cls.downloadnumber++;
@ -455,39 +507,43 @@ qboolean CL_CheckOrDownloadFile (char *filename) {
/* /*
* Request a download from the server * Request a download from the server
*/ */
void CL_Download_f (void) { void
CL_Download_f(void)
{
char filename[MAX_OSPATH]; char filename[MAX_OSPATH];
if (Cmd_Argc() != 2) { if (Cmd_Argc() != 2)
{
Com_Printf("Usage: download <filename>\n"); Com_Printf("Usage: download <filename>\n");
return; return;
} }
Com_sprintf(filename, sizeof(filename), "%s", Cmd_Argv(1)); Com_sprintf(filename, sizeof(filename), "%s", Cmd_Argv(1));
if (strstr (filename, "..")) { if (strstr(filename, ".."))
Com_Printf ("Refusing to download a path with ..\n"); {
Com_Printf("Refusing to download a path with ..\n");
return; return;
} }
if (FS_LoadFile (filename, NULL) != -1) { if (FS_LoadFile(filename, NULL) != -1)
{
/* it exists, no need to download */ /* it exists, no need to download */
Com_Printf("File already exists.\n"); Com_Printf("File already exists.\n");
return; return;
} }
strcpy (cls.downloadname, filename); strcpy(cls.downloadname, filename);
Com_Printf ("Downloading %s\n", cls.downloadname); Com_Printf("Downloading %s\n", cls.downloadname);
/* download to a temp name, and only rename /* download to a temp name, and only rename
to the real name when done, so if interrupted to the real name when done, so if interrupted
a runt file wont be left */ a runt file wont be left */
COM_StripExtension (cls.downloadname, cls.downloadtempname); COM_StripExtension(cls.downloadname, cls.downloadtempname);
strcat (cls.downloadtempname, ".tmp"); strcat(cls.downloadtempname, ".tmp");
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, MSG_WriteString(&cls.netchan.message, va("download %s", cls.downloadname));
va("download %s", cls.downloadname));
cls.downloadnumber++; cls.downloadnumber++;
} }
@ -495,73 +551,84 @@ void CL_Download_f (void) {
/* /*
* A download message has been received from the server * A download message has been received from the server
*/ */
void CL_ParseDownload (void) { void
int size, percent; CL_ParseDownload(void)
char name[MAX_OSPATH]; {
int r; int size, percent;
char name[MAX_OSPATH];
int r;
/* read the data */ /* read the data */
size = MSG_ReadShort (&net_message); size = MSG_ReadShort(&net_message);
percent = MSG_ReadByte (&net_message); percent = MSG_ReadByte(&net_message);
if (size == -1) { if (size == -1)
Com_Printf ("Server does not have this file.\n"); {
Com_Printf("Server does not have this file.\n");
if (cls.download) { if (cls.download)
{
/* if here, we tried to resume a /* if here, we tried to resume a
file but the server said no */ * file but the server said no */
fclose (cls.download); fclose(cls.download);
cls.download = NULL; cls.download = NULL;
} }
CL_RequestNextDownload (); CL_RequestNextDownload();
return; return;
} }
/* open the file if not opened yet */ /* open the file if not opened yet */
if (!cls.download) { if (!cls.download)
{
CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);
FS_CreatePath (name); FS_CreatePath(name);
cls.download = fopen (name, "wb"); cls.download = fopen(name, "wb");
if (!cls.download) { if (!cls.download)
{
net_message.readcount += size; net_message.readcount += size;
Com_Printf ("Failed to open %s\n", cls.downloadtempname); Com_Printf("Failed to open %s\n", cls.downloadtempname);
CL_RequestNextDownload (); CL_RequestNextDownload();
return; return;
} }
} }
fwrite (net_message.data + net_message.readcount, 1, size, cls.download); fwrite(net_message.data + net_message.readcount, 1, size, cls.download);
net_message.readcount += size; net_message.readcount += size;
if (percent != 100) { if (percent != 100)
{
/* request next block */ /* request next block */
cls.downloadpercent = percent; cls.downloadpercent = percent;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, "nextdl"); SZ_Print(&cls.netchan.message, "nextdl");
}
else
{
char oldn[MAX_OSPATH];
char newn[MAX_OSPATH];
} else { fclose(cls.download);
char oldn[MAX_OSPATH];
char newn[MAX_OSPATH];
fclose (cls.download);
/* rename the temp file to it's final name */ /* rename the temp file to it's final name */
CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname); CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname);
CL_DownloadFileName(newn, sizeof(newn), cls.downloadname); CL_DownloadFileName(newn, sizeof(newn), cls.downloadname);
r = rename (oldn, newn); r = rename(oldn, newn);
if (r) if (r)
Com_Printf ("failed to rename.\n"); {
Com_Printf("failed to rename.\n");
}
cls.download = NULL; cls.download = NULL;
cls.downloadpercent = 0; cls.downloadpercent = 0;
/* get another file if needed */ /* get another file if needed */
CL_RequestNextDownload (); CL_RequestNextDownload();
} }
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -27,11 +27,11 @@
#include "header/client.h" #include "header/client.h"
cvar_t *cl_nodelta; cvar_t *cl_nodelta;
extern unsigned sys_frame_time; extern unsigned sys_frame_time;
unsigned frame_msec; unsigned frame_msec;
unsigned old_sys_frame_time; unsigned old_sys_frame_time;
/* /*
* KEY BUTTONS * KEY BUTTONS
@ -55,64 +55,86 @@ unsigned old_sys_frame_time;
* +mlook src time * +mlook src time
*/ */
kbutton_t in_klook; kbutton_t in_klook;
kbutton_t in_left, in_right, in_forward, in_back; kbutton_t in_left, in_right, in_forward, in_back;
kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright; kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright;
kbutton_t in_strafe, in_speed, in_use, in_attack; kbutton_t in_strafe, in_speed, in_use, in_attack;
kbutton_t in_up, in_down; kbutton_t in_up, in_down;
int in_impulse; int in_impulse;
void KeyDown (kbutton_t *b) { void
int k; KeyDown(kbutton_t *b)
char *c; {
int k;
char *c;
c = Cmd_Argv(1); c = Cmd_Argv(1);
if (c[0]) if (c[0])
{
k = (int)strtol(c, (char **)NULL, 10); k = (int)strtol(c, (char **)NULL, 10);
}
else else
{
k = -1; /* typed manually at the console for continuous down */ k = -1; /* typed manually at the console for continuous down */
}
if (k == b->down[0] || k == b->down[1]) if ((k == b->down[0]) || (k == b->down[1]))
{
return; /* repeating key */ return; /* repeating key */
}
if (!b->down[0]) if (!b->down[0])
{
b->down[0] = k; b->down[0] = k;
}
else if (!b->down[1]) else if (!b->down[1])
{
b->down[1] = k; b->down[1] = k;
}
else { else
Com_Printf ("Three keys down for a button!\n"); {
Com_Printf("Three keys down for a button!\n");
return; return;
} }
if (b->state & 1) if (b->state & 1)
{
return; /* still down */ return; /* still down */
}
/* save timestamp */ /* save timestamp */
c = Cmd_Argv(2); c = Cmd_Argv(2);
b->downtime = (int)strtol(c, (char **)NULL, 10); b->downtime = (int)strtol(c, (char **)NULL, 10);
if (!b->downtime) if (!b->downtime)
{
b->downtime = sys_frame_time - 100; b->downtime = sys_frame_time - 100;
}
b->state |= 1 + 2; /* down + impulse down */ b->state |= 1 + 2; /* down + impulse down */
} }
void KeyUp (kbutton_t *b) { void
int k; KeyUp(kbutton_t *b)
char *c; {
unsigned uptime; int k;
char *c;
unsigned uptime;
c = Cmd_Argv(1); c = Cmd_Argv(1);
if (c[0]) if (c[0])
{
k = (int)strtol(c, (char **)NULL, 10); k = (int)strtol(c, (char **)NULL, 10);
}
else { else
{
/* typed manually at the console, assume for unsticking, so clear all */ /* typed manually at the console, assume for unsticking, so clear all */
b->down[0] = b->down[1] = 0; b->down[0] = b->down[1] = 0;
b->state = 4; /* impulse up */ b->state = 4; /* impulse up */
@ -120,146 +142,251 @@ void KeyUp (kbutton_t *b) {
} }
if (b->down[0] == k) if (b->down[0] == k)
{
b->down[0] = 0; b->down[0] = 0;
}
else if (b->down[1] == k) else if (b->down[1] == k)
{
b->down[1] = 0; b->down[1] = 0;
}
else else
{
return; /* key up without coresponding down (menu pass through) */ return; /* key up without coresponding down (menu pass through) */
}
if (b->down[0] || b->down[1]) if (b->down[0] || b->down[1])
{
return; /* some other key is still holding it down */ return; /* some other key is still holding it down */
}
if (!(b->state & 1)) if (!(b->state & 1))
{
return; /* still up (this should not happen) */ return; /* still up (this should not happen) */
}
/* save timestamp */ /* save timestamp */
c = Cmd_Argv(2); c = Cmd_Argv(2);
uptime = (int)strtol(c, (char **)NULL, 10); uptime = (int)strtol(c, (char **)NULL, 10);
if (uptime) if (uptime)
{
b->msec += uptime - b->downtime; b->msec += uptime - b->downtime;
}
else else
{
b->msec += 10; b->msec += 10;
}
b->state &= ~1; /* now up */ b->state &= ~1; /* now up */
b->state |= 4; /* impulse up */ b->state |= 4; /* impulse up */
} }
void IN_KLookDown (void) { void
IN_KLookDown(void)
{
KeyDown(&in_klook); KeyDown(&in_klook);
} }
void IN_KLookUp (void) {
void
IN_KLookUp(void)
{
KeyUp(&in_klook); KeyUp(&in_klook);
} }
void IN_UpDown(void) {
void
IN_UpDown(void)
{
KeyDown(&in_up); KeyDown(&in_up);
} }
void IN_UpUp(void) {
void
IN_UpUp(void)
{
KeyUp(&in_up); KeyUp(&in_up);
} }
void IN_DownDown(void) {
void
IN_DownDown(void)
{
KeyDown(&in_down); KeyDown(&in_down);
} }
void IN_DownUp(void) {
void
IN_DownUp(void)
{
KeyUp(&in_down); KeyUp(&in_down);
} }
void IN_LeftDown(void) {
void
IN_LeftDown(void)
{
KeyDown(&in_left); KeyDown(&in_left);
} }
void IN_LeftUp(void) {
void
IN_LeftUp(void)
{
KeyUp(&in_left); KeyUp(&in_left);
} }
void IN_RightDown(void) {
void
IN_RightDown(void)
{
KeyDown(&in_right); KeyDown(&in_right);
} }
void IN_RightUp(void) {
void
IN_RightUp(void)
{
KeyUp(&in_right); KeyUp(&in_right);
} }
void IN_ForwardDown(void) {
void
IN_ForwardDown(void)
{
KeyDown(&in_forward); KeyDown(&in_forward);
} }
void IN_ForwardUp(void) {
void
IN_ForwardUp(void)
{
KeyUp(&in_forward); KeyUp(&in_forward);
} }
void IN_BackDown(void) {
void
IN_BackDown(void)
{
KeyDown(&in_back); KeyDown(&in_back);
} }
void IN_BackUp(void) {
void
IN_BackUp(void)
{
KeyUp(&in_back); KeyUp(&in_back);
} }
void IN_LookupDown(void) {
void
IN_LookupDown(void)
{
KeyDown(&in_lookup); KeyDown(&in_lookup);
} }
void IN_LookupUp(void) {
void
IN_LookupUp(void)
{
KeyUp(&in_lookup); KeyUp(&in_lookup);
} }
void IN_LookdownDown(void) {
void
IN_LookdownDown(void)
{
KeyDown(&in_lookdown); KeyDown(&in_lookdown);
} }
void IN_LookdownUp(void) {
void
IN_LookdownUp(void)
{
KeyUp(&in_lookdown); KeyUp(&in_lookdown);
} }
void IN_MoveleftDown(void) {
void
IN_MoveleftDown(void)
{
KeyDown(&in_moveleft); KeyDown(&in_moveleft);
} }
void IN_MoveleftUp(void) {
void
IN_MoveleftUp(void)
{
KeyUp(&in_moveleft); KeyUp(&in_moveleft);
} }
void IN_MoverightDown(void) {
void
IN_MoverightDown(void)
{
KeyDown(&in_moveright); KeyDown(&in_moveright);
} }
void IN_MoverightUp(void) {
void
IN_MoverightUp(void)
{
KeyUp(&in_moveright); KeyUp(&in_moveright);
} }
void IN_SpeedDown(void) { void
IN_SpeedDown(void)
{
KeyDown(&in_speed); KeyDown(&in_speed);
} }
void IN_SpeedUp(void) {
void
IN_SpeedUp(void)
{
KeyUp(&in_speed); KeyUp(&in_speed);
} }
void IN_StrafeDown(void) {
void
IN_StrafeDown(void)
{
KeyDown(&in_strafe); KeyDown(&in_strafe);
} }
void IN_StrafeUp(void) {
void
IN_StrafeUp(void)
{
KeyUp(&in_strafe); KeyUp(&in_strafe);
} }
void IN_AttackDown(void) { void
IN_AttackDown(void)
{
KeyDown(&in_attack); KeyDown(&in_attack);
} }
void IN_AttackUp(void) {
void
IN_AttackUp(void)
{
KeyUp(&in_attack); KeyUp(&in_attack);
} }
void IN_UseDown (void) { void
IN_UseDown(void)
{
KeyDown(&in_use); KeyDown(&in_use);
} }
void IN_UseUp (void) {
void
IN_UseUp(void)
{
KeyUp(&in_use); KeyUp(&in_use);
} }
void IN_Impulse (void) { void
in_impulse=(int)strtol(Cmd_Argv(1), (char **)NULL, 10); IN_Impulse(void)
{
in_impulse = (int)strtol(Cmd_Argv(1), (char **)NULL, 10);
} }
/* /*
* Returns the fraction of the frame that * Returns the fraction of the
* the key was down * frame that the key was down
*/ */
float CL_KeyState (kbutton_t *key) { float
float val; CL_KeyState(kbutton_t *key)
int msec; {
float val;
int msec;
key->state &= 1; /* clear impulses */ key->state &= 1; /* clear impulses */
msec = key->msec; msec = key->msec;
key->msec = 0; key->msec = 0;
if (key->state) { if (key->state)
{
/* still down */ /* still down */
msec += sys_frame_time - key->downtime; msec += sys_frame_time - key->downtime;
key->downtime = sys_frame_time; key->downtime = sys_frame_time;
@ -268,141 +395,178 @@ float CL_KeyState (kbutton_t *key) {
val = (float)msec / frame_msec; val = (float)msec / frame_msec;
if (val < 0) if (val < 0)
{
val = 0; val = 0;
}
if (val > 1) if (val > 1)
{
val = 1; val = 1;
}
return val; return val;
} }
cvar_t *cl_upspeed; cvar_t *cl_upspeed;
cvar_t *cl_forwardspeed; cvar_t *cl_forwardspeed;
cvar_t *cl_sidespeed; cvar_t *cl_sidespeed;
cvar_t *cl_yawspeed;
cvar_t *cl_yawspeed; cvar_t *cl_pitchspeed;
cvar_t *cl_pitchspeed; cvar_t *cl_run;
cvar_t *cl_anglespeedkey;
cvar_t *cl_run;
cvar_t *cl_anglespeedkey;
/* /*
* Moves the local angle positions * Moves the local angle positions
*/ */
void CL_AdjustAngles (void) { void
float speed; CL_AdjustAngles(void)
float up, down; {
float speed;
float up, down;
if (in_speed.state & 1) if (in_speed.state & 1)
{
speed = cls.frametime * cl_anglespeedkey->value; speed = cls.frametime * cl_anglespeedkey->value;
}
else else
{
speed = cls.frametime; speed = cls.frametime;
if (!(in_strafe.state & 1)) {
cl.viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right);
cl.viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left);
} }
if (in_klook.state & 1) { if (!(in_strafe.state & 1))
cl.viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_forward); {
cl.viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_back); cl.viewangles[YAW] -= speed * cl_yawspeed->value * CL_KeyState(&in_right);
cl.viewangles[YAW] += speed * cl_yawspeed->value * CL_KeyState(&in_left);
} }
up = CL_KeyState (&in_lookup); if (in_klook.state & 1)
{
cl.viewangles[PITCH] -= speed * cl_pitchspeed->value * CL_KeyState(&in_forward);
cl.viewangles[PITCH] += speed * cl_pitchspeed->value * CL_KeyState(&in_back);
}
up = CL_KeyState(&in_lookup);
down = CL_KeyState(&in_lookdown); down = CL_KeyState(&in_lookdown);
cl.viewangles[PITCH] -= speed*cl_pitchspeed->value * up; cl.viewangles[PITCH] -= speed * cl_pitchspeed->value * up;
cl.viewangles[PITCH] += speed*cl_pitchspeed->value * down; cl.viewangles[PITCH] += speed * cl_pitchspeed->value * down;
} }
/* /*
* Send the intended movement message to the server * Send the intended movement message to the server
*/ */
void CL_BaseMove (usercmd_t *cmd) { void
CL_AdjustAngles (); CL_BaseMove(usercmd_t *cmd)
{
CL_AdjustAngles();
memset (cmd, 0, sizeof(*cmd)); memset(cmd, 0, sizeof(*cmd));
VectorCopy (cl.viewangles, cmd->angles); VectorCopy(cl.viewangles, cmd->angles);
if (in_strafe.state & 1) { if (in_strafe.state & 1)
cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_right); {
cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_left); cmd->sidemove += cl_sidespeed->value * CL_KeyState(&in_right);
cmd->sidemove -= cl_sidespeed->value * CL_KeyState(&in_left);
} }
cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_moveright); cmd->sidemove += cl_sidespeed->value * CL_KeyState(&in_moveright);
cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_moveleft); cmd->sidemove -= cl_sidespeed->value * CL_KeyState(&in_moveleft);
cmd->upmove += cl_upspeed->value * CL_KeyState (&in_up); cmd->upmove += cl_upspeed->value * CL_KeyState(&in_up);
cmd->upmove -= cl_upspeed->value * CL_KeyState (&in_down); cmd->upmove -= cl_upspeed->value * CL_KeyState(&in_down);
if (! (in_klook.state & 1) ) { if (!(in_klook.state & 1))
cmd->forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward); {
cmd->forwardmove -= cl_forwardspeed->value * CL_KeyState (&in_back); cmd->forwardmove += cl_forwardspeed->value * CL_KeyState(&in_forward);
cmd->forwardmove -= cl_forwardspeed->value * CL_KeyState(&in_back);
} }
/* adjust for speed key / running */ /* adjust for speed key / running */
if ( (in_speed.state & 1) ^ (int)(cl_run->value) ) { if ((in_speed.state & 1) ^ (int)(cl_run->value))
{
cmd->forwardmove *= 2; cmd->forwardmove *= 2;
cmd->sidemove *= 2; cmd->sidemove *= 2;
cmd->upmove *= 2; cmd->upmove *= 2;
} }
} }
void CL_ClampPitch (void) { void
float pitch; CL_ClampPitch(void)
{
float pitch;
pitch = SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]); pitch = SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]);
if (pitch > 180) if (pitch > 180)
{
pitch -= 360; pitch -= 360;
}
if (cl.viewangles[PITCH] + pitch < -360) if (cl.viewangles[PITCH] + pitch < -360)
{
cl.viewangles[PITCH] += 360; /* wrapped */ cl.viewangles[PITCH] += 360; /* wrapped */
}
if (cl.viewangles[PITCH] + pitch > 360) if (cl.viewangles[PITCH] + pitch > 360)
{
cl.viewangles[PITCH] -= 360; /* wrapped */ cl.viewangles[PITCH] -= 360; /* wrapped */
}
if (cl.viewangles[PITCH] + pitch > 89) if (cl.viewangles[PITCH] + pitch > 89)
{
cl.viewangles[PITCH] = 89 - pitch; cl.viewangles[PITCH] = 89 - pitch;
}
if (cl.viewangles[PITCH] + pitch < -89) if (cl.viewangles[PITCH] + pitch < -89)
{
cl.viewangles[PITCH] = -89 - pitch; cl.viewangles[PITCH] = -89 - pitch;
}
} }
void CL_FinishMove (usercmd_t *cmd) { void
int ms; CL_FinishMove(usercmd_t *cmd)
int i; {
int ms;
int i;
/* figure button bits */ /* figure button bits */
if ( in_attack.state & 3 ) if (in_attack.state & 3)
{
cmd->buttons |= BUTTON_ATTACK; cmd->buttons |= BUTTON_ATTACK;
}
in_attack.state &= ~2; in_attack.state &= ~2;
if (in_use.state & 3) if (in_use.state & 3)
{
cmd->buttons |= BUTTON_USE; cmd->buttons |= BUTTON_USE;
}
in_use.state &= ~2; in_use.state &= ~2;
if (anykeydown && cls.key_dest == key_game) if (anykeydown && (cls.key_dest == key_game))
{
cmd->buttons |= BUTTON_ANY; cmd->buttons |= BUTTON_ANY;
}
/* send milliseconds of time to apply the move */ /* send milliseconds of time to apply the move */
ms = cls.frametime * 1000; ms = cls.frametime * 1000;
if (ms > 250) if (ms > 250)
{
ms = 100; /* time was unreasonable */ ms = 100; /* time was unreasonable */
}
cmd->msec = ms; cmd->msec = ms;
CL_ClampPitch (); CL_ClampPitch();
for (i=0 ; i<3 ; i++) for (i = 0; i < 3; i++)
{
cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]); cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
}
cmd->impulse = in_impulse; cmd->impulse = in_impulse;
in_impulse = 0; in_impulse = 0;
@ -411,154 +575,179 @@ void CL_FinishMove (usercmd_t *cmd) {
cmd->lightlevel = (byte)cl_lightlevel->value; cmd->lightlevel = (byte)cl_lightlevel->value;
} }
usercmd_t CL_CreateCmd (void) { usercmd_t
usercmd_t cmd; CL_CreateCmd(void)
{
usercmd_t cmd;
frame_msec = sys_frame_time - old_sys_frame_time; frame_msec = sys_frame_time - old_sys_frame_time;
if (frame_msec < 1) if (frame_msec < 1)
{
frame_msec = 1; frame_msec = 1;
}
if (frame_msec > 200) if (frame_msec > 200)
{
frame_msec = 200; frame_msec = 200;
}
/* get basic movement from keyboard */ /* get basic movement from keyboard */
CL_BaseMove (&cmd); CL_BaseMove(&cmd);
/* allow mice or other external controllers to add to the move */ /* allow mice or other external controllers to add to the move */
IN_Move (&cmd); IN_Move(&cmd);
CL_FinishMove (&cmd); CL_FinishMove(&cmd);
old_sys_frame_time = sys_frame_time; old_sys_frame_time = sys_frame_time;
return cmd; return cmd;
} }
void IN_CenterView (void) { void
IN_CenterView(void)
{
cl.viewangles[PITCH] = -SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]); cl.viewangles[PITCH] = -SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]);
} }
void CL_InitInput (void) { void
Cmd_AddCommand ("centerview",IN_CenterView); CL_InitInput(void)
{
Cmd_AddCommand("centerview", IN_CenterView);
Cmd_AddCommand ("+moveup",IN_UpDown); Cmd_AddCommand("+moveup", IN_UpDown);
Cmd_AddCommand ("-moveup",IN_UpUp); Cmd_AddCommand("-moveup", IN_UpUp);
Cmd_AddCommand ("+movedown",IN_DownDown); Cmd_AddCommand("+movedown", IN_DownDown);
Cmd_AddCommand ("-movedown",IN_DownUp); Cmd_AddCommand("-movedown", IN_DownUp);
Cmd_AddCommand ("+left",IN_LeftDown); Cmd_AddCommand("+left", IN_LeftDown);
Cmd_AddCommand ("-left",IN_LeftUp); Cmd_AddCommand("-left", IN_LeftUp);
Cmd_AddCommand ("+right",IN_RightDown); Cmd_AddCommand("+right", IN_RightDown);
Cmd_AddCommand ("-right",IN_RightUp); Cmd_AddCommand("-right", IN_RightUp);
Cmd_AddCommand ("+forward",IN_ForwardDown); Cmd_AddCommand("+forward", IN_ForwardDown);
Cmd_AddCommand ("-forward",IN_ForwardUp); Cmd_AddCommand("-forward", IN_ForwardUp);
Cmd_AddCommand ("+back",IN_BackDown); Cmd_AddCommand("+back", IN_BackDown);
Cmd_AddCommand ("-back",IN_BackUp); Cmd_AddCommand("-back", IN_BackUp);
Cmd_AddCommand ("+lookup", IN_LookupDown); Cmd_AddCommand("+lookup", IN_LookupDown);
Cmd_AddCommand ("-lookup", IN_LookupUp); Cmd_AddCommand("-lookup", IN_LookupUp);
Cmd_AddCommand ("+lookdown", IN_LookdownDown); Cmd_AddCommand("+lookdown", IN_LookdownDown);
Cmd_AddCommand ("-lookdown", IN_LookdownUp); Cmd_AddCommand("-lookdown", IN_LookdownUp);
Cmd_AddCommand ("+strafe", IN_StrafeDown); Cmd_AddCommand("+strafe", IN_StrafeDown);
Cmd_AddCommand ("-strafe", IN_StrafeUp); Cmd_AddCommand("-strafe", IN_StrafeUp);
Cmd_AddCommand ("+moveleft", IN_MoveleftDown); Cmd_AddCommand("+moveleft", IN_MoveleftDown);
Cmd_AddCommand ("-moveleft", IN_MoveleftUp); Cmd_AddCommand("-moveleft", IN_MoveleftUp);
Cmd_AddCommand ("+moveright", IN_MoverightDown); Cmd_AddCommand("+moveright", IN_MoverightDown);
Cmd_AddCommand ("-moveright", IN_MoverightUp); Cmd_AddCommand("-moveright", IN_MoverightUp);
Cmd_AddCommand ("+speed", IN_SpeedDown); Cmd_AddCommand("+speed", IN_SpeedDown);
Cmd_AddCommand ("-speed", IN_SpeedUp); Cmd_AddCommand("-speed", IN_SpeedUp);
Cmd_AddCommand ("+attack", IN_AttackDown); Cmd_AddCommand("+attack", IN_AttackDown);
Cmd_AddCommand ("-attack", IN_AttackUp); Cmd_AddCommand("-attack", IN_AttackUp);
Cmd_AddCommand ("+use", IN_UseDown); Cmd_AddCommand("+use", IN_UseDown);
Cmd_AddCommand ("-use", IN_UseUp); Cmd_AddCommand("-use", IN_UseUp);
Cmd_AddCommand ("impulse", IN_Impulse); Cmd_AddCommand("impulse", IN_Impulse);
Cmd_AddCommand ("+klook", IN_KLookDown); Cmd_AddCommand("+klook", IN_KLookDown);
Cmd_AddCommand ("-klook", IN_KLookUp); Cmd_AddCommand("-klook", IN_KLookUp);
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0); cl_nodelta = Cvar_Get("cl_nodelta", "0", 0);
} }
void CL_SendCmd (void) { void
sizebuf_t buf; CL_SendCmd(void)
byte data[128]; {
int i; sizebuf_t buf;
usercmd_t *cmd, *oldcmd; byte data[128];
usercmd_t nullcmd; int i;
int checksumIndex; usercmd_t *cmd, *oldcmd;
usercmd_t nullcmd;
int checksumIndex;
/* build a command even if not connected */ /* build a command even if not connected */
/* save this command off for prediction */ /* save this command off for prediction */
i = cls.netchan.outgoing_sequence & (CMD_BACKUP-1); i = cls.netchan.outgoing_sequence & (CMD_BACKUP - 1);
cmd = &cl.cmds[i]; cmd = &cl.cmds[i];
cl.cmd_time[i] = cls.realtime; /* for netgraph ping calculation */ cl.cmd_time[i] = cls.realtime; /* for netgraph ping calculation */
*cmd = CL_CreateCmd (); *cmd = CL_CreateCmd();
cl.cmd = *cmd; cl.cmd = *cmd;
if (cls.state == ca_disconnected || cls.state == ca_connecting) if ((cls.state == ca_disconnected) || (cls.state == ca_connecting))
{
return; return;
}
if ( cls.state == ca_connected) { if (cls.state == ca_connected)
if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 100 ) {
Netchan_Transmit (&cls.netchan, 0, buf.data); if (cls.netchan.message.cursize ||
(curtime - cls.netchan.last_sent > 100))
{
Netchan_Transmit(&cls.netchan, 0, buf.data);
}
return; return;
} }
/* send a userinfo update if needed */ /* send a userinfo update if needed */
if (userinfo_modified) { if (userinfo_modified)
{
CL_FixUpGender(); CL_FixUpGender();
userinfo_modified = false; userinfo_modified = false;
MSG_WriteByte (&cls.netchan.message, clc_userinfo); MSG_WriteByte(&cls.netchan.message, clc_userinfo);
MSG_WriteString (&cls.netchan.message, Cvar_Userinfo() ); MSG_WriteString(&cls.netchan.message, Cvar_Userinfo());
} }
SZ_Init (&buf, data, sizeof(data)); SZ_Init(&buf, data, sizeof(data));
if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop if (cmd->buttons && (cl.cinematictime > 0) && !cl.attractloop &&
&& cls.realtime - cl.cinematictime > 1000) { (cls.realtime - cl.cinematictime > 1000))
{
/* skip the rest of the cinematic */ /* skip the rest of the cinematic */
SCR_FinishCinematic (); SCR_FinishCinematic();
} }
/* begin a client move command */ /* begin a client move command */
MSG_WriteByte (&buf, clc_move); MSG_WriteByte(&buf, clc_move);
/* save the position for a checksum byte */ /* save the position for a checksum byte */
checksumIndex = buf.cursize; checksumIndex = buf.cursize;
MSG_WriteByte (&buf, 0); MSG_WriteByte(&buf, 0);
/* let the server know what the last frame we /* let the server know what the last frame we
got was, so the next message can be delta compressed */ got was, so the next message can be delta
compressed */
if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting) if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting)
MSG_WriteLong (&buf, -1); /* no compression */ {
MSG_WriteLong(&buf, -1); /* no compression */
}
else else
MSG_WriteLong (&buf, cl.frame.serverframe); {
MSG_WriteLong(&buf, cl.frame.serverframe);
}
/* send this and the previous cmds in the message, so /* send this and the previous cmds in the message, so
if the last packet was dropped, it can be recovered */ if the last packet was dropped, it can be recovered */
i = (cls.netchan.outgoing_sequence-2) & (CMD_BACKUP-1); i = (cls.netchan.outgoing_sequence - 2) & (CMD_BACKUP - 1);
cmd = &cl.cmds[i]; cmd = &cl.cmds[i];
memset (&nullcmd, 0, sizeof(nullcmd)); memset(&nullcmd, 0, sizeof(nullcmd));
MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd); MSG_WriteDeltaUsercmd(&buf, &nullcmd, cmd);
oldcmd = cmd; oldcmd = cmd;
i = (cls.netchan.outgoing_sequence-1) & (CMD_BACKUP-1); i = (cls.netchan.outgoing_sequence - 1) & (CMD_BACKUP - 1);
cmd = &cl.cmds[i]; cmd = &cl.cmds[i];
MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); MSG_WriteDeltaUsercmd(&buf, oldcmd, cmd);
oldcmd = cmd; oldcmd = cmd;
i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP-1); i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP - 1);
cmd = &cl.cmds[i]; cmd = &cl.cmds[i];
MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd); MSG_WriteDeltaUsercmd(&buf, oldcmd, cmd);
/* calculate a checksum over the move commands */ /* calculate a checksum over the move commands */
buf.data[checksumIndex] = COM_BlockSequenceCRCByte( buf.data[checksumIndex] = COM_BlockSequenceCRCByte(
buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1, buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1,
cls.netchan.outgoing_sequence); cls.netchan.outgoing_sequence);
/* deliver the message */ /* deliver the message */
Netchan_Transmit (&cls.netchan, buf.cursize, buf.data); Netchan_Transmit(&cls.netchan, buf.cursize, buf.data);
} }

View file

@ -26,53 +26,63 @@
#include "header/client.h" #include "header/client.h"
void CL_ParseInventory (void) void
CL_ParseInventory(void)
{ {
int i; int i;
for (i=0 ; i<MAX_ITEMS ; i++) for (i = 0; i < MAX_ITEMS; i++)
cl.inventory[i] = MSG_ReadShort (&net_message); {
cl.inventory[i] = MSG_ReadShort(&net_message);
}
} }
static void Inv_DrawString (int x, int y, char *string) static void
Inv_DrawString(int x, int y, char *string)
{ {
while (*string) while (*string)
{ {
re.DrawChar (x, y, *string); re.DrawChar(x, y, *string);
x+=8; x += 8;
string++; string++;
} }
} }
static void SetStringHighBit (char *s) static void
SetStringHighBit(char *s)
{ {
while (*s) while (*s)
{
*s++ |= 128; *s++ |= 128;
}
} }
#define DISPLAY_ITEMS 17 #define DISPLAY_ITEMS 17
void CL_DrawInventory (void) void
CL_DrawInventory(void)
{ {
int i, j; int i, j;
int num, selected_num, item; int num, selected_num, item;
int index[MAX_ITEMS]; int index[MAX_ITEMS];
char string[1024]; char string[1024];
int x, y; int x, y;
char binding[1024]; char binding[1024];
const char *bind; const char *bind;
int selected; int selected;
int top; int top;
selected = cl.frame.playerstate.stats[STAT_SELECTED_ITEM]; selected = cl.frame.playerstate.stats[STAT_SELECTED_ITEM];
num = 0; num = 0;
selected_num = 0; selected_num = 0;
for (i=0 ; i<MAX_ITEMS ; i++) for (i = 0; i < MAX_ITEMS; i++)
{ {
if (i==selected) if (i == selected)
{
selected_num = num; selected_num = num;
}
if (cl.inventory[i]) if (cl.inventory[i])
{ {
@ -82,62 +92,70 @@ void CL_DrawInventory (void)
} }
/* determine scroll point */ /* determine scroll point */
top = selected_num - DISPLAY_ITEMS/2; top = selected_num - DISPLAY_ITEMS / 2;
if (num - top < DISPLAY_ITEMS) if (num - top < DISPLAY_ITEMS)
{
top = num - DISPLAY_ITEMS; top = num - DISPLAY_ITEMS;
}
if (top < 0) if (top < 0)
{
top = 0; top = 0;
}
x = (viddef.width-256)/2; x = (viddef.width - 256) / 2;
y = (viddef.height - 240) / 2;
y = (viddef.height-240)/2;
/* repaint everything next frame */ /* repaint everything next frame */
SCR_DirtyScreen (); SCR_DirtyScreen();
re.DrawPic (x, y+8, "inventory"); re.DrawPic(x, y + 8, "inventory");
y += 24; y += 24;
x += 24; x += 24;
Inv_DrawString (x, y, "hotkey ### item"); Inv_DrawString(x, y, "hotkey ### item");
Inv_DrawString(x, y + 8, "------ --- ----");
Inv_DrawString (x, y+8, "------ --- ----");
y += 16; y += 16;
for (i=top ; i<num && i < top+DISPLAY_ITEMS ; i++) for (i = top; i < num && i < top + DISPLAY_ITEMS; i++)
{ {
item = index[i]; item = index[i];
/* search for a binding */ /* search for a binding */
Com_sprintf (binding, sizeof(binding), "use %s", cl.configstrings[CS_ITEMS+item]); Com_sprintf(binding, sizeof(binding), "use %s",
cl.configstrings[CS_ITEMS + item]);
bind = ""; bind = "";
for (j=0 ; j<256 ; j++) for (j = 0; j < 256; j++)
if (keybindings[j] && !Q_stricmp (keybindings[j], binding)) {
if (keybindings[j] && !Q_stricmp(keybindings[j], binding))
{ {
bind = Key_KeynumToString(j); bind = Key_KeynumToString(j);
break; break;
} }
}
Com_sprintf (string, sizeof(string), "%6s %3i %s", bind, cl.inventory[item], Com_sprintf(string, sizeof(string), "%6s %3i %s", bind,
cl.inventory[item], cl.configstrings[CS_ITEMS + item]);
cl.configstrings[CS_ITEMS+item] );
if (item != selected) if (item != selected)
SetStringHighBit (string); {
SetStringHighBit(string);
}
else else
{ {
/* draw a blinky cursor by the selected item */ /* draw a blinky cursor by the selected item */
if ( (int)(cls.realtime*10) & 1) if ((int)(cls.realtime * 10) & 1)
re.DrawChar (x-8, y, 15); {
re.DrawChar(x - 8, y, 15);
}
} }
Inv_DrawString (x, y, string); Inv_DrawString(x, y, string);
y += 8; y += 8;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -26,83 +26,111 @@
#include "header/client.h" #include "header/client.h"
typedef struct { typedef struct
int length; {
float value[3]; int length;
float map[MAX_QPATH]; float value[3];
float map[MAX_QPATH];
} clightstyle_t; } clightstyle_t;
clightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; clightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
int lastofs; int lastofs;
void CL_ClearLightStyles (void) { void
memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); CL_ClearLightStyles(void)
{
memset(cl_lightstyle, 0, sizeof(cl_lightstyle));
lastofs = -1; lastofs = -1;
} }
void CL_RunLightStyles (void) { void
int ofs; CL_RunLightStyles(void)
int i; {
clightstyle_t *ls; int ofs;
int i;
clightstyle_t *ls;
ofs = cl.time / 100; ofs = cl.time / 100;
if (ofs == lastofs) if (ofs == lastofs)
{
return; return;
}
lastofs = ofs; lastofs = ofs;
for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++) { for (i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++)
if (!ls->length) { {
if (!ls->length)
{
ls->value[0] = ls->value[1] = ls->value[2] = 1.0; ls->value[0] = ls->value[1] = ls->value[2] = 1.0;
continue; continue;
} }
if (ls->length == 1) if (ls->length == 1)
{
ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0]; ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0];
}
else else
ls->value[0] = ls->value[1] = ls->value[2] = ls->map[ofs%ls->length]; {
ls->value[0] = ls->value[1] = ls->value[2] = ls->map[ofs % ls->length];
}
} }
} }
void CL_SetLightstyle (int i) { void
char *s; CL_SetLightstyle(int i)
int j, k; {
char *s;
int j, k;
s = cl.configstrings[i+CS_LIGHTS]; s = cl.configstrings[i + CS_LIGHTS];
j = (int)strlen (s); j = (int)strlen(s);
cl_lightstyle[i].length = j; cl_lightstyle[i].length = j;
for (k=0 ; k<j ; k++) for (k = 0; k < j; k++)
cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a'); {
cl_lightstyle[i].map[k] = (float)(s[k] - 'a') / (float)('m' - 'a');
}
} }
void CL_AddLightStyles (void) { void
int i; CL_AddLightStyles(void)
clightstyle_t *ls; {
int i;
clightstyle_t *ls;
for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++) for (i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++)
V_AddLightStyle (i, ls->value[0], ls->value[1], ls->value[2]); {
V_AddLightStyle(i, ls->value[0], ls->value[1], ls->value[2]);
}
} }
cdlight_t cl_dlights[MAX_DLIGHTS]; cdlight_t cl_dlights[MAX_DLIGHTS];
void CL_ClearDlights (void) { void
memset (cl_dlights, 0, sizeof(cl_dlights)); CL_ClearDlights(void)
{
memset(cl_dlights, 0, sizeof(cl_dlights));
} }
cdlight_t *CL_AllocDlight (int key) { cdlight_t *
int i; CL_AllocDlight(int key)
cdlight_t *dl; {
int i;
cdlight_t *dl;
/* first look for an exact key match */ /* first look for an exact key match */
if (key) { if (key)
{
dl = cl_dlights; dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) { for (i = 0; i < MAX_DLIGHTS; i++, dl++)
if (dl->key == key) { {
if (dl->key == key)
{
dl->key = key; dl->key = key;
return dl; return dl;
} }
@ -112,8 +140,10 @@ cdlight_t *CL_AllocDlight (int key) {
/* then look for anything else */ /* then look for anything else */
dl = cl_dlights; dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) { for (i = 0; i < MAX_DLIGHTS; i++, dl++)
if (dl->die < cl.time) { {
if (dl->die < cl.time)
{
dl->key = key; dl->key = key;
return dl; return dl;
} }
@ -124,10 +154,12 @@ cdlight_t *CL_AllocDlight (int key) {
return dl; return dl;
} }
void CL_NewDlight (int key, float x, float y, float z, float radius, float time) { void
cdlight_t *dl; CL_NewDlight(int key, float x, float y, float z, float radius, float time)
{
cdlight_t *dl;
dl = CL_AllocDlight (key); dl = CL_AllocDlight(key);
dl->origin[0] = x; dl->origin[0] = x;
dl->origin[1] = y; dl->origin[1] = y;
dl->origin[2] = z; dl->origin[2] = z;
@ -135,58 +167,76 @@ void CL_NewDlight (int key, float x, float y, float z, float radius, float time)
dl->die = cl.time + time; dl->die = cl.time + time;
} }
void CL_RunDLights (void) { void
int i; CL_RunDLights(void)
cdlight_t *dl; {
int i;
cdlight_t *dl;
dl = cl_dlights; dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) { for (i = 0; i < MAX_DLIGHTS; i++, dl++)
{
if (!dl->radius) if (!dl->radius)
{
continue; continue;
}
if (dl->die < cl.time) { if (dl->die < cl.time)
{
dl->radius = 0; dl->radius = 0;
return; return;
} }
dl->radius -= cls.frametime*dl->decay; dl->radius -= cls.frametime * dl->decay;
if (dl->radius < 0) if (dl->radius < 0)
{
dl->radius = 0; dl->radius = 0;
}
} }
} }
void CL_AddDLights (void) { void
int i; CL_AddDLights(void)
cdlight_t *dl; {
int i;
cdlight_t *dl;
dl = cl_dlights; dl = cl_dlights;
if(vidref_val == VIDREF_GL) { if (vidref_val == VIDREF_GL)
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) { {
for (i = 0; i < MAX_DLIGHTS; i++, dl++)
{
if (!dl->radius) if (!dl->radius)
{
continue; continue;
}
V_AddLight (dl->origin, dl->radius, V_AddLight(dl->origin, dl->radius, dl->color[0], dl->color[1], dl->color[2]);
dl->color[0], dl->color[1], dl->color[2]);
} }
}
} else { else
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++) { {
for (i = 0; i < MAX_DLIGHTS; i++, dl++)
{
if (!dl->radius) if (!dl->radius)
{
continue; continue;
}
/* negative light in software. only black allowed */ /* negative light in software. only black allowed */
if ((dl->color[0] < 0) || (dl->color[1] < 0) || (dl->color[2] < 0)) { if ((dl->color[0] < 0) || (dl->color[1] < 0) || (dl->color[2] < 0))
{
dl->radius = -(dl->radius); dl->radius = -(dl->radius);
dl->color[0] = 1; dl->color[0] = 1;
dl->color[1] = 1; dl->color[1] = 1;
dl->color[2] = 1; dl->color[2] = 1;
} }
V_AddLight (dl->origin, dl->radius, V_AddLight(dl->origin, dl->radius, dl->color[0], dl->color[1], dl->color[2]);
dl->color[0], dl->color[1], dl->color[2]);
} }
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -26,12 +26,12 @@
#include "header/client.h" #include "header/client.h"
void CL_ParseStatusMessage (void); void CL_ParseStatusMessage(void);
extern cvar_t *msg; extern cvar_t *msg;
extern cvar_t *rcon_client_password; extern cvar_t *rcon_client_password;
extern cvar_t *rcon_address; extern cvar_t *rcon_address;
extern cvar_t *cl_timeout; extern cvar_t *cl_timeout;
/* /*
* adds the current command line as a clc_stringcmd to the client * adds the current command line as a clc_stringcmd to the client
@ -39,164 +39,183 @@ extern cvar_t *cl_timeout;
* the server, so when they are typed in at the console, they will need * the server, so when they are typed in at the console, they will need
* to be forwarded. * to be forwarded.
*/ */
void Cmd_ForwardToServer (void) void
Cmd_ForwardToServer(void)
{ {
char *cmd; char *cmd;
cmd = Cmd_Argv(0); cmd = Cmd_Argv(0);
if (cls.state <= ca_connected || *cmd == '-' || *cmd == '+') if ((cls.state <= ca_connected) || (*cmd == '-') || (*cmd == '+'))
{ {
Com_Printf ("Unknown command \"%s\"\n", cmd); Com_Printf("Unknown command \"%s\"\n", cmd);
return; return;
} }
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, cmd); SZ_Print(&cls.netchan.message, cmd);
if (Cmd_Argc() > 1) if (Cmd_Argc() > 1)
{ {
SZ_Print (&cls.netchan.message, " "); SZ_Print(&cls.netchan.message, " ");
SZ_Print (&cls.netchan.message, Cmd_Args()); SZ_Print(&cls.netchan.message, Cmd_Args());
} }
} }
void CL_ForwardToServer_f (void) void
CL_ForwardToServer_f(void)
{ {
if (cls.state != ca_connected && cls.state != ca_active) if ((cls.state != ca_connected) && (cls.state != ca_active))
{ {
Com_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0)); Com_Printf("Can't \"%s\", not connected\n", Cmd_Argv(0));
return; return;
} }
/* don't forward the first argument */ /* don't forward the first argument */
if (Cmd_Argc() > 1) if (Cmd_Argc() > 1)
{ {
MSG_WriteByte (&cls.netchan.message, clc_stringcmd); MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, Cmd_Args()); SZ_Print(&cls.netchan.message, Cmd_Args());
} }
} }
/* /*
* Called after an ERR_DROP was thrown * Called after an ERR_DROP was thrown
*/ */
void CL_Drop (void) void
CL_Drop(void)
{ {
if (cls.state == ca_uninitialized) if (cls.state == ca_uninitialized)
{
return; return;
}
if (cls.state == ca_disconnected) if (cls.state == ca_disconnected)
{
return; return;
}
CL_Disconnect (); CL_Disconnect();
/* drop loading plaque unless this is the initial game start */ /* drop loading plaque unless this is the initial game start */
if (cls.disable_servercount != -1) if (cls.disable_servercount != -1)
SCR_EndLoadingPlaque (); /* get rid of loading plaque */ {
SCR_EndLoadingPlaque(); /* get rid of loading plaque */
}
} }
/* /*
* We have gotten a challenge from the server, so try and * We have gotten a challenge from the server, so try and
* connect. * connect.
*/ */
void CL_SendConnectPacket (void) void
CL_SendConnectPacket(void)
{ {
netadr_t adr; netadr_t adr;
int port; int port;
memset(&adr, 0, sizeof(adr)); memset(&adr, 0, sizeof(adr));
if (!NET_StringToAdr (cls.servername, &adr)) if (!NET_StringToAdr(cls.servername, &adr))
{ {
Com_Printf ("Bad server address\n"); Com_Printf("Bad server address\n");
cls.connect_time = 0; cls.connect_time = 0;
return; return;
} }
if (adr.port == 0) if (adr.port == 0)
adr.port = BigShort (PORT_SERVER); {
adr.port = BigShort(PORT_SERVER);
}
port = Cvar_VariableValue ("qport"); port = Cvar_VariableValue("qport");
userinfo_modified = false; userinfo_modified = false;
Netchan_OutOfBandPrint (NS_CLIENT, adr, "connect %i %i %i \"%s\"\n", Netchan_OutOfBandPrint(NS_CLIENT, adr, "connect %i %i %i \"%s\"\n",
PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo() ); PROTOCOL_VERSION, port, cls.challenge, Cvar_Userinfo());
} }
/* /*
* Resend a connect message if the last one has timed out * Resend a connect message if the last one has timed out
*/ */
void CL_CheckForResend (void) void
CL_CheckForResend(void)
{ {
netadr_t adr; netadr_t adr;
/* if the local server is running and we aren't just connect */ /* if the local server is running and we aren't just connect */
if ((cls.state == ca_disconnected) && Com_ServerState())
if (cls.state == ca_disconnected && Com_ServerState() )
{ {
cls.state = ca_connecting; cls.state = ca_connecting;
strncpy (cls.servername, "localhost", sizeof(cls.servername)-1); strncpy(cls.servername, "localhost", sizeof(cls.servername) - 1);
/* we don't need a challenge on the localhost */ /* we don't need a challenge on the localhost */
CL_SendConnectPacket (); CL_SendConnectPacket();
return; return;
} }
/* resend if we haven't gotten a reply yet */ /* resend if we haven't gotten a reply yet */
if (cls.state != ca_connecting) if (cls.state != ca_connecting)
{
return; return;
}
if (cls.realtime - cls.connect_time < 3000) if (cls.realtime - cls.connect_time < 3000)
return;
if (!NET_StringToAdr (cls.servername, &adr))
{ {
Com_Printf ("Bad server address\n"); return;
}
if (!NET_StringToAdr(cls.servername, &adr))
{
Com_Printf("Bad server address\n");
cls.state = ca_disconnected; cls.state = ca_disconnected;
return; return;
} }
if (adr.port == 0) if (adr.port == 0)
adr.port = BigShort (PORT_SERVER); {
adr.port = BigShort(PORT_SERVER);
}
cls.connect_time = cls.realtime; cls.connect_time = cls.realtime;
Com_Printf ("Connecting to %s...\n", cls.servername); Com_Printf("Connecting to %s...\n", cls.servername);
Netchan_OutOfBandPrint (NS_CLIENT, adr, "getchallenge\n"); Netchan_OutOfBandPrint(NS_CLIENT, adr, "getchallenge\n");
} }
void CL_Connect_f (void) void
CL_Connect_f(void)
{ {
char *server; char *server;
if (Cmd_Argc() != 2) if (Cmd_Argc() != 2)
{ {
Com_Printf ("usage: connect <server>\n"); Com_Printf("usage: connect <server>\n");
return; return;
} }
if (Com_ServerState ()) if (Com_ServerState())
{ {
/* if running a local server, kill it and reissue */ /* if running a local server, kill it and reissue
/* note: this is connect with the save game system */ note: this is connect with the save game system */
SV_Shutdown (va("Server quit\n", msg), false); SV_Shutdown(va("Server quit\n", msg), false);
} }
else else
{ {
CL_Disconnect (); CL_Disconnect();
} }
server = Cmd_Argv (1); server = Cmd_Argv(1);
NET_Config (true); /* allow remote */ NET_Config(true); /* allow remote */
CL_Disconnect (); CL_Disconnect();
cls.state = ca_connecting; cls.state = ca_connecting;
strncpy (cls.servername, server, sizeof(cls.servername)-1); strncpy(cls.servername, server, sizeof(cls.servername) - 1);
cls.connect_time = -99999; /* HACK: CL_CheckForResend() will fire immediately */ cls.connect_time = -99999; /* HACK: CL_CheckForResend() will fire immediately */
} }
@ -204,16 +223,17 @@ void CL_Connect_f (void)
* Send the rest of the command line over as * Send the rest of the command line over as
* an unconnected command. * an unconnected command.
*/ */
void CL_Rcon_f (void) void
CL_Rcon_f(void)
{ {
char message[1024]; char message[1024];
int i; int i;
netadr_t to; netadr_t to;
if (!rcon_client_password->string) if (!rcon_client_password->string)
{ {
Com_Printf ("You must set 'rcon_password' before\n" Com_Printf("You must set 'rcon_password' before\n"
"issuing an rcon command.\n"); "issuing an rcon command.\n");
return; return;
} }
@ -225,72 +245,84 @@ void CL_Rcon_f (void)
message[3] = (char)255; message[3] = (char)255;
message[4] = 0; message[4] = 0;
NET_Config (true); /* allow remote */ NET_Config(true); /* allow remote */
strcat (message, "rcon "); strcat(message, "rcon ");
strcat (message, rcon_client_password->string); strcat(message, rcon_client_password->string);
strcat (message, " "); strcat(message, " ");
for (i=1 ; i<Cmd_Argc() ; i++) for (i = 1; i < Cmd_Argc(); i++)
{ {
strcat (message, Cmd_Argv(i)); strcat(message, Cmd_Argv(i));
strcat (message, " "); strcat(message, " ");
} }
if (cls.state >= ca_connected) if (cls.state >= ca_connected)
{
to = cls.netchan.remote_address; to = cls.netchan.remote_address;
}
else else
{ {
if (!strlen(rcon_address->string)) if (!strlen(rcon_address->string))
{ {
Com_Printf ("You must either be connected,\n" Com_Printf("You must either be connected,\n"
"or set the 'rcon_address' cvar\n" "or set the 'rcon_address' cvar\n"
"to issue rcon commands\n"); "to issue rcon commands\n");
return; return;
} }
NET_StringToAdr (rcon_address->string, &to); NET_StringToAdr(rcon_address->string, &to);
if (to.port == 0) if (to.port == 0)
to.port = BigShort (PORT_SERVER); {
to.port = BigShort(PORT_SERVER);
}
} }
NET_SendPacket (NS_CLIENT, strlen(message)+1, message, to); NET_SendPacket(NS_CLIENT, strlen(message) + 1, message, to);
} }
/*
* Goes from a connected state to full screen console state Sends a /*
* disconnect message to the server This is also called on Com_Error, so * Goes from a connected state to full screen
* console state Sends a disconnect message to
* the server This is also called on Com_Error, so
* it shouldn't cause any errors * it shouldn't cause any errors
*/ */
void CL_Disconnect (void) void
CL_Disconnect(void)
{ {
byte final[32]; byte final[32];
if (cls.state == ca_disconnected) if (cls.state == ca_disconnected)
{
return; return;
}
if (cl_timedemo && cl_timedemo->value) if (cl_timedemo && cl_timedemo->value)
{ {
int time; int time;
time = Sys_Milliseconds () - cl.timedemo_start; time = Sys_Milliseconds() - cl.timedemo_start;
if (time > 0) if (time > 0)
Com_Printf ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames, {
time/1000.0, cl.timedemo_frames*1000.0 / time); Com_Printf("%i frames, %3.1f seconds: %3.1f fps\n",
cl.timedemo_frames, time / 1000.0,
cl.timedemo_frames * 1000.0 / time);
}
} }
VectorClear (cl.refdef.blend); VectorClear(cl.refdef.blend);
re.CinematicSetPalette(NULL); re.CinematicSetPalette(NULL);
M_ForceMenuOff (); M_ForceMenuOff();
cls.connect_time = 0; cls.connect_time = 0;
SCR_StopCinematic (); SCR_StopCinematic();
#ifdef OGG #ifdef OGG
OGG_Stop(); OGG_Stop();
#endif #endif
@ -299,20 +331,20 @@ void CL_Disconnect (void)
#endif #endif
if (cls.demorecording) if (cls.demorecording)
CL_Stop_f (); {
CL_Stop_f();
}
/* send a disconnect message to the server */ /* send a disconnect message to the server */
final[0] = clc_stringcmd; final[0] = clc_stringcmd;
strcpy ((char *)final+1, "disconnect"); strcpy((char *)final + 1, "disconnect");
Netchan_Transmit (&cls.netchan, strlen((const char *)final), final); Netchan_Transmit(&cls.netchan, strlen((const char *)final), final);
Netchan_Transmit(&cls.netchan, strlen((const char *)final), final);
Netchan_Transmit(&cls.netchan, strlen((const char *)final), final);
Netchan_Transmit (&cls.netchan, strlen((const char *)final), final); CL_ClearState();
Netchan_Transmit (&cls.netchan, strlen((const char *)final), final);
CL_ClearState ();
/* stop file download */ /* stop file download */
if (cls.download) if (cls.download)
@ -324,9 +356,10 @@ void CL_Disconnect (void)
cls.state = ca_disconnected; cls.state = ca_disconnected;
} }
void CL_Disconnect_f (void) void
CL_Disconnect_f(void)
{ {
Com_Error (ERR_DROP, "Disconnected from server"); Com_Error(ERR_DROP, "Disconnected from server");
} }
/* /*
@ -334,91 +367,102 @@ void CL_Disconnect_f (void)
* *
* Contents allows \n escape character * Contents allows \n escape character
*/ */
void CL_Packet_f (void) void
CL_Packet_f(void)
{ {
char send[2048]; char send[2048];
int i, l; int i, l;
char *in, *out; char *in, *out;
netadr_t adr; netadr_t adr;
if (Cmd_Argc() != 3) if (Cmd_Argc() != 3)
{ {
Com_Printf ("packet <destination> <contents>\n"); Com_Printf("packet <destination> <contents>\n");
return; return;
} }
NET_Config (true); /* allow remote */ NET_Config(true); /* allow remote */
if (!NET_StringToAdr (Cmd_Argv(1), &adr)) if (!NET_StringToAdr(Cmd_Argv(1), &adr))
{ {
Com_Printf ("Bad address\n"); Com_Printf("Bad address\n");
return; return;
} }
if (!adr.port) if (!adr.port)
adr.port = BigShort (PORT_SERVER); {
adr.port = BigShort(PORT_SERVER);
}
in = Cmd_Argv(2); in = Cmd_Argv(2);
out = send+4; out = send + 4;
send[0] = send[1] = send[2] = send[3] = (char)0xff; send[0] = send[1] = send[2] = send[3] = (char)0xff;
l = strlen (in); l = strlen(in);
for (i=0 ; i<l ; i++) for (i = 0; i < l; i++)
{ {
if (in[i] == '\\' && in[i+1] == 'n') if ((in[i] == '\\') && (in[i + 1] == 'n'))
{ {
*out++ = '\n'; *out++ = '\n';
i++; i++;
} }
else else
{
*out++ = in[i]; *out++ = in[i];
}
} }
*out = 0; *out = 0;
NET_SendPacket (NS_CLIENT, out-send, send, adr); NET_SendPacket(NS_CLIENT, out - send, send, adr);
} }
/* /*
* Just sent as a hint to the client that they should * Just sent as a hint to the client that they should
* drop to full console * drop to full console
*/ */
void CL_Changing_f (void) void
CL_Changing_f(void)
{ {
/* if we are downloading, we don't change! /* if we are downloading, we don't change!
This so we don't suddenly stop downloading a map */ This so we don't suddenly stop downloading a map */
if (cls.download) if (cls.download)
{
return; return;
}
SCR_BeginLoadingPlaque (); SCR_BeginLoadingPlaque();
cls.state = ca_connected; /* not active anymore, but not disconnected */ cls.state = ca_connected; /* not active anymore, but not disconnected */
Com_Printf ("\nChanging map...\n"); Com_Printf("\nChanging map...\n");
} }
/* /*
* The server is changing levels * The server is changing levels
*/ */
void CL_Reconnect_f (void) void
CL_Reconnect_f(void)
{ {
/* if we are downloading, we don't change! /* if we are downloading, we don't change!
This so we don't suddenly stop downloading a map */ This so we don't suddenly stop downloading a map */
if (cls.download) if (cls.download)
{
return; return;
}
S_StopAllSounds (); S_StopAllSounds();
if (cls.state == ca_connected) if (cls.state == ca_connected)
{ {
Com_Printf ("reconnecting...\n"); Com_Printf("reconnecting...\n");
cls.state = ca_connected; cls.state = ca_connected;
MSG_WriteChar (&cls.netchan.message, clc_stringcmd); MSG_WriteChar(&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "new"); MSG_WriteString(&cls.netchan.message, "new");
return; return;
} }
@ -431,107 +475,115 @@ void CL_Reconnect_f (void)
} }
else else
{
cls.connect_time = -99999; /* Hack: fire immediately */ cls.connect_time = -99999; /* Hack: fire immediately */
}
cls.state = ca_connecting; cls.state = ca_connecting;
Com_Printf ("reconnecting...\n"); Com_Printf("reconnecting...\n");
} }
} }
void CL_PingServers_f (void) void
CL_PingServers_f(void)
{ {
int i; int i;
netadr_t adr; netadr_t adr;
char name[32]; char name[32];
char *adrstring; char *adrstring;
cvar_t *noudp; cvar_t *noudp;
cvar_t *noipx; cvar_t *noipx;
NET_Config (true); /* allow remote but do we even need lokal pings? */ NET_Config(true); /* allow remote but do we even need lokal pings? */
/* send a broadcast packet */ /* send a broadcast packet */
Com_Printf ("pinging broadcast...\n"); Com_Printf("pinging broadcast...\n");
noudp = Cvar_Get ("noudp", "0", CVAR_NOSET); noudp = Cvar_Get("noudp", "0", CVAR_NOSET);
if (!noudp->value) if (!noudp->value)
{ {
adr.type = NA_BROADCAST; adr.type = NA_BROADCAST;
adr.port = BigShort(PORT_SERVER); adr.port = BigShort(PORT_SERVER);
Netchan_OutOfBandPrint (NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION)); Netchan_OutOfBandPrint(NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION));
Com_Printf ("pinging multicast...\n"); Com_Printf("pinging multicast...\n");
adr.type = NA_MULTICAST6; adr.type = NA_MULTICAST6;
adr.port = BigShort(PORT_SERVER); adr.port = BigShort(PORT_SERVER);
Netchan_OutOfBandPrint (NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION)); Netchan_OutOfBandPrint(NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION));
} }
noipx = Cvar_Get ("noipx", "0", CVAR_NOSET); noipx = Cvar_Get("noipx", "0", CVAR_NOSET);
if (!noipx->value) if (!noipx->value)
{ {
adr.type = NA_BROADCAST_IPX; adr.type = NA_BROADCAST_IPX;
adr.port = BigShort(PORT_SERVER); adr.port = BigShort(PORT_SERVER);
Netchan_OutOfBandPrint (NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION)); Netchan_OutOfBandPrint(NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION));
} }
/* send a packet to each address book entry */ /* send a packet to each address book entry */
for (i=0 ; i<16 ; i++) for (i = 0; i < 16; i++)
{ {
Com_sprintf (name, sizeof(name), "adr%i", i); Com_sprintf(name, sizeof(name), "adr%i", i);
adrstring = (char *) Cvar_VariableString (name); adrstring = (char *)Cvar_VariableString(name);
if (!adrstring || !adrstring[0]) if (!adrstring || !adrstring[0])
continue;
Com_Printf ("pinging %s...\n", adrstring);
if (!NET_StringToAdr (adrstring, &adr))
{ {
Com_Printf ("Bad address: %s\n", adrstring); continue;
}
Com_Printf("pinging %s...\n", adrstring);
if (!NET_StringToAdr(adrstring, &adr))
{
Com_Printf("Bad address: %s\n", adrstring);
continue; continue;
} }
if (!adr.port) if (!adr.port)
{
adr.port = BigShort(PORT_SERVER); adr.port = BigShort(PORT_SERVER);
}
Netchan_OutOfBandPrint (NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION)); Netchan_OutOfBandPrint(NS_CLIENT, adr, va("info %i", PROTOCOL_VERSION));
} }
} }
/* /*
* Responses to broadcasts, etc * Responses to broadcasts, etc
*/ */
void CL_ConnectionlessPacket (void) void
CL_ConnectionlessPacket(void)
{ {
char *s; char *s;
char *c; char *c;
MSG_BeginReading (&net_message); MSG_BeginReading(&net_message);
MSG_ReadLong (&net_message); // skip the -1 MSG_ReadLong(&net_message); /* skip the -1 */
s = MSG_ReadStringLine (&net_message); s = MSG_ReadStringLine(&net_message);
Cmd_TokenizeString (s, false); Cmd_TokenizeString(s, false);
c = Cmd_Argv(0); c = Cmd_Argv(0);
Com_Printf ("%s: %s\n", NET_AdrToString (net_from), c); Com_Printf("%s: %s\n", NET_AdrToString(net_from), c);
/* server connection */ /* server connection */
if (!strcmp(c, "client_connect")) if (!strcmp(c, "client_connect"))
{ {
if (cls.state == ca_connected) if (cls.state == ca_connected)
{ {
Com_Printf ("Dup connect received. Ignored.\n"); Com_Printf("Dup connect received. Ignored.\n");
return; return;
} }
Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, cls.quakePort); Netchan_Setup(NS_CLIENT, &cls.netchan, net_from, cls.quakePort);
MSG_WriteChar (&cls.netchan.message, clc_stringcmd); MSG_WriteChar(&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, "new"); MSG_WriteString(&cls.netchan.message, "new");
cls.state = ca_connected; cls.state = ca_connected;
return; return;
} }
@ -539,7 +591,7 @@ void CL_ConnectionlessPacket (void)
/* server responding to a status broadcast */ /* server responding to a status broadcast */
if (!strcmp(c, "info")) if (!strcmp(c, "info"))
{ {
CL_ParseStatusMessage (); CL_ParseStatusMessage();
return; return;
} }
@ -548,28 +600,28 @@ void CL_ConnectionlessPacket (void)
{ {
if (!NET_IsLocalAddress(net_from)) if (!NET_IsLocalAddress(net_from))
{ {
Com_Printf ("Command packet from remote host. Ignored.\n"); Com_Printf("Command packet from remote host. Ignored.\n");
return; return;
} }
s = MSG_ReadString (&net_message); s = MSG_ReadString(&net_message);
Cbuf_AddText (s); Cbuf_AddText(s);
Cbuf_AddText ("\n"); Cbuf_AddText("\n");
return; return;
} }
/* print command from somewhere */ /* print command from somewhere */
if (!strcmp(c, "print")) if (!strcmp(c, "print"))
{ {
s = MSG_ReadString (&net_message); s = MSG_ReadString(&net_message);
Com_Printf ("%s", s); Com_Printf("%s", s);
return; return;
} }
/* ping from somewhere */ /* ping from somewhere */
if (!strcmp(c, "ping")) if (!strcmp(c, "ping"))
{ {
Netchan_OutOfBandPrint (NS_CLIENT, net_from, "ack"); Netchan_OutOfBandPrint(NS_CLIENT, net_from, "ack");
return; return;
} }
@ -577,67 +629,74 @@ void CL_ConnectionlessPacket (void)
if (!strcmp(c, "challenge")) if (!strcmp(c, "challenge"))
{ {
cls.challenge = (int)strtol(Cmd_Argv(1), (char **)NULL, 10); cls.challenge = (int)strtol(Cmd_Argv(1), (char **)NULL, 10);
CL_SendConnectPacket (); CL_SendConnectPacket();
return; return;
} }
/* echo request from server */ /* echo request from server */
if (!strcmp(c, "echo")) if (!strcmp(c, "echo"))
{ {
Netchan_OutOfBandPrint (NS_CLIENT, net_from, "%s", Cmd_Argv(1) ); Netchan_OutOfBandPrint(NS_CLIENT, net_from, "%s", Cmd_Argv(1));
return; return;
} }
Com_Printf ("Unknown command.\n"); Com_Printf("Unknown command.\n");
} }
void CL_ReadPackets (void) void
CL_ReadPackets(void)
{ {
while (NET_GetPacket (NS_CLIENT, &net_from, &net_message)) while (NET_GetPacket(NS_CLIENT, &net_from, &net_message))
{ {
/* remote command packet */ /* remote command packet */
if (*(int *)net_message.data == -1) if (*(int *)net_message.data == -1)
{ {
CL_ConnectionlessPacket (); CL_ConnectionlessPacket();
continue; continue;
} }
if (cls.state == ca_disconnected || cls.state == ca_connecting) if ((cls.state == ca_disconnected) || (cls.state == ca_connecting))
{
continue; /* dump it if not connected */ continue; /* dump it if not connected */
}
if (net_message.cursize < 8) if (net_message.cursize < 8)
{ {
Com_Printf ("%s: Runt packet\n",NET_AdrToString(net_from)); Com_Printf("%s: Runt packet\n", NET_AdrToString(net_from));
continue; continue;
} }
/* packet from server */ /* packet from server */
if (!NET_CompareAdr (net_from, cls.netchan.remote_address)) if (!NET_CompareAdr(net_from, cls.netchan.remote_address))
{ {
Com_DPrintf ("%s:sequenced packet without connection\n" Com_DPrintf("%s:sequenced packet without connection\n",
,NET_AdrToString(net_from)); NET_AdrToString(net_from));
continue; continue;
} }
if (!Netchan_Process(&cls.netchan, &net_message)) if (!Netchan_Process(&cls.netchan, &net_message))
{
continue; /* wasn't accepted for some reason */ continue; /* wasn't accepted for some reason */
}
CL_ParseServerMessage (); CL_ParseServerMessage();
} }
/* check timeout */ /* check timeout */
if (cls.state >= ca_connected if ((cls.state >= ca_connected) &&
&& cls.realtime - cls.netchan.last_received > cl_timeout->value*1000) (cls.realtime - cls.netchan.last_received > cl_timeout->value * 1000))
{ {
if (++cl.timeoutcount > 5) if (++cl.timeoutcount > 5)
{ {
Com_Printf ("\nServer connection timed out.\n"); Com_Printf("\nServer connection timed out.\n");
CL_Disconnect (); CL_Disconnect();
return; return;
} }
} }
else else
{
cl.timeoutcount = 0; cl.timeoutcount = 0;
}
} }

File diff suppressed because it is too large Load diff

View file

@ -26,30 +26,39 @@
#include "header/client.h" #include "header/client.h"
cparticle_t *active_particles, *free_particles; cparticle_t *active_particles, *free_particles;
cparticle_t particles[MAX_PARTICLES]; cparticle_t particles[MAX_PARTICLES];
int cl_numparticles = MAX_PARTICLES; int cl_numparticles = MAX_PARTICLES;
void CL_ClearParticles (void) { void
int i; CL_ClearParticles(void)
{
int i;
free_particles = &particles[0]; free_particles = &particles[0];
active_particles = NULL; active_particles = NULL;
for (i=0 ; i<cl_numparticles ; i++) for (i = 0; i < cl_numparticles; i++)
particles[i].next = &particles[i+1]; {
particles[i].next = &particles[i + 1];
}
particles[cl_numparticles-1].next = NULL; particles[cl_numparticles - 1].next = NULL;
} }
void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count) { void
int i, j; CL_ParticleEffect(vec3_t org, vec3_t dir, int color, int count)
cparticle_t *p; {
float d; int i, j;
cparticle_t *p;
float d;
for (i=0 ; i<count ; i++) { for (i = 0; i < count; i++)
{
if (!free_particles) if (!free_particles)
{
return; return;
}
p = free_particles; p = free_particles;
free_particles = p->next; free_particles = p->next;
@ -57,32 +66,39 @@ void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count) {
active_particles = p; active_particles = p;
p->time = cl.time; p->time = cl.time;
p->color = color + (randk()&7); p->color = color + (randk() & 7);
d = randk()&31; d = randk() & 31;
for (j=0 ; j<3 ; j++) { for (j = 0; j < 3; j++)
p->org[j] = org[j] + ((randk()&7)-4) + d*dir[j]; {
p->vel[j] = crandk()*20; p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 20;
} }
p->accel[0] = p->accel[1] = 0; p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY+0.2f; p->accel[2] = -PARTICLE_GRAVITY + 0.2f;
p->alpha = 1.0; p->alpha = 1.0;
p->alphavel = -1.0 / (0.5 + frandk()*0.3); p->alphavel = -1.0 / (0.5 + frandk() * 0.3);
} }
} }
void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count) { void
int i, j; CL_ParticleEffect2(vec3_t org, vec3_t dir, int color, int count)
cparticle_t *p; {
float d; int i, j;
float time; cparticle_t *p;
float d;
float time;
time = (float)cl.time; time = (float)cl.time;
for (i=0 ; i<count ; i++) { for (i = 0; i < count; i++)
{
if (!free_particles) if (!free_particles)
{
return; return;
}
p = free_particles; p = free_particles;
free_particles = p->next; free_particles = p->next;
@ -90,33 +106,40 @@ void CL_ParticleEffect2 (vec3_t org, vec3_t dir, int color, int count) {
active_particles = p; active_particles = p;
p->time = time; p->time = time;
p->color = color + (randk()&7); p->color = color + (randk() & 7);
d = randk()&7; d = randk() & 7;
for (j=0 ; j<3 ; j++) { for (j = 0; j < 3; j++)
p->org[j] = org[j] + ((randk()&7)-4) + d*dir[j]; {
p->vel[j] = crandk()*20; p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 20;
} }
p->accel[0] = p->accel[1] = 0; p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY; p->accel[2] = -PARTICLE_GRAVITY;
p->alpha = 1.0; p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frandk()*0.3f); p->alphavel = -1.0f / (0.5f + frandk() * 0.3f);
} }
} }
void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count) { void
int i, j; CL_ParticleEffect3(vec3_t org, vec3_t dir, int color, int count)
cparticle_t *p; {
float d; int i, j;
float time; cparticle_t *p;
float d;
float time;
time = (float)cl.time; time = (float)cl.time;
for (i=0 ; i<count ; i++) { for (i = 0; i < count; i++)
{
if (!free_particles) if (!free_particles)
{
return; return;
}
p = free_particles; p = free_particles;
free_particles = p->next; free_particles = p->next;
@ -126,47 +149,54 @@ void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count) {
p->time = time; p->time = time;
p->color = color; p->color = color;
d = randk()&7; d = randk() & 7;
for (j=0 ; j<3 ; j++) { for (j = 0; j < 3; j++)
p->org[j] = org[j] + ((randk()&7)-4) + d*dir[j]; {
p->vel[j] = crandk()*20; p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 20;
} }
p->accel[0] = p->accel[1] = 0; p->accel[0] = p->accel[1] = 0;
p->accel[2] = PARTICLE_GRAVITY; p->accel[2] = PARTICLE_GRAVITY;
p->alpha = 1.0; p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frandk()*0.3f); p->alphavel = -1.0f / (0.5f + frandk() * 0.3f);
} }
} }
void CL_AddParticles (void) { void
cparticle_t *p, *next; CL_AddParticles(void)
float alpha; {
float time, time2; cparticle_t *p, *next;
vec3_t org; float alpha;
int color; float time, time2;
cparticle_t *active, *tail; vec3_t org;
int color;
cparticle_t *active, *tail;
active = NULL; active = NULL;
tail = NULL; tail = NULL;
for (p=active_particles ; p ; p=next) { for (p = active_particles; p; p = next)
{
next = p->next; next = p->next;
if (p->alphavel != INSTANT_PARTICLE) { if (p->alphavel != INSTANT_PARTICLE)
time = (cl.time - p->time)*0.001; {
alpha = p->alpha + time*p->alphavel; time = (cl.time - p->time) * 0.001;
alpha = p->alpha + time * p->alphavel;
if (alpha <= 0) { if (alpha <= 0)
{
/* faded out */ /* faded out */
p->next = free_particles; p->next = free_particles;
free_particles = p; free_particles = p;
continue; continue;
} }
}
} else { else
{
time = 0.0f; time = 0.0f;
alpha = p->alpha; alpha = p->alpha;
} }
@ -174,26 +204,32 @@ void CL_AddParticles (void) {
p->next = NULL; p->next = NULL;
if (!tail) if (!tail)
{
active = tail = p; active = tail = p;
}
else { else
{
tail->next = p; tail->next = p;
tail = p; tail = p;
} }
if (alpha > 1.0f) if (alpha > 1.0f)
{
alpha = 1; alpha = 1;
}
color = p->color; color = p->color;
time2 = time*time; time2 = time * time;
org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2; org[0] = p->org[0] + p->vel[0] * time + p->accel[0] * time2;
org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2; org[1] = p->org[1] + p->vel[1] * time + p->accel[1] * time2;
org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2; org[2] = p->org[2] + p->vel[2] * time + p->accel[2] * time2;
V_AddParticle (org, color, alpha); V_AddParticle(org, color, alpha);
if (p->alphavel == INSTANT_PARTICLE) { if (p->alphavel == INSTANT_PARTICLE)
{
p->alphavel = 0.0; p->alphavel = 0.0;
p->alpha = 0.0; p->alpha = 0.0;
} }
@ -202,16 +238,23 @@ void CL_AddParticles (void) {
active_particles = active; active_particles = active;
} }
void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int numcolors, int dirspread, float alphavel) { void
int i, j; CL_GenericParticleEffect(vec3_t org, vec3_t dir, int color,
cparticle_t *p; int count, int numcolors, int dirspread, float alphavel)
float d; {
float time; int i, j;
cparticle_t *p;
float d;
float time;
time = (float)cl.time; time = (float)cl.time;
for (i=0 ; i<count ; i++) { for (i = 0; i < count; i++)
{
if (!free_particles) if (!free_particles)
{
return; return;
}
p = free_particles; p = free_particles;
free_particles = p->next; free_particles = p->next;
@ -221,22 +264,28 @@ void CL_GenericParticleEffect (vec3_t org, vec3_t dir, int color, int count, int
p->time = time; p->time = time;
if (numcolors > 1) if (numcolors > 1)
{
p->color = color + (randk() & numcolors); p->color = color + (randk() & numcolors);
}
else else
{
p->color = color; p->color = color;
}
d = (float)(randk() & dirspread); d = (float)(randk() & dirspread);
for (j=0 ; j<3 ; j++) { for (j = 0; j < 3; j++)
p->org[j] = org[j] + ((randk()&7)-4) + d*dir[j]; {
p->vel[j] = crandk()*20; p->org[j] = org[j] + ((randk() & 7) - 4) + d * dir[j];
p->vel[j] = crandk() * 20;
} }
p->accel[0] = p->accel[1] = 0; p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY; p->accel[2] = -PARTICLE_GRAVITY;
p->alpha = 1.0; p->alpha = 1.0;
p->alphavel = -1.0f / (0.5f + frandk()*alphavel); p->alphavel = -1.0f / (0.5f + frandk() * alphavel);
} }
} }

View file

@ -27,148 +27,193 @@
#include "header/client.h" #include "header/client.h"
void CL_CheckPredictionError (void) { void
int frame; CL_CheckPredictionError(void)
int delta[3]; {
int i; int frame;
int len; int delta[3];
int i;
int len;
if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) if (!cl_predict->value ||
(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
{
return; return;
}
/* calculate the last usercmd_t we sent that the server has processed */ /* calculate the last usercmd_t we sent that the server has processed */
frame = cls.netchan.incoming_acknowledged; frame = cls.netchan.incoming_acknowledged;
frame &= (CMD_BACKUP-1); frame &= (CMD_BACKUP - 1);
/* compare what the server returned with what we had predicted it to be */ /* compare what the server returned with what we had predicted it to be */
VectorSubtract (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame], delta); VectorSubtract(cl.frame.playerstate.pmove.origin,
cl.predicted_origins[frame], delta);
/* save the prediction error for interpolation */ /* save the prediction error for interpolation */
len = abs(delta[0]) + abs(delta[1]) + abs(delta[2]); len = abs(delta[0]) + abs(delta[1]) + abs(delta[2]);
/* 80 world units */ /* 80 world units */
if (len > 640) { if (len > 640)
{
/* a teleport or something */ /* a teleport or something */
VectorClear (cl.prediction_error); VectorClear(cl.prediction_error);
}
else
{
if (cl_showmiss->value && (delta[0] || delta[1] || delta[2]))
{
Com_Printf("prediction miss on %i: %i\n", cl.frame.serverframe,
delta[0] + delta[1] + delta[2]);
}
} else { VectorCopy(cl.frame.playerstate.pmove.origin,
if (cl_showmiss->value && (delta[0] || delta[1] || delta[2]) ) cl.predicted_origins[frame]);
Com_Printf ("prediction miss on %i: %i\n", cl.frame.serverframe,
delta[0] + delta[1] + delta[2]);
VectorCopy (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame]);
/* save for error itnerpolation */ /* save for error itnerpolation */
for (i=0 ; i<3 ; i++) for (i = 0; i < 3; i++)
cl.prediction_error[i] = delta[i]*0.125f; {
cl.prediction_error[i] = delta[i] * 0.125f;
}
} }
} }
void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, trace_t *tr ) { void
int i, x, zd, zu; CL_ClipMoveToEntities(vec3_t start, vec3_t mins, vec3_t maxs,
trace_t trace; vec3_t end, trace_t *tr)
int headnode; {
float *angles; int i, x, zd, zu;
entity_state_t *ent; trace_t trace;
int num; int headnode;
cmodel_t *cmodel; float *angles;
vec3_t bmins, bmaxs; entity_state_t *ent;
int num;
cmodel_t *cmodel;
vec3_t bmins, bmaxs;
for (i=0 ; i<cl.frame.num_entities ; i++) { for (i = 0; i < cl.frame.num_entities; i++)
num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1); {
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
ent = &cl_parse_entities[num]; ent = &cl_parse_entities[num];
if (!ent->solid) if (!ent->solid)
{
continue; continue;
}
if (ent->number == cl.playernum+1) if (ent->number == cl.playernum + 1)
{
continue; continue;
}
if (ent->solid == 31) { if (ent->solid == 31)
{
/* special value for bmodel */ /* special value for bmodel */
cmodel = cl.model_clip[ent->modelindex]; cmodel = cl.model_clip[ent->modelindex];
if (!cmodel) if (!cmodel)
{
continue; continue;
}
headnode = cmodel->headnode; headnode = cmodel->headnode;
angles = ent->angles; angles = ent->angles;
}
} else { else
{
/* encoded bbox */ /* encoded bbox */
x = 8*(ent->solid & 31); x = 8 * (ent->solid & 31);
zd = 8*((ent->solid>>5) & 31); zd = 8 * ((ent->solid >> 5) & 31);
zu = 8*((ent->solid>>10) & 63) - 32; zu = 8 * ((ent->solid >> 10) & 63) - 32;
bmins[0] = bmins[1] = -(float)x; bmins[0] = bmins[1] = -(float)x;
bmaxs[0] = bmaxs[1] = (float)x; bmaxs[0] = bmaxs[1] = (float)x;
bmins[2] = -(float)zd; bmins[2] = -(float)zd;
bmaxs[2] = (float)zu; bmaxs[2] = (float)zu;
headnode = CM_HeadnodeForBox (bmins, bmaxs); headnode = CM_HeadnodeForBox(bmins, bmaxs);
angles = vec3_origin; /* boxes don't rotate */ angles = vec3_origin; /* boxes don't rotate */
} }
if (tr->allsolid) if (tr->allsolid)
{
return; return;
}
trace = CM_TransformedBoxTrace (start, end, trace = CM_TransformedBoxTrace(start, end,
mins, maxs, headnode, MASK_PLAYERSOLID, mins, maxs, headnode, MASK_PLAYERSOLID,
ent->origin, angles); ent->origin, angles);
if (trace.allsolid || trace.startsolid || if (trace.allsolid || trace.startsolid ||
trace.fraction < tr->fraction) { (trace.fraction < tr->fraction))
{
trace.ent = (struct edict_s *)ent; trace.ent = (struct edict_s *)ent;
if (tr->startsolid) { if (tr->startsolid)
{
*tr = trace; *tr = trace;
tr->startsolid = true; tr->startsolid = true;
}
} else else
{
*tr = trace; *tr = trace;
}
} else if (trace.startsolid) }
else if (trace.startsolid)
{
tr->startsolid = true; tr->startsolid = true;
}
} }
} }
trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { trace_t
trace_t t; CL_PMTrace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
{
trace_t t;
/* check against world */ /* check against world */
t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID); t = CM_BoxTrace(start, end, mins, maxs, 0, MASK_PLAYERSOLID);
if (t.fraction < 1.0) if (t.fraction < 1.0)
{
t.ent = (struct edict_s *)1; t.ent = (struct edict_s *)1;
}
/* check all other solid models */ /* check all other solid models */
CL_ClipMoveToEntities (start, mins, maxs, end, &t); CL_ClipMoveToEntities(start, mins, maxs, end, &t);
return t; return t;
} }
int CL_PMpointcontents (vec3_t point) { int
int i; CL_PMpointcontents(vec3_t point)
entity_state_t *ent; {
int num; int i;
cmodel_t *cmodel; entity_state_t *ent;
int contents; int num;
cmodel_t *cmodel;
int contents;
contents = CM_PointContents (point, 0); contents = CM_PointContents(point, 0);
for (i=0 ; i<cl.frame.num_entities ; i++) { for (i = 0; i < cl.frame.num_entities; i++)
num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1); {
num = (cl.frame.parse_entities + i) & (MAX_PARSE_ENTITIES - 1);
ent = &cl_parse_entities[num]; ent = &cl_parse_entities[num];
if (ent->solid != 31) /* special value for bmodel */ if (ent->solid != 31) /* special value for bmodel */
{
continue; continue;
}
cmodel = cl.model_clip[ent->modelindex]; cmodel = cl.model_clip[ent->modelindex];
if (!cmodel) if (!cmodel)
{
continue; continue;
}
contents |= CM_TransformedPointContents (point, cmodel->headnode, ent->origin, ent->angles); contents |= CM_TransformedPointContents(point, cmodel->headnode,
ent->origin, ent->angles);
} }
return contents; return contents;
@ -177,26 +222,36 @@ int CL_PMpointcontents (vec3_t point) {
/* /*
* Sets cl.predicted_origin and cl.predicted_angles * Sets cl.predicted_origin and cl.predicted_angles
*/ */
void CL_PredictMovement (void) { void
int ack, current; CL_PredictMovement(void)
int frame; {
int oldframe; int ack, current;
usercmd_t *cmd; int frame;
pmove_t pm; int oldframe;
int i; usercmd_t *cmd;
int step; pmove_t pm;
int oldz; int i;
int step;
int oldz;
if (cls.state != ca_active) if (cls.state != ca_active)
{
return; return;
}
if (cl_paused->value) if (cl_paused->value)
{
return; return;
}
if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION)) { if (!cl_predict->value ||
(cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
{
/* just set angles */ /* just set angles */
for (i=0 ; i<3 ; i++) { for (i = 0; i < 3; i++)
cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]); {
cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(
cl.frame.playerstate.pmove.delta_angles[i]);
} }
return; return;
@ -206,9 +261,12 @@ void CL_PredictMovement (void) {
current = cls.netchan.outgoing_sequence; current = cls.netchan.outgoing_sequence;
/* if we are too far out of date, just freeze */ /* if we are too far out of date, just freeze */
if (current - ack >= CMD_BACKUP) { if (current - ack >= CMD_BACKUP)
{
if (cl_showmiss->value) if (cl_showmiss->value)
Com_Printf ("exceeded CMD_BACKUP\n"); {
Com_Printf("exceeded CMD_BACKUP\n");
}
return; return;
} }
@ -219,34 +277,37 @@ void CL_PredictMovement (void) {
pm_airaccelerate = strtod(cl.configstrings[CS_AIRACCEL], (char **)NULL); pm_airaccelerate = strtod(cl.configstrings[CS_AIRACCEL], (char **)NULL);
pm.s = cl.frame.playerstate.pmove; pm.s = cl.frame.playerstate.pmove;
VectorSet (pm.mins, -16, -16, -24); VectorSet(pm.mins, -16, -16, -24);
VectorSet (pm.maxs, 16, 16, 32); VectorSet(pm.maxs, 16, 16, 32);
/* run frames */ /* run frames */
while (++ack < current) { while (++ack < current)
frame = ack & (CMD_BACKUP-1); {
frame = ack & (CMD_BACKUP - 1);
cmd = &cl.cmds[frame]; cmd = &cl.cmds[frame];
pm.cmd = *cmd; pm.cmd = *cmd;
Pmove (&pm); Pmove(&pm);
/* save for debug checking */ /* save for debug checking */
VectorCopy (pm.s.origin, cl.predicted_origins[frame]); VectorCopy(pm.s.origin, cl.predicted_origins[frame]);
} }
oldframe = (ack-2) & (CMD_BACKUP-1); oldframe = (ack - 2) & (CMD_BACKUP - 1);
oldz = cl.predicted_origins[oldframe][2]; oldz = cl.predicted_origins[oldframe][2];
step = pm.s.origin[2] - oldz; step = pm.s.origin[2] - oldz;
if (step > 63 && step < 160 && (pm.s.pm_flags & PMF_ON_GROUND) ) { if ((step > 63) && (step < 160) && (pm.s.pm_flags & PMF_ON_GROUND))
{
cl.predicted_step = step * 0.125f; cl.predicted_step = step * 0.125f;
cl.predicted_step_time = cls.realtime - cls.frametime * 500; cl.predicted_step_time = cls.realtime - cls.frametime * 500;
} }
/* copy results out for rendering */ /* copy results out for rendering */
cl.predicted_origin[0] = pm.s.origin[0]*0.125f; cl.predicted_origin[0] = pm.s.origin[0] * 0.125f;
cl.predicted_origin[1] = pm.s.origin[1]*0.125f; cl.predicted_origin[1] = pm.s.origin[1] * 0.125f;
cl.predicted_origin[2] = pm.s.origin[2]*0.125f; cl.predicted_origin[2] = pm.s.origin[2] * 0.125f;
VectorCopy (pm.viewangles, cl.predicted_angles); VectorCopy(pm.viewangles, cl.predicted_angles);
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -26,32 +26,31 @@
#include "header/client.h" #include "header/client.h"
void SCR_DrawCrosshair (void); void SCR_DrawCrosshair(void);
/* development tools for weapons */ /* development tools for weapons */
int gun_frame; int gun_frame;
struct model_s *gun_model; struct model_s *gun_model;
cvar_t *crosshair; cvar_t *crosshair;
cvar_t *crosshair_scale; cvar_t *crosshair_scale;
cvar_t *cl_testparticles; cvar_t *cl_testparticles;
cvar_t *cl_testentities; cvar_t *cl_testentities;
cvar_t *cl_testlights; cvar_t *cl_testlights;
cvar_t *cl_testblend; cvar_t *cl_testblend;
cvar_t *cl_stats; cvar_t *cl_stats;
int r_numdlights;
dlight_t r_dlights[MAX_DLIGHTS];
int r_numdlights; int r_numentities;
dlight_t r_dlights[MAX_DLIGHTS]; entity_t r_entities[MAX_ENTITIES];
int r_numentities; int r_numparticles;
entity_t r_entities[MAX_ENTITIES]; particle_t r_particles[MAX_PARTICLES];
int r_numparticles; lightstyle_t r_lightstyles[MAX_LIGHTSTYLES];
particle_t r_particles[MAX_PARTICLES];
lightstyle_t r_lightstyles[MAX_LIGHTSTYLES];
char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH]; char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH];
int num_cl_weaponmodels; int num_cl_weaponmodels;
@ -59,54 +58,72 @@ int num_cl_weaponmodels;
/* /*
* Specifies the model that will be used as the world * Specifies the model that will be used as the world
*/ */
void V_ClearScene (void) { void
V_ClearScene(void)
{
r_numdlights = 0; r_numdlights = 0;
r_numentities = 0; r_numentities = 0;
r_numparticles = 0; r_numparticles = 0;
} }
void V_AddEntity (entity_t *ent) { void
V_AddEntity(entity_t *ent)
{
if (r_numentities >= MAX_ENTITIES) if (r_numentities >= MAX_ENTITIES)
{
return; return;
}
r_entities[r_numentities++] = *ent; r_entities[r_numentities++] = *ent;
} }
void V_AddParticle (vec3_t org, unsigned int color, float alpha) { void
particle_t *p; V_AddParticle(vec3_t org, unsigned int color, float alpha)
{
particle_t *p;
if (r_numparticles >= MAX_PARTICLES) if (r_numparticles >= MAX_PARTICLES)
{
return; return;
}
p = &r_particles[r_numparticles++]; p = &r_particles[r_numparticles++];
VectorCopy (org, p->origin); VectorCopy(org, p->origin);
p->color = color; p->color = color;
p->alpha = alpha; p->alpha = alpha;
} }
void V_AddLight (vec3_t org, float intensity, float r, float g, float b) { void
dlight_t *dl; V_AddLight(vec3_t org, float intensity, float r, float g, float b)
{
dlight_t *dl;
if (r_numdlights >= MAX_DLIGHTS) if (r_numdlights >= MAX_DLIGHTS)
{
return; return;
}
dl = &r_dlights[r_numdlights++]; dl = &r_dlights[r_numdlights++];
VectorCopy (org, dl->origin); VectorCopy(org, dl->origin);
dl->intensity = intensity; dl->intensity = intensity;
dl->color[0] = r; dl->color[0] = r;
dl->color[1] = g; dl->color[1] = g;
dl->color[2] = b; dl->color[2] = b;
} }
void V_AddLightStyle (int style, float r, float g, float b) { void
lightstyle_t *ls; V_AddLightStyle(int style, float r, float g, float b)
{
lightstyle_t *ls;
if (style < 0 || style > MAX_LIGHTSTYLES) if ((style < 0) || (style > MAX_LIGHTSTYLES))
Com_Error (ERR_DROP, "Bad light style %i", style); {
Com_Error(ERR_DROP, "Bad light style %i", style);
}
ls = &r_lightstyles[style]; ls = &r_lightstyles[style];
ls->white = r+g+b; ls->white = r + g + b;
ls->rgb[0] = r; ls->rgb[0] = r;
ls->rgb[1] = g; ls->rgb[1] = g;
ls->rgb[2] = b; ls->rgb[2] = b;
@ -115,22 +132,27 @@ void V_AddLightStyle (int style, float r, float g, float b) {
/* /*
*If cl_testparticles is set, create 4096 particles in the view *If cl_testparticles is set, create 4096 particles in the view
*/ */
void V_TestParticles (void) { void
particle_t *p; V_TestParticles(void)
int i, j; {
float d, r, u; particle_t *p;
int i, j;
float d, r, u;
r_numparticles = MAX_PARTICLES; r_numparticles = MAX_PARTICLES;
for (i=0 ; i<r_numparticles ; i++) { for (i = 0; i < r_numparticles; i++)
d = i*0.25f; {
r = 4*((i&7)-3.5f); d = i * 0.25f;
u = 4*(((i>>3)&7)-3.5f); r = 4 * ((i & 7) - 3.5f);
u = 4 * (((i >> 3) & 7) - 3.5f);
p = &r_particles[i]; p = &r_particles[i];
for (j=0 ; j<3 ; j++) for (j = 0; j < 3; j++)
p->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*d + {
cl.v_right[j]*r + cl.v_up[j]*u; p->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * d +
cl.v_right[j] * r + cl.v_up[j] * u;
}
p->color = 8; p->color = 8;
p->alpha = cl_testparticles->value; p->alpha = cl_testparticles->value;
@ -140,23 +162,28 @@ void V_TestParticles (void) {
/* /*
* If cl_testentities is set, create 32 player models * If cl_testentities is set, create 32 player models
*/ */
void V_TestEntities (void) { void
int i, j; V_TestEntities(void)
float f, r; {
entity_t *ent; int i, j;
float f, r;
entity_t *ent;
r_numentities = 32; r_numentities = 32;
memset (r_entities, 0, sizeof(r_entities)); memset(r_entities, 0, sizeof(r_entities));
for (i=0 ; i<r_numentities ; i++) { for (i = 0; i < r_numentities; i++)
{
ent = &r_entities[i]; ent = &r_entities[i];
r = 64 * ( (i%4) - 1.5 ); r = 64 * ((i % 4) - 1.5);
f = 64 * (i/4) + 128; f = 64 * (i / 4) + 128;
for (j=0 ; j<3 ; j++) for (j = 0; j < 3; j++)
ent->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + {
cl.v_right[j]*r; ent->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * f +
cl.v_right[j] * r;
}
ent->model = cl.baseclientinfo.model; ent->model = cl.baseclientinfo.model;
ent->skin = cl.baseclientinfo.skin; ent->skin = cl.baseclientinfo.skin;
@ -166,27 +193,32 @@ void V_TestEntities (void) {
/* /*
* If cl_testlights is set, create 32 lights models * If cl_testlights is set, create 32 lights models
*/ */
void V_TestLights (void) { void
int i, j; V_TestLights(void)
float f, r; {
dlight_t *dl; int i, j;
float f, r;
dlight_t *dl;
r_numdlights = 32; r_numdlights = 32;
memset (r_dlights, 0, sizeof(r_dlights)); memset(r_dlights, 0, sizeof(r_dlights));
for (i=0 ; i<r_numdlights ; i++) { for (i = 0; i < r_numdlights; i++)
{
dl = &r_dlights[i]; dl = &r_dlights[i];
r = 64 * ( (i%4) - 1.5f ); r = 64 * ((i % 4) - 1.5f);
f = 64 * (i/4.0f) + 128; f = 64 * (i / 4.0f) + 128;
for (j=0 ; j<3 ; j++) for (j = 0; j < 3; j++)
dl->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + {
cl.v_right[j]*r; dl->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * f +
cl.v_right[j] * r;
}
dl->color[0] = (float)(((i%6)+1) & 1); dl->color[0] = (float)(((i % 6) + 1) & 1);
dl->color[1] = (float)((((i%6)+1) & 2)>>1); dl->color[1] = (float)((((i % 6) + 1) & 2) >> 1);
dl->color[2] = (float)((((i%6)+1) & 4)>>2); dl->color[2] = (float)((((i % 6) + 1) & 4) >> 2);
dl->intensity = 200; dl->intensity = 200;
} }
} }
@ -194,220 +226,279 @@ void V_TestLights (void) {
/* /*
* Call before entering a new level, or after changing dlls * Call before entering a new level, or after changing dlls
*/ */
void CL_PrepRefresh (void) { void
char mapname[32]; CL_PrepRefresh(void)
int i; {
char name[MAX_QPATH]; char mapname[32];
float rotate; int i;
vec3_t axis; char name[MAX_QPATH];
float rotate;
vec3_t axis;
if (!cl.configstrings[CS_MODELS+1][0]) if (!cl.configstrings[CS_MODELS + 1][0])
{
return; return;
}
SCR_AddDirtyPoint (0, 0); SCR_AddDirtyPoint(0, 0);
SCR_AddDirtyPoint (viddef.width-1, viddef.height-1); SCR_AddDirtyPoint(viddef.width - 1, viddef.height - 1);
/* let the refresher load the map */ /* let the refresher load the map */
strcpy (mapname, cl.configstrings[CS_MODELS+1] + 5); /* skip "maps/" */ strcpy(mapname, cl.configstrings[CS_MODELS + 1] + 5); /* skip "maps/" */
mapname[strlen(mapname)-4] = 0; /* cut off ".bsp" */ mapname[strlen(mapname) - 4] = 0; /* cut off ".bsp" */
/* register models, pics, and skins */ /* register models, pics, and skins */
Com_Printf ("Map: %s\r", mapname); Com_Printf("Map: %s\r", mapname);
SCR_UpdateScreen (); SCR_UpdateScreen();
re.BeginRegistration (mapname); re.BeginRegistration(mapname);
Com_Printf (" \r"); Com_Printf(" \r");
/* precache status bar pics */ /* precache status bar pics */
Com_Printf ("pics\r"); Com_Printf("pics\r");
SCR_UpdateScreen (); SCR_UpdateScreen();
SCR_TouchPics (); SCR_TouchPics();
Com_Printf (" \r"); Com_Printf(" \r");
CL_RegisterTEntModels (); CL_RegisterTEntModels();
num_cl_weaponmodels = 1; num_cl_weaponmodels = 1;
strcpy(cl_weaponmodels[0], "weapon.md2"); strcpy(cl_weaponmodels[0], "weapon.md2");
for (i=1 ; i<MAX_MODELS && cl.configstrings[CS_MODELS+i][0] ; i++) { for (i = 1; i < MAX_MODELS && cl.configstrings[CS_MODELS + i][0]; i++)
strcpy (name, cl.configstrings[CS_MODELS+i]); {
strcpy(name, cl.configstrings[CS_MODELS + i]);
name[37] = 0; /* never go beyond one line */ name[37] = 0; /* never go beyond one line */
if (name[0] != '*') if (name[0] != '*')
Com_Printf ("%s\r", name); {
Com_Printf("%s\r", name);
}
SCR_UpdateScreen (); SCR_UpdateScreen();
Sys_SendKeyEvents (); Sys_SendKeyEvents();
if (name[0] == '#') { if (name[0] == '#')
{
/* special player weapon model */ /* special player weapon model */
if (num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS) { if (num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS)
strncpy(cl_weaponmodels[num_cl_weaponmodels], cl.configstrings[CS_MODELS+i]+1, {
sizeof(cl_weaponmodels[num_cl_weaponmodels]) - 1); strncpy(cl_weaponmodels[num_cl_weaponmodels],
cl.configstrings[CS_MODELS + i] + 1,
sizeof(cl_weaponmodels[num_cl_weaponmodels]) - 1);
num_cl_weaponmodels++; num_cl_weaponmodels++;
} }
}
} else { else
cl.model_draw[i] = re.RegisterModel (cl.configstrings[CS_MODELS+i]); {
cl.model_draw[i] = re.RegisterModel(cl.configstrings[CS_MODELS + i]);
if (name[0] == '*') if (name[0] == '*')
cl.model_clip[i] = CM_InlineModel (cl.configstrings[CS_MODELS+i]); {
cl.model_clip[i] = CM_InlineModel(cl.configstrings[CS_MODELS + i]);
}
else else
{
cl.model_clip[i] = NULL; cl.model_clip[i] = NULL;
}
} }
if (name[0] != '*') if (name[0] != '*')
Com_Printf (" \r"); {
Com_Printf(" \r");
}
} }
Com_Printf ("images\r", i); Com_Printf("images\r", i);
SCR_UpdateScreen (); SCR_UpdateScreen();
for (i=1 ; i<MAX_IMAGES && cl.configstrings[CS_IMAGES+i][0] ; i++) { for (i = 1; i < MAX_IMAGES && cl.configstrings[CS_IMAGES + i][0]; i++)
cl.image_precache[i] = re.RegisterPic (cl.configstrings[CS_IMAGES+i]); {
Sys_SendKeyEvents (); cl.image_precache[i] = re.RegisterPic(cl.configstrings[CS_IMAGES + i]);
Sys_SendKeyEvents();
} }
Com_Printf (" \r"); Com_Printf(" \r");
for (i=0 ; i<MAX_CLIENTS ; i++) { for (i = 0; i < MAX_CLIENTS; i++)
if (!cl.configstrings[CS_PLAYERSKINS+i][0]) {
if (!cl.configstrings[CS_PLAYERSKINS + i][0])
{
continue; continue;
}
Com_Printf ("client %i\r", i); Com_Printf("client %i\r", i);
SCR_UpdateScreen (); SCR_UpdateScreen();
Sys_SendKeyEvents (); Sys_SendKeyEvents();
CL_ParseClientinfo (i); CL_ParseClientinfo(i);
Com_Printf (" \r"); Com_Printf(" \r");
} }
CL_LoadClientinfo (&cl.baseclientinfo, "unnamed\\male/grunt"); CL_LoadClientinfo(&cl.baseclientinfo, "unnamed\\male/grunt");
/* set sky textures and speed */ /* set sky textures and speed */
Com_Printf ("sky\r", i); Com_Printf("sky\r", i);
SCR_UpdateScreen (); SCR_UpdateScreen();
rotate = (float)strtod(cl.configstrings[CS_SKYROTATE], (char **)NULL); rotate = (float)strtod(cl.configstrings[CS_SKYROTATE], (char **)NULL);
sscanf (cl.configstrings[CS_SKYAXIS], "%f %f %f", sscanf(cl.configstrings[CS_SKYAXIS], "%f %f %f", &axis[0], &axis[1], &axis[2]);
&axis[0], &axis[1], &axis[2]); re.SetSky(cl.configstrings[CS_SKY], rotate, axis);
re.SetSky (cl.configstrings[CS_SKY], rotate, axis); Com_Printf(" \r");
Com_Printf (" \r");
/* the renderer can now free unneeded stuff */ /* the renderer can now free unneeded stuff */
re.EndRegistration (); re.EndRegistration();
/* clear any lines of console text */ /* clear any lines of console text */
Con_ClearNotify (); Con_ClearNotify();
SCR_UpdateScreen (); SCR_UpdateScreen();
cl.refresh_prepped = true; cl.refresh_prepped = true;
cl.force_refdef = true; /* make sure we have a valid refdef */ cl.force_refdef = true; /* make sure we have a valid refdef */
#if defined(OGG) || defined(CDA) #if defined(OGG) || defined(CDA)
/* start the cd track */
if (Cvar_VariableValue("cd_shuffle")) {
#ifdef CDA
CDAudio_RandomPlay();
#endif
} else {
#ifdef CDA
CDAudio_Play ((int)strtol(cl.configstrings[CS_CDTRACK], (char **)NULL, 10), true);
#endif
#ifdef OGG /* start the cd track */
if (Cvar_VariableValue("cd_shuffle"))
{
#ifdef CDA
CDAudio_RandomPlay();
#endif
}
else
{
#ifdef CDA
CDAudio_Play((int)strtol(cl.configstrings[CS_CDTRACK], (char **)NULL, 10), true);
#endif
#ifdef OGG
/* OGG/Vorbis */ /* OGG/Vorbis */
if ((int)strtol(cl.configstrings[CS_CDTRACK], (char **)NULL, 10) < 10) { if ((int)strtol(cl.configstrings[CS_CDTRACK], (char **)NULL, 10) < 10)
{
char tmp[3] = "0"; char tmp[3] = "0";
OGG_ParseCmd(strcat(tmp, cl.configstrings[CS_CDTRACK])); OGG_ParseCmd(strcat(tmp, cl.configstrings[CS_CDTRACK]));
}
} else { else
{
OGG_ParseCmd(cl.configstrings[CS_CDTRACK]); OGG_ParseCmd(cl.configstrings[CS_CDTRACK]);
} }
#endif
#endif
} }
#endif #endif
} }
float CalcFov (float fov_x, float width, float height) { float
float a; CalcFov(float fov_x, float width, float height)
float x; {
float a;
float x;
if (fov_x < 1 || fov_x > 179) if ((fov_x < 1) || (fov_x > 179))
Com_Error (ERR_DROP, "Bad fov: %f", fov_x); {
Com_Error(ERR_DROP, "Bad fov: %f", fov_x);
}
x = width/ (float)tan(fov_x/360*M_PI); x = width / (float)tan(fov_x / 360 * M_PI);
a = (float)atan(height/x); a = (float)atan(height / x);
a = a*360/M_PI; a = a * 360 / M_PI;
return a; return a;
} }
/* gun frame debugging functions */ /* gun frame debugging functions */
void V_Gun_Next_f (void) { void
V_Gun_Next_f(void)
{
gun_frame++; gun_frame++;
Com_Printf ("frame %i\n", gun_frame); Com_Printf("frame %i\n", gun_frame);
} }
void V_Gun_Prev_f (void) { void
V_Gun_Prev_f(void)
{
gun_frame--; gun_frame--;
if (gun_frame < 0) if (gun_frame < 0)
{
gun_frame = 0; gun_frame = 0;
}
Com_Printf ("frame %i\n", gun_frame); Com_Printf("frame %i\n", gun_frame);
} }
void V_Gun_Model_f (void) { void
char name[MAX_QPATH]; V_Gun_Model_f(void)
{
char name[MAX_QPATH];
if (Cmd_Argc() != 2) { if (Cmd_Argc() != 2)
{
gun_model = NULL; gun_model = NULL;
return; return;
} }
Com_sprintf (name, sizeof(name), "models/%s/tris.md2", Cmd_Argv(1)); Com_sprintf(name, sizeof(name), "models/%s/tris.md2", Cmd_Argv(1));
gun_model = re.RegisterModel (name); gun_model = re.RegisterModel(name);
} }
void V_RenderView( float stereo_separation ) { void
extern int entitycmpfnc( const entity_t *, const entity_t * ); V_RenderView(float stereo_separation)
{
extern int entitycmpfnc(const entity_t *, const entity_t *);
if (cls.state != ca_active) if (cls.state != ca_active)
{
return; return;
}
if (!cl.refresh_prepped) if (!cl.refresh_prepped)
{
return; return;
}
if (cl_timedemo->value) { if (cl_timedemo->value)
{
if (!cl.timedemo_start) if (!cl.timedemo_start)
cl.timedemo_start = Sys_Milliseconds (); {
cl.timedemo_start = Sys_Milliseconds();
}
cl.timedemo_frames++; cl.timedemo_frames++;
} }
/* an invalid frame will just use the exact previous refdef /* an invalid frame will just use the exact previous refdef
we can't use the old frame if the video mode has changed, though... */ we can't use the old frame if the video mode has changed, though... */
if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) ) { if (cl.frame.valid && (cl.force_refdef || !cl_paused->value))
{
cl.force_refdef = false; cl.force_refdef = false;
V_ClearScene (); V_ClearScene();
/* build a refresh entity list and calc cl.sim* /* build a refresh entity list and calc cl.sim*
this also calls CL_CalcViewValues which loads this also calls CL_CalcViewValues which loads
v_forward, etc. */ v_forward, etc. */
CL_AddEntities (); CL_AddEntities();
if (cl_testparticles->value) if (cl_testparticles->value)
V_TestParticles (); {
V_TestParticles();
}
if (cl_testentities->value) if (cl_testentities->value)
V_TestEntities (); {
V_TestEntities();
}
if (cl_testlights->value) if (cl_testlights->value)
V_TestLights (); {
V_TestLights();
}
if (cl_testblend->value) { if (cl_testblend->value)
{
cl.refdef.blend[0] = 1; cl.refdef.blend[0] = 1;
cl.refdef.blend[1] = 0.5; cl.refdef.blend[1] = 0.5;
cl.refdef.blend[2] = 0.25; cl.refdef.blend[2] = 0.25;
@ -416,40 +507,49 @@ void V_RenderView( float stereo_separation ) {
/* offset vieworg appropriately if /* offset vieworg appropriately if
we're doing stereo separation */ we're doing stereo separation */
if ( stereo_separation != 0 ) { if (stereo_separation != 0)
{
vec3_t tmp; vec3_t tmp;
VectorScale( cl.v_right, stereo_separation, tmp ); VectorScale(cl.v_right, stereo_separation, tmp);
VectorAdd( cl.refdef.vieworg, tmp, cl.refdef.vieworg ); VectorAdd(cl.refdef.vieworg, tmp, cl.refdef.vieworg);
} }
/* never let it sit exactly on a node line, because a water plane can /* never let it sit exactly on a node line, because a water plane can
dissapear when viewed with the eye exactly on it. dissapear when viewed with the eye exactly on it. the server protocol
the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis */ only specifies to 1/8 pixel, so add 1/16 in each axis */
cl.refdef.vieworg[0] += 1.0/16; cl.refdef.vieworg[0] += 1.0 / 16;
cl.refdef.vieworg[1] += 1.0/16; cl.refdef.vieworg[1] += 1.0 / 16;
cl.refdef.vieworg[2] += 1.0/16; cl.refdef.vieworg[2] += 1.0 / 16;
cl.refdef.x = scr_vrect.x; cl.refdef.x = scr_vrect.x;
cl.refdef.y = scr_vrect.y; cl.refdef.y = scr_vrect.y;
cl.refdef.width = scr_vrect.width; cl.refdef.width = scr_vrect.width;
cl.refdef.height = scr_vrect.height; cl.refdef.height = scr_vrect.height;
cl.refdef.fov_y = CalcFov (cl.refdef.fov_x, (float)cl.refdef.width, (float)cl.refdef.height); cl.refdef.fov_y = CalcFov(cl.refdef.fov_x, (float)cl.refdef.width,
cl.refdef.time = cl.time*0.001f; (float)cl.refdef.height);
cl.refdef.time = cl.time * 0.001f;
cl.refdef.areabits = cl.frame.areabits; cl.refdef.areabits = cl.frame.areabits;
if (!cl_add_entities->value) if (!cl_add_entities->value)
{
r_numentities = 0; r_numentities = 0;
}
if (!cl_add_particles->value) if (!cl_add_particles->value)
{
r_numparticles = 0; r_numparticles = 0;
}
if (!cl_add_lights->value) if (!cl_add_lights->value)
{
r_numdlights = 0; r_numdlights = 0;
}
if (!cl_add_blend->value) { if (!cl_add_blend->value)
VectorClear (cl.refdef.blend); {
VectorClear(cl.refdef.blend);
} }
cl.refdef.num_entities = r_numentities; cl.refdef.num_entities = r_numentities;
@ -463,44 +563,56 @@ void V_RenderView( float stereo_separation ) {
cl.refdef.rdflags = cl.frame.playerstate.rdflags; cl.refdef.rdflags = cl.frame.playerstate.rdflags;
/* sort entities for better cache locality */ /* sort entities for better cache locality */
qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int (*)(const void *, const void *))entitycmpfnc ); qsort(cl.refdef.entities, cl.refdef.num_entities,
sizeof(cl.refdef.entities[0]), (int (*)(const void *, const void *))
entitycmpfnc);
} }
re.RenderFrame (&cl.refdef); re.RenderFrame(&cl.refdef);
if (cl_stats->value) if (cl_stats->value)
Com_Printf ("ent:%i lt:%i part:%i\n", r_numentities, r_numdlights, r_numparticles); {
Com_Printf("ent:%i lt:%i part:%i\n", r_numentities,
r_numdlights, r_numparticles);
}
if ( log_stats->value && ( log_stats_file != 0 ) ) if (log_stats->value && (log_stats_file != 0))
fprintf( log_stats_file, "%i,%i,%i,",r_numentities, r_numdlights, r_numparticles); {
fprintf(log_stats_file, "%i,%i,%i,", r_numentities,
r_numdlights, r_numparticles);
}
SCR_AddDirtyPoint(scr_vrect.x, scr_vrect.y);
SCR_AddDirtyPoint(scr_vrect.x + scr_vrect.width - 1,
scr_vrect.y + scr_vrect.height - 1);
SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y); SCR_DrawCrosshair();
SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,
scr_vrect.y+scr_vrect.height-1);
SCR_DrawCrosshair ();
} }
void V_Viewpos_f (void) { void
Com_Printf ("(%i %i %i) : %i\n", (int)cl.refdef.vieworg[0], V_Viewpos_f(void)
(int)cl.refdef.vieworg[1], (int)cl.refdef.vieworg[2], {
(int)cl.refdef.viewangles[YAW]); Com_Printf("(%i %i %i) : %i\n", (int)cl.refdef.vieworg[0],
(int)cl.refdef.vieworg[1], (int)cl.refdef.vieworg[2],
(int)cl.refdef.viewangles[YAW]);
} }
void V_Init (void) { void
Cmd_AddCommand ("gun_next", V_Gun_Next_f); V_Init(void)
Cmd_AddCommand ("gun_prev", V_Gun_Prev_f); {
Cmd_AddCommand ("gun_model", V_Gun_Model_f); Cmd_AddCommand("gun_next", V_Gun_Next_f);
Cmd_AddCommand("gun_prev", V_Gun_Prev_f);
Cmd_AddCommand("gun_model", V_Gun_Model_f);
Cmd_AddCommand ("viewpos", V_Viewpos_f); Cmd_AddCommand("viewpos", V_Viewpos_f);
crosshair = Cvar_Get ("crosshair", "0", CVAR_ARCHIVE); crosshair = Cvar_Get("crosshair", "0", CVAR_ARCHIVE);
crosshair_scale = Cvar_Get ("crosshair_scale", "1", CVAR_ARCHIVE); crosshair_scale = Cvar_Get("crosshair_scale", "1", CVAR_ARCHIVE);
cl_testblend = Cvar_Get ("cl_testblend", "0", 0); cl_testblend = Cvar_Get("cl_testblend", "0", 0);
cl_testparticles = Cvar_Get ("cl_testparticles", "0", 0); cl_testparticles = Cvar_Get("cl_testparticles", "0", 0);
cl_testentities = Cvar_Get ("cl_testentities", "0", 0); cl_testentities = Cvar_Get("cl_testentities", "0", 0);
cl_testlights = Cvar_Get ("cl_testlights", "0", 0); cl_testlights = Cvar_Get("cl_testlights", "0", 0);
cl_stats = Cvar_Get ("cl_stats", "0", 0); cl_stats = Cvar_Get("cl_stats", "0", 0);
} }

View file

@ -27,61 +27,64 @@
#ifndef CL_MENU_QMENU_H #ifndef CL_MENU_QMENU_H
#define CL_MENU_QMENU_H #define CL_MENU_QMENU_H
#define MAXMENUITEMS 64 #define MAXMENUITEMS 64
#define MTYPE_SLIDER 0 #define MTYPE_SLIDER 0
#define MTYPE_LIST 1 #define MTYPE_LIST 1
#define MTYPE_ACTION 2 #define MTYPE_ACTION 2
#define MTYPE_SPINCONTROL 3 #define MTYPE_SPINCONTROL 3
#define MTYPE_SEPARATOR 4 #define MTYPE_SEPARATOR 4
#define MTYPE_FIELD 5 #define MTYPE_FIELD 5
#define QMF_LEFT_JUSTIFY 0x00000001 #define QMF_LEFT_JUSTIFY 0x00000001
#define QMF_GRAYED 0x00000002 #define QMF_GRAYED 0x00000002
#define QMF_NUMBERSONLY 0x00000004 #define QMF_NUMBERSONLY 0x00000004
typedef struct _tag_menuframework { typedef struct _tag_menuframework
{
int x, y; int x, y;
int cursor; int cursor;
int nitems; int nitems;
int nslots; int nslots;
void *items[64]; void *items[64];
const char *statusbar; const char *statusbar;
void (*cursordraw)( struct _tag_menuframework *m ); void (*cursordraw)(struct _tag_menuframework *m);
} menuframework_s; } menuframework_s;
typedef struct { typedef struct
{
int type; int type;
const char *name; const char *name;
int x, y; int x, y;
menuframework_s *parent; menuframework_s *parent;
int cursor_offset; int cursor_offset;
int localdata[4]; int localdata[4];
unsigned flags; unsigned flags;
const char *statusbar; const char *statusbar;
void (*callback)( void *self ); void (*callback)(void *self);
void (*statusbarfunc)( void *self ); void (*statusbarfunc)(void *self);
void (*ownerdraw)( void *self ); void (*ownerdraw)(void *self);
void (*cursordraw)( void *self ); void (*cursordraw)(void *self);
} menucommon_s; } menucommon_s;
typedef struct { typedef struct
{
menucommon_s generic; menucommon_s generic;
char buffer[80]; char buffer[80];
int cursor; int cursor;
int length; int length;
int visible_length; int visible_length;
int visible_offset; int visible_offset;
} menufield_s; } menufield_s;
typedef struct { typedef struct
{
menucommon_s generic; menucommon_s generic;
float minvalue; float minvalue;
@ -91,7 +94,8 @@ typedef struct {
float range; float range;
} menuslider_s; } menuslider_s;
typedef struct { typedef struct
{
menucommon_s generic; menucommon_s generic;
int curvalue; int curvalue;
@ -99,29 +103,31 @@ typedef struct {
const char **itemnames; const char **itemnames;
} menulist_s; } menulist_s;
typedef struct { typedef struct
{
menucommon_s generic; menucommon_s generic;
} menuaction_s; } menuaction_s;
typedef struct { typedef struct
{
menucommon_s generic; menucommon_s generic;
} menuseparator_s; } menuseparator_s;
qboolean Field_Key( menufield_s *field, int key ); qboolean Field_Key(menufield_s *field, int key);
void Menu_AddItem( menuframework_s *menu, void *item ); void Menu_AddItem(menuframework_s *menu, void *item);
void Menu_AdjustCursor( menuframework_s *menu, int dir ); void Menu_AdjustCursor(menuframework_s *menu, int dir);
void Menu_Center( menuframework_s *menu ); void Menu_Center(menuframework_s *menu);
void Menu_Draw( menuframework_s *menu ); void Menu_Draw(menuframework_s *menu);
void *Menu_ItemAtCursor( menuframework_s *m ); void *Menu_ItemAtCursor(menuframework_s *m);
qboolean Menu_SelectItem( menuframework_s *s ); qboolean Menu_SelectItem(menuframework_s *s);
void Menu_SetStatusBar( menuframework_s *s, const char *string ); void Menu_SetStatusBar(menuframework_s *s, const char *string);
void Menu_SlideItem( menuframework_s *s, int dir ); void Menu_SlideItem(menuframework_s *s, int dir);
int Menu_TallySlots( menuframework_s *menu ); int Menu_TallySlots(menuframework_s *menu);
void Menu_DrawString( int, int, const char * ); void Menu_DrawString(int, int, const char *);
void Menu_DrawStringDark( int, int, const char * ); void Menu_DrawStringDark(int, int, const char *);
void Menu_DrawStringR2L( int, int, const char * ); void Menu_DrawStringR2L(int, int, const char *);
void Menu_DrawStringR2LDark( int, int, const char * ); void Menu_DrawStringR2LDark(int, int, const char *);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -29,109 +29,164 @@
#include "../header/client.h" #include "../header/client.h"
#include "header/qmenu.h" #include "header/qmenu.h"
static void Action_DoEnter( menuaction_s *a ); static void Action_DoEnter(menuaction_s *a);
static void Action_Draw( menuaction_s *a ); static void Action_Draw(menuaction_s *a);
static void Menu_DrawStatusBar( const char *string ); static void Menu_DrawStatusBar(const char *string);
static void MenuList_Draw( menulist_s *l ); static void MenuList_Draw(menulist_s *l);
static void Separator_Draw( menuseparator_s *s ); static void Separator_Draw(menuseparator_s *s);
static void Slider_DoSlide( menuslider_s *s, int dir ); static void Slider_DoSlide(menuslider_s *s, int dir);
static void Slider_Draw( menuslider_s *s ); static void Slider_Draw(menuslider_s *s);
static void SpinControl_Draw( menulist_s *s ); static void SpinControl_Draw(menulist_s *s);
static void SpinControl_DoSlide( menulist_s *s, int dir ); static void SpinControl_DoSlide(menulist_s *s, int dir);
#define RCOLUMN_OFFSET 16 #define RCOLUMN_OFFSET 16
#define LCOLUMN_OFFSET -16 #define LCOLUMN_OFFSET -16
extern refexport_t re; extern refexport_t re;
extern viddef_t viddef; extern viddef_t viddef;
#define VID_WIDTH viddef.width #define VID_WIDTH viddef.width
#define VID_HEIGHT viddef.height #define VID_HEIGHT viddef.height
#define Draw_Char re.DrawChar #define Draw_Char re.DrawChar
#define Draw_Fill re.DrawFill #define Draw_Fill re.DrawFill
void Action_DoEnter( menuaction_s *a ) { void
if ( a->generic.callback ) Action_DoEnter(menuaction_s *a)
a->generic.callback( a ); {
if (a->generic.callback)
{
a->generic.callback(a);
}
} }
void Action_Draw( menuaction_s *a ) { void
if ( a->generic.flags & QMF_LEFT_JUSTIFY ) { Action_Draw(menuaction_s *a)
if ( a->generic.flags & QMF_GRAYED ) {
Menu_DrawStringDark( a->generic.x + a->generic.parent->x + LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y, a->generic.name ); if (a->generic.flags & QMF_LEFT_JUSTIFY)
{
if (a->generic.flags & QMF_GRAYED)
{
Menu_DrawStringDark(a->generic.x + a->generic.parent->x +
LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y,
a->generic.name);
}
else else
Menu_DrawString( a->generic.x + a->generic.parent->x + LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y, a->generic.name ); {
Menu_DrawString(a->generic.x + a->generic.parent->x +
} else { LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y,
if ( a->generic.flags & QMF_GRAYED ) a->generic.name);
Menu_DrawStringR2LDark( a->generic.x + a->generic.parent->x + LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y, a->generic.name ); }
}
else
{
if (a->generic.flags & QMF_GRAYED)
{
Menu_DrawStringR2LDark(a->generic.x + a->generic.parent->x +
LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y,
a->generic.name);
}
else else
Menu_DrawStringR2L( a->generic.x + a->generic.parent->x + LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y, a->generic.name ); {
Menu_DrawStringR2L(a->generic.x + a->generic.parent->x +
LCOLUMN_OFFSET, a->generic.y + a->generic.parent->y,
a->generic.name);
}
} }
if ( a->generic.ownerdraw ) if (a->generic.ownerdraw)
a->generic.ownerdraw( a ); {
a->generic.ownerdraw(a);
}
} }
qboolean Field_DoEnter( menufield_s *f ) { qboolean
if ( f->generic.callback ) { Field_DoEnter(menufield_s *f)
f->generic.callback( f ); {
if (f->generic.callback)
{
f->generic.callback(f);
return true; return true;
} }
return false; return false;
} }
void Field_Draw( menufield_s *f ) { void
Field_Draw(menufield_s *f)
{
int i; int i;
char tempbuffer[128]=""; char tempbuffer[128] = "";
if ( f->generic.name ) if (f->generic.name)
Menu_DrawStringR2LDark( f->generic.x + f->generic.parent->x + LCOLUMN_OFFSET, f->generic.y + f->generic.parent->y, f->generic.name ); {
Menu_DrawStringR2LDark(f->generic.x + f->generic.parent->x +
strncpy( tempbuffer, f->buffer + f->visible_offset, f->visible_length ); LCOLUMN_OFFSET, f->generic.y + f->generic.parent->y,
f->generic.name);
Draw_Char( f->generic.x + f->generic.parent->x + 16, f->generic.y + f->generic.parent->y - 4, 18 );
Draw_Char( f->generic.x + f->generic.parent->x + 16, f->generic.y + f->generic.parent->y + 4, 24 );
Draw_Char( f->generic.x + f->generic.parent->x + 24 + f->visible_length * 8, f->generic.y + f->generic.parent->y - 4, 20 );
Draw_Char( f->generic.x + f->generic.parent->x + 24 + f->visible_length * 8, f->generic.y + f->generic.parent->y + 4, 26 );
for ( i = 0; i < f->visible_length; i++ ) {
Draw_Char( f->generic.x + f->generic.parent->x + 24 + i * 8, f->generic.y + f->generic.parent->y - 4, 19 );
Draw_Char( f->generic.x + f->generic.parent->x + 24 + i * 8, f->generic.y + f->generic.parent->y + 4, 25 );
} }
Menu_DrawString( f->generic.x + f->generic.parent->x + 24, f->generic.y + f->generic.parent->y, tempbuffer ); strncpy(tempbuffer, f->buffer + f->visible_offset, f->visible_length);
if ( Menu_ItemAtCursor( f->generic.parent ) == f ) { Draw_Char(f->generic.x + f->generic.parent->x + 16,
f->generic.y + f->generic.parent->y - 4, 18);
Draw_Char(f->generic.x + f->generic.parent->x + 16,
f->generic.y + f->generic.parent->y + 4, 24);
Draw_Char(f->generic.x + f->generic.parent->x + 24 +
f->visible_length * 8, f->generic.y +
f->generic.parent->y - 4, 20);
Draw_Char(f->generic.x + f->generic.parent->x + 24 +
f->visible_length * 8, f->generic.y +
f->generic.parent->y + 4, 26);
for (i = 0; i < f->visible_length; i++)
{
Draw_Char(f->generic.x + f->generic.parent->x + 24 + i * 8,
f->generic.y + f->generic.parent->y - 4, 19);
Draw_Char(f->generic.x + f->generic.parent->x + 24 + i * 8,
f->generic.y + f->generic.parent->y + 4, 25);
}
Menu_DrawString(f->generic.x + f->generic.parent->x + 24,
f->generic.y + f->generic.parent->y, tempbuffer);
if (Menu_ItemAtCursor(f->generic.parent) == f)
{
int offset; int offset;
if ( f->visible_offset ) if (f->visible_offset)
{
offset = f->visible_length; offset = f->visible_length;
}
else else
{
offset = f->cursor; offset = f->cursor;
}
if ( ( ( int ) ( Sys_Milliseconds() / 250 ) ) & 1 ) { if (((int)(Sys_Milliseconds() / 250)) & 1)
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8, {
f->generic.y + f->generic.parent->y, Draw_Char(f->generic.x + f->generic.parent->x +
11 ); (offset + 2) * 8 + 8, f->generic.y +
f->generic.parent->y, 11);
} else { }
Draw_Char( f->generic.x + f->generic.parent->x + ( offset + 2 ) * 8 + 8, else
f->generic.y + f->generic.parent->y, {
' ' ); Draw_Char(f->generic.x + f->generic.parent->x +
(offset + 2) * 8 + 8, f->generic.y +
f->generic.parent->y, ' ');
} }
} }
} }
extern int keydown[]; extern int keydown[];
qboolean Field_Key( menufield_s *f, int key ) { qboolean
switch ( key ) { Field_Key(menufield_s *f, int key)
{
switch (key)
{
case K_KP_SLASH: case K_KP_SLASH:
key = '/'; key = '/';
break; break;
@ -176,24 +231,31 @@ qboolean Field_Key( menufield_s *f, int key ) {
break; break;
} }
if ( key > 127 ) { if (key > 127)
switch ( key ) { {
switch (key)
{
case K_DEL: case K_DEL:
default: default:
return false; return false;
} }
} }
switch ( key ) { switch (key)
{
case K_KP_LEFTARROW: case K_KP_LEFTARROW:
case K_LEFTARROW: case K_LEFTARROW:
case K_BACKSPACE: case K_BACKSPACE:
if ( f->cursor > 0 ) { if (f->cursor > 0)
memmove( &f->buffer[f->cursor-1], &f->buffer[f->cursor], strlen( &f->buffer[f->cursor] ) + 1 ); {
memmove(&f->buffer[f->cursor - 1],
&f->buffer[f->cursor],
strlen(&f->buffer[f->cursor]) + 1);
f->cursor--; f->cursor--;
if ( f->visible_offset ) { if (f->visible_offset)
{
f->visible_offset--; f->visible_offset--;
} }
} }
@ -202,7 +264,8 @@ qboolean Field_Key( menufield_s *f, int key ) {
case K_KP_DEL: case K_KP_DEL:
case K_DEL: case K_DEL:
memmove( &f->buffer[f->cursor], &f->buffer[f->cursor+1], strlen( &f->buffer[f->cursor+1] ) + 1 ); memmove(&f->buffer[f->cursor], &f->buffer[f->cursor + 1],
strlen(&f->buffer[f->cursor + 1]) + 1);
break; break;
case K_KP_ENTER: case K_KP_ENTER:
@ -214,14 +277,18 @@ qboolean Field_Key( menufield_s *f, int key ) {
case K_SPACE: case K_SPACE:
default: default:
if ( !isdigit( key ) && ( f->generic.flags & QMF_NUMBERSONLY ) ) if (!isdigit(key) && (f->generic.flags & QMF_NUMBERSONLY))
{
return false; return false;
}
if ( f->cursor < f->length ) { if (f->cursor < f->length)
{
f->buffer[f->cursor++] = key; f->buffer[f->cursor++] = key;
f->buffer[f->cursor] = 0; f->buffer[f->cursor] = 0;
if ( f->cursor > f->visible_length ) { if (f->cursor > f->visible_length)
{
f->visible_offset++; f->visible_offset++;
} }
} }
@ -230,17 +297,22 @@ qboolean Field_Key( menufield_s *f, int key ) {
return true; return true;
} }
void Menu_AddItem( menuframework_s *menu, void *item ) { void
if ( menu->nitems == 0 ) Menu_AddItem(menuframework_s *menu, void *item)
{
if (menu->nitems == 0)
{
menu->nslots = 0; menu->nslots = 0;
}
if ( menu->nitems < MAXMENUITEMS ) { if (menu->nitems < MAXMENUITEMS)
{
menu->items[menu->nitems] = item; menu->items[menu->nitems] = item;
( ( menucommon_s * ) menu->items[menu->nitems] )->parent = menu; ((menucommon_s *)menu->items[menu->nitems])->parent = menu;
menu->nitems++; menu->nitems++;
} }
menu->nslots = Menu_TallySlots( menu ); menu->nslots = Menu_TallySlots(menu);
} }
/* /*
@ -248,180 +320,248 @@ void Menu_AddItem( menuframework_s *menu, void *item ) {
* to adjust the menu's cursor so that it's at the next available * to adjust the menu's cursor so that it's at the next available
* slot. * slot.
*/ */
void Menu_AdjustCursor( menuframework_s *m, int dir ) { void
Menu_AdjustCursor(menuframework_s *m, int dir)
{
menucommon_s *citem; menucommon_s *citem;
/* see if it's in a valid spot */ /* see if it's in a valid spot */
if ( m->cursor >= 0 && m->cursor < m->nitems ) { if ((m->cursor >= 0) && (m->cursor < m->nitems))
if ( ( citem = Menu_ItemAtCursor( m ) ) != 0 ) { {
if ( citem->type != MTYPE_SEPARATOR ) if ((citem = Menu_ItemAtCursor(m)) != 0)
{
if (citem->type != MTYPE_SEPARATOR)
{
return; return;
}
} }
} }
/* it's not in a valid spot, so crawl in the direction /* it's not in a valid spot, so crawl in the direction
indicated until we find a valid spot */ indicated until we find a valid spot */
if ( dir == 1 ) { if (dir == 1)
while ( 1 ) { {
citem = Menu_ItemAtCursor( m ); while (1)
{
citem = Menu_ItemAtCursor(m);
if ( citem ) if (citem)
if ( citem->type != MTYPE_SEPARATOR ) {
if (citem->type != MTYPE_SEPARATOR)
{
break; break;
}
}
m->cursor += dir; m->cursor += dir;
if ( m->cursor >= m->nitems ) if (m->cursor >= m->nitems)
{
m->cursor = 0; m->cursor = 0;
}
} }
}
else
{
while (1)
{
citem = Menu_ItemAtCursor(m);
} else { if (citem)
while ( 1 ) { {
citem = Menu_ItemAtCursor( m ); if (citem->type != MTYPE_SEPARATOR)
{
if ( citem )
if ( citem->type != MTYPE_SEPARATOR )
break; break;
}
}
m->cursor += dir; m->cursor += dir;
if ( m->cursor < 0 ) if (m->cursor < 0)
{
m->cursor = m->nitems - 1; m->cursor = m->nitems - 1;
}
} }
} }
} }
void Menu_Center( menuframework_s *menu ) { void
Menu_Center(menuframework_s *menu)
{
int height; int height;
height = ( ( menucommon_s * ) menu->items[menu->nitems-1])->y; height = ((menucommon_s *)menu->items[menu->nitems - 1])->y;
height += 10; height += 10;
menu->y = ( VID_HEIGHT - height ) / 2; menu->y = (VID_HEIGHT - height) / 2;
} }
void Menu_Draw( menuframework_s *menu ) { void
Menu_Draw(menuframework_s *menu)
{
int i; int i;
menucommon_s *item; menucommon_s *item;
/* draw contents */ /* draw contents */
for ( i = 0; i < menu->nitems; i++ ) { for (i = 0; i < menu->nitems; i++)
switch ( ( ( menucommon_s * ) menu->items[i] )->type ) { {
switch (((menucommon_s *)menu->items[i])->type)
{
case MTYPE_FIELD: case MTYPE_FIELD:
Field_Draw( ( menufield_s * ) menu->items[i] ); Field_Draw((menufield_s *)menu->items[i]);
break; break;
case MTYPE_SLIDER: case MTYPE_SLIDER:
Slider_Draw( ( menuslider_s * ) menu->items[i] ); Slider_Draw((menuslider_s *)menu->items[i]);
break; break;
case MTYPE_LIST: case MTYPE_LIST:
MenuList_Draw( ( menulist_s * ) menu->items[i] ); MenuList_Draw((menulist_s *)menu->items[i]);
break; break;
case MTYPE_SPINCONTROL: case MTYPE_SPINCONTROL:
SpinControl_Draw( ( menulist_s * ) menu->items[i] ); SpinControl_Draw((menulist_s *)menu->items[i]);
break; break;
case MTYPE_ACTION: case MTYPE_ACTION:
Action_Draw( ( menuaction_s * ) menu->items[i] ); Action_Draw((menuaction_s *)menu->items[i]);
break; break;
case MTYPE_SEPARATOR: case MTYPE_SEPARATOR:
Separator_Draw( ( menuseparator_s * ) menu->items[i] ); Separator_Draw((menuseparator_s *)menu->items[i]);
break; break;
} }
} }
item = Menu_ItemAtCursor( menu ); item = Menu_ItemAtCursor(menu);
if ( item && item->cursordraw ) { if (item && item->cursordraw)
item->cursordraw( item ); {
item->cursordraw(item);
} else if ( menu->cursordraw ) { }
menu->cursordraw( menu ); else if (menu->cursordraw)
{
} else if ( item && item->type != MTYPE_FIELD ) { menu->cursordraw(menu);
if ( item->flags & QMF_LEFT_JUSTIFY ) { }
Draw_Char( menu->x + item->x - 24 + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) ); else if (item && (item->type != MTYPE_FIELD))
{
} else { if (item->flags & QMF_LEFT_JUSTIFY)
Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) ); {
Draw_Char(menu->x + item->x - 24 + item->cursor_offset,
menu->y + item->y, 12 + ((int)(Sys_Milliseconds() /
250) & 1));
}
else
{
Draw_Char(menu->x + item->cursor_offset, menu->y + item->y,
12 + ((int)(Sys_Milliseconds() / 250) & 1));
} }
} }
if ( item ) { if (item)
if ( item->statusbarfunc ) {
item->statusbarfunc( ( void * ) item ); if (item->statusbarfunc)
{
item->statusbarfunc((void *)item);
}
else if ( item->statusbar ) else if (item->statusbar)
Menu_DrawStatusBar( item->statusbar ); {
Menu_DrawStatusBar(item->statusbar);
}
else else
Menu_DrawStatusBar( menu->statusbar ); {
Menu_DrawStatusBar(menu->statusbar);
} else { }
Menu_DrawStatusBar( menu->statusbar ); }
else
{
Menu_DrawStatusBar(menu->statusbar);
} }
} }
void Menu_DrawStatusBar( const char *string ) { void
if ( string ) { Menu_DrawStatusBar(const char *string)
int l = (int)strlen( string ); {
if (string)
{
int l = (int)strlen(string);
int maxcol = VID_WIDTH / 8; int maxcol = VID_WIDTH / 8;
int col = maxcol / 2 - l / 2; int col = maxcol / 2 - l / 2;
Draw_Fill( 0, VID_HEIGHT-8, VID_WIDTH, 8, 4 ); Draw_Fill(0, VID_HEIGHT - 8, VID_WIDTH, 8, 4);
Menu_DrawString( col*8, VID_HEIGHT - 8, string ); Menu_DrawString(col * 8, VID_HEIGHT - 8, string);
}
} else { else
Draw_Fill( 0, VID_HEIGHT-8, VID_WIDTH, 8, 0 ); {
Draw_Fill(0, VID_HEIGHT - 8, VID_WIDTH, 8, 0);
} }
} }
void Menu_DrawString( int x, int y, const char *string ) { void
Menu_DrawString(int x, int y, const char *string)
{
unsigned i; unsigned i;
for ( i = 0; i < strlen( string ); i++ ) { for (i = 0; i < strlen(string); i++)
Draw_Char( ( x + i*8 ), y, string[i] ); {
Draw_Char((x + i * 8), y, string[i]);
} }
} }
void Menu_DrawStringDark( int x, int y, const char *string ) { void
Menu_DrawStringDark(int x, int y, const char *string)
{
unsigned i; unsigned i;
for ( i = 0; i < strlen( string ); i++ ) { for (i = 0; i < strlen(string); i++)
Draw_Char( ( x + i*8 ), y, string[i] + 128 ); {
Draw_Char((x + i * 8), y, string[i] + 128);
} }
} }
void Menu_DrawStringR2L( int x, int y, const char *string ) { void
Menu_DrawStringR2L(int x, int y, const char *string)
{
unsigned i; unsigned i;
for ( i = 0; i < strlen( string ); i++ ) { for (i = 0; i < strlen(string); i++)
Draw_Char( ( x - i*8 ), y, string[strlen(string)-i-1] ); {
Draw_Char((x - i * 8), y, string[strlen(string) - i - 1]);
} }
} }
void Menu_DrawStringR2LDark( int x, int y, const char *string ) { void
Menu_DrawStringR2LDark(int x, int y, const char *string)
{
unsigned i; unsigned i;
for ( i = 0; i < strlen( string ); i++ ) { for (i = 0; i < strlen(string); i++)
Draw_Char( ( x - i*8 ), y, string[strlen(string)-i-1]+128 ); {
Draw_Char((x - i * 8), y, string[strlen(string) - i - 1] + 128);
} }
} }
void *Menu_ItemAtCursor( menuframework_s *m ) { void *
if ( m->cursor < 0 || m->cursor >= m->nitems ) Menu_ItemAtCursor(menuframework_s *m)
{
if ((m->cursor < 0) || (m->cursor >= m->nitems))
{
return 0; return 0;
}
return m->items[m->cursor]; return m->items[m->cursor];
} }
qboolean Menu_SelectItem( menuframework_s *s ) { qboolean
menucommon_s *item = ( menucommon_s * ) Menu_ItemAtCursor( s ); Menu_SelectItem(menuframework_s *s)
{
menucommon_s *item = (menucommon_s *)Menu_ItemAtCursor(s);
if ( item ) { if (item)
switch ( item->type ) { {
switch (item->type)
{
case MTYPE_FIELD: case MTYPE_FIELD:
return Field_DoEnter( ( menufield_s * ) item ) ; return Field_DoEnter((menufield_s *)item);
case MTYPE_ACTION: case MTYPE_ACTION:
Action_DoEnter( ( menuaction_s * ) item ); Action_DoEnter((menuaction_s *)item);
return true; return true;
case MTYPE_LIST: case MTYPE_LIST:
return false; return false;
@ -433,40 +573,53 @@ qboolean Menu_SelectItem( menuframework_s *s ) {
return false; return false;
} }
void Menu_SetStatusBar( menuframework_s *m, const char *string ) { void
Menu_SetStatusBar(menuframework_s *m, const char *string)
{
m->statusbar = string; m->statusbar = string;
} }
void Menu_SlideItem( menuframework_s *s, int dir ) { void
menucommon_s *item = ( menucommon_s * ) Menu_ItemAtCursor( s ); Menu_SlideItem(menuframework_s *s, int dir)
{
menucommon_s *item = (menucommon_s *)Menu_ItemAtCursor(s);
if ( item ) { if (item)
switch ( item->type ) { {
switch (item->type)
{
case MTYPE_SLIDER: case MTYPE_SLIDER:
Slider_DoSlide( ( menuslider_s * ) item, dir ); Slider_DoSlide((menuslider_s *)item, dir);
break; break;
case MTYPE_SPINCONTROL: case MTYPE_SPINCONTROL:
SpinControl_DoSlide( ( menulist_s * ) item, dir ); SpinControl_DoSlide((menulist_s *)item, dir);
break; break;
} }
} }
} }
int Menu_TallySlots( menuframework_s *menu ) { int
Menu_TallySlots(menuframework_s *menu)
{
int i; int i;
int total = 0; int total = 0;
for ( i = 0; i < menu->nitems; i++ ) { for (i = 0; i < menu->nitems; i++)
if ( ( ( menucommon_s * ) menu->items[i] )->type == MTYPE_LIST ) { {
if (((menucommon_s *)menu->items[i])->type == MTYPE_LIST)
{
int nitems = 0; int nitems = 0;
const char **n = ( ( menulist_s * ) menu->items[i] )->itemnames; const char **n = ((menulist_s *)menu->items[i])->itemnames;
while (*n) while (*n)
{
nitems++, n++; nitems++, n++;
}
total += nitems; total += nitems;
}
} else { else
{
total++; total++;
} }
} }
@ -474,98 +627,160 @@ int Menu_TallySlots( menuframework_s *menu ) {
return total; return total;
} }
void MenuList_Draw( menulist_s *l ) { void
MenuList_Draw(menulist_s *l)
{
const char **n; const char **n;
int y = 0; int y = 0;
Menu_DrawStringR2LDark( l->generic.x + l->generic.parent->x + LCOLUMN_OFFSET, l->generic.y + l->generic.parent->y, l->generic.name ); Menu_DrawStringR2LDark(l->generic.x + l->generic.parent->x
+ LCOLUMN_OFFSET, l->generic.y + l->generic.parent->y,
l->generic.name);
n = l->itemnames; n = l->itemnames;
Draw_Fill( l->generic.x - 112 + l->generic.parent->x, l->generic.parent->y + l->generic.y + l->curvalue*10 + 10, 128, 10, 16 ); Draw_Fill(l->generic.x - 112 + l->generic.parent->x,
l->generic.parent->y + l->generic.y +
l->curvalue * 10 + 10, 128, 10, 16);
while ( *n ) { while (*n)
Menu_DrawStringR2LDark( l->generic.x + l->generic.parent->x + LCOLUMN_OFFSET, l->generic.y + l->generic.parent->y + y + 10, *n ); {
Menu_DrawStringR2LDark(l->generic.x + l->generic.parent->x +
LCOLUMN_OFFSET, l->generic.y + l->generic.parent->y +
y + 10, *n);
n++; n++;
y += 10; y += 10;
} }
} }
void Separator_Draw( menuseparator_s *s ) { void
if ( s->generic.name ) Separator_Draw(menuseparator_s *s)
Menu_DrawStringR2LDark( s->generic.x + s->generic.parent->x, s->generic.y + s->generic.parent->y, s->generic.name ); {
if (s->generic.name)
{
Menu_DrawStringR2LDark(s->generic.x + s->generic.parent->x,
s->generic.y + s->generic.parent->y,
s->generic.name);
}
} }
void Slider_DoSlide( menuslider_s *s, int dir ) { void
Slider_DoSlide(menuslider_s *s, int dir)
{
s->curvalue += dir; s->curvalue += dir;
if ( s->curvalue > s->maxvalue ) if (s->curvalue > s->maxvalue)
{
s->curvalue = s->maxvalue; s->curvalue = s->maxvalue;
}
else if ( s->curvalue < s->minvalue ) else if (s->curvalue < s->minvalue)
{
s->curvalue = s->minvalue; s->curvalue = s->minvalue;
}
if ( s->generic.callback ) if (s->generic.callback)
s->generic.callback( s ); {
s->generic.callback(s);
}
} }
#define SLIDER_RANGE 10 #define SLIDER_RANGE 10
void Slider_Draw( menuslider_s *s ) { void
int i; Slider_Draw(menuslider_s *s)
{
int i;
Menu_DrawStringR2LDark( s->generic.x + s->generic.parent->x + LCOLUMN_OFFSET, Menu_DrawStringR2LDark(s->generic.x + s->generic.parent->x +
s->generic.y + s->generic.parent->y, LCOLUMN_OFFSET, s->generic.y + s->generic.parent->y,
s->generic.name ); s->generic.name);
s->range = ( s->curvalue - s->minvalue ) / ( float ) ( s->maxvalue - s->minvalue ); s->range = (s->curvalue - s->minvalue) /
(float)(s->maxvalue - s->minvalue);
if ( s->range < 0) if (s->range < 0)
{
s->range = 0; s->range = 0;
}
if ( s->range > 1) if (s->range > 1)
{
s->range = 1; s->range = 1;
}
Draw_Char( s->generic.x + s->generic.parent->x + RCOLUMN_OFFSET, s->generic.y + s->generic.parent->y, 128); Draw_Char(s->generic.x + s->generic.parent->x + RCOLUMN_OFFSET,
s->generic.y + s->generic.parent->y,
128);
for ( i = 0; i < SLIDER_RANGE; i++ ) for (i = 0; i < SLIDER_RANGE; i++)
Draw_Char( RCOLUMN_OFFSET + s->generic.x + i*8 + s->generic.parent->x + 8, s->generic.y + s->generic.parent->y, 129); {
Draw_Char(RCOLUMN_OFFSET + s->generic.x + i * 8 +
s->generic.parent->x + 8, s->generic.y +
s->generic.parent->y, 129);
}
Draw_Char( RCOLUMN_OFFSET + s->generic.x + i*8 + s->generic.parent->x + 8, s->generic.y + s->generic.parent->y, 130); Draw_Char(RCOLUMN_OFFSET + s->generic.x + i * 8 +
Draw_Char( ( int ) ( 8 + RCOLUMN_OFFSET + s->generic.parent->x + s->generic.x + (SLIDER_RANGE-1)*8 * s->range ), s->generic.y + s->generic.parent->y, 131); s->generic.parent->x + 8, s->generic.y +
s->generic.parent->y, 130);
Draw_Char((int)(8 + RCOLUMN_OFFSET + s->generic.parent->x +
s->generic.x + (SLIDER_RANGE - 1) * 8 * s->range),
s->generic.y + s->generic.parent->y,
131);
} }
void SpinControl_DoSlide( menulist_s *s, int dir ) { void
SpinControl_DoSlide(menulist_s *s, int dir)
{
s->curvalue += dir; s->curvalue += dir;
if ( s->curvalue < 0 ) if (s->curvalue < 0)
{
s->curvalue = 0; s->curvalue = 0;
}
else if ( s->itemnames[s->curvalue] == 0 ) else if (s->itemnames[s->curvalue] == 0)
{
s->curvalue--; s->curvalue--;
}
if ( s->generic.callback ) if (s->generic.callback)
s->generic.callback( s ); {
s->generic.callback(s);
}
} }
void SpinControl_Draw( menulist_s *s ) { void
SpinControl_Draw(menulist_s *s)
{
char buffer[100]; char buffer[100];
if ( s->generic.name ) { if (s->generic.name)
Menu_DrawStringR2LDark( s->generic.x + s->generic.parent->x + LCOLUMN_OFFSET, {
s->generic.y + s->generic.parent->y, Menu_DrawStringR2LDark(s->generic.x + s->generic.parent->x +
s->generic.name ); LCOLUMN_OFFSET, s->generic.y + s->generic.parent->y,
s->generic.name);
} }
if ( !strchr( s->itemnames[s->curvalue], '\n' ) ) { if (!strchr(s->itemnames[s->curvalue], '\n'))
Menu_DrawString( RCOLUMN_OFFSET + s->generic.x + s->generic.parent->x, s->generic.y + s->generic.parent->y, s->itemnames[s->curvalue] ); {
Menu_DrawString(RCOLUMN_OFFSET + s->generic.x +
} else { s->generic.parent->x, s->generic.y +
strcpy( buffer, s->itemnames[s->curvalue] ); s->generic.parent->y,
*strchr( buffer, '\n' ) = 0; s->itemnames[s->curvalue]);
Menu_DrawString( RCOLUMN_OFFSET + s->generic.x + s->generic.parent->x, s->generic.y + s->generic.parent->y, buffer ); }
strcpy( buffer, strchr( s->itemnames[s->curvalue], '\n' ) + 1 ); else
Menu_DrawString( RCOLUMN_OFFSET + s->generic.x + s->generic.parent->x, s->generic.y + s->generic.parent->y + 10, buffer ); {
strcpy(buffer, s->itemnames[s->curvalue]);
*strchr(buffer, '\n') = 0;
Menu_DrawString(RCOLUMN_OFFSET + s->generic.x +
s->generic.parent->x, s->generic.y +
s->generic.parent->y, buffer);
strcpy(buffer, strchr(s->itemnames[s->curvalue], '\n') + 1);
Menu_DrawString(RCOLUMN_OFFSET + s->generic.x +
s->generic.parent->x, s->generic.y +
s->generic.parent->y + 10, buffer);
} }
} }

View file

@ -33,21 +33,21 @@
#define NUMBER_OF_REFS 1 #define NUMBER_OF_REFS 1
/* all the refs should be initially set to 0 */ /* all the refs should be initially set to 0 */
static char *refs [ NUMBER_OF_REFS + 1 ] = { 0 }; static char *refs[NUMBER_OF_REFS + 1] = {0};
/* make all these have illegal values, as they will be redefined */ /* make all these have illegal values, as they will be redefined */
static int REF_GL = NUMBER_OF_REFS; static int REF_GL = NUMBER_OF_REFS;
static int GL_REF_START = NUMBER_OF_REFS; static int GL_REF_START = NUMBER_OF_REFS;
typedef struct typedef struct
{ {
char menuname [ 32 ]; char menuname[32];
char realname [ 32 ]; char realname[32];
int *pointer; int *pointer;
} ref_t; } ref_t;
static const ref_t possible_refs [ NUMBER_OF_REFS ] = { static const ref_t possible_refs[NUMBER_OF_REFS] = {
{ "[OpenGL ]", "gl", &REF_GL }, {"[OpenGL ]", "gl", &REF_GL},
}; };
extern cvar_t *vid_ref; extern cvar_t *vid_ref;
@ -62,106 +62,110 @@ static cvar_t *gl_ext_palettedtexture;
static cvar_t *windowed_mouse; static cvar_t *windowed_mouse;
extern void M_ForceMenuOff ( void ); extern void M_ForceMenuOff(void);
extern qboolean VID_CheckRefExists ( const char *name ); extern qboolean VID_CheckRefExists(const char *name);
/* MENU INTERACTION */ /* MENU INTERACTION */
#define SOFTWARE_MENU 0 #define SOFTWARE_MENU 0
#define OPENGL_MENU 1 #define OPENGL_MENU 1
#define CUSTOM_MODE 20 #define CUSTOM_MODE 20
static menuframework_s s_opengl_menu; static menuframework_s s_opengl_menu;
static menuframework_s *s_current_menu; static menuframework_s *s_current_menu;
static int s_current_menu_index; static int s_current_menu_index;
static menulist_s s_mode_list [ 2 ]; static menulist_s s_mode_list[2];
static menulist_s s_ref_list [ 2 ]; static menulist_s s_ref_list[2];
static menuslider_s s_tq_slider; static menuslider_s s_tq_slider;
static menuslider_s s_screensize_slider [ 2 ]; static menuslider_s s_screensize_slider[2];
static menuslider_s s_brightness_slider [ 2 ]; static menuslider_s s_brightness_slider[2];
static menulist_s s_fs_box [ 2 ]; static menulist_s s_fs_box[2];
static menulist_s s_paletted_texture_box; static menulist_s s_paletted_texture_box;
static menuaction_s s_apply_action [ 2 ]; static menuaction_s s_apply_action[2];
static menuaction_s s_defaults_action [ 2 ]; static menuaction_s s_defaults_action[2];
static void static void
DriverCallback ( void *unused ) DriverCallback(void *unused)
{ {
s_ref_list [ !s_current_menu_index ].curvalue = s_ref_list [ s_current_menu_index ].curvalue; s_ref_list[!s_current_menu_index].curvalue =
s_ref_list[s_current_menu_index].curvalue;
s_current_menu = &s_opengl_menu; s_current_menu = &s_opengl_menu;
s_current_menu_index = 1; s_current_menu_index = 1;
} }
static void static void
ScreenSizeCallback ( void *s ) ScreenSizeCallback(void *s)
{ {
menuslider_s *slider = (menuslider_s *) s; menuslider_s *slider = (menuslider_s *)s;
Cvar_SetValue( "viewsize", slider->curvalue * 10 ); Cvar_SetValue("viewsize", slider->curvalue * 10);
} }
static void static void
BrightnessCallback ( void *s ) BrightnessCallback(void *s)
{ {
menuslider_s *slider = (menuslider_s *) s; menuslider_s *slider = (menuslider_s *)s;
if ( s_current_menu_index == 0 ) if (s_current_menu_index == 0)
{ {
s_brightness_slider [ 1 ].curvalue = s_brightness_slider [ 0 ].curvalue; s_brightness_slider[1].curvalue = s_brightness_slider[0].curvalue;
} }
else else
{ {
s_brightness_slider [ 0 ].curvalue = s_brightness_slider [ 1 ].curvalue; s_brightness_slider[0].curvalue = s_brightness_slider[1].curvalue;
} }
float gamma = slider->curvalue / 10.0; float gamma = slider->curvalue / 10.0;
Cvar_SetValue( "vid_gamma", gamma ); Cvar_SetValue("vid_gamma", gamma);
} }
static void static void
ResetDefaults ( void *unused ) ResetDefaults(void *unused)
{ {
VID_MenuInit(); VID_MenuInit();
} }
static void static void
ApplyChanges ( void *unused ) ApplyChanges(void *unused)
{ {
int ref; int ref;
/* make values consistent */ /* make values consistent */
s_fs_box [ !s_current_menu_index ].curvalue = s_fs_box [ s_current_menu_index ].curvalue; s_fs_box[!s_current_menu_index].curvalue =
s_brightness_slider [ !s_current_menu_index ].curvalue = s_brightness_slider [ s_current_menu_index ].curvalue; s_fs_box[s_current_menu_index].curvalue;
s_ref_list [ !s_current_menu_index ].curvalue = s_ref_list [ s_current_menu_index ].curvalue; s_brightness_slider[!s_current_menu_index].curvalue =
s_brightness_slider[s_current_menu_index].curvalue;
s_ref_list[!s_current_menu_index].curvalue =
s_ref_list[s_current_menu_index].curvalue;
Cvar_SetValue( "gl_picmip", 3 - s_tq_slider.curvalue ); Cvar_SetValue("gl_picmip", 3 - s_tq_slider.curvalue);
Cvar_SetValue( "vid_fullscreen", s_fs_box [ s_current_menu_index ].curvalue ); Cvar_SetValue("vid_fullscreen", s_fs_box[s_current_menu_index].curvalue);
Cvar_SetValue( "gl_ext_palettedtexture", s_paletted_texture_box.curvalue ); Cvar_SetValue("gl_ext_palettedtexture", s_paletted_texture_box.curvalue);
/* custom mode */ /* custom mode */
if ( s_mode_list [ OPENGL_MENU ].curvalue != CUSTOM_MODE ) if (s_mode_list[OPENGL_MENU].curvalue != CUSTOM_MODE)
{ {
printf( "DEBUG: %i\n", s_mode_list [ OPENGL_MENU ].curvalue ); printf("DEBUG: %i\n", s_mode_list[OPENGL_MENU].curvalue);
Cvar_SetValue( "gl_mode", s_mode_list [ OPENGL_MENU ].curvalue ); Cvar_SetValue("gl_mode", s_mode_list[OPENGL_MENU].curvalue);
} }
else else
{ {
Cvar_SetValue( "gl_mode", -1 ); Cvar_SetValue("gl_mode", -1);
} }
/* must use an if here (instead of a switch), since the /* must use an if here (instead of a switch), since the
REF_'s are now variables and not #DEFINE's (constants) */ REF_'s are now variables and not #DEFINE's (constants) */
ref = s_ref_list [ s_current_menu_index ].curvalue; ref = s_ref_list[s_current_menu_index].curvalue;
if ( ref == REF_GL ) if (ref == REF_GL)
{ {
Cvar_Set( "vid_ref", "gl" ); Cvar_Set("vid_ref", "gl");
/* below is wrong if we use different libs for different GL reflibs */ /* below is wrong if we use different libs for different GL reflibs */
Cvar_Get( "gl_driver", "libGL.so.1", CVAR_ARCHIVE ); Cvar_Get("gl_driver", "libGL.so.1", CVAR_ARCHIVE);
if ( gl_driver->modified ) if (gl_driver->modified)
{ {
vid_ref->modified = true; vid_ref->modified = true;
} }
@ -171,7 +175,7 @@ ApplyChanges ( void *unused )
} }
void void
VID_MenuInit ( void ) VID_MenuInit(void)
{ {
int i, counter; int i, counter;
@ -209,30 +213,30 @@ VID_MenuInit ( void )
}; };
/* make sure these are invalided before showing the menu again */ /* make sure these are invalided before showing the menu again */
REF_GL = NUMBER_OF_REFS; REF_GL = NUMBER_OF_REFS;
GL_REF_START = NUMBER_OF_REFS; GL_REF_START = NUMBER_OF_REFS;
/* now test to see which ref's are present */ /* now test to see which ref's are present */
i = counter = 0; i = counter = 0;
while ( i < NUMBER_OF_REFS ) while (i < NUMBER_OF_REFS)
{ {
if ( VID_CheckRefExists( possible_refs [ i ].realname ) ) if (VID_CheckRefExists(possible_refs[i].realname))
{ {
*( possible_refs [ i ].pointer ) = counter; *(possible_refs[i].pointer) = counter;
/* free any previous string */ /* free any previous string */
if ( refs [ i ] ) if (refs[i])
{ {
free( refs [ i ] ); free(refs[i]);
} }
refs [ counter ] = strdup( possible_refs [ i ].menuname ); refs[counter] = strdup(possible_refs[i].menuname);
/* if we reach the 1rd item in the list, this indicates that a /* if we reach the 1rd item in the list, this indicates that a
GL ref has been found; this will change if more software GL ref has been found; this will change if more software
modes are added to the possible_ref's array */ modes are added to the possible_ref's array */
if ( i == 0 ) if (i == 0)
{ {
GL_REF_START = counter; GL_REF_START = counter;
} }
@ -243,203 +247,207 @@ VID_MenuInit ( void )
i++; i++;
} }
refs [ counter ] = (char *) 0; refs[counter] = (char *)0;
if ( !gl_driver ) if (!gl_driver)
{ {
gl_driver = Cvar_Get( "gl_driver", "libGL.so.1", 0 ); gl_driver = Cvar_Get("gl_driver", "libGL.so.1", 0);
} }
if ( !gl_picmip ) if (!gl_picmip)
{ {
gl_picmip = Cvar_Get( "gl_picmip", "0", 0 ); gl_picmip = Cvar_Get("gl_picmip", "0", 0);
} }
if ( !gl_mode ) if (!gl_mode)
{ {
gl_mode = Cvar_Get( "gl_mode", "3", 0 ); gl_mode = Cvar_Get("gl_mode", "3", 0);
} }
if ( !gl_ext_palettedtexture ) if (!gl_ext_palettedtexture)
{ {
gl_ext_palettedtexture = Cvar_Get( "gl_ext_palettedtexture", "0", CVAR_ARCHIVE ); gl_ext_palettedtexture = Cvar_Get("gl_ext_palettedtexture",
"0", CVAR_ARCHIVE);
} }
if ( !windowed_mouse ) if (!windowed_mouse)
{ {
windowed_mouse = Cvar_Get( "windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE ); windowed_mouse = Cvar_Get("windowed_mouse", "1",
CVAR_USERINFO | CVAR_ARCHIVE);
} }
/* custom mode */ /* custom mode */
if ( gl_mode->value >= 1.0 ) if (gl_mode->value >= 1.0)
{ {
s_mode_list [ OPENGL_MENU ].curvalue = gl_mode->value; s_mode_list[OPENGL_MENU].curvalue = gl_mode->value;
} }
else else
{ {
s_mode_list [ OPENGL_MENU ].curvalue = CUSTOM_MODE; s_mode_list[OPENGL_MENU].curvalue = CUSTOM_MODE;
} }
if ( !scr_viewsize ) if (!scr_viewsize)
{ {
scr_viewsize = Cvar_Get( "viewsize", "100", CVAR_ARCHIVE ); scr_viewsize = Cvar_Get("viewsize", "100", CVAR_ARCHIVE);
} }
s_screensize_slider [ OPENGL_MENU ].curvalue = scr_viewsize->value / 10; s_screensize_slider[OPENGL_MENU].curvalue = scr_viewsize->value / 10;
if ( strcmp( vid_ref->string, "gl" ) == 0 ) if (strcmp(vid_ref->string, "gl") == 0)
{ {
s_current_menu_index = OPENGL_MENU; s_current_menu_index = OPENGL_MENU;
s_ref_list [ s_current_menu_index ].curvalue = REF_GL; s_ref_list[s_current_menu_index].curvalue = REF_GL;
} }
s_opengl_menu.x = viddef.width * 0.50; s_opengl_menu.x = viddef.width * 0.50;
s_opengl_menu.nitems = 0; s_opengl_menu.nitems = 0;
for ( i = 0; i < 2; i++ ) for (i = 0; i < 2; i++)
{ {
s_ref_list [ i ].generic.type = MTYPE_SPINCONTROL; s_ref_list[i].generic.type = MTYPE_SPINCONTROL;
s_ref_list [ i ].generic.name = "driver"; s_ref_list[i].generic.name = "driver";
s_ref_list [ i ].generic.x = 0; s_ref_list[i].generic.x = 0;
s_ref_list [ i ].generic.y = 0; s_ref_list[i].generic.y = 0;
s_ref_list [ i ].generic.callback = DriverCallback; s_ref_list[i].generic.callback = DriverCallback;
s_ref_list [ i ].itemnames = (const char **) refs; s_ref_list[i].itemnames = (const char **)refs;
s_mode_list [ i ].generic.type = MTYPE_SPINCONTROL; s_mode_list[i].generic.type = MTYPE_SPINCONTROL;
s_mode_list [ i ].generic.name = "video mode"; s_mode_list[i].generic.name = "video mode";
s_mode_list [ i ].generic.x = 0; s_mode_list[i].generic.x = 0;
s_mode_list [ i ].generic.y = 10; s_mode_list[i].generic.y = 10;
s_mode_list [ i ].itemnames = resolutions; s_mode_list[i].itemnames = resolutions;
s_screensize_slider [ i ].generic.type = MTYPE_SLIDER; s_screensize_slider[i].generic.type = MTYPE_SLIDER;
s_screensize_slider [ i ].generic.x = 0; s_screensize_slider[i].generic.x = 0;
s_screensize_slider [ i ].generic.y = 20; s_screensize_slider[i].generic.y = 20;
s_screensize_slider [ i ].generic.name = "screen size"; s_screensize_slider[i].generic.name = "screen size";
s_screensize_slider [ i ].minvalue = 3; s_screensize_slider[i].minvalue = 3;
s_screensize_slider [ i ].maxvalue = 12; s_screensize_slider[i].maxvalue = 12;
s_screensize_slider [ i ].generic.callback = ScreenSizeCallback; s_screensize_slider[i].generic.callback = ScreenSizeCallback;
s_brightness_slider [ i ].generic.type = MTYPE_SLIDER; s_brightness_slider[i].generic.type = MTYPE_SLIDER;
s_brightness_slider [ i ].generic.x = 0; s_brightness_slider[i].generic.x = 0;
s_brightness_slider [ i ].generic.y = 30; s_brightness_slider[i].generic.y = 30;
s_brightness_slider [ i ].generic.name = "brightness"; s_brightness_slider[i].generic.name = "brightness";
s_brightness_slider [ i ].generic.callback = BrightnessCallback; s_brightness_slider[i].generic.callback = BrightnessCallback;
s_brightness_slider [ i ].minvalue = 1; s_brightness_slider[i].minvalue = 1;
s_brightness_slider [ i ].maxvalue = 20; s_brightness_slider[i].maxvalue = 20;
s_brightness_slider [ i ].curvalue = vid_gamma->value * 10; s_brightness_slider[i].curvalue = vid_gamma->value * 10;
s_fs_box [ i ].generic.type = MTYPE_SPINCONTROL; s_fs_box[i].generic.type = MTYPE_SPINCONTROL;
s_fs_box [ i ].generic.x = 0; s_fs_box[i].generic.x = 0;
s_fs_box [ i ].generic.y = 40; s_fs_box[i].generic.y = 40;
s_fs_box [ i ].generic.name = "fullscreen"; s_fs_box[i].generic.name = "fullscreen";
s_fs_box [ i ].itemnames = yesno_names; s_fs_box[i].itemnames = yesno_names;
s_fs_box [ i ].curvalue = vid_fullscreen->value; s_fs_box[i].curvalue = vid_fullscreen->value;
s_defaults_action [ i ].generic.type = MTYPE_ACTION; s_defaults_action[i].generic.type = MTYPE_ACTION;
s_defaults_action [ i ].generic.name = "reset to default"; s_defaults_action[i].generic.name = "reset to default";
s_defaults_action [ i ].generic.x = 0; s_defaults_action[i].generic.x = 0;
s_defaults_action [ i ].generic.y = 90; s_defaults_action[i].generic.y = 90;
s_defaults_action [ i ].generic.callback = ResetDefaults; s_defaults_action[i].generic.callback = ResetDefaults;
s_apply_action [ i ].generic.type = MTYPE_ACTION; s_apply_action[i].generic.type = MTYPE_ACTION;
s_apply_action [ i ].generic.name = "apply"; s_apply_action[i].generic.name = "apply";
s_apply_action [ i ].generic.x = 0; s_apply_action[i].generic.x = 0;
s_apply_action [ i ].generic.y = 100; s_apply_action[i].generic.y = 100;
s_apply_action [ i ].generic.callback = ApplyChanges; s_apply_action[i].generic.callback = ApplyChanges;
} }
s_tq_slider.generic.type = MTYPE_SLIDER; s_tq_slider.generic.type = MTYPE_SLIDER;
s_tq_slider.generic.x = 0; s_tq_slider.generic.x = 0;
s_tq_slider.generic.y = 60; s_tq_slider.generic.y = 60;
s_tq_slider.generic.name = "texture quality"; s_tq_slider.generic.name = "texture quality";
s_tq_slider.minvalue = 0; s_tq_slider.minvalue = 0;
s_tq_slider.maxvalue = 3; s_tq_slider.maxvalue = 3;
s_tq_slider.curvalue = 3 - gl_picmip->value; s_tq_slider.curvalue = 3 - gl_picmip->value;
s_paletted_texture_box.generic.type = MTYPE_SPINCONTROL; s_paletted_texture_box.generic.type = MTYPE_SPINCONTROL;
s_paletted_texture_box.generic.x = 0; s_paletted_texture_box.generic.x = 0;
s_paletted_texture_box.generic.y = 70; s_paletted_texture_box.generic.y = 70;
s_paletted_texture_box.generic.name = "8-bit textures"; s_paletted_texture_box.generic.name = "8-bit textures";
s_paletted_texture_box.itemnames = yesno_names; s_paletted_texture_box.itemnames = yesno_names;
s_paletted_texture_box.curvalue = gl_ext_palettedtexture->value; s_paletted_texture_box.curvalue = gl_ext_palettedtexture->value;
Menu_AddItem( &s_opengl_menu, (void *) &s_ref_list [ OPENGL_MENU ] ); Menu_AddItem(&s_opengl_menu, (void *)&s_ref_list[OPENGL_MENU]);
Menu_AddItem( &s_opengl_menu, (void *) &s_mode_list [ OPENGL_MENU ] ); Menu_AddItem(&s_opengl_menu, (void *)&s_mode_list[OPENGL_MENU]);
Menu_AddItem( &s_opengl_menu, (void *) &s_screensize_slider [ OPENGL_MENU ] ); Menu_AddItem(&s_opengl_menu, (void *)&s_screensize_slider[OPENGL_MENU]);
Menu_AddItem( &s_opengl_menu, (void *) &s_brightness_slider [ OPENGL_MENU ] ); Menu_AddItem(&s_opengl_menu, (void *)&s_brightness_slider[OPENGL_MENU]);
Menu_AddItem( &s_opengl_menu, (void *) &s_fs_box [ OPENGL_MENU ] ); Menu_AddItem(&s_opengl_menu, (void *)&s_fs_box[OPENGL_MENU]);
Menu_AddItem( &s_opengl_menu, (void *) &s_tq_slider ); Menu_AddItem(&s_opengl_menu, (void *)&s_tq_slider);
Menu_AddItem( &s_opengl_menu, (void *) &s_paletted_texture_box ); Menu_AddItem(&s_opengl_menu, (void *)&s_paletted_texture_box);
Menu_AddItem( &s_opengl_menu, ( void * ) &s_defaults_action[OPENGL_MENU] ); Menu_AddItem(&s_opengl_menu, (void *)&s_defaults_action[OPENGL_MENU]);
Menu_AddItem( &s_opengl_menu, ( void * ) &s_apply_action[OPENGL_MENU] ); Menu_AddItem(&s_opengl_menu, (void *)&s_apply_action[OPENGL_MENU]);
Menu_Center( &s_opengl_menu ); Menu_Center(&s_opengl_menu);
s_opengl_menu.x -= 8; s_opengl_menu.x -= 8;
} }
void void
VID_MenuShutdown ( void ) VID_MenuShutdown(void)
{ {
int i; int i;
for ( i = 0; i < NUMBER_OF_REFS; i++ ) for (i = 0; i < NUMBER_OF_REFS; i++)
{ {
if ( refs [ i ] ) if (refs[i])
{ {
free( refs [ i ] ); free(refs[i]);
} }
} }
} }
void void
VID_MenuDraw ( void ) VID_MenuDraw(void)
{ {
int w, h; int w, h;
s_current_menu = &s_opengl_menu; s_current_menu = &s_opengl_menu;
/* draw the banner */ /* draw the banner */
re.DrawGetPicSize( &w, &h, "m_banner_video" ); re.DrawGetPicSize(&w, &h, "m_banner_video");
re.DrawPic( viddef.width / 2 - w / 2, viddef.height / 2 - 110, "m_banner_video" ); re.DrawPic(viddef.width / 2 - w / 2, viddef.height / 2 - 110,
"m_banner_video");
/* move cursor to a reasonable starting position */ /* move cursor to a reasonable starting position */
Menu_AdjustCursor( s_current_menu, 1 ); Menu_AdjustCursor(s_current_menu, 1);
/* draw the menu */ /* draw the menu */
Menu_Draw( s_current_menu ); Menu_Draw(s_current_menu);
} }
const char * const char *
VID_MenuKey ( int key ) VID_MenuKey(int key)
{ {
extern void M_PopMenu ( void ); extern void M_PopMenu(void);
menuframework_s *m = s_current_menu; menuframework_s *m = s_current_menu;
static const char *sound = "misc/menu1.wav"; static const char *sound = "misc/menu1.wav";
switch ( key ) switch (key)
{ {
case K_ESCAPE: case K_ESCAPE:
M_PopMenu(); M_PopMenu();
return ( NULL ); return NULL;
case K_UPARROW: case K_UPARROW:
m->cursor--; m->cursor--;
Menu_AdjustCursor( m, -1 ); Menu_AdjustCursor(m, -1);
break; break;
case K_DOWNARROW: case K_DOWNARROW:
m->cursor++; m->cursor++;
Menu_AdjustCursor( m, 1 ); Menu_AdjustCursor(m, 1);
break; break;
case K_LEFTARROW: case K_LEFTARROW:
Menu_SlideItem( m, -1 ); Menu_SlideItem(m, -1);
break; break;
case K_RIGHTARROW: case K_RIGHTARROW:
Menu_SlideItem( m, 1 ); Menu_SlideItem(m, 1);
break; break;
case K_ENTER: case K_ENTER:
Menu_SelectItem( m ); Menu_SelectItem(m);
break; break;
} }
return ( sound ); return sound;
} }