An alternate server browser, accessable via menu_servers2.

Needs tweeks. A good base for killing off the origional browser. Mouse driven. Needs keyboard input to actually connect still.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2035 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-02-28 00:46:04 +00:00
parent 38c36360f6
commit d0661cdc47
13 changed files with 530 additions and 46 deletions

View File

@ -40,6 +40,9 @@ typedef enum{
SLKEY_MAXPLAYERS,
SLKEY_GAMEDIR,
SLKEY_FREEPLAYERS,
SLKEY_BASEGAME,
SLKEY_TOOMANY,
SLKEY_CUSTOM
} hostcachekey_t;
@ -90,7 +93,7 @@ typedef struct serverinfo_s {
short tl;
short fl;
char gamedir[8+1];
char map[8+1];
char map[16];
float refreshtime;

View File

@ -748,6 +748,7 @@ void CL_TimeDemo_f (void);
extern int packet_latency[NET_TIMINGS];
int CL_CalcNet (void);
void CL_ParseServerMessage (void);
void CL_DumpPacket(void);
void CLNQ_ParseServerMessage (void);
#ifdef Q2CLIENT
void CLQ2_ParseServerMessage (void);

View File

@ -173,6 +173,11 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
Draw_TransPic (xpos+option->common.posx, ypos+option->common.posy, p);
break;
case mt_strechpic:
p = Draw_SafeCachePic(option->picture.picturename);
if (p) Draw_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width, option->common.height, p);
break;
case mt_childwindow:
MenuDrawItems(xpos+option->common.posx, ypos+option->common.posy, ((menu_t *)option->custom.data)->options, (menu_t *)option->custom.data);
break;
@ -216,7 +221,7 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
int y = ypos+option->common.posy;
qboolean on;
if (option->check.func)
on = option->check.func(option, CHK_CHECKED);
on = option->check.func(&option->check, menu, CHK_CHECKED);
else if (!option->check.var)
on = option->check.value;
else if (option->check.bits) //bits is a bitmask for use with cvars (users can be clumsy, so bittage of 0 uses non-zero as true, but sets only bit 1)
@ -340,7 +345,8 @@ void MenuDraw(menu_t *menu)
{
if (menu->event)
menu->event(menu);
menu->xpos = ((vid.width - 320)>>1);
if (!menu->dontexpand)
menu->xpos = ((vid.width - 320)>>1);
MenuDrawItems(menu->xpos, menu->ypos, menu->options, menu);
}
@ -429,6 +435,29 @@ menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, char *picname)
return n;
}
menupicture_t *MC_AddStrechPicture(menu_t *menu, int x, int y, int width, int height, char *picname)
{
menupicture_t *n;
if (!qrenderer)
return NULL;
Draw_SafeCachePic(picname);
n = Z_Malloc(sizeof(menupicture_t) + strlen(picname)+1);
n->common.type = mt_strechpic;
n->common.iszone = true;
n->common.posx = x;
n->common.posy = y;
n->common.width = width;
n->common.height = height;
n->picturename = (char *)(n+1);
strcpy(n->picturename, picname);
n->common.next = menu->options;
menu->options = (menuoption_t *)n;
return n;
}
menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, char *picname)
{
int x;
@ -568,6 +597,25 @@ menucheck_t *MC_AddCheckBox(menu_t *menu, int x, int y, const char *text, cvar_t
menu->options = (menuoption_t *)n;
return n;
}
menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int x, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits)
{
menucheck_t *n = Z_Malloc(sizeof(menucheck_t)+strlen(text)+1);
n->common.type = mt_checkbox;
n->common.iszone = true;
n->common.posx = x;
n->common.posy = y;
n->common.height = 8;
n->common.width = (strlen(text)+7)*8;
n->text = (char *)(n+1);
strcpy((char *)(n+1), text);
n->func = func;
n->bits = bits;
n->common.next = menu->options;
menu->options = (menuoption_t *)n;
return n;
}
menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max)
{
menuslider_t *n = Z_Malloc(sizeof(menuslider_t)+strlen(text)+1);
@ -774,12 +822,12 @@ void MC_Slider_Key(menuslider_t *option, int key)
S_LocalSound ("misc/menu2.wav");
}
void MC_CheckBox_Key(menucheck_t *option, int key)
void MC_CheckBox_Key(menucheck_t *option, menu_t *menu, int key)
{
if (key != K_ENTER && key != K_LEFTARROW && key != K_RIGHTARROW && key != K_MOUSE1)
return;
if (option->func)
option->func((union menuoption_s *)option, CHK_TOGGLE);
option->func(option, menu, CHK_TOGGLE);
else if (!option->var)
option->value = !option->value;
else
@ -1164,7 +1212,7 @@ void M_Complex_Key(int key)
MC_Slider_Key(&currentmenu->selecteditem->slider, key);
break;
case mt_checkbox:
MC_CheckBox_Key(&currentmenu->selecteditem->check, key);
MC_CheckBox_Key(&currentmenu->selecteditem->check, currentmenu, key);
break;
case mt_button:
case mt_buttonbigfont:

View File

@ -3,18 +3,6 @@
#ifdef CL_MASTER
#include "cl_master.h"
enum {
SLISTTYPE_SERVERS,
SLISTTYPE_FAVORITES,
SLISTTYPE_SOURCES,
SLISTTYPE_OPTIONS //must be last
} slist_option;
int slist_numoptions;
int slist_firstoption;
int slist_type;
//filtering
cvar_t sb_hideempty = SCVARF("sb_hideempty", "0", CVAR_ARCHIVE);
cvar_t sb_hidenotempty = SCVARF("sb_hidenotempty", "0", CVAR_ARCHIVE);
@ -71,6 +59,19 @@ void M_Serverlist_Init(void)
Cvar_Register(&slist_cacheinfo, grp);
}
enum {
SLISTTYPE_SERVERS,
SLISTTYPE_FAVORITES,
SLISTTYPE_SOURCES,
SLISTTYPE_OPTIONS //must be last
} slist_option;
int slist_numoptions;
int slist_firstoption;
int slist_type;
static void NM_DrawColouredCharacter (int cx, int line, unsigned int num)
{
@ -871,4 +872,398 @@ void M_SListKey(int key)
return;
}
}
typedef struct {
int visibleslots;
int scrollpos;
int selectedpos;
int numslots;
qboolean stillpolling;
qbyte filter[8];
qboolean sliderpressed;
menupicture_t *mappic;
} serverlist_t;
void SL_TitlesDraw (int x, int y, menucustom_t *ths, menu_t *menu)
{
x = ths->common.width/8;
if (sb_showtimelimit.value) {x-=4; Draw_FunStringLen(x+8, y, "tl", 3); }
if (sb_showfraglimit.value) {x-=4; Draw_FunStringLen(x+8, y, "fl", 3); }
if (sb_showplayers.value) {Draw_FunStringLen((x-5)*8, y, "plyrs", 5); x-=6;}
if (sb_showmap.value) {Draw_FunStringLen((x-8)*8, y, "map", 8); x-=9;}
if (sb_showgamedir.value) {Draw_FunStringLen((x-8)*8, y, "gamedir", 8); x-=9;}
if (sb_showping.value) {Draw_FunStringLen((x-3)*8, y, "png", 3); x-=4;}
if (sb_showaddress.value) {Draw_FunStringLen((x-21)*8, y, "address", 21); x-=22;}
Draw_FunStringLen(0, y, "name", x);
}
qboolean SL_TitlesKey (menucustom_t *ths, menu_t *menu, int key)
{
int x;
extern int mousecursor_x, mousecursor_y;
int mx = mousecursor_x/8;
int sortkey;
if (key != K_MOUSE1)
return false;
do {
x = ths->common.width/8;
if (mx > x) return false; //out of bounds
if (sb_showtimelimit.value) {x-=4;if (mx > x) {sortkey = SLKEY_NAME; break;}}
if (sb_showfraglimit.value) {x-=4;if (mx > x) {sortkey = SLKEY_NAME; break;}}
if (sb_showplayers.value) {x-=6;if (mx > x) {sortkey = SLKEY_NUMPLAYERS; break;}}
if (sb_showmap.value) {x-=9;if (mx > x) {sortkey = SLKEY_MAP; break;}}
if (sb_showgamedir.value) {x-=9;if (mx > x) {sortkey = SLKEY_GAMEDIR; break;}}
if (sb_showping.value) {x-=4;if (mx > x) {sortkey = SLKEY_PING; break;}}
if (sb_showaddress.value) {x-=22;if (mx > x) {sortkey = SLKEY_ADDRESS; break;}}
sortkey = SLKEY_NAME;break;
} while (0);
Master_SetSortField(sortkey, Master_GetSortField()!=sortkey||!Master_GetSortDescending());
return true;
}
void SL_ServerDraw (int x, int y, menucustom_t *ths, menu_t *menu)
{
extern int mousecursor_x, mousecursor_y;
serverlist_t *info = (serverlist_t*)(menu + 1);
serverinfo_t *si;
int thisone = (int)ths->data + info->scrollpos;
si = Master_SortedServer(thisone);
if (si)
{
x = ths->common.width;
if (thisone == info->selectedpos)
Draw_Fill(0, y, ths->common.width, 8, 63-24);
else if (thisone == info->scrollpos + (mousecursor_y-16)/8 && mousecursor_x < x)
Draw_Fill(0, y, ths->common.width, 8, (int)(sin(realtime*4.4)*4)+12+16);
else if (thisone & 1)
Draw_Fill(0, y, ths->common.width, 8, 1);
else
Draw_Fill(0, y, ths->common.width, 8, 2);
x /= 8;
if (sb_showtimelimit.value) {Draw_FunStringLen((x-3)*8, y, va("%i", si->tl), 3); x-=4;}
if (sb_showfraglimit.value) {Draw_FunStringLen((x-3)*8, y, va("%i", si->fl), 3); x-=4;}
if (sb_showplayers.value) {Draw_FunStringLen((x-5)*8, y, va("%2i/%2i", si->players, si->maxplayers), 5); x-=6;}
if (sb_showmap.value) {Draw_FunStringLen((x-8)*8, y, si->map, 8); x-=9;}
if (sb_showgamedir.value) {Draw_FunStringLen((x-8)*8, y, si->gamedir, 8); x-=9;}
if (sb_showping.value) {Draw_FunStringLen((x-3)*8, y, va("%i", si->ping), 3); x-=4;}
if (sb_showaddress.value) {Draw_FunStringLen((x-21)*8, y, NET_AdrToString(si->adr), 21); x-=22;}
Draw_FunStringLen(0, y, si->name, x);
}
}
qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key)
{
extern int mousecursor_x, mousecursor_y;
serverlist_t *info = (serverlist_t*)(menu + 1);
serverinfo_t *server;
if (key == K_MOUSE1)
{
info->selectedpos = info->scrollpos + (mousecursor_y-16)/8;
{
serverinfo_t *server;
server = Master_SortedServer(info->selectedpos);
if (server)
{
_snprintf(info->mappic->picturename, 32, "levelshots/%s", server->map);
}
else
{
_snprintf(info->mappic->picturename, 32, "levelshots/nomap");
}
}
}
if (key == K_ENTER || key == 's' || key == 'j')
{
server = Master_SortedServer((int)ths->data + info->scrollpos);
if (server)
{
if (key == 's')
Cbuf_AddText("spectator 1\n", RESTRICT_LOCAL);
else if (key == 'j')
Cbuf_AddText("spectator 0\n", RESTRICT_LOCAL);
if (server->special & SS_NETQUAKE)
Cbuf_AddText(va("nqconnect %s\n", NET_AdrToString(server->adr)), RESTRICT_LOCAL);
else
Cbuf_AddText(va("connect %s\n", NET_AdrToString(server->adr)), RESTRICT_LOCAL);
}
return true;
}
return false;
}
void SL_PreDraw (menu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
NET_CheckPollSockets();
CL_QueryServers();
info->numslots = Master_NumSorted();
}
qboolean SL_Key (int key, menu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
if (key == K_HOME)
{
info->scrollpos = 0;
info->selectedpos = 0;
return true;
}
if (key == K_END)
{
info->selectedpos = info->numslots-1;
info->scrollpos = info->selectedpos - (vid.height-16-7)/8;
return true;
}
if (key == K_PGDN)
info->selectedpos += 10;
else if (key == K_PGUP)
info->selectedpos -= 10;
else if (key == K_DOWNARROW)
info->selectedpos += 1;
else if (key == K_UPARROW)
info->selectedpos -= 1;
else if (key == K_MWHEELUP)
info->selectedpos -= 3;
else if (key == K_MWHEELDOWN)
info->selectedpos += 3;
else
return false;
{
serverinfo_t *server;
server = Master_SortedServer(info->selectedpos);
if (server)
{
_snprintf(info->mappic->picturename, 32, "levelshots/%s", server->map);
}
else
{
_snprintf(info->mappic->picturename, 32, "levelshots/nomap");
}
}
if (info->selectedpos < 0)
info->selectedpos = 0;
if (info->selectedpos > info->numslots-1)
info->selectedpos = info->numslots-1;
if (info->scrollpos < info->selectedpos - info->visibleslots)
info->scrollpos = info->selectedpos - info->visibleslots;
if (info->selectedpos < info->scrollpos)
info->scrollpos = info->selectedpos;
return true;
}
void SL_SliderDraw (int x, int y, menucustom_t *ths, menu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
Draw_Fill(x, y, ths->common.width, ths->common.height, 54);
y += ((info->scrollpos) / ((float)info->numslots - info->visibleslots)) * (ths->common.height-8);
Draw_Fill(x, y, 8, 8, 45);
if (info->sliderpressed)
{
extern qboolean keydown[K_MAX];
if (keydown[K_MOUSE1])
{
extern int mousecursor_x, mousecursor_y;
float my;
serverlist_t *info = (serverlist_t*)(menu + 1);
my = mousecursor_y;
my -= ths->common.posy;
my /= ths->common.height;
my *= (info->numslots-info->visibleslots);
if (my > info->numslots-info->visibleslots-1)
my = info->numslots-info->visibleslots-1;
if (my < 0)
my = 0;
info->scrollpos = my;
}
else
info->sliderpressed = false;
}
}
qboolean SL_SliderKey (menucustom_t *ths, menu_t *menu, int key)
{
if (key == K_MOUSE1)
{
extern int mousecursor_x, mousecursor_y;
float my;
serverlist_t *info = (serverlist_t*)(menu + 1);
my = mousecursor_y;
my -= ths->common.posy;
my /= ths->common.height;
my *= (info->numslots-info->visibleslots);
if (my > info->numslots-info->visibleslots-1)
my = info->numslots-info->visibleslots-1;
if (my < 0)
my = 0;
info->scrollpos = my;
info->sliderpressed = true;
return true;
}
return false;
}
void CalcFilters(menu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
Master_ClearMasks();
Master_SetMaskInteger(false, SLKEY_PING, 0, SLIST_TEST_LESS);
if (info->filter[1]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_NETQUAKE|SS_DARKPLACES, SLIST_TEST_CONTAINS);
if (info->filter[2]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_NETQUAKE|SS_DARKPLACES|SS_QUAKE2|SS_QUAKE3, SLIST_TEST_NOTCONTAIN);
if (info->filter[3]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_QUAKE2, SLIST_TEST_CONTAINS);
if (info->filter[4]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_QUAKE3, SLIST_TEST_CONTAINS);
if (info->filter[6]) Master_SetMaskInteger(false, SLKEY_NUMPLAYERS, 0, SLIST_TEST_NOTEQUAL);
if (info->filter[7]) Master_SetMaskInteger(false, SLKEY_FREEPLAYERS, 0, SLIST_TEST_NOTEQUAL);
}
qboolean SL_ReFilter (menucheck_t *option, menu_t *menu, chk_set_t set)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
switch(set)
{
case CHK_CHECKED:
return info->filter[option->bits];
case CHK_TOGGLE:
if (option->bits>0)
info->filter[option->bits] ^= 1;
CalcFilters(menu);
return true;
}
return true;
}
void SL_Remove (menu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
Cvar_Set(&sb_hidenetquake, info->filter[1]?"0":"1");
Cvar_Set(&sb_hidequakeworld, info->filter[2]?"0":"1");
Cvar_Set(&sb_hidequake2, info->filter[3]?"0":"1");
Cvar_Set(&sb_hidequake3, info->filter[4]?"0":"1");
Cvar_Set(&sb_hideempty, info->filter[6]?"1":"0");
Cvar_Set(&sb_hidefull, info->filter[7]?"1":"0");
}
void M_Menu_ServerList2_f(void)
{
int i, y;
menu_t *menu;
menucustom_t *cust;
serverlist_t *info;
key_dest = key_menu;
m_state = m_complex;
MasterInfo_Begin();
menu = M_CreateMenu(sizeof(serverlist_t));
menu->event = SL_PreDraw;
menu->key = SL_Key;
menu->remove = SL_Remove;
info = (serverlist_t*)(menu + 1);
y = 8;
cust = MC_AddCustom(menu, 0, y, 0);
cust->draw = SL_TitlesDraw;
cust->key = SL_TitlesKey;
cust->common.height = 8;
cust->common.width = vid.width-8;
info->visibleslots = (vid.height-16 - 64);
cust = MC_AddCustom(menu, vid.width-8, 16, NULL);
cust->draw = SL_SliderDraw;
cust->key = SL_SliderKey;
cust->common.height = info->visibleslots;
cust->common.width = 8;
info->visibleslots = (info->visibleslots-7)/8;
for (i = 0, y = 16; i <= info->visibleslots; y +=8, i++)
{
cust = MC_AddCustom(menu, 0, y, (void*)i);
cust->draw = SL_ServerDraw;
cust->key = SL_ServerKey;
cust->common.height = 8;
cust->common.width = vid.width-8;
}
menu->dontexpand = true;
MC_AddCheckBox(menu, 0, vid.height - 64+8*1, "Ping ", &sb_showping, 1);
MC_AddCheckBox(menu, 0, vid.height - 64+8*2, "Address ", &sb_showaddress, 1);
MC_AddCheckBox(menu, 0, vid.height - 64+8*3, "Map ", &sb_showmap, 1);
MC_AddCheckBox(menu, 0, vid.height - 64+8*4, "Gamedir ", &sb_showgamedir, 1);
MC_AddCheckBox(menu, 0, vid.height - 64+8*5, "Players ", &sb_showplayers, 1);
MC_AddCheckBox(menu, 0, vid.height - 64+8*6, "Fraglimit", &sb_showfraglimit, 1);
MC_AddCheckBox(menu, 0, vid.height - 64+8*7, "Timelimit", &sb_showtimelimit, 1);
MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*1, "List NQ ", SL_ReFilter, 1);
MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*2, "List QW ", SL_ReFilter, 2);
MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*3, "List Q2 ", SL_ReFilter, 3);
MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*4, "List Q3 ", SL_ReFilter, 4);
MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*6, "Hide Empty", SL_ReFilter, 6);
MC_AddCheckBoxFunc(menu, 128, vid.height - 64+8*7, "Hide Full ", SL_ReFilter, 7);
info->filter[1] = !sb_hidenetquake.value;
info->filter[2] = !sb_hidequakeworld.value;
info->filter[3] = !sb_hidequake2.value;
info->filter[4] = !sb_hidequake3.value;
info->filter[6] = !!sb_hideempty.value;
info->filter[7] = !!sb_hidefull.value;
info->mappic = (menupicture_t *)MC_AddStrechPicture(menu, vid.width - 64, vid.height - 64, 64, 64, "012345678901234567890123456789012");
CalcFilters(menu);
Master_SetSortField(SLKEY_PING, true);
}
#endif

View File

@ -4,7 +4,7 @@
#include "winquake.h"
//these are awkward/strange
qboolean M_Options_AlwaysRun (union menuoption_s *option, chk_set_t set)
qboolean M_Options_AlwaysRun (menucheck_t *option, struct menu_s *menu, chk_set_t set)
{
if (set == CHK_CHECKED)
return cl_forwardspeed.value > 200;
@ -21,7 +21,7 @@ qboolean M_Options_AlwaysRun (union menuoption_s *option, chk_set_t set)
return true;
}
}
qboolean M_Options_InvertMouse (union menuoption_s *option, chk_set_t set)
qboolean M_Options_InvertMouse (menucheck_t *option, struct menu_s *menu, chk_set_t set)
{
if (set == CHK_CHECKED)
return m_pitch.value < 0;

View File

@ -804,6 +804,7 @@ void M_Menu_Quit_f (void)
//=============================================================================
/* Menu Subsystem */
void M_Menu_ServerList2_f(void);
void M_Menu_MediaFiles_f (void);
void M_Menu_FPS_f (void);
@ -838,6 +839,8 @@ void M_Init_Internal (void)
Cmd_AddRemCommand ("menu_mediafiles", M_Menu_MediaFiles_f);
#ifdef CL_MASTER
Cmd_AddRemCommand ("menu_servers2", M_Menu_ServerList2_f);
Cmd_AddRemCommand ("menu_servers", M_Menu_ServerList_f);
Cmd_AddRemCommand ("menu_slist", M_Menu_ServerList_f);
#endif

View File

@ -116,7 +116,7 @@ struct menu_s;
typedef enum {m_none, m_complex, m_help, m_keys, m_slist, m_media, m_plugin, m_menu_dat} m_state_t;
extern m_state_t m_state;
typedef enum {mt_childwindow, mt_button, mt_buttonbigfont, mt_box, mt_colouredbox, mt_line, mt_edit, mt_text, mt_slider, mt_combo, mt_bind, mt_checkbox, mt_picture, mt_menudot, mt_custom} menutype_t;
typedef enum {mt_childwindow, mt_button, mt_buttonbigfont, mt_box, mt_colouredbox, mt_line, mt_edit, mt_text, mt_slider, mt_combo, mt_bind, mt_checkbox, mt_picture, mt_strechpic, mt_menudot, mt_custom} menutype_t;
typedef struct { //must be first of each structure type.
menutype_t type;
@ -158,13 +158,13 @@ typedef struct {
} menuslider_t;
typedef enum {CHK_CHECKED, CHK_TOGGLE} chk_set_t;
typedef struct {
typedef struct menucheck_s {
menucommon_t common;
const char *text;
cvar_t *var;
int bits;
float value;
qboolean (*func) (union menuoption_s *option, chk_set_t set);
qboolean (*func) (struct menucheck_s *option, struct menu_s *menu, chk_set_t set);
} menucheck_t;
typedef struct {
@ -227,6 +227,7 @@ typedef struct menu_s {
int ypos;
int width;
int height;
qboolean dontexpand;
int numoptions;
qboolean iszone;
@ -254,10 +255,12 @@ menutext_t *MC_AddWhiteText(menu_t *menu, int x, int y, const char *text, qboole
menubind_t *MC_AddBind(menu_t *menu, int x, int y, const char *caption, char *command);
menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height);
menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, char *picname);
menupicture_t *MC_AddStrechPicture(menu_t *menu, int x, int y, int width, int height, char *picname);
menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, char *picname);
menupicture_t *MC_AddCursor(menu_t *menu, int x, int y);
menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max);
menucheck_t *MC_AddCheckBox(menu_t *menu, int x, int y, const char *text, cvar_t *var, int cvarbitmask);
menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int x, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits);
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int x, int y, const char *text, const char *command);
menubutton_t *MC_AddCommand(menu_t *menu, int x, int y, char *text, qboolean (*command) (union menuoption_s *,struct menu_s *,int));
menucombo_t *MC_AddCombo(menu_t *menu, int x, int y, const char *caption, const char **text, int initialvalue);

View File

@ -106,6 +106,7 @@ extern int FNC(Mod_SkinForName) (struct model_s *model, char *name);
#undef FNC
void Draw_FunString(int x, int y, unsigned char *str);
void Draw_FunStringLen(int x, int y, unsigned char *str, int len);
#ifdef SERVERONLY

View File

@ -153,7 +153,7 @@ qboolean Master_CompareInteger(int a, int b, slist_test_t rule)
switch(rule)
{
case SLIST_TEST_CONTAINS:
return a&b;
return !!(a&b);
case SLIST_TEST_NOTCONTAIN:
return !(a&b);
case SLIST_TEST_LESSEQUAL:
@ -205,6 +205,10 @@ qboolean Master_ServerIsGreater(serverinfo_t *a, serverinfo_t *b)
return Master_CompareInteger(a->players, b->players, SLIST_TEST_LESS);
case SLKEY_MAXPLAYERS:
return Master_CompareInteger(a->maxplayers, b->maxplayers, SLIST_TEST_LESS);
case SLKEY_FREEPLAYERS:
return Master_CompareInteger(a->maxplayers - a->players, b->maxplayers - b->players, SLIST_TEST_LESS);
case SLKEY_BASEGAME:
return Master_CompareInteger(a->special, b->special, SLIST_TEST_LESS);
case SLKEY_MAP:
return Master_CompareString(a->map, b->map, SLIST_TEST_LESS);
case SLKEY_GAMEDIR:
@ -218,43 +222,53 @@ qboolean Master_ServerIsGreater(serverinfo_t *a, serverinfo_t *b)
qboolean Master_PassesMasks(serverinfo_t *a)
{
int i;
qboolean val, res;
//always filter out dead unresponsive servers.
if (!a->ping)
return false;
val = 1;
for (i = 0; i < numvisrules; i++)
{
switch(visrules[i].fieldindex)
{
case SLKEY_PING:
if (!Master_CompareInteger(a->ping, visrules[i].operandi, visrules[i].compareop))
return false;
res = Master_CompareInteger(a->ping, visrules[i].operandi, visrules[i].compareop);
break;
case SLKEY_NUMPLAYERS:
if (!Master_CompareInteger(a->players, visrules[i].operandi, visrules[i].compareop))
return false;
res = Master_CompareInteger(a->players, visrules[i].operandi, visrules[i].compareop);
break;
case SLKEY_MAXPLAYERS:
if (!Master_CompareInteger(a->maxplayers, visrules[i].operandi, visrules[i].compareop))
return false;
res = Master_CompareInteger(a->maxplayers, visrules[i].operandi, visrules[i].compareop);
break;
case SLKEY_FREEPLAYERS:
res = Master_CompareInteger(a->maxplayers-a->players, visrules[i].operandi, visrules[i].compareop);
break;
case SLKEY_MAP:
if (!Master_CompareString(a->map, visrules[i].operands, visrules[i].compareop))
return false;
res = Master_CompareString(a->map, visrules[i].operands, visrules[i].compareop);
break;
case SLKEY_NAME:
if (!Master_CompareString(a->name, visrules[i].operands, visrules[i].compareop))
return false;
res = Master_CompareString(a->name, visrules[i].operands, visrules[i].compareop);
break;
case SLKEY_GAMEDIR:
if (!Master_CompareString(a->gamedir, visrules[i].operands, visrules[i].compareop))
return false;
res = Master_CompareString(a->gamedir, visrules[i].operands, visrules[i].compareop);
break;
case SLKEY_BASEGAME:
res = Master_CompareInteger(a->special, visrules[i].operandi, visrules[i].compareop);
break;
default:
continue;
}
if (visrules[i].or)
val |= res;
else
val &= res;
}
return true;
return val;
}
void Master_ClearMasks(void)
@ -408,6 +422,10 @@ float Master_ReadKeyFloat(serverinfo_t *server, int keynum)
return server->players;
case SLKEY_MAXPLAYERS:
return server->maxplayers;
case SLKEY_FREEPLAYERS:
return server->maxplayers - server->players;
case SLKEY_BASEGAME:
return server->special;
default:
return atof(Master_ReadKeyString(server, keynum));
@ -463,8 +481,12 @@ int Master_KeyForName(char *keyname)
return SLKEY_MAXPLAYERS;
else if (!strcmp(keyname, "numplayers"))
return SLKEY_NUMPLAYERS;
else if (!strcmp(keyname, "freeplayers"))
return SLKEY_FREEPLAYERS;
else if (!strcmp(keyname, "gamedir") || !strcmp(keyname, "game") || !strcmp(keyname, "*gamedir") || !strcmp(keyname, "mod"))
return SLKEY_GAMEDIR;
else if (!strcmp(keyname, "special"))
return SLKEY_BASEGAME;
else if (slist_customkeys == SLIST_MAXKEYS)
return SLKEY_TOOMANY;

View File

@ -165,6 +165,7 @@ LINK32=link.exe
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client\gltod3d\sdk7\include" /I "..\client\gltod3d\D3DFrame" /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /I "..\client" /D "NQPROT" /D "_DEBUG" /D "GLQUAKE" /D "SERVERDLL" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c
# ADD CPP /nologo /G5 /W3 /Gi /GX /ZI /Od /I "..\client" /I "../libs/dxsdk7/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /Fr /Fp".\MDebug/qwcl.pch" /Yu"quakedef.h" /FD /c
# SUBTRACT CPP /WX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
@ -9284,8 +9285,8 @@ SOURCE=..\client\winquake.rc
!IF "$(CFG)" == "ftequake - Win32 Release"
# ADD BASE RSC /l 0x809 /i "\Projects\fteqw\engine\client" /i "\ftetgcvs\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client"
# ADD RSC /l 0x809 /i "\Projects\fteqw\engine\client" /i "\ftetgcvs\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client" /d "MINIMAL"
# ADD BASE RSC /l 0x809 /i "\ftetgcvs\engine\client" /i "\Projects\fteqw\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client"
# ADD RSC /l 0x809 /i "\ftetgcvs\engine\client" /i "\Projects\fteqw\engine\client" /i "\windows\J\ftetgcvs\engine\client" /i "\ftetgcvs\source\client" /i "\ftetgcvs\temp\client" /i "\ftetgcvs\fte\QW\client" /d "MINIMAL"
!ELSEIF "$(CFG)" == "ftequake - Win32 Debug"
@ -9354,6 +9355,10 @@ SOURCE=..\nqnet\net_dgrm.h
SOURCE=..\common\protocol.h
# End Source File
# Begin Source File
SOURCE=..\client\quakedef.h
# End Source File
# End Group
# Begin Group "Resource Files"

View File

@ -2001,7 +2001,7 @@ void R_DrawGAliasModel (entity_t *e)
skin = GL_ChooseSkin(inf, clmodel->name, surfnum, e);
if (!skin || (skin->base == NULL
if (!skin || ((void*)skin->base == NULL
#ifdef Q3SHADERS
&& skin->shader == NULL
#endif
@ -3524,12 +3524,15 @@ static void Q2_LoadSkins(char *skins)
galias->numskins = LittleLong(pq2inmodel->num_skins);
#ifndef SERVERONLY
while (galias->numskins)
outskin = (galiasskin_t *)((char *)galias + galias->ofsskins);
outskin += galias->numskins - 1;
if (galias->numskins)
{
texnums = (galiastexnum_t*)((char *)outskin +outskin->ofstexnums);
if (texnums->base)
break;
return;
if (texnums->shader)
break;
return;
galias->numskins--;
}

View File

@ -380,8 +380,8 @@ void GLR_PushDlights (void)
if (!r_dynamic.value || !cl.worldmodel)
return;
// if (!cl.worldmodel->nodes)
// return;
if (!cl.worldmodel->nodes)
return;
currentmodel = cl.worldmodel;

View File

@ -1616,7 +1616,7 @@ void R_RenderScene (void)
{
qboolean GLR_DoomWorld(void);
if (!cl.worldmodel)
if (!cl.worldmodel || !cl.worldmodel->nodes)
r_refdef.flags |= Q2RDF_NOWORLDMODEL;
GLR_SetupFrame ();