From 6bf20c78f5b69d40bcc4931df93d29198435ab67 Mon Sep 17 00:00:00 2001 From: zakk Date: Fri, 26 Aug 2005 17:39:27 +0000 Subject: newlines fixed git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/q3_ui/Conscript | 186 +- code/q3_ui/compile.bat | 4 +- code/q3_ui/keycodes.h | 326 ++-- code/q3_ui/q3_ui.bat | 200 +- code/q3_ui/q3_ui.q3asm | 86 +- code/q3_ui/q3_ui.sh | 110 +- code/q3_ui/q3_ui.vcproj | 4016 ++++++++++++++++++++-------------------- code/q3_ui/ui.def | 6 +- code/q3_ui/ui.q3asm | 90 +- code/q3_ui/ui_addbots.c | 824 ++++----- code/q3_ui/ui_atoms.c | 2534 ++++++++++++------------- code/q3_ui/ui_cdkey.c | 582 +++--- code/q3_ui/ui_cinematics.c | 700 +++---- code/q3_ui/ui_confirm.c | 586 +++--- code/q3_ui/ui_connect.c | 564 +++--- code/q3_ui/ui_controls2.c | 3334 ++++++++++++++++----------------- code/q3_ui/ui_credits.c | 258 +-- code/q3_ui/ui_demo2.c | 582 +++--- code/q3_ui/ui_display.c | 530 +++--- code/q3_ui/ui_gameinfo.c | 1640 ++++++++-------- code/q3_ui/ui_ingame.c | 698 +++---- code/q3_ui/ui_loadconfig.c | 548 +++--- code/q3_ui/ui_local.h | 1600 ++++++++-------- code/q3_ui/ui_login.c | 416 ++--- code/q3_ui/ui_main.c | 498 ++--- code/q3_ui/ui_menu.c | 838 ++++----- code/q3_ui/ui_mfield.c | 878 ++++----- code/q3_ui/ui_mods.c | 566 +++--- code/q3_ui/ui_network.c | 562 +++--- code/q3_ui/ui_options.c | 458 ++--- code/q3_ui/ui_playermodel.c | 1462 +++++++-------- code/q3_ui/ui_players.c | 2496 ++++++++++++------------- code/q3_ui/ui_playersettings.c | 1026 +++++----- code/q3_ui/ui_preferences.c | 838 ++++----- code/q3_ui/ui_qmenu.c | 3492 +++++++++++++++++----------------- code/q3_ui/ui_rankings.c | 840 ++++----- code/q3_ui/ui_rankstatus.c | 418 ++--- code/q3_ui/ui_removebots.c | 684 +++---- code/q3_ui/ui_saveconfig.c | 424 ++--- code/q3_ui/ui_serverinfo.c | 544 +++--- code/q3_ui/ui_servers2.c | 3280 ++++++++++++++++---------------- code/q3_ui/ui_setup.c | 654 +++---- code/q3_ui/ui_signup.c | 572 +++--- code/q3_ui/ui_sound.c | 632 +++---- code/q3_ui/ui_sparena.c | 100 +- code/q3_ui/ui_specifyleague.c | 666 +++---- code/q3_ui/ui_specifyserver.c | 426 ++--- code/q3_ui/ui_splevel.c | 2016 ++++++++++---------- code/q3_ui/ui_sppostgame.c | 1288 ++++++------- code/q3_ui/ui_spreset.c | 388 ++-- code/q3_ui/ui_spskill.c | 658 +++---- code/q3_ui/ui_startserver.c | 3936 +++++++++++++++++++-------------------- code/q3_ui/ui_team.c | 420 ++--- code/q3_ui/ui_teamorders.c | 898 ++++----- code/q3_ui/ui_video.c | 2140 ++++++++++----------- 55 files changed, 27259 insertions(+), 27259 deletions(-) (limited to 'code/q3_ui') diff --git a/code/q3_ui/Conscript b/code/q3_ui/Conscript index 2387e25..d3967d7 100755 --- a/code/q3_ui/Conscript +++ b/code/q3_ui/Conscript @@ -1,93 +1,93 @@ -# Q3 ui building - -# qvm building against native: -# only native has ui_syscalls.c -# qvm uses a ui_syscalls.asm with equ stubs -# qvm has additional bg_lib.c - -Import qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK ); - -$env = new cons( - # the code has the very bad habit of doing things like #include "../ui/ui_shared.h" - # this seems to confuse the dependency analysis, explicit toplevel includes seem to fix - CPPPATH => '#cgame:#game:#q3_ui', - CC => $CC, - CXX => $CXX, - LINK => $LINK, - ENV => { PATH => $ENV{PATH}, HOME => $ENV{HOME} }, - CFLAGS => $BASE_CFLAGS . '-fPIC', - LDFLAGS => '-shared -ldl -lm' -); - -# qvm building -# we heavily customize the cons environment -$vm_env = new cons( - # the code has the very bad habit of doing things like #include "../ui/ui_shared.h" - # this seems to confuse the dependency analysis, explicit toplevel includes seem to fix - CPPPATH => '#cgame:#game:#q3_ui', - CC => 'q3lcc', - CCCOM => '%CC %CFLAGS %_IFLAGS -c %< -o %>', - SUFOBJ => '.asm', - LINK => 'q3asm', - CFLAGS => '-DQ3_VM -S -Wf-target=bytecode -Wf-g', - # need to know where to find the compiler tools - ENV => { PATH => $ENV{PATH} . ":./qvmtools", }, -); - -# the file with vmMain function MUST be the first one of the list -@FILES = qw( - ui_main.c - ../game/bg_misc.c - ../game/q_math.c - ../game/q_shared.c - ui_addbots.c - ui_atoms.c - ui_cdkey.c - ui_cinematics.c - ui_confirm.c - ui_connect.c - ui_controls2.c - ui_credits.c - ui_demo2.c - ui_display.c - ui_gameinfo.c - ui_ingame.c - ui_menu.c - ui_mfield.c - ui_mods.c - ui_network.c - ui_options.c - ui_playermodel.c - ui_players.c - ui_playersettings.c - ui_preferences.c - ui_qmenu.c - ui_removebots.c - ui_serverinfo.c - ui_servers2.c - ui_setup.c - ui_sound.c - ui_sparena.c - ui_specifyserver.c - ui_splevel.c - ui_sppostgame.c - ui_spskill.c - ui_startserver.c - ui_team.c - ui_teamorders.c - ui_video.c - ); -$FILESREF = \@FILES; - -if ($NO_SO eq 0) -{ - Program $env 'uii386.so', @$FILESREF, '../ui/ui_syscalls.c'; - Install $env $INSTALL_DIR, 'uii386.so'; -} -if ($NO_VM eq 0) -{ - Depends $vm_env 'ui.qvm', '#qvmtools/q3lcc'; - Depends $vm_env 'ui.qvm', '#qvmtools/q3asm'; - Program $vm_env 'ui.qvm', @$FILESREF, '../game/bg_lib.c', '../ui/ui_syscalls.asm'; - Install $vm_env $INSTALL_DIR . '/vm', 'ui.qvm'; -} +# Q3 ui building + +# qvm building against native: +# only native has ui_syscalls.c +# qvm uses a ui_syscalls.asm with equ stubs +# qvm has additional bg_lib.c + +Import qw( BASE_CFLAGS TARGET_DIR INSTALL_DIR NO_VM NO_SO CC CXX LINK ); + +$env = new cons( + # the code has the very bad habit of doing things like #include "../ui/ui_shared.h" + # this seems to confuse the dependency analysis, explicit toplevel includes seem to fix + CPPPATH => '#cgame:#game:#q3_ui', + CC => $CC, + CXX => $CXX, + LINK => $LINK, + ENV => { PATH => $ENV{PATH}, HOME => $ENV{HOME} }, + CFLAGS => $BASE_CFLAGS . '-fPIC', + LDFLAGS => '-shared -ldl -lm' +); + +# qvm building +# we heavily customize the cons environment +$vm_env = new cons( + # the code has the very bad habit of doing things like #include "../ui/ui_shared.h" + # this seems to confuse the dependency analysis, explicit toplevel includes seem to fix + CPPPATH => '#cgame:#game:#q3_ui', + CC => 'q3lcc', + CCCOM => '%CC %CFLAGS %_IFLAGS -c %< -o %>', + SUFOBJ => '.asm', + LINK => 'q3asm', + CFLAGS => '-DQ3_VM -S -Wf-target=bytecode -Wf-g', + # need to know where to find the compiler tools + ENV => { PATH => $ENV{PATH} . ":./qvmtools", }, +); + +# the file with vmMain function MUST be the first one of the list +@FILES = qw( + ui_main.c + ../game/bg_misc.c + ../game/q_math.c + ../game/q_shared.c + ui_addbots.c + ui_atoms.c + ui_cdkey.c + ui_cinematics.c + ui_confirm.c + ui_connect.c + ui_controls2.c + ui_credits.c + ui_demo2.c + ui_display.c + ui_gameinfo.c + ui_ingame.c + ui_menu.c + ui_mfield.c + ui_mods.c + ui_network.c + ui_options.c + ui_playermodel.c + ui_players.c + ui_playersettings.c + ui_preferences.c + ui_qmenu.c + ui_removebots.c + ui_serverinfo.c + ui_servers2.c + ui_setup.c + ui_sound.c + ui_sparena.c + ui_specifyserver.c + ui_splevel.c + ui_sppostgame.c + ui_spskill.c + ui_startserver.c + ui_team.c + ui_teamorders.c + ui_video.c + ); +$FILESREF = \@FILES; + +if ($NO_SO eq 0) +{ + Program $env 'uii386.so', @$FILESREF, '../ui/ui_syscalls.c'; + Install $env $INSTALL_DIR, 'uii386.so'; +} +if ($NO_VM eq 0) +{ + Depends $vm_env 'ui.qvm', '#qvmtools/q3lcc'; + Depends $vm_env 'ui.qvm', '#qvmtools/q3asm'; + Program $vm_env 'ui.qvm', @$FILESREF, '../game/bg_lib.c', '../ui/ui_syscalls.asm'; + Install $vm_env $INSTALL_DIR . '/vm', 'ui.qvm'; +} diff --git a/code/q3_ui/compile.bat b/code/q3_ui/compile.bat index 8299251..64308bb 100755 --- a/code/q3_ui/compile.bat +++ b/code/q3_ui/compile.bat @@ -1,2 +1,2 @@ -lcc -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1 - +lcc -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1 + diff --git a/code/q3_ui/keycodes.h b/code/q3_ui/keycodes.h index a1a0f1f..8f58482 100755 --- a/code/q3_ui/keycodes.h +++ b/code/q3_ui/keycodes.h @@ -1,163 +1,163 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#ifndef __KEYCODES_H__ -#define __KEYCODES_H__ - -// -// these are the key numbers that should be passed to KeyEvent -// - -// normal keys should be passed as lowercased ascii - -typedef enum { - K_TAB = 9, - K_ENTER = 13, - K_ESCAPE = 27, - K_SPACE = 32, - - K_BACKSPACE = 127, - - K_COMMAND = 128, - K_CAPSLOCK, - K_POWER, - K_PAUSE, - - K_UPARROW, - K_DOWNARROW, - K_LEFTARROW, - K_RIGHTARROW, - - K_ALT, - K_CTRL, - K_SHIFT, - K_INS, - K_DEL, - K_PGDN, - K_PGUP, - K_HOME, - K_END, - - K_F1, - K_F2, - K_F3, - K_F4, - K_F5, - K_F6, - K_F7, - K_F8, - K_F9, - K_F10, - K_F11, - K_F12, - K_F13, - K_F14, - K_F15, - - K_KP_HOME, - K_KP_UPARROW, - K_KP_PGUP, - K_KP_LEFTARROW, - K_KP_5, - K_KP_RIGHTARROW, - K_KP_END, - K_KP_DOWNARROW, - K_KP_PGDN, - K_KP_ENTER, - K_KP_INS, - K_KP_DEL, - K_KP_SLASH, - K_KP_MINUS, - K_KP_PLUS, - K_KP_NUMLOCK, - K_KP_STAR, - K_KP_EQUALS, - - K_MOUSE1, - K_MOUSE2, - K_MOUSE3, - K_MOUSE4, - K_MOUSE5, - - K_MWHEELDOWN, - K_MWHEELUP, - - K_JOY1, - K_JOY2, - K_JOY3, - K_JOY4, - K_JOY5, - K_JOY6, - K_JOY7, - K_JOY8, - K_JOY9, - K_JOY10, - K_JOY11, - K_JOY12, - K_JOY13, - K_JOY14, - K_JOY15, - K_JOY16, - K_JOY17, - K_JOY18, - K_JOY19, - K_JOY20, - K_JOY21, - K_JOY22, - K_JOY23, - K_JOY24, - K_JOY25, - K_JOY26, - K_JOY27, - K_JOY28, - K_JOY29, - K_JOY30, - K_JOY31, - K_JOY32, - - K_AUX1, - K_AUX2, - K_AUX3, - K_AUX4, - K_AUX5, - K_AUX6, - K_AUX7, - K_AUX8, - K_AUX9, - K_AUX10, - K_AUX11, - K_AUX12, - K_AUX13, - K_AUX14, - K_AUX15, - K_AUX16, - - K_LAST_KEY // this had better be <256! -} keyNum_t; - - -// The menu code needs to get both key and char events, but -// to avoid duplicating the paths, the char events are just -// distinguished by or'ing in K_CHAR_FLAG (ugly) -#define K_CHAR_FLAG 1024 - -#endif +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#ifndef __KEYCODES_H__ +#define __KEYCODES_H__ + +// +// these are the key numbers that should be passed to KeyEvent +// + +// normal keys should be passed as lowercased ascii + +typedef enum { + K_TAB = 9, + K_ENTER = 13, + K_ESCAPE = 27, + K_SPACE = 32, + + K_BACKSPACE = 127, + + K_COMMAND = 128, + K_CAPSLOCK, + K_POWER, + K_PAUSE, + + K_UPARROW, + K_DOWNARROW, + K_LEFTARROW, + K_RIGHTARROW, + + K_ALT, + K_CTRL, + K_SHIFT, + K_INS, + K_DEL, + K_PGDN, + K_PGUP, + K_HOME, + K_END, + + K_F1, + K_F2, + K_F3, + K_F4, + K_F5, + K_F6, + K_F7, + K_F8, + K_F9, + K_F10, + K_F11, + K_F12, + K_F13, + K_F14, + K_F15, + + K_KP_HOME, + K_KP_UPARROW, + K_KP_PGUP, + K_KP_LEFTARROW, + K_KP_5, + K_KP_RIGHTARROW, + K_KP_END, + K_KP_DOWNARROW, + K_KP_PGDN, + K_KP_ENTER, + K_KP_INS, + K_KP_DEL, + K_KP_SLASH, + K_KP_MINUS, + K_KP_PLUS, + K_KP_NUMLOCK, + K_KP_STAR, + K_KP_EQUALS, + + K_MOUSE1, + K_MOUSE2, + K_MOUSE3, + K_MOUSE4, + K_MOUSE5, + + K_MWHEELDOWN, + K_MWHEELUP, + + K_JOY1, + K_JOY2, + K_JOY3, + K_JOY4, + K_JOY5, + K_JOY6, + K_JOY7, + K_JOY8, + K_JOY9, + K_JOY10, + K_JOY11, + K_JOY12, + K_JOY13, + K_JOY14, + K_JOY15, + K_JOY16, + K_JOY17, + K_JOY18, + K_JOY19, + K_JOY20, + K_JOY21, + K_JOY22, + K_JOY23, + K_JOY24, + K_JOY25, + K_JOY26, + K_JOY27, + K_JOY28, + K_JOY29, + K_JOY30, + K_JOY31, + K_JOY32, + + K_AUX1, + K_AUX2, + K_AUX3, + K_AUX4, + K_AUX5, + K_AUX6, + K_AUX7, + K_AUX8, + K_AUX9, + K_AUX10, + K_AUX11, + K_AUX12, + K_AUX13, + K_AUX14, + K_AUX15, + K_AUX16, + + K_LAST_KEY // this had better be <256! +} keyNum_t; + + +// The menu code needs to get both key and char events, but +// to avoid duplicating the paths, the char events are just +// distinguished by or'ing in K_CHAR_FLAG (ugly) +#define K_CHAR_FLAG 1024 + +#endif diff --git a/code/q3_ui/q3_ui.bat b/code/q3_ui/q3_ui.bat index b86f4f6..189e648 100755 --- a/code/q3_ui/q3_ui.bat +++ b/code/q3_ui/q3_ui.bat @@ -1,100 +1,100 @@ -rem make sure we have a safe environement -set LIBRARY= -set INCLUDE= - -mkdir vm -cd vm - -set cc=lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui %1 - -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_main.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_cdkey.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_ingame.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_serverinfo.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_confirm.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_setup.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/bg_misc.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/bg_lib.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/q_math.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/q_shared.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_gameinfo.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_atoms.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_connect.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_controls2.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_demo2.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_mfield.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_credits.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_menu.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_options.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_display.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_sound.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_network.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_playermodel.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_players.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_playersettings.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_preferences.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_qmenu.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_servers2.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_sparena.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_specifyserver.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_splevel.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_sppostgame.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_startserver.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_team.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_video.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_cinematics.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_spskill.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_addbots.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_removebots.c -@if errorlevel 1 goto quit -rem lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_loadconfig.c -rem @if errorlevel 1 goto quit -rem lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_saveconfig.c -rem @if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_teamorders.c -@if errorlevel 1 goto quit -lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_mods.c -@if errorlevel 1 goto quit - - -q3asm -f ../q3_ui -:quit -cd .. +rem make sure we have a safe environement +set LIBRARY= +set INCLUDE= + +mkdir vm +cd vm + +set cc=lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui %1 + +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_main.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_cdkey.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_ingame.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_serverinfo.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_confirm.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_setup.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/bg_misc.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/bg_lib.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/q_math.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../../game/q_shared.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_gameinfo.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_atoms.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_connect.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_controls2.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_demo2.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_mfield.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_credits.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_menu.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_options.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_display.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_sound.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_network.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_playermodel.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_players.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_playersettings.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_preferences.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_qmenu.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_servers2.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_sparena.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_specifyserver.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_splevel.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_sppostgame.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_startserver.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_team.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_video.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_cinematics.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_spskill.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_addbots.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_removebots.c +@if errorlevel 1 goto quit +rem lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_loadconfig.c +rem @if errorlevel 1 goto quit +rem lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_saveconfig.c +rem @if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_teamorders.c +@if errorlevel 1 goto quit +lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\q3_ui ../ui_mods.c +@if errorlevel 1 goto quit + + +q3asm -f ../q3_ui +:quit +cd .. diff --git a/code/q3_ui/q3_ui.q3asm b/code/q3_ui/q3_ui.q3asm index 09ec962..8257bc3 100755 --- a/code/q3_ui/q3_ui.q3asm +++ b/code/q3_ui/q3_ui.q3asm @@ -1,43 +1,43 @@ --o "\quake3\baseq3\vm\ui" -ui_main -..\..\ui\ui_syscalls -ui_gameinfo -ui_atoms -ui_cinematics -ui_connect -ui_controls2 -ui_demo2 -ui_mfield -ui_credits -ui_menu -ui_ingame -ui_confirm -ui_setup -ui_options -ui_display -ui_sound -ui_network -ui_playermodel -ui_players -ui_playersettings -ui_preferences -ui_qmenu -ui_serverinfo -ui_servers2 -ui_sparena -ui_specifyserver -ui_sppostgame -ui_splevel -ui_spskill -ui_startserver -ui_team -ui_video -ui_addbots -ui_removebots -ui_teamorders -ui_cdkey -ui_mods -bg_misc -bg_lib -q_math -q_shared +-o "\quake3\baseq3\vm\ui" +ui_main +..\..\ui\ui_syscalls +ui_gameinfo +ui_atoms +ui_cinematics +ui_connect +ui_controls2 +ui_demo2 +ui_mfield +ui_credits +ui_menu +ui_ingame +ui_confirm +ui_setup +ui_options +ui_display +ui_sound +ui_network +ui_playermodel +ui_players +ui_playersettings +ui_preferences +ui_qmenu +ui_serverinfo +ui_servers2 +ui_sparena +ui_specifyserver +ui_sppostgame +ui_splevel +ui_spskill +ui_startserver +ui_team +ui_video +ui_addbots +ui_removebots +ui_teamorders +ui_cdkey +ui_mods +bg_misc +bg_lib +q_math +q_shared diff --git a/code/q3_ui/q3_ui.sh b/code/q3_ui/q3_ui.sh index 377d16e..18ebaf3 100755 --- a/code/q3_ui/q3_ui.sh +++ b/code/q3_ui/q3_ui.sh @@ -1,55 +1,55 @@ -#!/bin/sh - -mkdir -p vm -cd vm - -CC="q3lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I../../cgame -I../../game -I../../q3_ui " - -$CC ../ui_main.c -$CC ../ui_cdkey.c -$CC ../ui_ingame.c -$CC ../ui_confirm.c -$CC ../ui_setup.c -$CC ../../game/bg_misc.c -$CC ../../game/bg_lib.c -$CC ../../game/q_math.c -$CC ../../game/q_shared.c -$CC ../ui_gameinfo.c -$CC ../ui_atoms.c -$CC ../ui_connect.c -$CC ../ui_controls2.c -$CC ../ui_demo2.c -$CC ../ui_mfield.c -$CC ../ui_credits.c -$CC ../ui_menu.c -$CC ../ui_options.c -$CC ../ui_display.c -$CC ../ui_sound.c -$CC ../ui_network.c -$CC ../ui_playermodel.c -$CC ../ui_players.c -$CC ../ui_playersettings.c -$CC ../ui_preferences.c -$CC ../ui_qmenu.c -$CC ../ui_serverinfo.c -$CC ../ui_servers2.c -$CC ../ui_sparena.c -$CC ../ui_specifyserver.c -$CC ../ui_splevel.c -$CC ../ui_sppostgame.c -$CC ../ui_startserver.c -$CC ../ui_syscalls.c -$CC ../ui_team.c -$CC ../ui_video.c -$CC ../ui_cinematics.c -$CC ../ui_spskill.c -$CC ../ui_addbots.c -$CC ../ui_removebots.c -$CC ../ui_loadconfig.c -$CC ../ui_saveconfig.c -$CC ../ui_teamorders.c -$CC ../ui_mods.c - -q3asm -f ../q3_ui - -cd .. +#!/bin/sh + +mkdir -p vm +cd vm + +CC="q3lcc -DQ3_VM -S -Wf-target=bytecode -Wf-g -I../../cgame -I../../game -I../../q3_ui " + +$CC ../ui_main.c +$CC ../ui_cdkey.c +$CC ../ui_ingame.c +$CC ../ui_confirm.c +$CC ../ui_setup.c +$CC ../../game/bg_misc.c +$CC ../../game/bg_lib.c +$CC ../../game/q_math.c +$CC ../../game/q_shared.c +$CC ../ui_gameinfo.c +$CC ../ui_atoms.c +$CC ../ui_connect.c +$CC ../ui_controls2.c +$CC ../ui_demo2.c +$CC ../ui_mfield.c +$CC ../ui_credits.c +$CC ../ui_menu.c +$CC ../ui_options.c +$CC ../ui_display.c +$CC ../ui_sound.c +$CC ../ui_network.c +$CC ../ui_playermodel.c +$CC ../ui_players.c +$CC ../ui_playersettings.c +$CC ../ui_preferences.c +$CC ../ui_qmenu.c +$CC ../ui_serverinfo.c +$CC ../ui_servers2.c +$CC ../ui_sparena.c +$CC ../ui_specifyserver.c +$CC ../ui_splevel.c +$CC ../ui_sppostgame.c +$CC ../ui_startserver.c +$CC ../ui_syscalls.c +$CC ../ui_team.c +$CC ../ui_video.c +$CC ../ui_cinematics.c +$CC ../ui_spskill.c +$CC ../ui_addbots.c +$CC ../ui_removebots.c +$CC ../ui_loadconfig.c +$CC ../ui_saveconfig.c +$CC ../ui_teamorders.c +$CC ../ui_mods.c + +q3asm -f ../q3_ui + +cd .. diff --git a/code/q3_ui/q3_ui.vcproj b/code/q3_ui/q3_ui.vcproj index 8c1d78d..4ffaba9 100755 --- a/code/q3_ui/q3_ui.vcproj +++ b/code/q3_ui/q3_ui.vcproj @@ -1,2008 +1,2008 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/q3_ui/ui.def b/code/q3_ui/ui.def index 01861ba..2ee748e 100755 --- a/code/q3_ui/ui.def +++ b/code/q3_ui/ui.def @@ -1,3 +1,3 @@ -EXPORTS - vmMain - dllEntry +EXPORTS + vmMain + dllEntry diff --git a/code/q3_ui/ui.q3asm b/code/q3_ui/ui.q3asm index 80936bd..cbb6251 100755 --- a/code/q3_ui/ui.q3asm +++ b/code/q3_ui/ui.q3asm @@ -1,45 +1,45 @@ --o "\quake3\baseq3\vm\ui" -ui_main -..\ui_syscalls -ui_gameinfo -ui_atoms -ui_cinematics -ui_connect -ui_controls2 -ui_demo2 -ui_mfield -ui_credits -ui_menu -ui_ingame -ui_confirm -ui_setup -ui_options -ui_display -ui_sound -ui_network -ui_playermodel -ui_players -ui_playersettings -ui_preferences -ui_qmenu -ui_serverinfo -ui_servers2 -ui_sparena -ui_specifyserver -ui_sppostgame -ui_splevel -ui_spskill -ui_startserver -ui_team -ui_video -ui_addbots -ui_removebots -ui_teamorders -ui_loadconfig -ui_saveconfig -ui_cdkey -ui_mods -bg_misc -bg_lib -q_math -q_shared +-o "\quake3\baseq3\vm\ui" +ui_main +..\ui_syscalls +ui_gameinfo +ui_atoms +ui_cinematics +ui_connect +ui_controls2 +ui_demo2 +ui_mfield +ui_credits +ui_menu +ui_ingame +ui_confirm +ui_setup +ui_options +ui_display +ui_sound +ui_network +ui_playermodel +ui_players +ui_playersettings +ui_preferences +ui_qmenu +ui_serverinfo +ui_servers2 +ui_sparena +ui_specifyserver +ui_sppostgame +ui_splevel +ui_spskill +ui_startserver +ui_team +ui_video +ui_addbots +ui_removebots +ui_teamorders +ui_loadconfig +ui_saveconfig +ui_cdkey +ui_mods +bg_misc +bg_lib +q_math +q_shared diff --git a/code/q3_ui/ui_addbots.c b/code/q3_ui/ui_addbots.c index ba906f3..c01bc58 100755 --- a/code/q3_ui/ui_addbots.c +++ b/code/q3_ui/ui_addbots.c @@ -1,412 +1,412 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -ADD BOTS MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FIGHT0 "menu/art/accept_0" -#define ART_FIGHT1 "menu/art/accept_1" -#define ART_BACKGROUND "menu/art/addbotframe" -#define ART_ARROWS "menu/art/arrows_vert_0" -#define ART_ARROWUP "menu/art/arrows_vert_top" -#define ART_ARROWDOWN "menu/art/arrows_vert_bot" - -#define ID_BACK 10 -#define ID_GO 11 -#define ID_LIST 12 -#define ID_UP 13 -#define ID_DOWN 14 -#define ID_SKILL 15 -#define ID_TEAM 16 -#define ID_BOTNAME0 20 -#define ID_BOTNAME1 21 -#define ID_BOTNAME2 22 -#define ID_BOTNAME3 23 -#define ID_BOTNAME4 24 -#define ID_BOTNAME5 25 -#define ID_BOTNAME6 26 - - -typedef struct { - menuframework_s menu; - menubitmap_s arrows; - menubitmap_s up; - menubitmap_s down; - menutext_s bots[7]; - menulist_s skill; - menulist_s team; - menubitmap_s go; - menubitmap_s back; - - int numBots; - int delay; - int baseBotNum; - int selectedBotNum; - int sortedBotNums[MAX_BOTS]; - char botnames[7][32]; -} addBotsMenuInfo_t; - -static addBotsMenuInfo_t addBotsMenuInfo; - - -/* -================= -UI_AddBotsMenu_FightEvent -================= -*/ -static void UI_AddBotsMenu_FightEvent( void* ptr, int event ) { - const char *team; - int skill; - - if (event != QM_ACTIVATED) { - return; - } - - team = addBotsMenuInfo.team.itemnames[addBotsMenuInfo.team.curvalue]; - skill = addBotsMenuInfo.skill.curvalue + 1; - - trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot %s %i %s %i\n", - addBotsMenuInfo.botnames[addBotsMenuInfo.selectedBotNum], skill, team, addBotsMenuInfo.delay) ); - - addBotsMenuInfo.delay += 1500; -} - - -/* -================= -UI_AddBotsMenu_BotEvent -================= -*/ -static void UI_AddBotsMenu_BotEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - - addBotsMenuInfo.bots[addBotsMenuInfo.selectedBotNum].color = color_orange; - addBotsMenuInfo.selectedBotNum = ((menucommon_s*)ptr)->id - ID_BOTNAME0; - addBotsMenuInfo.bots[addBotsMenuInfo.selectedBotNum].color = color_white; -} - - -/* -================= -UI_AddBotsMenu_BackEvent -================= -*/ -static void UI_AddBotsMenu_BackEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - UI_PopMenu(); -} - - -/* -================= -UI_AddBotsMenu_SetBotNames -================= -*/ -static void UI_AddBotsMenu_SetBotNames( void ) { - int n; - const char *info; - - for ( n = 0; n < 7; n++ ) { - info = UI_GetBotInfoByNumber( addBotsMenuInfo.sortedBotNums[addBotsMenuInfo.baseBotNum + n] ); - Q_strncpyz( addBotsMenuInfo.botnames[n], Info_ValueForKey( info, "name" ), sizeof(addBotsMenuInfo.botnames[n]) ); - } - -} - - -/* -================= -UI_AddBotsMenu_UpEvent -================= -*/ -static void UI_AddBotsMenu_UpEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - - if( addBotsMenuInfo.baseBotNum > 0 ) { - addBotsMenuInfo.baseBotNum--; - UI_AddBotsMenu_SetBotNames(); - } -} - - -/* -================= -UI_AddBotsMenu_DownEvent -================= -*/ -static void UI_AddBotsMenu_DownEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - - if( addBotsMenuInfo.baseBotNum + 7 < addBotsMenuInfo.numBots ) { - addBotsMenuInfo.baseBotNum++; - UI_AddBotsMenu_SetBotNames(); - } -} - - -/* -================= -UI_AddBotsMenu_GetSortedBotNums -================= -*/ -static int QDECL UI_AddBotsMenu_SortCompare( const void *arg1, const void *arg2 ) { - int num1, num2; - const char *info1, *info2; - const char *name1, *name2; - - num1 = *(int *)arg1; - num2 = *(int *)arg2; - - info1 = UI_GetBotInfoByNumber( num1 ); - info2 = UI_GetBotInfoByNumber( num2 ); - - name1 = Info_ValueForKey( info1, "name" ); - name2 = Info_ValueForKey( info2, "name" ); - - return Q_stricmp( name1, name2 ); -} - -static void UI_AddBotsMenu_GetSortedBotNums( void ) { - int n; - - // initialize the array - for( n = 0; n < addBotsMenuInfo.numBots; n++ ) { - addBotsMenuInfo.sortedBotNums[n] = n; - } - - qsort( addBotsMenuInfo.sortedBotNums, addBotsMenuInfo.numBots, sizeof(addBotsMenuInfo.sortedBotNums[0]), UI_AddBotsMenu_SortCompare ); -} - - -/* -================= -UI_AddBotsMenu_Draw -================= -*/ -static void UI_AddBotsMenu_Draw( void ) { - UI_DrawBannerString( 320, 16, "ADD BOTS", UI_CENTER, color_white ); - UI_DrawNamedPic( 320-233, 240-166, 466, 332, ART_BACKGROUND ); - - // standard menu drawing - Menu_Draw( &addBotsMenuInfo.menu ); -} - - -/* -================= -UI_AddBotsMenu_Init -================= -*/ -static const char *skillNames[] = { - "I Can Win", - "Bring It On", - "Hurt Me Plenty", - "Hardcore", - "Nightmare!", - 0 -}; - -static const char *teamNames1[] = { - "Free", - 0 -}; - -static const char *teamNames2[] = { - "Red", - "Blue", - 0 -}; - -static void UI_AddBotsMenu_Init( void ) { - int n; - int y; - int gametype; - int count; - char info[MAX_INFO_STRING]; - - trap_GetConfigString(CS_SERVERINFO, info, MAX_INFO_STRING); - gametype = atoi( Info_ValueForKey( info,"g_gametype" ) ); - - memset( &addBotsMenuInfo, 0 ,sizeof(addBotsMenuInfo) ); - addBotsMenuInfo.menu.draw = UI_AddBotsMenu_Draw; - addBotsMenuInfo.menu.fullscreen = qfalse; - addBotsMenuInfo.menu.wrapAround = qtrue; - addBotsMenuInfo.delay = 1000; - - UI_AddBots_Cache(); - - addBotsMenuInfo.numBots = UI_GetNumBots(); - count = addBotsMenuInfo.numBots < 7 ? addBotsMenuInfo.numBots : 7; - - addBotsMenuInfo.arrows.generic.type = MTYPE_BITMAP; - addBotsMenuInfo.arrows.generic.name = ART_ARROWS; - addBotsMenuInfo.arrows.generic.flags = QMF_INACTIVE; - addBotsMenuInfo.arrows.generic.x = 200; - addBotsMenuInfo.arrows.generic.y = 128; - addBotsMenuInfo.arrows.width = 64; - addBotsMenuInfo.arrows.height = 128; - - addBotsMenuInfo.up.generic.type = MTYPE_BITMAP; - addBotsMenuInfo.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - addBotsMenuInfo.up.generic.x = 200; - addBotsMenuInfo.up.generic.y = 128; - addBotsMenuInfo.up.generic.id = ID_UP; - addBotsMenuInfo.up.generic.callback = UI_AddBotsMenu_UpEvent; - addBotsMenuInfo.up.width = 64; - addBotsMenuInfo.up.height = 64; - addBotsMenuInfo.up.focuspic = ART_ARROWUP; - - addBotsMenuInfo.down.generic.type = MTYPE_BITMAP; - addBotsMenuInfo.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - addBotsMenuInfo.down.generic.x = 200; - addBotsMenuInfo.down.generic.y = 128+64; - addBotsMenuInfo.down.generic.id = ID_DOWN; - addBotsMenuInfo.down.generic.callback = UI_AddBotsMenu_DownEvent; - addBotsMenuInfo.down.width = 64; - addBotsMenuInfo.down.height = 64; - addBotsMenuInfo.down.focuspic = ART_ARROWDOWN; - - for( n = 0, y = 120; n < count; n++, y += 20 ) { - addBotsMenuInfo.bots[n].generic.type = MTYPE_PTEXT; - addBotsMenuInfo.bots[n].generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - addBotsMenuInfo.bots[n].generic.id = ID_BOTNAME0 + n; - addBotsMenuInfo.bots[n].generic.x = 320 - 56; - addBotsMenuInfo.bots[n].generic.y = y; - addBotsMenuInfo.bots[n].generic.callback = UI_AddBotsMenu_BotEvent; - addBotsMenuInfo.bots[n].string = addBotsMenuInfo.botnames[n]; - addBotsMenuInfo.bots[n].color = color_orange; - addBotsMenuInfo.bots[n].style = UI_LEFT|UI_SMALLFONT; - } - - y += 12; - addBotsMenuInfo.skill.generic.type = MTYPE_SPINCONTROL; - addBotsMenuInfo.skill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - addBotsMenuInfo.skill.generic.x = 320; - addBotsMenuInfo.skill.generic.y = y; - addBotsMenuInfo.skill.generic.name = "Skill:"; - addBotsMenuInfo.skill.generic.id = ID_SKILL; - addBotsMenuInfo.skill.itemnames = skillNames; - addBotsMenuInfo.skill.curvalue = Com_Clamp( 0, 4, (int)trap_Cvar_VariableValue( "g_spSkill" ) - 1 ); - - y += SMALLCHAR_HEIGHT; - addBotsMenuInfo.team.generic.type = MTYPE_SPINCONTROL; - addBotsMenuInfo.team.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - addBotsMenuInfo.team.generic.x = 320; - addBotsMenuInfo.team.generic.y = y; - addBotsMenuInfo.team.generic.name = "Team: "; - addBotsMenuInfo.team.generic.id = ID_TEAM; - if( gametype >= GT_TEAM ) { - addBotsMenuInfo.team.itemnames = teamNames2; - } - else { - addBotsMenuInfo.team.itemnames = teamNames1; - addBotsMenuInfo.team.generic.flags = QMF_GRAYED; - } - - addBotsMenuInfo.go.generic.type = MTYPE_BITMAP; - addBotsMenuInfo.go.generic.name = ART_FIGHT0; - addBotsMenuInfo.go.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - addBotsMenuInfo.go.generic.id = ID_GO; - addBotsMenuInfo.go.generic.callback = UI_AddBotsMenu_FightEvent; - addBotsMenuInfo.go.generic.x = 320+128-128; - addBotsMenuInfo.go.generic.y = 256+128-64; - addBotsMenuInfo.go.width = 128; - addBotsMenuInfo.go.height = 64; - addBotsMenuInfo.go.focuspic = ART_FIGHT1; - - addBotsMenuInfo.back.generic.type = MTYPE_BITMAP; - addBotsMenuInfo.back.generic.name = ART_BACK0; - addBotsMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - addBotsMenuInfo.back.generic.id = ID_BACK; - addBotsMenuInfo.back.generic.callback = UI_AddBotsMenu_BackEvent; - addBotsMenuInfo.back.generic.x = 320-128; - addBotsMenuInfo.back.generic.y = 256+128-64; - addBotsMenuInfo.back.width = 128; - addBotsMenuInfo.back.height = 64; - addBotsMenuInfo.back.focuspic = ART_BACK1; - - addBotsMenuInfo.baseBotNum = 0; - addBotsMenuInfo.selectedBotNum = 0; - addBotsMenuInfo.bots[0].color = color_white; - - UI_AddBotsMenu_GetSortedBotNums(); - UI_AddBotsMenu_SetBotNames(); - - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.arrows ); - - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.up ); - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.down ); - for( n = 0; n < count; n++ ) { - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.bots[n] ); - } - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.skill ); - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.team ); - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.go ); - Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.back ); -} - - -/* -================= -UI_AddBots_Cache -================= -*/ -void UI_AddBots_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FIGHT0 ); - trap_R_RegisterShaderNoMip( ART_FIGHT1 ); - trap_R_RegisterShaderNoMip( ART_BACKGROUND ); - trap_R_RegisterShaderNoMip( ART_ARROWS ); - trap_R_RegisterShaderNoMip( ART_ARROWUP ); - trap_R_RegisterShaderNoMip( ART_ARROWDOWN ); -} - - -/* -================= -UI_AddBotsMenu -================= -*/ -void UI_AddBotsMenu( void ) { - UI_AddBotsMenu_Init(); - UI_PushMenu( &addBotsMenuInfo.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +ADD BOTS MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FIGHT0 "menu/art/accept_0" +#define ART_FIGHT1 "menu/art/accept_1" +#define ART_BACKGROUND "menu/art/addbotframe" +#define ART_ARROWS "menu/art/arrows_vert_0" +#define ART_ARROWUP "menu/art/arrows_vert_top" +#define ART_ARROWDOWN "menu/art/arrows_vert_bot" + +#define ID_BACK 10 +#define ID_GO 11 +#define ID_LIST 12 +#define ID_UP 13 +#define ID_DOWN 14 +#define ID_SKILL 15 +#define ID_TEAM 16 +#define ID_BOTNAME0 20 +#define ID_BOTNAME1 21 +#define ID_BOTNAME2 22 +#define ID_BOTNAME3 23 +#define ID_BOTNAME4 24 +#define ID_BOTNAME5 25 +#define ID_BOTNAME6 26 + + +typedef struct { + menuframework_s menu; + menubitmap_s arrows; + menubitmap_s up; + menubitmap_s down; + menutext_s bots[7]; + menulist_s skill; + menulist_s team; + menubitmap_s go; + menubitmap_s back; + + int numBots; + int delay; + int baseBotNum; + int selectedBotNum; + int sortedBotNums[MAX_BOTS]; + char botnames[7][32]; +} addBotsMenuInfo_t; + +static addBotsMenuInfo_t addBotsMenuInfo; + + +/* +================= +UI_AddBotsMenu_FightEvent +================= +*/ +static void UI_AddBotsMenu_FightEvent( void* ptr, int event ) { + const char *team; + int skill; + + if (event != QM_ACTIVATED) { + return; + } + + team = addBotsMenuInfo.team.itemnames[addBotsMenuInfo.team.curvalue]; + skill = addBotsMenuInfo.skill.curvalue + 1; + + trap_Cmd_ExecuteText( EXEC_APPEND, va("addbot %s %i %s %i\n", + addBotsMenuInfo.botnames[addBotsMenuInfo.selectedBotNum], skill, team, addBotsMenuInfo.delay) ); + + addBotsMenuInfo.delay += 1500; +} + + +/* +================= +UI_AddBotsMenu_BotEvent +================= +*/ +static void UI_AddBotsMenu_BotEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + + addBotsMenuInfo.bots[addBotsMenuInfo.selectedBotNum].color = color_orange; + addBotsMenuInfo.selectedBotNum = ((menucommon_s*)ptr)->id - ID_BOTNAME0; + addBotsMenuInfo.bots[addBotsMenuInfo.selectedBotNum].color = color_white; +} + + +/* +================= +UI_AddBotsMenu_BackEvent +================= +*/ +static void UI_AddBotsMenu_BackEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + UI_PopMenu(); +} + + +/* +================= +UI_AddBotsMenu_SetBotNames +================= +*/ +static void UI_AddBotsMenu_SetBotNames( void ) { + int n; + const char *info; + + for ( n = 0; n < 7; n++ ) { + info = UI_GetBotInfoByNumber( addBotsMenuInfo.sortedBotNums[addBotsMenuInfo.baseBotNum + n] ); + Q_strncpyz( addBotsMenuInfo.botnames[n], Info_ValueForKey( info, "name" ), sizeof(addBotsMenuInfo.botnames[n]) ); + } + +} + + +/* +================= +UI_AddBotsMenu_UpEvent +================= +*/ +static void UI_AddBotsMenu_UpEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + + if( addBotsMenuInfo.baseBotNum > 0 ) { + addBotsMenuInfo.baseBotNum--; + UI_AddBotsMenu_SetBotNames(); + } +} + + +/* +================= +UI_AddBotsMenu_DownEvent +================= +*/ +static void UI_AddBotsMenu_DownEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + + if( addBotsMenuInfo.baseBotNum + 7 < addBotsMenuInfo.numBots ) { + addBotsMenuInfo.baseBotNum++; + UI_AddBotsMenu_SetBotNames(); + } +} + + +/* +================= +UI_AddBotsMenu_GetSortedBotNums +================= +*/ +static int QDECL UI_AddBotsMenu_SortCompare( const void *arg1, const void *arg2 ) { + int num1, num2; + const char *info1, *info2; + const char *name1, *name2; + + num1 = *(int *)arg1; + num2 = *(int *)arg2; + + info1 = UI_GetBotInfoByNumber( num1 ); + info2 = UI_GetBotInfoByNumber( num2 ); + + name1 = Info_ValueForKey( info1, "name" ); + name2 = Info_ValueForKey( info2, "name" ); + + return Q_stricmp( name1, name2 ); +} + +static void UI_AddBotsMenu_GetSortedBotNums( void ) { + int n; + + // initialize the array + for( n = 0; n < addBotsMenuInfo.numBots; n++ ) { + addBotsMenuInfo.sortedBotNums[n] = n; + } + + qsort( addBotsMenuInfo.sortedBotNums, addBotsMenuInfo.numBots, sizeof(addBotsMenuInfo.sortedBotNums[0]), UI_AddBotsMenu_SortCompare ); +} + + +/* +================= +UI_AddBotsMenu_Draw +================= +*/ +static void UI_AddBotsMenu_Draw( void ) { + UI_DrawBannerString( 320, 16, "ADD BOTS", UI_CENTER, color_white ); + UI_DrawNamedPic( 320-233, 240-166, 466, 332, ART_BACKGROUND ); + + // standard menu drawing + Menu_Draw( &addBotsMenuInfo.menu ); +} + + +/* +================= +UI_AddBotsMenu_Init +================= +*/ +static const char *skillNames[] = { + "I Can Win", + "Bring It On", + "Hurt Me Plenty", + "Hardcore", + "Nightmare!", + 0 +}; + +static const char *teamNames1[] = { + "Free", + 0 +}; + +static const char *teamNames2[] = { + "Red", + "Blue", + 0 +}; + +static void UI_AddBotsMenu_Init( void ) { + int n; + int y; + int gametype; + int count; + char info[MAX_INFO_STRING]; + + trap_GetConfigString(CS_SERVERINFO, info, MAX_INFO_STRING); + gametype = atoi( Info_ValueForKey( info,"g_gametype" ) ); + + memset( &addBotsMenuInfo, 0 ,sizeof(addBotsMenuInfo) ); + addBotsMenuInfo.menu.draw = UI_AddBotsMenu_Draw; + addBotsMenuInfo.menu.fullscreen = qfalse; + addBotsMenuInfo.menu.wrapAround = qtrue; + addBotsMenuInfo.delay = 1000; + + UI_AddBots_Cache(); + + addBotsMenuInfo.numBots = UI_GetNumBots(); + count = addBotsMenuInfo.numBots < 7 ? addBotsMenuInfo.numBots : 7; + + addBotsMenuInfo.arrows.generic.type = MTYPE_BITMAP; + addBotsMenuInfo.arrows.generic.name = ART_ARROWS; + addBotsMenuInfo.arrows.generic.flags = QMF_INACTIVE; + addBotsMenuInfo.arrows.generic.x = 200; + addBotsMenuInfo.arrows.generic.y = 128; + addBotsMenuInfo.arrows.width = 64; + addBotsMenuInfo.arrows.height = 128; + + addBotsMenuInfo.up.generic.type = MTYPE_BITMAP; + addBotsMenuInfo.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + addBotsMenuInfo.up.generic.x = 200; + addBotsMenuInfo.up.generic.y = 128; + addBotsMenuInfo.up.generic.id = ID_UP; + addBotsMenuInfo.up.generic.callback = UI_AddBotsMenu_UpEvent; + addBotsMenuInfo.up.width = 64; + addBotsMenuInfo.up.height = 64; + addBotsMenuInfo.up.focuspic = ART_ARROWUP; + + addBotsMenuInfo.down.generic.type = MTYPE_BITMAP; + addBotsMenuInfo.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + addBotsMenuInfo.down.generic.x = 200; + addBotsMenuInfo.down.generic.y = 128+64; + addBotsMenuInfo.down.generic.id = ID_DOWN; + addBotsMenuInfo.down.generic.callback = UI_AddBotsMenu_DownEvent; + addBotsMenuInfo.down.width = 64; + addBotsMenuInfo.down.height = 64; + addBotsMenuInfo.down.focuspic = ART_ARROWDOWN; + + for( n = 0, y = 120; n < count; n++, y += 20 ) { + addBotsMenuInfo.bots[n].generic.type = MTYPE_PTEXT; + addBotsMenuInfo.bots[n].generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + addBotsMenuInfo.bots[n].generic.id = ID_BOTNAME0 + n; + addBotsMenuInfo.bots[n].generic.x = 320 - 56; + addBotsMenuInfo.bots[n].generic.y = y; + addBotsMenuInfo.bots[n].generic.callback = UI_AddBotsMenu_BotEvent; + addBotsMenuInfo.bots[n].string = addBotsMenuInfo.botnames[n]; + addBotsMenuInfo.bots[n].color = color_orange; + addBotsMenuInfo.bots[n].style = UI_LEFT|UI_SMALLFONT; + } + + y += 12; + addBotsMenuInfo.skill.generic.type = MTYPE_SPINCONTROL; + addBotsMenuInfo.skill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + addBotsMenuInfo.skill.generic.x = 320; + addBotsMenuInfo.skill.generic.y = y; + addBotsMenuInfo.skill.generic.name = "Skill:"; + addBotsMenuInfo.skill.generic.id = ID_SKILL; + addBotsMenuInfo.skill.itemnames = skillNames; + addBotsMenuInfo.skill.curvalue = Com_Clamp( 0, 4, (int)trap_Cvar_VariableValue( "g_spSkill" ) - 1 ); + + y += SMALLCHAR_HEIGHT; + addBotsMenuInfo.team.generic.type = MTYPE_SPINCONTROL; + addBotsMenuInfo.team.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + addBotsMenuInfo.team.generic.x = 320; + addBotsMenuInfo.team.generic.y = y; + addBotsMenuInfo.team.generic.name = "Team: "; + addBotsMenuInfo.team.generic.id = ID_TEAM; + if( gametype >= GT_TEAM ) { + addBotsMenuInfo.team.itemnames = teamNames2; + } + else { + addBotsMenuInfo.team.itemnames = teamNames1; + addBotsMenuInfo.team.generic.flags = QMF_GRAYED; + } + + addBotsMenuInfo.go.generic.type = MTYPE_BITMAP; + addBotsMenuInfo.go.generic.name = ART_FIGHT0; + addBotsMenuInfo.go.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + addBotsMenuInfo.go.generic.id = ID_GO; + addBotsMenuInfo.go.generic.callback = UI_AddBotsMenu_FightEvent; + addBotsMenuInfo.go.generic.x = 320+128-128; + addBotsMenuInfo.go.generic.y = 256+128-64; + addBotsMenuInfo.go.width = 128; + addBotsMenuInfo.go.height = 64; + addBotsMenuInfo.go.focuspic = ART_FIGHT1; + + addBotsMenuInfo.back.generic.type = MTYPE_BITMAP; + addBotsMenuInfo.back.generic.name = ART_BACK0; + addBotsMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + addBotsMenuInfo.back.generic.id = ID_BACK; + addBotsMenuInfo.back.generic.callback = UI_AddBotsMenu_BackEvent; + addBotsMenuInfo.back.generic.x = 320-128; + addBotsMenuInfo.back.generic.y = 256+128-64; + addBotsMenuInfo.back.width = 128; + addBotsMenuInfo.back.height = 64; + addBotsMenuInfo.back.focuspic = ART_BACK1; + + addBotsMenuInfo.baseBotNum = 0; + addBotsMenuInfo.selectedBotNum = 0; + addBotsMenuInfo.bots[0].color = color_white; + + UI_AddBotsMenu_GetSortedBotNums(); + UI_AddBotsMenu_SetBotNames(); + + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.arrows ); + + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.up ); + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.down ); + for( n = 0; n < count; n++ ) { + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.bots[n] ); + } + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.skill ); + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.team ); + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.go ); + Menu_AddItem( &addBotsMenuInfo.menu, &addBotsMenuInfo.back ); +} + + +/* +================= +UI_AddBots_Cache +================= +*/ +void UI_AddBots_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FIGHT0 ); + trap_R_RegisterShaderNoMip( ART_FIGHT1 ); + trap_R_RegisterShaderNoMip( ART_BACKGROUND ); + trap_R_RegisterShaderNoMip( ART_ARROWS ); + trap_R_RegisterShaderNoMip( ART_ARROWUP ); + trap_R_RegisterShaderNoMip( ART_ARROWDOWN ); +} + + +/* +================= +UI_AddBotsMenu +================= +*/ +void UI_AddBotsMenu( void ) { + UI_AddBotsMenu_Init(); + UI_PushMenu( &addBotsMenuInfo.menu ); +} diff --git a/code/q3_ui/ui_atoms.c b/code/q3_ui/ui_atoms.c index 4a2177d..ae4cbb9 100755 --- a/code/q3_ui/ui_atoms.c +++ b/code/q3_ui/ui_atoms.c @@ -1,1267 +1,1267 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/********************************************************************** - UI_ATOMS.C - - User interface building blocks and support functions. -**********************************************************************/ -#include "ui_local.h" - -uiStatic_t uis; -qboolean m_entersound; // after a frame, so caching won't disrupt the sound - -// these are here so the functions in q_shared.c can link -#ifndef UI_HARD_LINKED - -void QDECL Com_Error( int level, const char *error, ... ) { - va_list argptr; - char text[1024]; - - va_start (argptr, error); - vsprintf (text, error, argptr); - va_end (argptr); - - trap_Error( va("%s", text) ); -} - -void QDECL Com_Printf( const char *msg, ... ) { - va_list argptr; - char text[1024]; - - va_start (argptr, msg); - vsprintf (text, msg, argptr); - va_end (argptr); - - trap_Print( va("%s", text) ); -} - -#endif - -/* -================= -UI_ClampCvar -================= -*/ -float UI_ClampCvar( float min, float max, float value ) -{ - if ( value < min ) return min; - if ( value > max ) return max; - return value; -} - -/* -================= -UI_StartDemoLoop -================= -*/ -void UI_StartDemoLoop( void ) { - trap_Cmd_ExecuteText( EXEC_APPEND, "d1\n" ); -} - -/* -================= -UI_PushMenu -================= -*/ -void UI_PushMenu( menuframework_s *menu ) -{ - int i; - menucommon_s* item; - - // avoid stacking menus invoked by hotkeys - for (i=0 ; i= MAX_MENUDEPTH) - trap_Error("UI_PushMenu: menu stack overflow"); - - uis.stack[uis.menusp++] = menu; - } - - uis.activemenu = menu; - - // default cursor position - menu->cursor = 0; - menu->cursor_prev = 0; - - m_entersound = qtrue; - - trap_Key_SetCatcher( KEYCATCH_UI ); - - // force first available item to have focus - for (i=0; initems; i++) - { - item = (menucommon_s *)menu->items[i]; - if (!(item->flags & (QMF_GRAYED|QMF_MOUSEONLY|QMF_INACTIVE))) - { - menu->cursor_prev = -1; - Menu_SetCursor( menu, i ); - break; - } - } - - uis.firstdraw = qtrue; -} - -/* -================= -UI_PopMenu -================= -*/ -void UI_PopMenu (void) -{ - trap_S_StartLocalSound( menu_out_sound, CHAN_LOCAL_SOUND ); - - uis.menusp--; - - if (uis.menusp < 0) - trap_Error ("UI_PopMenu: menu stack underflow"); - - if (uis.menusp) { - uis.activemenu = uis.stack[uis.menusp-1]; - uis.firstdraw = qtrue; - } - else { - UI_ForceMenuOff (); - } -} - -void UI_ForceMenuOff (void) -{ - uis.menusp = 0; - uis.activemenu = NULL; - - trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); - trap_Key_ClearStates(); - trap_Cvar_Set( "cl_paused", "0" ); -} - -/* -================= -UI_LerpColor -================= -*/ -void UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t) -{ - int i; - - // lerp and clamp each component - for (i=0; i<4; i++) - { - c[i] = a[i] + t*(b[i]-a[i]); - if (c[i] < 0) - c[i] = 0; - else if (c[i] > 1.0) - c[i] = 1.0; - } -} - -/* -================= -UI_DrawProportionalString2 -================= -*/ -static int propMap[128][3] = { -{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, -{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, - -{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, -{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, - -{0, 0, PROP_SPACE_WIDTH}, // SPACE -{11, 122, 7}, // ! -{154, 181, 14}, // " -{55, 122, 17}, // # -{79, 122, 18}, // $ -{101, 122, 23}, // % -{153, 122, 18}, // & -{9, 93, 7}, // ' -{207, 122, 8}, // ( -{230, 122, 9}, // ) -{177, 122, 18}, // * -{30, 152, 18}, // + -{85, 181, 7}, // , -{34, 93, 11}, // - -{110, 181, 6}, // . -{130, 152, 14}, // / - -{22, 64, 17}, // 0 -{41, 64, 12}, // 1 -{58, 64, 17}, // 2 -{78, 64, 18}, // 3 -{98, 64, 19}, // 4 -{120, 64, 18}, // 5 -{141, 64, 18}, // 6 -{204, 64, 16}, // 7 -{162, 64, 17}, // 8 -{182, 64, 18}, // 9 -{59, 181, 7}, // : -{35,181, 7}, // ; -{203, 152, 14}, // < -{56, 93, 14}, // = -{228, 152, 14}, // > -{177, 181, 18}, // ? - -{28, 122, 22}, // @ -{5, 4, 18}, // A -{27, 4, 18}, // B -{48, 4, 18}, // C -{69, 4, 17}, // D -{90, 4, 13}, // E -{106, 4, 13}, // F -{121, 4, 18}, // G -{143, 4, 17}, // H -{164, 4, 8}, // I -{175, 4, 16}, // J -{195, 4, 18}, // K -{216, 4, 12}, // L -{230, 4, 23}, // M -{6, 34, 18}, // N -{27, 34, 18}, // O - -{48, 34, 18}, // P -{68, 34, 18}, // Q -{90, 34, 17}, // R -{110, 34, 18}, // S -{130, 34, 14}, // T -{146, 34, 18}, // U -{166, 34, 19}, // V -{185, 34, 29}, // W -{215, 34, 18}, // X -{234, 34, 18}, // Y -{5, 64, 14}, // Z -{60, 152, 7}, // [ -{106, 151, 13}, // '\' -{83, 152, 7}, // ] -{128, 122, 17}, // ^ -{4, 152, 21}, // _ - -{134, 181, 5}, // ' -{5, 4, 18}, // A -{27, 4, 18}, // B -{48, 4, 18}, // C -{69, 4, 17}, // D -{90, 4, 13}, // E -{106, 4, 13}, // F -{121, 4, 18}, // G -{143, 4, 17}, // H -{164, 4, 8}, // I -{175, 4, 16}, // J -{195, 4, 18}, // K -{216, 4, 12}, // L -{230, 4, 23}, // M -{6, 34, 18}, // N -{27, 34, 18}, // O - -{48, 34, 18}, // P -{68, 34, 18}, // Q -{90, 34, 17}, // R -{110, 34, 18}, // S -{130, 34, 14}, // T -{146, 34, 18}, // U -{166, 34, 19}, // V -{185, 34, 29}, // W -{215, 34, 18}, // X -{234, 34, 18}, // Y -{5, 64, 14}, // Z -{153, 152, 13}, // { -{11, 181, 5}, // | -{180, 152, 13}, // } -{79, 93, 17}, // ~ -{0, 0, -1} // DEL -}; - -static int propMapB[26][3] = { -{11, 12, 33}, -{49, 12, 31}, -{85, 12, 31}, -{120, 12, 30}, -{156, 12, 21}, -{183, 12, 21}, -{207, 12, 32}, - -{13, 55, 30}, -{49, 55, 13}, -{66, 55, 29}, -{101, 55, 31}, -{135, 55, 21}, -{158, 55, 40}, -{204, 55, 32}, - -{12, 97, 31}, -{48, 97, 31}, -{82, 97, 30}, -{118, 97, 30}, -{153, 97, 30}, -{185, 97, 25}, -{213, 97, 30}, - -{11, 139, 32}, -{42, 139, 51}, -{93, 139, 32}, -{126, 139, 31}, -{158, 139, 25}, -}; - -#define PROPB_GAP_WIDTH 4 -#define PROPB_SPACE_WIDTH 12 -#define PROPB_HEIGHT 36 - -// bk001205 - code below duplicated in cgame/cg_drawtools.c -// bk001205 - FIXME: does this belong in ui_shared.c? -/* -================= -UI_DrawBannerString -================= -*/ -static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color ) -{ - const char* s; - unsigned char ch; // bk001204 - unsigned - float ax; - float ay; - float aw; - float ah; - float frow; - float fcol; - float fwidth; - float fheight; - - // draw the colored text - trap_R_SetColor( color ); - - ax = x * uis.scale + uis.bias; - ay = y * uis.scale; - - s = str; - while ( *s ) - { - ch = *s & 127; - if ( ch == ' ' ) { - ax += ((float)PROPB_SPACE_WIDTH + (float)PROPB_GAP_WIDTH)* uis.scale; - } - else if ( ch >= 'A' && ch <= 'Z' ) { - ch -= 'A'; - fcol = (float)propMapB[ch][0] / 256.0f; - frow = (float)propMapB[ch][1] / 256.0f; - fwidth = (float)propMapB[ch][2] / 256.0f; - fheight = (float)PROPB_HEIGHT / 256.0f; - aw = (float)propMapB[ch][2] * uis.scale; - ah = (float)PROPB_HEIGHT * uis.scale; - trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, uis.charsetPropB ); - ax += (aw + (float)PROPB_GAP_WIDTH * uis.scale); - } - s++; - } - - trap_R_SetColor( NULL ); -} - -void UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color ) { - const char * s; - int ch; - int width; - vec4_t drawcolor; - - // find the width of the drawn text - s = str; - width = 0; - while ( *s ) { - ch = *s; - if ( ch == ' ' ) { - width += PROPB_SPACE_WIDTH; - } - else if ( ch >= 'A' && ch <= 'Z' ) { - width += propMapB[ch - 'A'][2] + PROPB_GAP_WIDTH; - } - s++; - } - width -= PROPB_GAP_WIDTH; - - switch( style & UI_FORMATMASK ) { - case UI_CENTER: - x -= width / 2; - break; - - case UI_RIGHT: - x -= width; - break; - - case UI_LEFT: - default: - break; - } - - if ( style & UI_DROPSHADOW ) { - drawcolor[0] = drawcolor[1] = drawcolor[2] = 0; - drawcolor[3] = color[3]; - UI_DrawBannerString2( x+2, y+2, str, drawcolor ); - } - - UI_DrawBannerString2( x, y, str, color ); -} - - -int UI_ProportionalStringWidth( const char* str ) { - const char * s; - int ch; - int charWidth; - int width; - - s = str; - width = 0; - while ( *s ) { - ch = *s & 127; - charWidth = propMap[ch][2]; - if ( charWidth != -1 ) { - width += charWidth; - width += PROP_GAP_WIDTH; - } - s++; - } - - width -= PROP_GAP_WIDTH; - return width; -} - -static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t color, float sizeScale, qhandle_t charset ) -{ - const char* s; - unsigned char ch; // bk001204 - unsigned - float ax; - float ay; - float aw = 0; // bk001204 - init - float ah; - float frow; - float fcol; - float fwidth; - float fheight; - - // draw the colored text - trap_R_SetColor( color ); - - ax = x * uis.scale + uis.bias; - ay = y * uis.scale; - - s = str; - while ( *s ) - { - ch = *s & 127; - if ( ch == ' ' ) { - aw = (float)PROP_SPACE_WIDTH * uis.scale * sizeScale; - } - else if ( propMap[ch][2] != -1 ) { - fcol = (float)propMap[ch][0] / 256.0f; - frow = (float)propMap[ch][1] / 256.0f; - fwidth = (float)propMap[ch][2] / 256.0f; - fheight = (float)PROP_HEIGHT / 256.0f; - aw = (float)propMap[ch][2] * uis.scale * sizeScale; - ah = (float)PROP_HEIGHT * uis.scale * sizeScale; - trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, charset ); - } - - ax += (aw + (float)PROP_GAP_WIDTH * uis.scale * sizeScale); - s++; - } - - trap_R_SetColor( NULL ); -} - -/* -================= -UI_ProportionalSizeScale -================= -*/ -float UI_ProportionalSizeScale( int style ) { - if( style & UI_SMALLFONT ) { - return PROP_SMALL_SIZE_SCALE; - } - - return 1.00; -} - - -/* -================= -UI_DrawProportionalString -================= -*/ -void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ) { - vec4_t drawcolor; - int width; - float sizeScale; - - sizeScale = UI_ProportionalSizeScale( style ); - - switch( style & UI_FORMATMASK ) { - case UI_CENTER: - width = UI_ProportionalStringWidth( str ) * sizeScale; - x -= width / 2; - break; - - case UI_RIGHT: - width = UI_ProportionalStringWidth( str ) * sizeScale; - x -= width; - break; - - case UI_LEFT: - default: - break; - } - - if ( style & UI_DROPSHADOW ) { - drawcolor[0] = drawcolor[1] = drawcolor[2] = 0; - drawcolor[3] = color[3]; - UI_DrawProportionalString2( x+2, y+2, str, drawcolor, sizeScale, uis.charsetProp ); - } - - if ( style & UI_INVERSE ) { - drawcolor[0] = color[0] * 0.7; - drawcolor[1] = color[1] * 0.7; - drawcolor[2] = color[2] * 0.7; - drawcolor[3] = color[3]; - UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, uis.charsetProp ); - return; - } - - if ( style & UI_PULSE ) { - drawcolor[0] = color[0] * 0.7; - drawcolor[1] = color[1] * 0.7; - drawcolor[2] = color[2] * 0.7; - drawcolor[3] = color[3]; - UI_DrawProportionalString2( x, y, str, color, sizeScale, uis.charsetProp ); - - drawcolor[0] = color[0]; - drawcolor[1] = color[1]; - drawcolor[2] = color[2]; - drawcolor[3] = 0.5 + 0.5 * sin( uis.realtime / PULSE_DIVISOR ); - UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, uis.charsetPropGlow ); - return; - } - - UI_DrawProportionalString2( x, y, str, color, sizeScale, uis.charsetProp ); -} - -/* -================= -UI_DrawProportionalString_Wrapped -================= -*/ -void UI_DrawProportionalString_AutoWrapped( int x, int y, int xmax, int ystep, const char* str, int style, vec4_t color ) { - int width; - char *s1,*s2,*s3; - char c_bcp; - char buf[1024]; - float sizeScale; - - if (!str || str[0]=='\0') - return; - - sizeScale = UI_ProportionalSizeScale( style ); - - Q_strncpyz(buf, str, sizeof(buf)); - s1 = s2 = s3 = buf; - - while (1) { - do { - s3++; - } while (*s3!=' ' && *s3!='\0'); - c_bcp = *s3; - *s3 = '\0'; - width = UI_ProportionalStringWidth(s1) * sizeScale; - *s3 = c_bcp; - if (width > xmax) { - if (s1==s2) - { - // fuck, don't have a clean cut, we'll overflow - s2 = s3; - } - *s2 = '\0'; - UI_DrawProportionalString(x, y, s1, style, color); - y += ystep; - if (c_bcp == '\0') - { - // that was the last word - // we could start a new loop, but that wouldn't be much use - // even if the word is too long, we would overflow it (see above) - // so just print it now if needed - s2++; - if (*s2 != '\0') // if we are printing an overflowing line we have s2 == s3 - UI_DrawProportionalString(x, y, s2, style, color); - break; - } - s2++; - s1 = s2; - s3 = s2; - } - else - { - s2 = s3; - if (c_bcp == '\0') // we reached the end - { - UI_DrawProportionalString(x, y, s1, style, color); - break; - } - } - } -} - -/* -================= -UI_DrawString2 -================= -*/ -static void UI_DrawString2( int x, int y, const char* str, vec4_t color, int charw, int charh ) -{ - const char* s; - char ch; - int forceColor = qfalse; //APSFIXME; - vec4_t tempcolor; - float ax; - float ay; - float aw; - float ah; - float frow; - float fcol; - - if (y < -charh) - // offscreen - return; - - // draw the colored text - trap_R_SetColor( color ); - - ax = x * uis.scale + uis.bias; - ay = y * uis.scale; - aw = charw * uis.scale; - ah = charh * uis.scale; - - s = str; - while ( *s ) - { - if ( Q_IsColorString( s ) ) - { - if ( !forceColor ) - { - memcpy( tempcolor, g_color_table[ColorIndex(s[1])], sizeof( tempcolor ) ); - tempcolor[3] = color[3]; - trap_R_SetColor( tempcolor ); - } - s += 2; - continue; - } - - ch = *s & 255; - if (ch != ' ') - { - frow = (ch>>4)*0.0625; - fcol = (ch&15)*0.0625; - trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + 0.0625, frow + 0.0625, uis.charset ); - } - - ax += aw; - s++; - } - - trap_R_SetColor( NULL ); -} - -/* -================= -UI_DrawString -================= -*/ -void UI_DrawString( int x, int y, const char* str, int style, vec4_t color ) -{ - int len; - int charw; - int charh; - vec4_t newcolor; - vec4_t lowlight; - float *drawcolor; - vec4_t dropcolor; - - if( !str ) { - return; - } - - if ((style & UI_BLINK) && ((uis.realtime/BLINK_DIVISOR) & 1)) - return; - - if (style & UI_SMALLFONT) - { - charw = SMALLCHAR_WIDTH; - charh = SMALLCHAR_HEIGHT; - } - else if (style & UI_GIANTFONT) - { - charw = GIANTCHAR_WIDTH; - charh = GIANTCHAR_HEIGHT; - } - else - { - charw = BIGCHAR_WIDTH; - charh = BIGCHAR_HEIGHT; - } - - if (style & UI_PULSE) - { - lowlight[0] = 0.8*color[0]; - lowlight[1] = 0.8*color[1]; - lowlight[2] = 0.8*color[2]; - lowlight[3] = 0.8*color[3]; - UI_LerpColor(color,lowlight,newcolor,0.5+0.5*sin(uis.realtime/PULSE_DIVISOR)); - drawcolor = newcolor; - } - else - drawcolor = color; - - switch (style & UI_FORMATMASK) - { - case UI_CENTER: - // center justify at x - len = strlen(str); - x = x - len*charw/2; - break; - - case UI_RIGHT: - // right justify at x - len = strlen(str); - x = x - len*charw; - break; - - default: - // left justify at x - break; - } - - if ( style & UI_DROPSHADOW ) - { - dropcolor[0] = dropcolor[1] = dropcolor[2] = 0; - dropcolor[3] = drawcolor[3]; - UI_DrawString2(x+2,y+2,str,dropcolor,charw,charh); - } - - UI_DrawString2(x,y,str,drawcolor,charw,charh); -} - -/* -================= -UI_DrawChar -================= -*/ -void UI_DrawChar( int x, int y, int ch, int style, vec4_t color ) -{ - char buff[2]; - - buff[0] = ch; - buff[1] = '\0'; - - UI_DrawString( x, y, buff, style, color ); -} - -qboolean UI_IsFullscreen( void ) { - if ( uis.activemenu && ( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { - return uis.activemenu->fullscreen; - } - - return qfalse; -} - -static void NeedCDAction( qboolean result ) { - if ( !result ) { - trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" ); - } -} - -static void NeedCDKeyAction( qboolean result ) { - if ( !result ) { - trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" ); - } -} - -void UI_SetActiveMenu( uiMenuCommand_t menu ) { - // this should be the ONLY way the menu system is brought up - // enusure minumum menu data is cached - Menu_Cache(); - - switch ( menu ) { - case UIMENU_NONE: - UI_ForceMenuOff(); - return; - case UIMENU_MAIN: - UI_MainMenu(); - return; - case UIMENU_NEED_CD: - UI_ConfirmMenu( "Insert the CD", (voidfunc_f)NULL, NeedCDAction ); - return; - case UIMENU_BAD_CD_KEY: - UI_ConfirmMenu( "Bad CD Key", (voidfunc_f)NULL, NeedCDKeyAction ); - return; - case UIMENU_INGAME: - /* - //GRank - UI_RankingsMenu(); - return; - */ - trap_Cvar_Set( "cl_paused", "1" ); - UI_InGameMenu(); - return; - - // bk001204 - case UIMENU_TEAM: - case UIMENU_POSTGAME: - default: -#ifndef NDEBUG - Com_Printf("UI_SetActiveMenu: bad enum %d\n", menu ); -#endif - break; - } -} - -/* -================= -UI_KeyEvent -================= -*/ -void UI_KeyEvent( int key, int down ) { - sfxHandle_t s; - - if (!uis.activemenu) { - return; - } - - if (!down) { - return; - } - - if (uis.activemenu->key) - s = uis.activemenu->key( key ); - else - s = Menu_DefaultKey( uis.activemenu, key ); - - if ((s > 0) && (s != menu_null_sound)) - trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND ); -} - -/* -================= -UI_MouseEvent -================= -*/ -void UI_MouseEvent( int dx, int dy ) -{ - int i; - menucommon_s* m; - - if (!uis.activemenu) - return; - - // update mouse screen position - uis.cursorx += dx; - if (uis.cursorx < 0) - uis.cursorx = 0; - else if (uis.cursorx > SCREEN_WIDTH) - uis.cursorx = SCREEN_WIDTH; - - uis.cursory += dy; - if (uis.cursory < 0) - uis.cursory = 0; - else if (uis.cursory > SCREEN_HEIGHT) - uis.cursory = SCREEN_HEIGHT; - - // region test the active menu items - for (i=0; initems; i++) - { - m = (menucommon_s*)uis.activemenu->items[i]; - - if (m->flags & (QMF_GRAYED|QMF_INACTIVE)) - continue; - - if ((uis.cursorx < m->left) || - (uis.cursorx > m->right) || - (uis.cursory < m->top) || - (uis.cursory > m->bottom)) - { - // cursor out of item bounds - continue; - } - - // set focus to item at cursor - if (uis.activemenu->cursor != i) - { - Menu_SetCursor( uis.activemenu, i ); - ((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor_prev]))->flags &= ~QMF_HASMOUSEFOCUS; - - if ( !(((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags & QMF_SILENT ) ) { - trap_S_StartLocalSound( menu_move_sound, CHAN_LOCAL_SOUND ); - } - } - - ((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags |= QMF_HASMOUSEFOCUS; - return; - } - - if (uis.activemenu->nitems > 0) { - // out of any region - ((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags &= ~QMF_HASMOUSEFOCUS; - } -} - -char *UI_Argv( int arg ) { - static char buffer[MAX_STRING_CHARS]; - - trap_Argv( arg, buffer, sizeof( buffer ) ); - - return buffer; -} - - -char *UI_Cvar_VariableString( const char *var_name ) { - static char buffer[MAX_STRING_CHARS]; - - trap_Cvar_VariableStringBuffer( var_name, buffer, sizeof( buffer ) ); - - return buffer; -} - - -/* -================= -UI_Cache -================= -*/ -void UI_Cache_f( void ) { - MainMenu_Cache(); - InGame_Cache(); - ConfirmMenu_Cache(); - PlayerModel_Cache(); - PlayerSettings_Cache(); - Controls_Cache(); - Demos_Cache(); - UI_CinematicsMenu_Cache(); - Preferences_Cache(); - ServerInfo_Cache(); - SpecifyServer_Cache(); - ArenaServers_Cache(); - StartServer_Cache(); - ServerOptions_Cache(); - DriverInfo_Cache(); - GraphicsOptions_Cache(); - UI_DisplayOptionsMenu_Cache(); - UI_SoundOptionsMenu_Cache(); - UI_NetworkOptionsMenu_Cache(); - UI_SPLevelMenu_Cache(); - UI_SPSkillMenu_Cache(); - UI_SPPostgameMenu_Cache(); - TeamMain_Cache(); - UI_AddBots_Cache(); - UI_RemoveBots_Cache(); - UI_SetupMenu_Cache(); -// UI_LoadConfig_Cache(); -// UI_SaveConfigMenu_Cache(); - UI_BotSelectMenu_Cache(); - UI_CDKeyMenu_Cache(); - UI_ModsMenu_Cache(); - -} - - -/* -================= -UI_ConsoleCommand -================= -*/ -qboolean UI_ConsoleCommand( int realTime ) { - char *cmd; - - cmd = UI_Argv( 0 ); - - // ensure minimum menu data is available - Menu_Cache(); - - if ( Q_stricmp (cmd, "levelselect") == 0 ) { - UI_SPLevelMenu_f(); - return qtrue; - } - - if ( Q_stricmp (cmd, "postgame") == 0 ) { - UI_SPPostgameMenu_f(); - return qtrue; - } - - if ( Q_stricmp (cmd, "ui_cache") == 0 ) { - UI_Cache_f(); - return qtrue; - } - - if ( Q_stricmp (cmd, "ui_cinematics") == 0 ) { - UI_CinematicsMenu_f(); - return qtrue; - } - - if ( Q_stricmp (cmd, "ui_teamOrders") == 0 ) { - UI_TeamOrdersMenu_f(); - return qtrue; - } - - if ( Q_stricmp (cmd, "iamacheater") == 0 ) { - UI_SPUnlock_f(); - return qtrue; - } - - if ( Q_stricmp (cmd, "iamamonkey") == 0 ) { - UI_SPUnlockMedals_f(); - return qtrue; - } - - if ( Q_stricmp (cmd, "ui_cdkey") == 0 ) { - UI_CDKeyMenu_f(); - return qtrue; - } - - return qfalse; -} - -/* -================= -UI_Shutdown -================= -*/ -void UI_Shutdown( void ) { -} - -/* -================= -UI_Init -================= -*/ -void UI_Init( void ) { - UI_RegisterCvars(); - - UI_InitGameinfo(); - - // cache redundant calulations - trap_GetGlconfig( &uis.glconfig ); - - // for 640x480 virtualized screen - uis.scale = uis.glconfig.vidHeight * (1.0/480.0); - if ( uis.glconfig.vidWidth * 480 > uis.glconfig.vidHeight * 640 ) { - // wide screen - uis.bias = 0.5 * ( uis.glconfig.vidWidth - ( uis.glconfig.vidHeight * (640.0/480.0) ) ); - } - else { - // no wide screen - uis.bias = 0; - } - - // initialize the menu system - Menu_Cache(); - - uis.activemenu = NULL; - uis.menusp = 0; -} - -/* -================ -UI_AdjustFrom640 - -Adjusted for resolution and screen aspect ratio -================ -*/ -void UI_AdjustFrom640( float *x, float *y, float *w, float *h ) { - // expect valid pointers - *x = *x * uis.scale + uis.bias; - *y *= uis.scale; - *w *= uis.scale; - *h *= uis.scale; -} - -void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ) { - qhandle_t hShader; - - hShader = trap_R_RegisterShaderNoMip( picname ); - UI_AdjustFrom640( &x, &y, &width, &height ); - trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader ); -} - -void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ) { - float s0; - float s1; - float t0; - float t1; - - if( w < 0 ) { // flip about vertical - w = -w; - s0 = 1; - s1 = 0; - } - else { - s0 = 0; - s1 = 1; - } - - if( h < 0 ) { // flip about horizontal - h = -h; - t0 = 1; - t1 = 0; - } - else { - t0 = 0; - t1 = 1; - } - - UI_AdjustFrom640( &x, &y, &w, &h ); - trap_R_DrawStretchPic( x, y, w, h, s0, t0, s1, t1, hShader ); -} - -/* -================ -UI_FillRect - -Coordinates are 640*480 virtual values -================= -*/ -void UI_FillRect( float x, float y, float width, float height, const float *color ) { - trap_R_SetColor( color ); - - UI_AdjustFrom640( &x, &y, &width, &height ); - trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, uis.whiteShader ); - - trap_R_SetColor( NULL ); -} - -/* -================ -UI_DrawRect - -Coordinates are 640*480 virtual values -================= -*/ -void UI_DrawRect( float x, float y, float width, float height, const float *color ) { - trap_R_SetColor( color ); - - UI_AdjustFrom640( &x, &y, &width, &height ); - - trap_R_DrawStretchPic( x, y, width, 1, 0, 0, 0, 0, uis.whiteShader ); - trap_R_DrawStretchPic( x, y, 1, height, 0, 0, 0, 0, uis.whiteShader ); - trap_R_DrawStretchPic( x, y + height - 1, width, 1, 0, 0, 0, 0, uis.whiteShader ); - trap_R_DrawStretchPic( x + width - 1, y, 1, height, 0, 0, 0, 0, uis.whiteShader ); - - trap_R_SetColor( NULL ); -} - -void UI_SetColor( const float *rgba ) { - trap_R_SetColor( rgba ); -} - -void UI_UpdateScreen( void ) { - trap_UpdateScreen(); -} - -/* -================= -UI_Refresh -================= -*/ -void UI_Refresh( int realtime ) -{ - uis.frametime = realtime - uis.realtime; - uis.realtime = realtime; - - if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { - return; - } - - UI_UpdateCvars(); - - if ( uis.activemenu ) - { - if (uis.activemenu->fullscreen) - { - // draw the background - if( uis.activemenu->showlogo ) { - UI_DrawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.menuBackShader ); - } - else { - UI_DrawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.menuBackNoLogoShader ); - } - } - - if (uis.activemenu->draw) - uis.activemenu->draw(); - else - Menu_Draw( uis.activemenu ); - - if( uis.firstdraw ) { - UI_MouseEvent( 0, 0 ); - uis.firstdraw = qfalse; - } - } - - // draw cursor - UI_SetColor( NULL ); - UI_DrawHandlePic( uis.cursorx-16, uis.cursory-16, 32, 32, uis.cursor); - -#ifndef NDEBUG - if (uis.debug) - { - // cursor coordinates - UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed ); - } -#endif - - // delay playing the enter sound until after the - // menu has been drawn, to avoid delay while - // caching images - if (m_entersound) - { - trap_S_StartLocalSound( menu_in_sound, CHAN_LOCAL_SOUND ); - m_entersound = qfalse; - } -} - -void UI_DrawTextBox (int x, int y, int width, int lines) -{ - UI_FillRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorBlack ); - UI_DrawRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorWhite ); -} - -qboolean UI_CursorInRect (int x, int y, int width, int height) -{ - if (uis.cursorx < x || - uis.cursory < y || - uis.cursorx > x+width || - uis.cursory > y+height) - return qfalse; - - return qtrue; -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/********************************************************************** + UI_ATOMS.C + + User interface building blocks and support functions. +**********************************************************************/ +#include "ui_local.h" + +uiStatic_t uis; +qboolean m_entersound; // after a frame, so caching won't disrupt the sound + +// these are here so the functions in q_shared.c can link +#ifndef UI_HARD_LINKED + +void QDECL Com_Error( int level, const char *error, ... ) { + va_list argptr; + char text[1024]; + + va_start (argptr, error); + vsprintf (text, error, argptr); + va_end (argptr); + + trap_Error( va("%s", text) ); +} + +void QDECL Com_Printf( const char *msg, ... ) { + va_list argptr; + char text[1024]; + + va_start (argptr, msg); + vsprintf (text, msg, argptr); + va_end (argptr); + + trap_Print( va("%s", text) ); +} + +#endif + +/* +================= +UI_ClampCvar +================= +*/ +float UI_ClampCvar( float min, float max, float value ) +{ + if ( value < min ) return min; + if ( value > max ) return max; + return value; +} + +/* +================= +UI_StartDemoLoop +================= +*/ +void UI_StartDemoLoop( void ) { + trap_Cmd_ExecuteText( EXEC_APPEND, "d1\n" ); +} + +/* +================= +UI_PushMenu +================= +*/ +void UI_PushMenu( menuframework_s *menu ) +{ + int i; + menucommon_s* item; + + // avoid stacking menus invoked by hotkeys + for (i=0 ; i= MAX_MENUDEPTH) + trap_Error("UI_PushMenu: menu stack overflow"); + + uis.stack[uis.menusp++] = menu; + } + + uis.activemenu = menu; + + // default cursor position + menu->cursor = 0; + menu->cursor_prev = 0; + + m_entersound = qtrue; + + trap_Key_SetCatcher( KEYCATCH_UI ); + + // force first available item to have focus + for (i=0; initems; i++) + { + item = (menucommon_s *)menu->items[i]; + if (!(item->flags & (QMF_GRAYED|QMF_MOUSEONLY|QMF_INACTIVE))) + { + menu->cursor_prev = -1; + Menu_SetCursor( menu, i ); + break; + } + } + + uis.firstdraw = qtrue; +} + +/* +================= +UI_PopMenu +================= +*/ +void UI_PopMenu (void) +{ + trap_S_StartLocalSound( menu_out_sound, CHAN_LOCAL_SOUND ); + + uis.menusp--; + + if (uis.menusp < 0) + trap_Error ("UI_PopMenu: menu stack underflow"); + + if (uis.menusp) { + uis.activemenu = uis.stack[uis.menusp-1]; + uis.firstdraw = qtrue; + } + else { + UI_ForceMenuOff (); + } +} + +void UI_ForceMenuOff (void) +{ + uis.menusp = 0; + uis.activemenu = NULL; + + trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); + trap_Key_ClearStates(); + trap_Cvar_Set( "cl_paused", "0" ); +} + +/* +================= +UI_LerpColor +================= +*/ +void UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t) +{ + int i; + + // lerp and clamp each component + for (i=0; i<4; i++) + { + c[i] = a[i] + t*(b[i]-a[i]); + if (c[i] < 0) + c[i] = 0; + else if (c[i] > 1.0) + c[i] = 1.0; + } +} + +/* +================= +UI_DrawProportionalString2 +================= +*/ +static int propMap[128][3] = { +{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, +{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, + +{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, +{0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, {0, 0, -1}, + +{0, 0, PROP_SPACE_WIDTH}, // SPACE +{11, 122, 7}, // ! +{154, 181, 14}, // " +{55, 122, 17}, // # +{79, 122, 18}, // $ +{101, 122, 23}, // % +{153, 122, 18}, // & +{9, 93, 7}, // ' +{207, 122, 8}, // ( +{230, 122, 9}, // ) +{177, 122, 18}, // * +{30, 152, 18}, // + +{85, 181, 7}, // , +{34, 93, 11}, // - +{110, 181, 6}, // . +{130, 152, 14}, // / + +{22, 64, 17}, // 0 +{41, 64, 12}, // 1 +{58, 64, 17}, // 2 +{78, 64, 18}, // 3 +{98, 64, 19}, // 4 +{120, 64, 18}, // 5 +{141, 64, 18}, // 6 +{204, 64, 16}, // 7 +{162, 64, 17}, // 8 +{182, 64, 18}, // 9 +{59, 181, 7}, // : +{35,181, 7}, // ; +{203, 152, 14}, // < +{56, 93, 14}, // = +{228, 152, 14}, // > +{177, 181, 18}, // ? + +{28, 122, 22}, // @ +{5, 4, 18}, // A +{27, 4, 18}, // B +{48, 4, 18}, // C +{69, 4, 17}, // D +{90, 4, 13}, // E +{106, 4, 13}, // F +{121, 4, 18}, // G +{143, 4, 17}, // H +{164, 4, 8}, // I +{175, 4, 16}, // J +{195, 4, 18}, // K +{216, 4, 12}, // L +{230, 4, 23}, // M +{6, 34, 18}, // N +{27, 34, 18}, // O + +{48, 34, 18}, // P +{68, 34, 18}, // Q +{90, 34, 17}, // R +{110, 34, 18}, // S +{130, 34, 14}, // T +{146, 34, 18}, // U +{166, 34, 19}, // V +{185, 34, 29}, // W +{215, 34, 18}, // X +{234, 34, 18}, // Y +{5, 64, 14}, // Z +{60, 152, 7}, // [ +{106, 151, 13}, // '\' +{83, 152, 7}, // ] +{128, 122, 17}, // ^ +{4, 152, 21}, // _ + +{134, 181, 5}, // ' +{5, 4, 18}, // A +{27, 4, 18}, // B +{48, 4, 18}, // C +{69, 4, 17}, // D +{90, 4, 13}, // E +{106, 4, 13}, // F +{121, 4, 18}, // G +{143, 4, 17}, // H +{164, 4, 8}, // I +{175, 4, 16}, // J +{195, 4, 18}, // K +{216, 4, 12}, // L +{230, 4, 23}, // M +{6, 34, 18}, // N +{27, 34, 18}, // O + +{48, 34, 18}, // P +{68, 34, 18}, // Q +{90, 34, 17}, // R +{110, 34, 18}, // S +{130, 34, 14}, // T +{146, 34, 18}, // U +{166, 34, 19}, // V +{185, 34, 29}, // W +{215, 34, 18}, // X +{234, 34, 18}, // Y +{5, 64, 14}, // Z +{153, 152, 13}, // { +{11, 181, 5}, // | +{180, 152, 13}, // } +{79, 93, 17}, // ~ +{0, 0, -1} // DEL +}; + +static int propMapB[26][3] = { +{11, 12, 33}, +{49, 12, 31}, +{85, 12, 31}, +{120, 12, 30}, +{156, 12, 21}, +{183, 12, 21}, +{207, 12, 32}, + +{13, 55, 30}, +{49, 55, 13}, +{66, 55, 29}, +{101, 55, 31}, +{135, 55, 21}, +{158, 55, 40}, +{204, 55, 32}, + +{12, 97, 31}, +{48, 97, 31}, +{82, 97, 30}, +{118, 97, 30}, +{153, 97, 30}, +{185, 97, 25}, +{213, 97, 30}, + +{11, 139, 32}, +{42, 139, 51}, +{93, 139, 32}, +{126, 139, 31}, +{158, 139, 25}, +}; + +#define PROPB_GAP_WIDTH 4 +#define PROPB_SPACE_WIDTH 12 +#define PROPB_HEIGHT 36 + +// bk001205 - code below duplicated in cgame/cg_drawtools.c +// bk001205 - FIXME: does this belong in ui_shared.c? +/* +================= +UI_DrawBannerString +================= +*/ +static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color ) +{ + const char* s; + unsigned char ch; // bk001204 - unsigned + float ax; + float ay; + float aw; + float ah; + float frow; + float fcol; + float fwidth; + float fheight; + + // draw the colored text + trap_R_SetColor( color ); + + ax = x * uis.scale + uis.bias; + ay = y * uis.scale; + + s = str; + while ( *s ) + { + ch = *s & 127; + if ( ch == ' ' ) { + ax += ((float)PROPB_SPACE_WIDTH + (float)PROPB_GAP_WIDTH)* uis.scale; + } + else if ( ch >= 'A' && ch <= 'Z' ) { + ch -= 'A'; + fcol = (float)propMapB[ch][0] / 256.0f; + frow = (float)propMapB[ch][1] / 256.0f; + fwidth = (float)propMapB[ch][2] / 256.0f; + fheight = (float)PROPB_HEIGHT / 256.0f; + aw = (float)propMapB[ch][2] * uis.scale; + ah = (float)PROPB_HEIGHT * uis.scale; + trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, uis.charsetPropB ); + ax += (aw + (float)PROPB_GAP_WIDTH * uis.scale); + } + s++; + } + + trap_R_SetColor( NULL ); +} + +void UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color ) { + const char * s; + int ch; + int width; + vec4_t drawcolor; + + // find the width of the drawn text + s = str; + width = 0; + while ( *s ) { + ch = *s; + if ( ch == ' ' ) { + width += PROPB_SPACE_WIDTH; + } + else if ( ch >= 'A' && ch <= 'Z' ) { + width += propMapB[ch - 'A'][2] + PROPB_GAP_WIDTH; + } + s++; + } + width -= PROPB_GAP_WIDTH; + + switch( style & UI_FORMATMASK ) { + case UI_CENTER: + x -= width / 2; + break; + + case UI_RIGHT: + x -= width; + break; + + case UI_LEFT: + default: + break; + } + + if ( style & UI_DROPSHADOW ) { + drawcolor[0] = drawcolor[1] = drawcolor[2] = 0; + drawcolor[3] = color[3]; + UI_DrawBannerString2( x+2, y+2, str, drawcolor ); + } + + UI_DrawBannerString2( x, y, str, color ); +} + + +int UI_ProportionalStringWidth( const char* str ) { + const char * s; + int ch; + int charWidth; + int width; + + s = str; + width = 0; + while ( *s ) { + ch = *s & 127; + charWidth = propMap[ch][2]; + if ( charWidth != -1 ) { + width += charWidth; + width += PROP_GAP_WIDTH; + } + s++; + } + + width -= PROP_GAP_WIDTH; + return width; +} + +static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t color, float sizeScale, qhandle_t charset ) +{ + const char* s; + unsigned char ch; // bk001204 - unsigned + float ax; + float ay; + float aw = 0; // bk001204 - init + float ah; + float frow; + float fcol; + float fwidth; + float fheight; + + // draw the colored text + trap_R_SetColor( color ); + + ax = x * uis.scale + uis.bias; + ay = y * uis.scale; + + s = str; + while ( *s ) + { + ch = *s & 127; + if ( ch == ' ' ) { + aw = (float)PROP_SPACE_WIDTH * uis.scale * sizeScale; + } + else if ( propMap[ch][2] != -1 ) { + fcol = (float)propMap[ch][0] / 256.0f; + frow = (float)propMap[ch][1] / 256.0f; + fwidth = (float)propMap[ch][2] / 256.0f; + fheight = (float)PROP_HEIGHT / 256.0f; + aw = (float)propMap[ch][2] * uis.scale * sizeScale; + ah = (float)PROP_HEIGHT * uis.scale * sizeScale; + trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, charset ); + } + + ax += (aw + (float)PROP_GAP_WIDTH * uis.scale * sizeScale); + s++; + } + + trap_R_SetColor( NULL ); +} + +/* +================= +UI_ProportionalSizeScale +================= +*/ +float UI_ProportionalSizeScale( int style ) { + if( style & UI_SMALLFONT ) { + return PROP_SMALL_SIZE_SCALE; + } + + return 1.00; +} + + +/* +================= +UI_DrawProportionalString +================= +*/ +void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ) { + vec4_t drawcolor; + int width; + float sizeScale; + + sizeScale = UI_ProportionalSizeScale( style ); + + switch( style & UI_FORMATMASK ) { + case UI_CENTER: + width = UI_ProportionalStringWidth( str ) * sizeScale; + x -= width / 2; + break; + + case UI_RIGHT: + width = UI_ProportionalStringWidth( str ) * sizeScale; + x -= width; + break; + + case UI_LEFT: + default: + break; + } + + if ( style & UI_DROPSHADOW ) { + drawcolor[0] = drawcolor[1] = drawcolor[2] = 0; + drawcolor[3] = color[3]; + UI_DrawProportionalString2( x+2, y+2, str, drawcolor, sizeScale, uis.charsetProp ); + } + + if ( style & UI_INVERSE ) { + drawcolor[0] = color[0] * 0.7; + drawcolor[1] = color[1] * 0.7; + drawcolor[2] = color[2] * 0.7; + drawcolor[3] = color[3]; + UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, uis.charsetProp ); + return; + } + + if ( style & UI_PULSE ) { + drawcolor[0] = color[0] * 0.7; + drawcolor[1] = color[1] * 0.7; + drawcolor[2] = color[2] * 0.7; + drawcolor[3] = color[3]; + UI_DrawProportionalString2( x, y, str, color, sizeScale, uis.charsetProp ); + + drawcolor[0] = color[0]; + drawcolor[1] = color[1]; + drawcolor[2] = color[2]; + drawcolor[3] = 0.5 + 0.5 * sin( uis.realtime / PULSE_DIVISOR ); + UI_DrawProportionalString2( x, y, str, drawcolor, sizeScale, uis.charsetPropGlow ); + return; + } + + UI_DrawProportionalString2( x, y, str, color, sizeScale, uis.charsetProp ); +} + +/* +================= +UI_DrawProportionalString_Wrapped +================= +*/ +void UI_DrawProportionalString_AutoWrapped( int x, int y, int xmax, int ystep, const char* str, int style, vec4_t color ) { + int width; + char *s1,*s2,*s3; + char c_bcp; + char buf[1024]; + float sizeScale; + + if (!str || str[0]=='\0') + return; + + sizeScale = UI_ProportionalSizeScale( style ); + + Q_strncpyz(buf, str, sizeof(buf)); + s1 = s2 = s3 = buf; + + while (1) { + do { + s3++; + } while (*s3!=' ' && *s3!='\0'); + c_bcp = *s3; + *s3 = '\0'; + width = UI_ProportionalStringWidth(s1) * sizeScale; + *s3 = c_bcp; + if (width > xmax) { + if (s1==s2) + { + // fuck, don't have a clean cut, we'll overflow + s2 = s3; + } + *s2 = '\0'; + UI_DrawProportionalString(x, y, s1, style, color); + y += ystep; + if (c_bcp == '\0') + { + // that was the last word + // we could start a new loop, but that wouldn't be much use + // even if the word is too long, we would overflow it (see above) + // so just print it now if needed + s2++; + if (*s2 != '\0') // if we are printing an overflowing line we have s2 == s3 + UI_DrawProportionalString(x, y, s2, style, color); + break; + } + s2++; + s1 = s2; + s3 = s2; + } + else + { + s2 = s3; + if (c_bcp == '\0') // we reached the end + { + UI_DrawProportionalString(x, y, s1, style, color); + break; + } + } + } +} + +/* +================= +UI_DrawString2 +================= +*/ +static void UI_DrawString2( int x, int y, const char* str, vec4_t color, int charw, int charh ) +{ + const char* s; + char ch; + int forceColor = qfalse; //APSFIXME; + vec4_t tempcolor; + float ax; + float ay; + float aw; + float ah; + float frow; + float fcol; + + if (y < -charh) + // offscreen + return; + + // draw the colored text + trap_R_SetColor( color ); + + ax = x * uis.scale + uis.bias; + ay = y * uis.scale; + aw = charw * uis.scale; + ah = charh * uis.scale; + + s = str; + while ( *s ) + { + if ( Q_IsColorString( s ) ) + { + if ( !forceColor ) + { + memcpy( tempcolor, g_color_table[ColorIndex(s[1])], sizeof( tempcolor ) ); + tempcolor[3] = color[3]; + trap_R_SetColor( tempcolor ); + } + s += 2; + continue; + } + + ch = *s & 255; + if (ch != ' ') + { + frow = (ch>>4)*0.0625; + fcol = (ch&15)*0.0625; + trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol + 0.0625, frow + 0.0625, uis.charset ); + } + + ax += aw; + s++; + } + + trap_R_SetColor( NULL ); +} + +/* +================= +UI_DrawString +================= +*/ +void UI_DrawString( int x, int y, const char* str, int style, vec4_t color ) +{ + int len; + int charw; + int charh; + vec4_t newcolor; + vec4_t lowlight; + float *drawcolor; + vec4_t dropcolor; + + if( !str ) { + return; + } + + if ((style & UI_BLINK) && ((uis.realtime/BLINK_DIVISOR) & 1)) + return; + + if (style & UI_SMALLFONT) + { + charw = SMALLCHAR_WIDTH; + charh = SMALLCHAR_HEIGHT; + } + else if (style & UI_GIANTFONT) + { + charw = GIANTCHAR_WIDTH; + charh = GIANTCHAR_HEIGHT; + } + else + { + charw = BIGCHAR_WIDTH; + charh = BIGCHAR_HEIGHT; + } + + if (style & UI_PULSE) + { + lowlight[0] = 0.8*color[0]; + lowlight[1] = 0.8*color[1]; + lowlight[2] = 0.8*color[2]; + lowlight[3] = 0.8*color[3]; + UI_LerpColor(color,lowlight,newcolor,0.5+0.5*sin(uis.realtime/PULSE_DIVISOR)); + drawcolor = newcolor; + } + else + drawcolor = color; + + switch (style & UI_FORMATMASK) + { + case UI_CENTER: + // center justify at x + len = strlen(str); + x = x - len*charw/2; + break; + + case UI_RIGHT: + // right justify at x + len = strlen(str); + x = x - len*charw; + break; + + default: + // left justify at x + break; + } + + if ( style & UI_DROPSHADOW ) + { + dropcolor[0] = dropcolor[1] = dropcolor[2] = 0; + dropcolor[3] = drawcolor[3]; + UI_DrawString2(x+2,y+2,str,dropcolor,charw,charh); + } + + UI_DrawString2(x,y,str,drawcolor,charw,charh); +} + +/* +================= +UI_DrawChar +================= +*/ +void UI_DrawChar( int x, int y, int ch, int style, vec4_t color ) +{ + char buff[2]; + + buff[0] = ch; + buff[1] = '\0'; + + UI_DrawString( x, y, buff, style, color ); +} + +qboolean UI_IsFullscreen( void ) { + if ( uis.activemenu && ( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { + return uis.activemenu->fullscreen; + } + + return qfalse; +} + +static void NeedCDAction( qboolean result ) { + if ( !result ) { + trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" ); + } +} + +static void NeedCDKeyAction( qboolean result ) { + if ( !result ) { + trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" ); + } +} + +void UI_SetActiveMenu( uiMenuCommand_t menu ) { + // this should be the ONLY way the menu system is brought up + // enusure minumum menu data is cached + Menu_Cache(); + + switch ( menu ) { + case UIMENU_NONE: + UI_ForceMenuOff(); + return; + case UIMENU_MAIN: + UI_MainMenu(); + return; + case UIMENU_NEED_CD: + UI_ConfirmMenu( "Insert the CD", (voidfunc_f)NULL, NeedCDAction ); + return; + case UIMENU_BAD_CD_KEY: + UI_ConfirmMenu( "Bad CD Key", (voidfunc_f)NULL, NeedCDKeyAction ); + return; + case UIMENU_INGAME: + /* + //GRank + UI_RankingsMenu(); + return; + */ + trap_Cvar_Set( "cl_paused", "1" ); + UI_InGameMenu(); + return; + + // bk001204 + case UIMENU_TEAM: + case UIMENU_POSTGAME: + default: +#ifndef NDEBUG + Com_Printf("UI_SetActiveMenu: bad enum %d\n", menu ); +#endif + break; + } +} + +/* +================= +UI_KeyEvent +================= +*/ +void UI_KeyEvent( int key, int down ) { + sfxHandle_t s; + + if (!uis.activemenu) { + return; + } + + if (!down) { + return; + } + + if (uis.activemenu->key) + s = uis.activemenu->key( key ); + else + s = Menu_DefaultKey( uis.activemenu, key ); + + if ((s > 0) && (s != menu_null_sound)) + trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND ); +} + +/* +================= +UI_MouseEvent +================= +*/ +void UI_MouseEvent( int dx, int dy ) +{ + int i; + menucommon_s* m; + + if (!uis.activemenu) + return; + + // update mouse screen position + uis.cursorx += dx; + if (uis.cursorx < 0) + uis.cursorx = 0; + else if (uis.cursorx > SCREEN_WIDTH) + uis.cursorx = SCREEN_WIDTH; + + uis.cursory += dy; + if (uis.cursory < 0) + uis.cursory = 0; + else if (uis.cursory > SCREEN_HEIGHT) + uis.cursory = SCREEN_HEIGHT; + + // region test the active menu items + for (i=0; initems; i++) + { + m = (menucommon_s*)uis.activemenu->items[i]; + + if (m->flags & (QMF_GRAYED|QMF_INACTIVE)) + continue; + + if ((uis.cursorx < m->left) || + (uis.cursorx > m->right) || + (uis.cursory < m->top) || + (uis.cursory > m->bottom)) + { + // cursor out of item bounds + continue; + } + + // set focus to item at cursor + if (uis.activemenu->cursor != i) + { + Menu_SetCursor( uis.activemenu, i ); + ((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor_prev]))->flags &= ~QMF_HASMOUSEFOCUS; + + if ( !(((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags & QMF_SILENT ) ) { + trap_S_StartLocalSound( menu_move_sound, CHAN_LOCAL_SOUND ); + } + } + + ((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags |= QMF_HASMOUSEFOCUS; + return; + } + + if (uis.activemenu->nitems > 0) { + // out of any region + ((menucommon_s*)(uis.activemenu->items[uis.activemenu->cursor]))->flags &= ~QMF_HASMOUSEFOCUS; + } +} + +char *UI_Argv( int arg ) { + static char buffer[MAX_STRING_CHARS]; + + trap_Argv( arg, buffer, sizeof( buffer ) ); + + return buffer; +} + + +char *UI_Cvar_VariableString( const char *var_name ) { + static char buffer[MAX_STRING_CHARS]; + + trap_Cvar_VariableStringBuffer( var_name, buffer, sizeof( buffer ) ); + + return buffer; +} + + +/* +================= +UI_Cache +================= +*/ +void UI_Cache_f( void ) { + MainMenu_Cache(); + InGame_Cache(); + ConfirmMenu_Cache(); + PlayerModel_Cache(); + PlayerSettings_Cache(); + Controls_Cache(); + Demos_Cache(); + UI_CinematicsMenu_Cache(); + Preferences_Cache(); + ServerInfo_Cache(); + SpecifyServer_Cache(); + ArenaServers_Cache(); + StartServer_Cache(); + ServerOptions_Cache(); + DriverInfo_Cache(); + GraphicsOptions_Cache(); + UI_DisplayOptionsMenu_Cache(); + UI_SoundOptionsMenu_Cache(); + UI_NetworkOptionsMenu_Cache(); + UI_SPLevelMenu_Cache(); + UI_SPSkillMenu_Cache(); + UI_SPPostgameMenu_Cache(); + TeamMain_Cache(); + UI_AddBots_Cache(); + UI_RemoveBots_Cache(); + UI_SetupMenu_Cache(); +// UI_LoadConfig_Cache(); +// UI_SaveConfigMenu_Cache(); + UI_BotSelectMenu_Cache(); + UI_CDKeyMenu_Cache(); + UI_ModsMenu_Cache(); + +} + + +/* +================= +UI_ConsoleCommand +================= +*/ +qboolean UI_ConsoleCommand( int realTime ) { + char *cmd; + + cmd = UI_Argv( 0 ); + + // ensure minimum menu data is available + Menu_Cache(); + + if ( Q_stricmp (cmd, "levelselect") == 0 ) { + UI_SPLevelMenu_f(); + return qtrue; + } + + if ( Q_stricmp (cmd, "postgame") == 0 ) { + UI_SPPostgameMenu_f(); + return qtrue; + } + + if ( Q_stricmp (cmd, "ui_cache") == 0 ) { + UI_Cache_f(); + return qtrue; + } + + if ( Q_stricmp (cmd, "ui_cinematics") == 0 ) { + UI_CinematicsMenu_f(); + return qtrue; + } + + if ( Q_stricmp (cmd, "ui_teamOrders") == 0 ) { + UI_TeamOrdersMenu_f(); + return qtrue; + } + + if ( Q_stricmp (cmd, "iamacheater") == 0 ) { + UI_SPUnlock_f(); + return qtrue; + } + + if ( Q_stricmp (cmd, "iamamonkey") == 0 ) { + UI_SPUnlockMedals_f(); + return qtrue; + } + + if ( Q_stricmp (cmd, "ui_cdkey") == 0 ) { + UI_CDKeyMenu_f(); + return qtrue; + } + + return qfalse; +} + +/* +================= +UI_Shutdown +================= +*/ +void UI_Shutdown( void ) { +} + +/* +================= +UI_Init +================= +*/ +void UI_Init( void ) { + UI_RegisterCvars(); + + UI_InitGameinfo(); + + // cache redundant calulations + trap_GetGlconfig( &uis.glconfig ); + + // for 640x480 virtualized screen + uis.scale = uis.glconfig.vidHeight * (1.0/480.0); + if ( uis.glconfig.vidWidth * 480 > uis.glconfig.vidHeight * 640 ) { + // wide screen + uis.bias = 0.5 * ( uis.glconfig.vidWidth - ( uis.glconfig.vidHeight * (640.0/480.0) ) ); + } + else { + // no wide screen + uis.bias = 0; + } + + // initialize the menu system + Menu_Cache(); + + uis.activemenu = NULL; + uis.menusp = 0; +} + +/* +================ +UI_AdjustFrom640 + +Adjusted for resolution and screen aspect ratio +================ +*/ +void UI_AdjustFrom640( float *x, float *y, float *w, float *h ) { + // expect valid pointers + *x = *x * uis.scale + uis.bias; + *y *= uis.scale; + *w *= uis.scale; + *h *= uis.scale; +} + +void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ) { + qhandle_t hShader; + + hShader = trap_R_RegisterShaderNoMip( picname ); + UI_AdjustFrom640( &x, &y, &width, &height ); + trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader ); +} + +void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ) { + float s0; + float s1; + float t0; + float t1; + + if( w < 0 ) { // flip about vertical + w = -w; + s0 = 1; + s1 = 0; + } + else { + s0 = 0; + s1 = 1; + } + + if( h < 0 ) { // flip about horizontal + h = -h; + t0 = 1; + t1 = 0; + } + else { + t0 = 0; + t1 = 1; + } + + UI_AdjustFrom640( &x, &y, &w, &h ); + trap_R_DrawStretchPic( x, y, w, h, s0, t0, s1, t1, hShader ); +} + +/* +================ +UI_FillRect + +Coordinates are 640*480 virtual values +================= +*/ +void UI_FillRect( float x, float y, float width, float height, const float *color ) { + trap_R_SetColor( color ); + + UI_AdjustFrom640( &x, &y, &width, &height ); + trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, uis.whiteShader ); + + trap_R_SetColor( NULL ); +} + +/* +================ +UI_DrawRect + +Coordinates are 640*480 virtual values +================= +*/ +void UI_DrawRect( float x, float y, float width, float height, const float *color ) { + trap_R_SetColor( color ); + + UI_AdjustFrom640( &x, &y, &width, &height ); + + trap_R_DrawStretchPic( x, y, width, 1, 0, 0, 0, 0, uis.whiteShader ); + trap_R_DrawStretchPic( x, y, 1, height, 0, 0, 0, 0, uis.whiteShader ); + trap_R_DrawStretchPic( x, y + height - 1, width, 1, 0, 0, 0, 0, uis.whiteShader ); + trap_R_DrawStretchPic( x + width - 1, y, 1, height, 0, 0, 0, 0, uis.whiteShader ); + + trap_R_SetColor( NULL ); +} + +void UI_SetColor( const float *rgba ) { + trap_R_SetColor( rgba ); +} + +void UI_UpdateScreen( void ) { + trap_UpdateScreen(); +} + +/* +================= +UI_Refresh +================= +*/ +void UI_Refresh( int realtime ) +{ + uis.frametime = realtime - uis.realtime; + uis.realtime = realtime; + + if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { + return; + } + + UI_UpdateCvars(); + + if ( uis.activemenu ) + { + if (uis.activemenu->fullscreen) + { + // draw the background + if( uis.activemenu->showlogo ) { + UI_DrawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.menuBackShader ); + } + else { + UI_DrawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.menuBackNoLogoShader ); + } + } + + if (uis.activemenu->draw) + uis.activemenu->draw(); + else + Menu_Draw( uis.activemenu ); + + if( uis.firstdraw ) { + UI_MouseEvent( 0, 0 ); + uis.firstdraw = qfalse; + } + } + + // draw cursor + UI_SetColor( NULL ); + UI_DrawHandlePic( uis.cursorx-16, uis.cursory-16, 32, 32, uis.cursor); + +#ifndef NDEBUG + if (uis.debug) + { + // cursor coordinates + UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed ); + } +#endif + + // delay playing the enter sound until after the + // menu has been drawn, to avoid delay while + // caching images + if (m_entersound) + { + trap_S_StartLocalSound( menu_in_sound, CHAN_LOCAL_SOUND ); + m_entersound = qfalse; + } +} + +void UI_DrawTextBox (int x, int y, int width, int lines) +{ + UI_FillRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorBlack ); + UI_DrawRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorWhite ); +} + +qboolean UI_CursorInRect (int x, int y, int width, int height) +{ + if (uis.cursorx < x || + uis.cursory < y || + uis.cursorx > x+width || + uis.cursory > y+height) + return qfalse; + + return qtrue; +} diff --git a/code/q3_ui/ui_cdkey.c b/code/q3_ui/ui_cdkey.c index 0b1f718..e9ed1e5 100755 --- a/code/q3_ui/ui_cdkey.c +++ b/code/q3_ui/ui_cdkey.c @@ -1,291 +1,291 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -CD KEY MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ART_FRAME "menu/art/cut_frame" -#define ART_ACCEPT0 "menu/art/accept_0" -#define ART_ACCEPT1 "menu/art/accept_1" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" - -#define ID_CDKEY 10 -#define ID_ACCEPT 11 -#define ID_BACK 12 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s frame; - - menufield_s cdkey; - - menubitmap_s accept; - menubitmap_s back; -} cdkeyMenuInfo_t; - -static cdkeyMenuInfo_t cdkeyMenuInfo; - - -/* -=============== -UI_CDKeyMenu_Event -=============== -*/ -static void UI_CDKeyMenu_Event( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_ACCEPT: - if( cdkeyMenuInfo.cdkey.field.buffer[0] ) { - trap_SetCDKey( cdkeyMenuInfo.cdkey.field.buffer ); - } - UI_PopMenu(); - break; - - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -================= -UI_CDKeyMenu_PreValidateKey -================= -*/ -static int UI_CDKeyMenu_PreValidateKey( const char *key ) { - char ch; - - if( strlen( key ) != 16 ) { - return 1; - } - - while( ( ch = *key++ ) ) { - switch( ch ) { - case '2': - case '3': - case '7': - case 'a': - case 'b': - case 'c': - case 'd': - case 'g': - case 'h': - case 'j': - case 'l': - case 'p': - case 'r': - case 's': - case 't': - case 'w': - continue; - default: - return -1; - } - } - - return 0; -} - - -/* -================= -UI_CDKeyMenu_DrawKey -================= -*/ -static void UI_CDKeyMenu_DrawKey( void *self ) { - menufield_s *f; - qboolean focus; - int style; - char c; - float *color; - int x, y; - int val; - - f = (menufield_s *)self; - - focus = (f->generic.parent->cursor == f->generic.menuPosition); - - style = UI_LEFT; - if( focus ) { - color = color_yellow; - } - else { - color = color_orange; - } - - x = 320 - 8 * BIGCHAR_WIDTH; - y = 240 - BIGCHAR_HEIGHT / 2; - UI_FillRect( x, y, 16 * BIGCHAR_WIDTH, BIGCHAR_HEIGHT, listbar_color ); - UI_DrawString( x, y, f->field.buffer, style, color ); - - // draw cursor if we have focus - if( focus ) { - if ( trap_Key_GetOverstrikeMode() ) { - c = 11; - } else { - c = 10; - } - - style &= ~UI_PULSE; - style |= UI_BLINK; - - UI_DrawChar( x + f->field.cursor * BIGCHAR_WIDTH, y, c, style, color_white ); - } - - val = UI_CDKeyMenu_PreValidateKey( f->field.buffer ); - if( val == 1 ) { - UI_DrawProportionalString( 320, 376, "Please enter your CD Key", UI_CENTER|UI_SMALLFONT, color_yellow ); - } - else if ( val == 0 ) { - UI_DrawProportionalString( 320, 376, "The CD Key appears to be valid, thank you", UI_CENTER|UI_SMALLFONT, color_white ); - } - else { - UI_DrawProportionalString( 320, 376, "The CD Key is not valid", UI_CENTER|UI_SMALLFONT, color_red ); - } -} - - -/* -=============== -UI_CDKeyMenu_Init -=============== -*/ -static void UI_CDKeyMenu_Init( void ) { - trap_Cvar_Set( "ui_cdkeychecked", "1" ); - - UI_CDKeyMenu_Cache(); - - memset( &cdkeyMenuInfo, 0, sizeof(cdkeyMenuInfo) ); - cdkeyMenuInfo.menu.wrapAround = qtrue; - cdkeyMenuInfo.menu.fullscreen = qtrue; - - cdkeyMenuInfo.banner.generic.type = MTYPE_BTEXT; - cdkeyMenuInfo.banner.generic.x = 320; - cdkeyMenuInfo.banner.generic.y = 16; - cdkeyMenuInfo.banner.string = "CD KEY"; - cdkeyMenuInfo.banner.color = color_white; - cdkeyMenuInfo.banner.style = UI_CENTER; - - cdkeyMenuInfo.frame.generic.type = MTYPE_BITMAP; - cdkeyMenuInfo.frame.generic.name = ART_FRAME; - cdkeyMenuInfo.frame.generic.flags = QMF_INACTIVE; - cdkeyMenuInfo.frame.generic.x = 142; - cdkeyMenuInfo.frame.generic.y = 118; - cdkeyMenuInfo.frame.width = 359; - cdkeyMenuInfo.frame.height = 256; - - cdkeyMenuInfo.cdkey.generic.type = MTYPE_FIELD; - cdkeyMenuInfo.cdkey.generic.name = "CD Key:"; - cdkeyMenuInfo.cdkey.generic.flags = QMF_LOWERCASE; - cdkeyMenuInfo.cdkey.generic.x = 320 - BIGCHAR_WIDTH * 2.5; - cdkeyMenuInfo.cdkey.generic.y = 240 - BIGCHAR_HEIGHT / 2; - cdkeyMenuInfo.cdkey.field.widthInChars = 16; - cdkeyMenuInfo.cdkey.field.maxchars = 16; - cdkeyMenuInfo.cdkey.generic.ownerdraw = UI_CDKeyMenu_DrawKey; - - cdkeyMenuInfo.accept.generic.type = MTYPE_BITMAP; - cdkeyMenuInfo.accept.generic.name = ART_ACCEPT0; - cdkeyMenuInfo.accept.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - cdkeyMenuInfo.accept.generic.id = ID_ACCEPT; - cdkeyMenuInfo.accept.generic.callback = UI_CDKeyMenu_Event; - cdkeyMenuInfo.accept.generic.x = 640; - cdkeyMenuInfo.accept.generic.y = 480-64; - cdkeyMenuInfo.accept.width = 128; - cdkeyMenuInfo.accept.height = 64; - cdkeyMenuInfo.accept.focuspic = ART_ACCEPT1; - - cdkeyMenuInfo.back.generic.type = MTYPE_BITMAP; - cdkeyMenuInfo.back.generic.name = ART_BACK0; - cdkeyMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - cdkeyMenuInfo.back.generic.id = ID_BACK; - cdkeyMenuInfo.back.generic.callback = UI_CDKeyMenu_Event; - cdkeyMenuInfo.back.generic.x = 0; - cdkeyMenuInfo.back.generic.y = 480-64; - cdkeyMenuInfo.back.width = 128; - cdkeyMenuInfo.back.height = 64; - cdkeyMenuInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.banner ); - Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.frame ); - Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.cdkey ); - Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.accept ); - if( uis.menusp ) { - Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.back ); - } - - trap_GetCDKey( cdkeyMenuInfo.cdkey.field.buffer, cdkeyMenuInfo.cdkey.field.maxchars + 1 ); - if( trap_VerifyCDKey( cdkeyMenuInfo.cdkey.field.buffer, NULL ) == qfalse ) { - cdkeyMenuInfo.cdkey.field.buffer[0] = 0; - } -} - - -/* -================= -UI_CDKeyMenu_Cache -================= -*/ -void UI_CDKeyMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_ACCEPT0 ); - trap_R_RegisterShaderNoMip( ART_ACCEPT1 ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FRAME ); -} - - -/* -=============== -UI_CDKeyMenu -=============== -*/ -void UI_CDKeyMenu( void ) { - UI_CDKeyMenu_Init(); - UI_PushMenu( &cdkeyMenuInfo.menu ); -} - - -/* -=============== -UI_CDKeyMenu_f -=============== -*/ -void UI_CDKeyMenu_f( void ) { - UI_CDKeyMenu(); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +CD KEY MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ART_FRAME "menu/art/cut_frame" +#define ART_ACCEPT0 "menu/art/accept_0" +#define ART_ACCEPT1 "menu/art/accept_1" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" + +#define ID_CDKEY 10 +#define ID_ACCEPT 11 +#define ID_BACK 12 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s frame; + + menufield_s cdkey; + + menubitmap_s accept; + menubitmap_s back; +} cdkeyMenuInfo_t; + +static cdkeyMenuInfo_t cdkeyMenuInfo; + + +/* +=============== +UI_CDKeyMenu_Event +=============== +*/ +static void UI_CDKeyMenu_Event( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_ACCEPT: + if( cdkeyMenuInfo.cdkey.field.buffer[0] ) { + trap_SetCDKey( cdkeyMenuInfo.cdkey.field.buffer ); + } + UI_PopMenu(); + break; + + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +================= +UI_CDKeyMenu_PreValidateKey +================= +*/ +static int UI_CDKeyMenu_PreValidateKey( const char *key ) { + char ch; + + if( strlen( key ) != 16 ) { + return 1; + } + + while( ( ch = *key++ ) ) { + switch( ch ) { + case '2': + case '3': + case '7': + case 'a': + case 'b': + case 'c': + case 'd': + case 'g': + case 'h': + case 'j': + case 'l': + case 'p': + case 'r': + case 's': + case 't': + case 'w': + continue; + default: + return -1; + } + } + + return 0; +} + + +/* +================= +UI_CDKeyMenu_DrawKey +================= +*/ +static void UI_CDKeyMenu_DrawKey( void *self ) { + menufield_s *f; + qboolean focus; + int style; + char c; + float *color; + int x, y; + int val; + + f = (menufield_s *)self; + + focus = (f->generic.parent->cursor == f->generic.menuPosition); + + style = UI_LEFT; + if( focus ) { + color = color_yellow; + } + else { + color = color_orange; + } + + x = 320 - 8 * BIGCHAR_WIDTH; + y = 240 - BIGCHAR_HEIGHT / 2; + UI_FillRect( x, y, 16 * BIGCHAR_WIDTH, BIGCHAR_HEIGHT, listbar_color ); + UI_DrawString( x, y, f->field.buffer, style, color ); + + // draw cursor if we have focus + if( focus ) { + if ( trap_Key_GetOverstrikeMode() ) { + c = 11; + } else { + c = 10; + } + + style &= ~UI_PULSE; + style |= UI_BLINK; + + UI_DrawChar( x + f->field.cursor * BIGCHAR_WIDTH, y, c, style, color_white ); + } + + val = UI_CDKeyMenu_PreValidateKey( f->field.buffer ); + if( val == 1 ) { + UI_DrawProportionalString( 320, 376, "Please enter your CD Key", UI_CENTER|UI_SMALLFONT, color_yellow ); + } + else if ( val == 0 ) { + UI_DrawProportionalString( 320, 376, "The CD Key appears to be valid, thank you", UI_CENTER|UI_SMALLFONT, color_white ); + } + else { + UI_DrawProportionalString( 320, 376, "The CD Key is not valid", UI_CENTER|UI_SMALLFONT, color_red ); + } +} + + +/* +=============== +UI_CDKeyMenu_Init +=============== +*/ +static void UI_CDKeyMenu_Init( void ) { + trap_Cvar_Set( "ui_cdkeychecked", "1" ); + + UI_CDKeyMenu_Cache(); + + memset( &cdkeyMenuInfo, 0, sizeof(cdkeyMenuInfo) ); + cdkeyMenuInfo.menu.wrapAround = qtrue; + cdkeyMenuInfo.menu.fullscreen = qtrue; + + cdkeyMenuInfo.banner.generic.type = MTYPE_BTEXT; + cdkeyMenuInfo.banner.generic.x = 320; + cdkeyMenuInfo.banner.generic.y = 16; + cdkeyMenuInfo.banner.string = "CD KEY"; + cdkeyMenuInfo.banner.color = color_white; + cdkeyMenuInfo.banner.style = UI_CENTER; + + cdkeyMenuInfo.frame.generic.type = MTYPE_BITMAP; + cdkeyMenuInfo.frame.generic.name = ART_FRAME; + cdkeyMenuInfo.frame.generic.flags = QMF_INACTIVE; + cdkeyMenuInfo.frame.generic.x = 142; + cdkeyMenuInfo.frame.generic.y = 118; + cdkeyMenuInfo.frame.width = 359; + cdkeyMenuInfo.frame.height = 256; + + cdkeyMenuInfo.cdkey.generic.type = MTYPE_FIELD; + cdkeyMenuInfo.cdkey.generic.name = "CD Key:"; + cdkeyMenuInfo.cdkey.generic.flags = QMF_LOWERCASE; + cdkeyMenuInfo.cdkey.generic.x = 320 - BIGCHAR_WIDTH * 2.5; + cdkeyMenuInfo.cdkey.generic.y = 240 - BIGCHAR_HEIGHT / 2; + cdkeyMenuInfo.cdkey.field.widthInChars = 16; + cdkeyMenuInfo.cdkey.field.maxchars = 16; + cdkeyMenuInfo.cdkey.generic.ownerdraw = UI_CDKeyMenu_DrawKey; + + cdkeyMenuInfo.accept.generic.type = MTYPE_BITMAP; + cdkeyMenuInfo.accept.generic.name = ART_ACCEPT0; + cdkeyMenuInfo.accept.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + cdkeyMenuInfo.accept.generic.id = ID_ACCEPT; + cdkeyMenuInfo.accept.generic.callback = UI_CDKeyMenu_Event; + cdkeyMenuInfo.accept.generic.x = 640; + cdkeyMenuInfo.accept.generic.y = 480-64; + cdkeyMenuInfo.accept.width = 128; + cdkeyMenuInfo.accept.height = 64; + cdkeyMenuInfo.accept.focuspic = ART_ACCEPT1; + + cdkeyMenuInfo.back.generic.type = MTYPE_BITMAP; + cdkeyMenuInfo.back.generic.name = ART_BACK0; + cdkeyMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + cdkeyMenuInfo.back.generic.id = ID_BACK; + cdkeyMenuInfo.back.generic.callback = UI_CDKeyMenu_Event; + cdkeyMenuInfo.back.generic.x = 0; + cdkeyMenuInfo.back.generic.y = 480-64; + cdkeyMenuInfo.back.width = 128; + cdkeyMenuInfo.back.height = 64; + cdkeyMenuInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.banner ); + Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.frame ); + Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.cdkey ); + Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.accept ); + if( uis.menusp ) { + Menu_AddItem( &cdkeyMenuInfo.menu, &cdkeyMenuInfo.back ); + } + + trap_GetCDKey( cdkeyMenuInfo.cdkey.field.buffer, cdkeyMenuInfo.cdkey.field.maxchars + 1 ); + if( trap_VerifyCDKey( cdkeyMenuInfo.cdkey.field.buffer, NULL ) == qfalse ) { + cdkeyMenuInfo.cdkey.field.buffer[0] = 0; + } +} + + +/* +================= +UI_CDKeyMenu_Cache +================= +*/ +void UI_CDKeyMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_ACCEPT0 ); + trap_R_RegisterShaderNoMip( ART_ACCEPT1 ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FRAME ); +} + + +/* +=============== +UI_CDKeyMenu +=============== +*/ +void UI_CDKeyMenu( void ) { + UI_CDKeyMenu_Init(); + UI_PushMenu( &cdkeyMenuInfo.menu ); +} + + +/* +=============== +UI_CDKeyMenu_f +=============== +*/ +void UI_CDKeyMenu_f( void ) { + UI_CDKeyMenu(); +} diff --git a/code/q3_ui/ui_cinematics.c b/code/q3_ui/ui_cinematics.c index 6092b4a..b2e4ea6 100755 --- a/code/q3_ui/ui_cinematics.c +++ b/code/q3_ui/ui_cinematics.c @@ -1,350 +1,350 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" - -#define VERTICAL_SPACING 30 - -#define ID_BACK 10 -#define ID_CIN_IDLOGO 11 -#define ID_CIN_INTRO 12 -#define ID_CIN_TIER1 13 -#define ID_CIN_TIER2 14 -#define ID_CIN_TIER3 15 -#define ID_CIN_TIER4 16 -#define ID_CIN_TIER5 17 -#define ID_CIN_TIER6 18 -#define ID_CIN_TIER7 19 -#define ID_CIN_END 20 - - -typedef struct { - menuframework_s menu; - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - menutext_s cin_idlogo; - menutext_s cin_intro; - menutext_s cin_tier1; - menutext_s cin_tier2; - menutext_s cin_tier3; - menutext_s cin_tier4; - menutext_s cin_tier5; - menutext_s cin_tier6; - menutext_s cin_tier7; - menutext_s cin_end; - menubitmap_s back; -} cinematicsMenuInfo_t; - -static cinematicsMenuInfo_t cinematicsMenuInfo; - -static char *cinematics[] = { - "idlogo", - "intro", - "tier1", - "tier2", - "tier3", - "tier4", - "tier5", - "tier6", - "tier7", - "end" -}; - -/* -=============== -UI_CinematicsMenu_BackEvent -=============== -*/ -static void UI_CinematicsMenu_BackEvent( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - UI_PopMenu(); -} - - -/* -=============== -UI_CinematicsMenu_Event -=============== -*/ -static void UI_CinematicsMenu_Event( void *ptr, int event ) { - int n; - - if (event != QM_ACTIVATED) - return; - - n = ((menucommon_s*)ptr)->id - ID_CIN_IDLOGO; - trap_Cvar_Set( "nextmap", va( "ui_cinematics %i", n ) ); - if( uis.demoversion && ((menucommon_s*)ptr)->id == ID_CIN_END ) { - trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic demoEnd.RoQ 1\n" ); - } - else { - trap_Cmd_ExecuteText( EXEC_APPEND, va( "disconnect; cinematic %s.RoQ\n", cinematics[n] ) ); - } -} - - -/* -=============== -UI_CinematicsMenu_Init -=============== -*/ -static void UI_CinematicsMenu_Init( void ) { - int y; - - UI_CinematicsMenu_Cache(); - - memset( &cinematicsMenuInfo, 0, sizeof(cinematicsMenuInfo) ); - cinematicsMenuInfo.menu.fullscreen = qtrue; - - cinematicsMenuInfo.banner.generic.type = MTYPE_BTEXT; - cinematicsMenuInfo.banner.generic.x = 320; - cinematicsMenuInfo.banner.generic.y = 16; - cinematicsMenuInfo.banner.string = "CINEMATICS"; - cinematicsMenuInfo.banner.color = color_white; - cinematicsMenuInfo.banner.style = UI_CENTER; - - cinematicsMenuInfo.framel.generic.type = MTYPE_BITMAP; - cinematicsMenuInfo.framel.generic.name = ART_FRAMEL; - cinematicsMenuInfo.framel.generic.flags = QMF_INACTIVE; - cinematicsMenuInfo.framel.generic.x = 0; - cinematicsMenuInfo.framel.generic.y = 78; - cinematicsMenuInfo.framel.width = 256; - cinematicsMenuInfo.framel.height = 329; - - cinematicsMenuInfo.framer.generic.type = MTYPE_BITMAP; - cinematicsMenuInfo.framer.generic.name = ART_FRAMER; - cinematicsMenuInfo.framer.generic.flags = QMF_INACTIVE; - cinematicsMenuInfo.framer.generic.x = 376; - cinematicsMenuInfo.framer.generic.y = 76; - cinematicsMenuInfo.framer.width = 256; - cinematicsMenuInfo.framer.height = 334; - - y = 100; - cinematicsMenuInfo.cin_idlogo.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_idlogo.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_idlogo.generic.x = 320; - cinematicsMenuInfo.cin_idlogo.generic.y = y; - cinematicsMenuInfo.cin_idlogo.generic.id = ID_CIN_IDLOGO; - cinematicsMenuInfo.cin_idlogo.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_idlogo.string = "ID LOGO"; - cinematicsMenuInfo.cin_idlogo.color = color_red; - cinematicsMenuInfo.cin_idlogo.style = UI_CENTER; - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_intro.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_intro.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_intro.generic.x = 320; - cinematicsMenuInfo.cin_intro.generic.y = y; - cinematicsMenuInfo.cin_intro.generic.id = ID_CIN_INTRO; - cinematicsMenuInfo.cin_intro.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_intro.string = "INTRO"; - cinematicsMenuInfo.cin_intro.color = color_red; - cinematicsMenuInfo.cin_intro.style = UI_CENTER; - if( uis.demoversion ) { - cinematicsMenuInfo.cin_intro.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_tier1.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_tier1.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_tier1.generic.x = 320; - cinematicsMenuInfo.cin_tier1.generic.y = y; - cinematicsMenuInfo.cin_tier1.generic.id = ID_CIN_TIER1; - cinematicsMenuInfo.cin_tier1.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_tier1.string = "Tier 1"; - cinematicsMenuInfo.cin_tier1.color = color_red; - cinematicsMenuInfo.cin_tier1.style = UI_CENTER; - if( !UI_CanShowTierVideo( 1 ) ) { - cinematicsMenuInfo.cin_tier1.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_tier2.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_tier2.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_tier2.generic.x = 320; - cinematicsMenuInfo.cin_tier2.generic.y = y; - cinematicsMenuInfo.cin_tier2.generic.id = ID_CIN_TIER2; - cinematicsMenuInfo.cin_tier2.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_tier2.string = "Tier 2"; - cinematicsMenuInfo.cin_tier2.color = color_red; - cinematicsMenuInfo.cin_tier2.style = UI_CENTER; - if( !UI_CanShowTierVideo( 2 ) ) { - cinematicsMenuInfo.cin_tier2.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_tier3.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_tier3.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_tier3.generic.x = 320; - cinematicsMenuInfo.cin_tier3.generic.y = y; - cinematicsMenuInfo.cin_tier3.generic.id = ID_CIN_TIER3; - cinematicsMenuInfo.cin_tier3.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_tier3.string = "Tier 3"; - cinematicsMenuInfo.cin_tier3.color = color_red; - cinematicsMenuInfo.cin_tier3.style = UI_CENTER; - if( !UI_CanShowTierVideo( 3 ) ) { - cinematicsMenuInfo.cin_tier3.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_tier4.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_tier4.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_tier4.generic.x = 320; - cinematicsMenuInfo.cin_tier4.generic.y = y; - cinematicsMenuInfo.cin_tier4.generic.id = ID_CIN_TIER4; - cinematicsMenuInfo.cin_tier4.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_tier4.string = "Tier 4"; - cinematicsMenuInfo.cin_tier4.color = color_red; - cinematicsMenuInfo.cin_tier4.style = UI_CENTER; - if( !UI_CanShowTierVideo( 4 ) ) { - cinematicsMenuInfo.cin_tier4.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_tier5.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_tier5.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_tier5.generic.x = 320; - cinematicsMenuInfo.cin_tier5.generic.y = y; - cinematicsMenuInfo.cin_tier5.generic.id = ID_CIN_TIER5; - cinematicsMenuInfo.cin_tier5.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_tier5.string = "Tier 5"; - cinematicsMenuInfo.cin_tier5.color = color_red; - cinematicsMenuInfo.cin_tier5.style = UI_CENTER; - if( !UI_CanShowTierVideo( 5 ) ) { - cinematicsMenuInfo.cin_tier5.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_tier6.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_tier6.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_tier6.generic.x = 320; - cinematicsMenuInfo.cin_tier6.generic.y = y; - cinematicsMenuInfo.cin_tier6.generic.id = ID_CIN_TIER6; - cinematicsMenuInfo.cin_tier6.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_tier6.string = "Tier 6"; - cinematicsMenuInfo.cin_tier6.color = color_red; - cinematicsMenuInfo.cin_tier6.style = UI_CENTER; - if( !UI_CanShowTierVideo( 6 ) ) { - cinematicsMenuInfo.cin_tier6.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_tier7.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_tier7.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_tier7.generic.x = 320; - cinematicsMenuInfo.cin_tier7.generic.y = y; - cinematicsMenuInfo.cin_tier7.generic.id = ID_CIN_TIER7; - cinematicsMenuInfo.cin_tier7.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_tier7.string = "Tier 7"; - cinematicsMenuInfo.cin_tier7.color = color_red; - cinematicsMenuInfo.cin_tier7.style = UI_CENTER; - if( !UI_CanShowTierVideo( 7 ) ) { - cinematicsMenuInfo.cin_tier7.generic.flags |= QMF_GRAYED; - } - - y += VERTICAL_SPACING; - cinematicsMenuInfo.cin_end.generic.type = MTYPE_PTEXT; - cinematicsMenuInfo.cin_end.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.cin_end.generic.x = 320; - cinematicsMenuInfo.cin_end.generic.y = y; - cinematicsMenuInfo.cin_end.generic.id = ID_CIN_END; - cinematicsMenuInfo.cin_end.generic.callback = UI_CinematicsMenu_Event; - cinematicsMenuInfo.cin_end.string = "END"; - cinematicsMenuInfo.cin_end.color = color_red; - cinematicsMenuInfo.cin_end.style = UI_CENTER; - if( !UI_CanShowTierVideo( 8 ) ) { - cinematicsMenuInfo.cin_end.generic.flags |= QMF_GRAYED; - } - - cinematicsMenuInfo.back.generic.type = MTYPE_BITMAP; - cinematicsMenuInfo.back.generic.name = ART_BACK0; - cinematicsMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - cinematicsMenuInfo.back.generic.id = ID_BACK; - cinematicsMenuInfo.back.generic.callback = UI_CinematicsMenu_BackEvent; - cinematicsMenuInfo.back.generic.x = 0; - cinematicsMenuInfo.back.generic.y = 480-64; - cinematicsMenuInfo.back.width = 128; - cinematicsMenuInfo.back.height = 64; - cinematicsMenuInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.banner ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.framel ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.framer ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_idlogo ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_intro ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier1 ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier2 ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier3 ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier4 ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier5 ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier6 ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier7 ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_end ); - Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.back ); -} - - -/* -================= -UI_CinematicsMenu_Cache -================= -*/ -void UI_CinematicsMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); -} - - -/* -=============== -UI_CinematicsMenu -=============== -*/ -void UI_CinematicsMenu( void ) { - UI_CinematicsMenu_Init(); - UI_PushMenu( &cinematicsMenuInfo.menu ); -} - - -/* -=============== -UI_CinematicsMenu_f -=============== -*/ -void UI_CinematicsMenu_f( void ) { - int n; - - n = atoi( UI_Argv( 1 ) ); - UI_CinematicsMenu(); - Menu_SetCursorToItem( &cinematicsMenuInfo.menu, cinematicsMenuInfo.menu.items[n + 3] ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" + +#define VERTICAL_SPACING 30 + +#define ID_BACK 10 +#define ID_CIN_IDLOGO 11 +#define ID_CIN_INTRO 12 +#define ID_CIN_TIER1 13 +#define ID_CIN_TIER2 14 +#define ID_CIN_TIER3 15 +#define ID_CIN_TIER4 16 +#define ID_CIN_TIER5 17 +#define ID_CIN_TIER6 18 +#define ID_CIN_TIER7 19 +#define ID_CIN_END 20 + + +typedef struct { + menuframework_s menu; + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + menutext_s cin_idlogo; + menutext_s cin_intro; + menutext_s cin_tier1; + menutext_s cin_tier2; + menutext_s cin_tier3; + menutext_s cin_tier4; + menutext_s cin_tier5; + menutext_s cin_tier6; + menutext_s cin_tier7; + menutext_s cin_end; + menubitmap_s back; +} cinematicsMenuInfo_t; + +static cinematicsMenuInfo_t cinematicsMenuInfo; + +static char *cinematics[] = { + "idlogo", + "intro", + "tier1", + "tier2", + "tier3", + "tier4", + "tier5", + "tier6", + "tier7", + "end" +}; + +/* +=============== +UI_CinematicsMenu_BackEvent +=============== +*/ +static void UI_CinematicsMenu_BackEvent( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + UI_PopMenu(); +} + + +/* +=============== +UI_CinematicsMenu_Event +=============== +*/ +static void UI_CinematicsMenu_Event( void *ptr, int event ) { + int n; + + if (event != QM_ACTIVATED) + return; + + n = ((menucommon_s*)ptr)->id - ID_CIN_IDLOGO; + trap_Cvar_Set( "nextmap", va( "ui_cinematics %i", n ) ); + if( uis.demoversion && ((menucommon_s*)ptr)->id == ID_CIN_END ) { + trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic demoEnd.RoQ 1\n" ); + } + else { + trap_Cmd_ExecuteText( EXEC_APPEND, va( "disconnect; cinematic %s.RoQ\n", cinematics[n] ) ); + } +} + + +/* +=============== +UI_CinematicsMenu_Init +=============== +*/ +static void UI_CinematicsMenu_Init( void ) { + int y; + + UI_CinematicsMenu_Cache(); + + memset( &cinematicsMenuInfo, 0, sizeof(cinematicsMenuInfo) ); + cinematicsMenuInfo.menu.fullscreen = qtrue; + + cinematicsMenuInfo.banner.generic.type = MTYPE_BTEXT; + cinematicsMenuInfo.banner.generic.x = 320; + cinematicsMenuInfo.banner.generic.y = 16; + cinematicsMenuInfo.banner.string = "CINEMATICS"; + cinematicsMenuInfo.banner.color = color_white; + cinematicsMenuInfo.banner.style = UI_CENTER; + + cinematicsMenuInfo.framel.generic.type = MTYPE_BITMAP; + cinematicsMenuInfo.framel.generic.name = ART_FRAMEL; + cinematicsMenuInfo.framel.generic.flags = QMF_INACTIVE; + cinematicsMenuInfo.framel.generic.x = 0; + cinematicsMenuInfo.framel.generic.y = 78; + cinematicsMenuInfo.framel.width = 256; + cinematicsMenuInfo.framel.height = 329; + + cinematicsMenuInfo.framer.generic.type = MTYPE_BITMAP; + cinematicsMenuInfo.framer.generic.name = ART_FRAMER; + cinematicsMenuInfo.framer.generic.flags = QMF_INACTIVE; + cinematicsMenuInfo.framer.generic.x = 376; + cinematicsMenuInfo.framer.generic.y = 76; + cinematicsMenuInfo.framer.width = 256; + cinematicsMenuInfo.framer.height = 334; + + y = 100; + cinematicsMenuInfo.cin_idlogo.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_idlogo.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_idlogo.generic.x = 320; + cinematicsMenuInfo.cin_idlogo.generic.y = y; + cinematicsMenuInfo.cin_idlogo.generic.id = ID_CIN_IDLOGO; + cinematicsMenuInfo.cin_idlogo.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_idlogo.string = "ID LOGO"; + cinematicsMenuInfo.cin_idlogo.color = color_red; + cinematicsMenuInfo.cin_idlogo.style = UI_CENTER; + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_intro.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_intro.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_intro.generic.x = 320; + cinematicsMenuInfo.cin_intro.generic.y = y; + cinematicsMenuInfo.cin_intro.generic.id = ID_CIN_INTRO; + cinematicsMenuInfo.cin_intro.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_intro.string = "INTRO"; + cinematicsMenuInfo.cin_intro.color = color_red; + cinematicsMenuInfo.cin_intro.style = UI_CENTER; + if( uis.demoversion ) { + cinematicsMenuInfo.cin_intro.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_tier1.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_tier1.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_tier1.generic.x = 320; + cinematicsMenuInfo.cin_tier1.generic.y = y; + cinematicsMenuInfo.cin_tier1.generic.id = ID_CIN_TIER1; + cinematicsMenuInfo.cin_tier1.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_tier1.string = "Tier 1"; + cinematicsMenuInfo.cin_tier1.color = color_red; + cinematicsMenuInfo.cin_tier1.style = UI_CENTER; + if( !UI_CanShowTierVideo( 1 ) ) { + cinematicsMenuInfo.cin_tier1.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_tier2.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_tier2.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_tier2.generic.x = 320; + cinematicsMenuInfo.cin_tier2.generic.y = y; + cinematicsMenuInfo.cin_tier2.generic.id = ID_CIN_TIER2; + cinematicsMenuInfo.cin_tier2.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_tier2.string = "Tier 2"; + cinematicsMenuInfo.cin_tier2.color = color_red; + cinematicsMenuInfo.cin_tier2.style = UI_CENTER; + if( !UI_CanShowTierVideo( 2 ) ) { + cinematicsMenuInfo.cin_tier2.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_tier3.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_tier3.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_tier3.generic.x = 320; + cinematicsMenuInfo.cin_tier3.generic.y = y; + cinematicsMenuInfo.cin_tier3.generic.id = ID_CIN_TIER3; + cinematicsMenuInfo.cin_tier3.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_tier3.string = "Tier 3"; + cinematicsMenuInfo.cin_tier3.color = color_red; + cinematicsMenuInfo.cin_tier3.style = UI_CENTER; + if( !UI_CanShowTierVideo( 3 ) ) { + cinematicsMenuInfo.cin_tier3.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_tier4.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_tier4.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_tier4.generic.x = 320; + cinematicsMenuInfo.cin_tier4.generic.y = y; + cinematicsMenuInfo.cin_tier4.generic.id = ID_CIN_TIER4; + cinematicsMenuInfo.cin_tier4.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_tier4.string = "Tier 4"; + cinematicsMenuInfo.cin_tier4.color = color_red; + cinematicsMenuInfo.cin_tier4.style = UI_CENTER; + if( !UI_CanShowTierVideo( 4 ) ) { + cinematicsMenuInfo.cin_tier4.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_tier5.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_tier5.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_tier5.generic.x = 320; + cinematicsMenuInfo.cin_tier5.generic.y = y; + cinematicsMenuInfo.cin_tier5.generic.id = ID_CIN_TIER5; + cinematicsMenuInfo.cin_tier5.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_tier5.string = "Tier 5"; + cinematicsMenuInfo.cin_tier5.color = color_red; + cinematicsMenuInfo.cin_tier5.style = UI_CENTER; + if( !UI_CanShowTierVideo( 5 ) ) { + cinematicsMenuInfo.cin_tier5.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_tier6.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_tier6.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_tier6.generic.x = 320; + cinematicsMenuInfo.cin_tier6.generic.y = y; + cinematicsMenuInfo.cin_tier6.generic.id = ID_CIN_TIER6; + cinematicsMenuInfo.cin_tier6.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_tier6.string = "Tier 6"; + cinematicsMenuInfo.cin_tier6.color = color_red; + cinematicsMenuInfo.cin_tier6.style = UI_CENTER; + if( !UI_CanShowTierVideo( 6 ) ) { + cinematicsMenuInfo.cin_tier6.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_tier7.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_tier7.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_tier7.generic.x = 320; + cinematicsMenuInfo.cin_tier7.generic.y = y; + cinematicsMenuInfo.cin_tier7.generic.id = ID_CIN_TIER7; + cinematicsMenuInfo.cin_tier7.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_tier7.string = "Tier 7"; + cinematicsMenuInfo.cin_tier7.color = color_red; + cinematicsMenuInfo.cin_tier7.style = UI_CENTER; + if( !UI_CanShowTierVideo( 7 ) ) { + cinematicsMenuInfo.cin_tier7.generic.flags |= QMF_GRAYED; + } + + y += VERTICAL_SPACING; + cinematicsMenuInfo.cin_end.generic.type = MTYPE_PTEXT; + cinematicsMenuInfo.cin_end.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.cin_end.generic.x = 320; + cinematicsMenuInfo.cin_end.generic.y = y; + cinematicsMenuInfo.cin_end.generic.id = ID_CIN_END; + cinematicsMenuInfo.cin_end.generic.callback = UI_CinematicsMenu_Event; + cinematicsMenuInfo.cin_end.string = "END"; + cinematicsMenuInfo.cin_end.color = color_red; + cinematicsMenuInfo.cin_end.style = UI_CENTER; + if( !UI_CanShowTierVideo( 8 ) ) { + cinematicsMenuInfo.cin_end.generic.flags |= QMF_GRAYED; + } + + cinematicsMenuInfo.back.generic.type = MTYPE_BITMAP; + cinematicsMenuInfo.back.generic.name = ART_BACK0; + cinematicsMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + cinematicsMenuInfo.back.generic.id = ID_BACK; + cinematicsMenuInfo.back.generic.callback = UI_CinematicsMenu_BackEvent; + cinematicsMenuInfo.back.generic.x = 0; + cinematicsMenuInfo.back.generic.y = 480-64; + cinematicsMenuInfo.back.width = 128; + cinematicsMenuInfo.back.height = 64; + cinematicsMenuInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.banner ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.framel ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.framer ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_idlogo ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_intro ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier1 ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier2 ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier3 ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier4 ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier5 ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier6 ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_tier7 ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.cin_end ); + Menu_AddItem( &cinematicsMenuInfo.menu, &cinematicsMenuInfo.back ); +} + + +/* +================= +UI_CinematicsMenu_Cache +================= +*/ +void UI_CinematicsMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); +} + + +/* +=============== +UI_CinematicsMenu +=============== +*/ +void UI_CinematicsMenu( void ) { + UI_CinematicsMenu_Init(); + UI_PushMenu( &cinematicsMenuInfo.menu ); +} + + +/* +=============== +UI_CinematicsMenu_f +=============== +*/ +void UI_CinematicsMenu_f( void ) { + int n; + + n = atoi( UI_Argv( 1 ) ); + UI_CinematicsMenu(); + Menu_SetCursorToItem( &cinematicsMenuInfo.menu, cinematicsMenuInfo.menu.items[n + 3] ); +} diff --git a/code/q3_ui/ui_confirm.c b/code/q3_ui/ui_confirm.c index c58071b..f8ed86f 100755 --- a/code/q3_ui/ui_confirm.c +++ b/code/q3_ui/ui_confirm.c @@ -1,293 +1,293 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -CONFIRMATION MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ART_CONFIRM_FRAME "menu/art/cut_frame" - -#define ID_CONFIRM_NO 10 -#define ID_CONFIRM_YES 11 - - -typedef struct { - menuframework_s menu; - - menutext_s no; - menutext_s yes; - - int slashX; - const char * question; - void (*draw)( void ); - void (*action)( qboolean result ); - - int style; - const char **lines; -} confirmMenu_t; - - -static confirmMenu_t s_confirm; - - -/* -================= -ConfirmMenu_Event -================= -*/ -static void ConfirmMenu_Event( void* ptr, int event ) { - qboolean result; - - if( event != QM_ACTIVATED ) { - return; - } - - UI_PopMenu(); - - if( ((menucommon_s*)ptr)->id == ID_CONFIRM_NO ) { - result = qfalse; - } - else { - result = qtrue; - } - - if( s_confirm.action ) { - s_confirm.action( result ); - } -} - - -/* -================= -ConfirmMenu_Key -================= -*/ -static sfxHandle_t ConfirmMenu_Key( int key ) { - switch ( key ) { - case K_KP_LEFTARROW: - case K_LEFTARROW: - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - key = K_TAB; - break; - - case 'n': - case 'N': - ConfirmMenu_Event( &s_confirm.no, QM_ACTIVATED ); - break; - - case 'y': - case 'Y': - ConfirmMenu_Event( &s_confirm.yes, QM_ACTIVATED ); - break; - } - - return Menu_DefaultKey( &s_confirm.menu, key ); -} - - -/* -================= -MessaheMenu_Draw -================= -*/ -static void MessageMenu_Draw( void ) { - int i,y; - - UI_DrawNamedPic( 142, 118, 359, 256, ART_CONFIRM_FRAME ); - - y = 188; - for(i=0; s_confirm.lines[i]; i++) - { - UI_DrawProportionalString( 320, y, s_confirm.lines[i], s_confirm.style, color_red ); - y += 18; - } - - Menu_Draw( &s_confirm.menu ); - - if( s_confirm.draw ) { - s_confirm.draw(); - } -} - -/* -================= -ConfirmMenu_Draw -================= -*/ -static void ConfirmMenu_Draw( void ) { - UI_DrawNamedPic( 142, 118, 359, 256, ART_CONFIRM_FRAME ); - UI_DrawProportionalString( 320, 204, s_confirm.question, s_confirm.style, color_red ); - UI_DrawProportionalString( s_confirm.slashX, 265, "/", UI_LEFT|UI_INVERSE, color_red ); - - Menu_Draw( &s_confirm.menu ); - - if( s_confirm.draw ) { - s_confirm.draw(); - } -} - - -/* -================= -ConfirmMenu_Cache -================= -*/ -void ConfirmMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_CONFIRM_FRAME ); -} - - -/* -================= -UI_ConfirmMenu_Stlye -================= -*/ -void UI_ConfirmMenu_Style( const char *question, int style, void (*draw)( void ), void (*action)( qboolean result ) ) { - uiClientState_t cstate; - int n1, n2, n3; - int l1, l2, l3; - - // zero set all our globals - memset( &s_confirm, 0, sizeof(s_confirm) ); - - ConfirmMenu_Cache(); - - n1 = UI_ProportionalStringWidth( "YES/NO" ); - n2 = UI_ProportionalStringWidth( "YES" ) + PROP_GAP_WIDTH; - n3 = UI_ProportionalStringWidth( "/" ) + PROP_GAP_WIDTH; - l1 = 320 - ( n1 / 2 ); - l2 = l1 + n2; - l3 = l2 + n3; - s_confirm.slashX = l2; - - s_confirm.question = question; - s_confirm.draw = draw; - s_confirm.action = action; - s_confirm.style = style; - - s_confirm.menu.draw = ConfirmMenu_Draw; - s_confirm.menu.key = ConfirmMenu_Key; - s_confirm.menu.wrapAround = qtrue; - - trap_GetClientState( &cstate ); - if ( cstate.connState >= CA_CONNECTED ) { - s_confirm.menu.fullscreen = qfalse; - } - else { - s_confirm.menu.fullscreen = qtrue; - } - - s_confirm.yes.generic.type = MTYPE_PTEXT; - s_confirm.yes.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_confirm.yes.generic.callback = ConfirmMenu_Event; - s_confirm.yes.generic.id = ID_CONFIRM_YES; - s_confirm.yes.generic.x = l1; - s_confirm.yes.generic.y = 264; - s_confirm.yes.string = "YES"; - s_confirm.yes.color = color_red; - s_confirm.yes.style = UI_LEFT; - - s_confirm.no.generic.type = MTYPE_PTEXT; - s_confirm.no.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_confirm.no.generic.callback = ConfirmMenu_Event; - s_confirm.no.generic.id = ID_CONFIRM_NO; - s_confirm.no.generic.x = l3; - s_confirm.no.generic.y = 264; - s_confirm.no.string = "NO"; - s_confirm.no.color = color_red; - s_confirm.no.style = UI_LEFT; - - Menu_AddItem( &s_confirm.menu, &s_confirm.yes ); - Menu_AddItem( &s_confirm.menu, &s_confirm.no ); - - UI_PushMenu( &s_confirm.menu ); - - Menu_SetCursorToItem( &s_confirm.menu, &s_confirm.no ); -} - -/* -================= -UI_ConfirmMenu -================= -*/ -void UI_ConfirmMenu( const char *question, void (*draw)( void ), void (*action)( qboolean result ) ) { - UI_ConfirmMenu_Style(question, UI_CENTER|UI_INVERSE, draw, action); -} - -/* -================= -UI_Message -hacked over from Confirm stuff -================= -*/ -void UI_Message( const char **lines ) { - uiClientState_t cstate; - int n1, l1; - - // zero set all our globals - memset( &s_confirm, 0, sizeof(s_confirm) ); - - ConfirmMenu_Cache(); - - n1 = UI_ProportionalStringWidth( "OK" ); - l1 = 320 - ( n1 / 2 ); - - s_confirm.lines = lines; - s_confirm.style = UI_CENTER|UI_INVERSE|UI_SMALLFONT; - - s_confirm.menu.draw = MessageMenu_Draw; - s_confirm.menu.key = ConfirmMenu_Key; - s_confirm.menu.wrapAround = qtrue; - - trap_GetClientState( &cstate ); - if ( cstate.connState >= CA_CONNECTED ) { - s_confirm.menu.fullscreen = qfalse; - } - else { - s_confirm.menu.fullscreen = qtrue; - } - - s_confirm.yes.generic.type = MTYPE_PTEXT; - s_confirm.yes.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_confirm.yes.generic.callback = ConfirmMenu_Event; - s_confirm.yes.generic.id = ID_CONFIRM_YES; - s_confirm.yes.generic.x = l1; - s_confirm.yes.generic.y = 280; - s_confirm.yes.string = "OK"; - s_confirm.yes.color = color_red; - s_confirm.yes.style = UI_LEFT; - - Menu_AddItem( &s_confirm.menu, &s_confirm.yes ); - - UI_PushMenu( &s_confirm.menu ); - - Menu_SetCursorToItem( &s_confirm.menu, &s_confirm.yes ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +CONFIRMATION MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ART_CONFIRM_FRAME "menu/art/cut_frame" + +#define ID_CONFIRM_NO 10 +#define ID_CONFIRM_YES 11 + + +typedef struct { + menuframework_s menu; + + menutext_s no; + menutext_s yes; + + int slashX; + const char * question; + void (*draw)( void ); + void (*action)( qboolean result ); + + int style; + const char **lines; +} confirmMenu_t; + + +static confirmMenu_t s_confirm; + + +/* +================= +ConfirmMenu_Event +================= +*/ +static void ConfirmMenu_Event( void* ptr, int event ) { + qboolean result; + + if( event != QM_ACTIVATED ) { + return; + } + + UI_PopMenu(); + + if( ((menucommon_s*)ptr)->id == ID_CONFIRM_NO ) { + result = qfalse; + } + else { + result = qtrue; + } + + if( s_confirm.action ) { + s_confirm.action( result ); + } +} + + +/* +================= +ConfirmMenu_Key +================= +*/ +static sfxHandle_t ConfirmMenu_Key( int key ) { + switch ( key ) { + case K_KP_LEFTARROW: + case K_LEFTARROW: + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + key = K_TAB; + break; + + case 'n': + case 'N': + ConfirmMenu_Event( &s_confirm.no, QM_ACTIVATED ); + break; + + case 'y': + case 'Y': + ConfirmMenu_Event( &s_confirm.yes, QM_ACTIVATED ); + break; + } + + return Menu_DefaultKey( &s_confirm.menu, key ); +} + + +/* +================= +MessaheMenu_Draw +================= +*/ +static void MessageMenu_Draw( void ) { + int i,y; + + UI_DrawNamedPic( 142, 118, 359, 256, ART_CONFIRM_FRAME ); + + y = 188; + for(i=0; s_confirm.lines[i]; i++) + { + UI_DrawProportionalString( 320, y, s_confirm.lines[i], s_confirm.style, color_red ); + y += 18; + } + + Menu_Draw( &s_confirm.menu ); + + if( s_confirm.draw ) { + s_confirm.draw(); + } +} + +/* +================= +ConfirmMenu_Draw +================= +*/ +static void ConfirmMenu_Draw( void ) { + UI_DrawNamedPic( 142, 118, 359, 256, ART_CONFIRM_FRAME ); + UI_DrawProportionalString( 320, 204, s_confirm.question, s_confirm.style, color_red ); + UI_DrawProportionalString( s_confirm.slashX, 265, "/", UI_LEFT|UI_INVERSE, color_red ); + + Menu_Draw( &s_confirm.menu ); + + if( s_confirm.draw ) { + s_confirm.draw(); + } +} + + +/* +================= +ConfirmMenu_Cache +================= +*/ +void ConfirmMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_CONFIRM_FRAME ); +} + + +/* +================= +UI_ConfirmMenu_Stlye +================= +*/ +void UI_ConfirmMenu_Style( const char *question, int style, void (*draw)( void ), void (*action)( qboolean result ) ) { + uiClientState_t cstate; + int n1, n2, n3; + int l1, l2, l3; + + // zero set all our globals + memset( &s_confirm, 0, sizeof(s_confirm) ); + + ConfirmMenu_Cache(); + + n1 = UI_ProportionalStringWidth( "YES/NO" ); + n2 = UI_ProportionalStringWidth( "YES" ) + PROP_GAP_WIDTH; + n3 = UI_ProportionalStringWidth( "/" ) + PROP_GAP_WIDTH; + l1 = 320 - ( n1 / 2 ); + l2 = l1 + n2; + l3 = l2 + n3; + s_confirm.slashX = l2; + + s_confirm.question = question; + s_confirm.draw = draw; + s_confirm.action = action; + s_confirm.style = style; + + s_confirm.menu.draw = ConfirmMenu_Draw; + s_confirm.menu.key = ConfirmMenu_Key; + s_confirm.menu.wrapAround = qtrue; + + trap_GetClientState( &cstate ); + if ( cstate.connState >= CA_CONNECTED ) { + s_confirm.menu.fullscreen = qfalse; + } + else { + s_confirm.menu.fullscreen = qtrue; + } + + s_confirm.yes.generic.type = MTYPE_PTEXT; + s_confirm.yes.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_confirm.yes.generic.callback = ConfirmMenu_Event; + s_confirm.yes.generic.id = ID_CONFIRM_YES; + s_confirm.yes.generic.x = l1; + s_confirm.yes.generic.y = 264; + s_confirm.yes.string = "YES"; + s_confirm.yes.color = color_red; + s_confirm.yes.style = UI_LEFT; + + s_confirm.no.generic.type = MTYPE_PTEXT; + s_confirm.no.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_confirm.no.generic.callback = ConfirmMenu_Event; + s_confirm.no.generic.id = ID_CONFIRM_NO; + s_confirm.no.generic.x = l3; + s_confirm.no.generic.y = 264; + s_confirm.no.string = "NO"; + s_confirm.no.color = color_red; + s_confirm.no.style = UI_LEFT; + + Menu_AddItem( &s_confirm.menu, &s_confirm.yes ); + Menu_AddItem( &s_confirm.menu, &s_confirm.no ); + + UI_PushMenu( &s_confirm.menu ); + + Menu_SetCursorToItem( &s_confirm.menu, &s_confirm.no ); +} + +/* +================= +UI_ConfirmMenu +================= +*/ +void UI_ConfirmMenu( const char *question, void (*draw)( void ), void (*action)( qboolean result ) ) { + UI_ConfirmMenu_Style(question, UI_CENTER|UI_INVERSE, draw, action); +} + +/* +================= +UI_Message +hacked over from Confirm stuff +================= +*/ +void UI_Message( const char **lines ) { + uiClientState_t cstate; + int n1, l1; + + // zero set all our globals + memset( &s_confirm, 0, sizeof(s_confirm) ); + + ConfirmMenu_Cache(); + + n1 = UI_ProportionalStringWidth( "OK" ); + l1 = 320 - ( n1 / 2 ); + + s_confirm.lines = lines; + s_confirm.style = UI_CENTER|UI_INVERSE|UI_SMALLFONT; + + s_confirm.menu.draw = MessageMenu_Draw; + s_confirm.menu.key = ConfirmMenu_Key; + s_confirm.menu.wrapAround = qtrue; + + trap_GetClientState( &cstate ); + if ( cstate.connState >= CA_CONNECTED ) { + s_confirm.menu.fullscreen = qfalse; + } + else { + s_confirm.menu.fullscreen = qtrue; + } + + s_confirm.yes.generic.type = MTYPE_PTEXT; + s_confirm.yes.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_confirm.yes.generic.callback = ConfirmMenu_Event; + s_confirm.yes.generic.id = ID_CONFIRM_YES; + s_confirm.yes.generic.x = l1; + s_confirm.yes.generic.y = 280; + s_confirm.yes.string = "OK"; + s_confirm.yes.color = color_red; + s_confirm.yes.style = UI_LEFT; + + Menu_AddItem( &s_confirm.menu, &s_confirm.yes ); + + UI_PushMenu( &s_confirm.menu ); + + Menu_SetCursorToItem( &s_confirm.menu, &s_confirm.yes ); +} diff --git a/code/q3_ui/ui_connect.c b/code/q3_ui/ui_connect.c index a348db2..5226407 100755 --- a/code/q3_ui/ui_connect.c +++ b/code/q3_ui/ui_connect.c @@ -1,282 +1,282 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -/* -=============================================================================== - -CONNECTION SCREEN - -=============================================================================== -*/ - -qboolean passwordNeeded = qtrue; -menufield_s passwordField; - -static connstate_t lastConnState; -static char lastLoadingText[MAX_INFO_VALUE]; - -static void UI_ReadableSize ( char *buf, int bufsize, int value ) -{ - if (value > 1024*1024*1024 ) { // gigs - Com_sprintf( buf, bufsize, "%d", value / (1024*1024*1024) ); - Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d GB", - (value % (1024*1024*1024))*100 / (1024*1024*1024) ); - } else if (value > 1024*1024 ) { // megs - Com_sprintf( buf, bufsize, "%d", value / (1024*1024) ); - Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d MB", - (value % (1024*1024))*100 / (1024*1024) ); - } else if (value > 1024 ) { // kilos - Com_sprintf( buf, bufsize, "%d KB", value / 1024 ); - } else { // bytes - Com_sprintf( buf, bufsize, "%d bytes", value ); - } -} - -// Assumes time is in msec -static void UI_PrintTime ( char *buf, int bufsize, int time ) { - time /= 1000; // change to seconds - - if (time > 3600) { // in the hours range - Com_sprintf( buf, bufsize, "%d hr %d min", time / 3600, (time % 3600) / 60 ); - } else if (time > 60) { // mins - Com_sprintf( buf, bufsize, "%d min %d sec", time / 60, time % 60 ); - } else { // secs - Com_sprintf( buf, bufsize, "%d sec", time ); - } -} - -static void UI_DisplayDownloadInfo( const char *downloadName ) { - static char dlText[] = "Downloading:"; - static char etaText[] = "Estimated time left:"; - static char xferText[] = "Transfer rate:"; - - int downloadSize, downloadCount, downloadTime; - char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64]; - int xferRate; - int width, leftWidth; - int style = UI_LEFT|UI_SMALLFONT|UI_DROPSHADOW; - const char *s; - - downloadSize = trap_Cvar_VariableValue( "cl_downloadSize" ); - downloadCount = trap_Cvar_VariableValue( "cl_downloadCount" ); - downloadTime = trap_Cvar_VariableValue( "cl_downloadTime" ); - -#if 0 // bk010104 - fprintf( stderr, "\n\n-----------------------------------------------\n"); - fprintf( stderr, "DB: downloadSize: %16d\n", downloadSize ); - fprintf( stderr, "DB: downloadCount: %16d\n", downloadCount ); - fprintf( stderr, "DB: downloadTime: %16d\n", downloadTime ); - fprintf( stderr, "DB: UI realtime: %16d\n", uis.realtime ); // bk - fprintf( stderr, "DB: UI frametime: %16d\n", uis.frametime ); // bk -#endif - - leftWidth = width = UI_ProportionalStringWidth( dlText ) * UI_ProportionalSizeScale( style ); - width = UI_ProportionalStringWidth( etaText ) * UI_ProportionalSizeScale( style ); - if (width > leftWidth) leftWidth = width; - width = UI_ProportionalStringWidth( xferText ) * UI_ProportionalSizeScale( style ); - if (width > leftWidth) leftWidth = width; - leftWidth += 16; - - UI_DrawProportionalString( 8, 128, dlText, style, color_white ); - UI_DrawProportionalString( 8, 160, etaText, style, color_white ); - UI_DrawProportionalString( 8, 224, xferText, style, color_white ); - - if (downloadSize > 0) { - s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize ); - } else { - s = downloadName; - } - - UI_DrawProportionalString( leftWidth, 128, s, style, color_white ); - - UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount ); - UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize ); - - if (downloadCount < 4096 || !downloadTime) { - UI_DrawProportionalString( leftWidth, 160, "estimating", style, color_white ); - UI_DrawProportionalString( leftWidth, 192, - va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); - } else { - // bk010108 - //float elapsedTime = (float)(uis.realtime - downloadTime); // current - start (msecs) - //elapsedTime = elapsedTime * 0.001f; // in seconds - //if ( elapsedTime <= 0.0f ) elapsedTime == 0.0f; - if ( (uis.realtime - downloadTime) / 1000) { - xferRate = downloadCount / ((uis.realtime - downloadTime) / 1000); - //xferRate = (int)( ((float)downloadCount) / elapsedTime); - } else { - xferRate = 0; - } - - //fprintf( stderr, "DB: elapsedTime: %16.8f\n", elapsedTime ); // bk - //fprintf( stderr, "DB: xferRate: %16d\n", xferRate ); // bk - - UI_ReadableSize( xferRateBuf, sizeof xferRateBuf, xferRate ); - - // Extrapolate estimated completion time - if (downloadSize && xferRate) { - int n = downloadSize / xferRate; // estimated time for entire d/l in secs - - // We do it in K (/1024) because we'd overflow around 4MB - n = (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000; - - UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf, n ); // bk010104 - //(n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000); - - UI_DrawProportionalString( leftWidth, 160, - dlTimeBuf, style, color_white ); - UI_DrawProportionalString( leftWidth, 192, - va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); - } else { - UI_DrawProportionalString( leftWidth, 160, - "estimating", style, color_white ); - if (downloadSize) { - UI_DrawProportionalString( leftWidth, 192, - va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); - } else { - UI_DrawProportionalString( leftWidth, 192, - va("(%s copied)", dlSizeBuf), style, color_white ); - } - } - - if (xferRate) { - UI_DrawProportionalString( leftWidth, 224, - va("%s/Sec", xferRateBuf), style, color_white ); - } - } -} - -/* -======================== -UI_DrawConnectScreen - -This will also be overlaid on the cgame info screen during loading -to prevent it from blinking away too rapidly on local or lan games. -======================== -*/ -void UI_DrawConnectScreen( qboolean overlay ) { - char *s; - uiClientState_t cstate; - char info[MAX_INFO_VALUE]; - - Menu_Cache(); - - if ( !overlay ) { - // draw the dialog background - UI_SetColor( color_white ); - UI_DrawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.menuBackShader ); - } - - // see what information we should display - trap_GetClientState( &cstate ); - - info[0] = '\0'; - if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) { - UI_DrawProportionalString( 320, 16, va( "Loading %s", Info_ValueForKey( info, "mapname" ) ), UI_BIGFONT|UI_CENTER|UI_DROPSHADOW, color_white ); - } - - UI_DrawProportionalString( 320, 64, va("Connecting to %s", cstate.servername), UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); - //UI_DrawProportionalString( 320, 96, "Press Esc to abort", UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); - - // display global MOTD at bottom - UI_DrawProportionalString( SCREEN_WIDTH/2, SCREEN_HEIGHT-32, - Info_ValueForKey( cstate.updateInfoString, "motd" ), UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); - - // print any server info (server full, bad version, etc) - if ( cstate.connState < CA_CONNECTED ) { - UI_DrawProportionalString_AutoWrapped( 320, 192, 630, 20, cstate.messageString, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); - } - -#if 0 - // display password field - if ( passwordNeeded ) { - s_ingame_menu.x = SCREEN_WIDTH * 0.50 - 128; - s_ingame_menu.nitems = 0; - s_ingame_menu.wrapAround = qtrue; - - passwordField.generic.type = MTYPE_FIELD; - passwordField.generic.name = "Password:"; - passwordField.generic.callback = 0; - passwordField.generic.x = 10; - passwordField.generic.y = 180; - Field_Clear( &passwordField.field ); - passwordField.width = 256; - passwordField.field.widthInChars = 16; - Q_strncpyz( passwordField.field.buffer, Cvar_VariableString("password"), - sizeof(passwordField.field.buffer) ); - - Menu_AddItem( &s_ingame_menu, ( void * ) &s_customize_player_action ); - - MField_Draw( &passwordField ); - } -#endif - - if ( lastConnState > cstate.connState ) { - lastLoadingText[0] = '\0'; - } - lastConnState = cstate.connState; - - switch ( cstate.connState ) { - case CA_CONNECTING: - s = va("Awaiting challenge...%i", cstate.connectPacketCount); - break; - case CA_CHALLENGING: - s = va("Awaiting connection...%i", cstate.connectPacketCount); - break; - case CA_CONNECTED: { - char downloadName[MAX_INFO_VALUE]; - - trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) ); - if (*downloadName) { - UI_DisplayDownloadInfo( downloadName ); - return; - } - } - s = "Awaiting gamestate..."; - break; - case CA_LOADING: - return; - case CA_PRIMED: - return; - default: - return; - } - - UI_DrawProportionalString( 320, 128, s, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, color_white ); - - // password required / connection rejected information goes here -} - - -/* -=================== -UI_KeyConnect -=================== -*/ -void UI_KeyConnect( int key ) { - if ( key == K_ESCAPE ) { - trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); - return; - } -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +/* +=============================================================================== + +CONNECTION SCREEN + +=============================================================================== +*/ + +qboolean passwordNeeded = qtrue; +menufield_s passwordField; + +static connstate_t lastConnState; +static char lastLoadingText[MAX_INFO_VALUE]; + +static void UI_ReadableSize ( char *buf, int bufsize, int value ) +{ + if (value > 1024*1024*1024 ) { // gigs + Com_sprintf( buf, bufsize, "%d", value / (1024*1024*1024) ); + Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d GB", + (value % (1024*1024*1024))*100 / (1024*1024*1024) ); + } else if (value > 1024*1024 ) { // megs + Com_sprintf( buf, bufsize, "%d", value / (1024*1024) ); + Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d MB", + (value % (1024*1024))*100 / (1024*1024) ); + } else if (value > 1024 ) { // kilos + Com_sprintf( buf, bufsize, "%d KB", value / 1024 ); + } else { // bytes + Com_sprintf( buf, bufsize, "%d bytes", value ); + } +} + +// Assumes time is in msec +static void UI_PrintTime ( char *buf, int bufsize, int time ) { + time /= 1000; // change to seconds + + if (time > 3600) { // in the hours range + Com_sprintf( buf, bufsize, "%d hr %d min", time / 3600, (time % 3600) / 60 ); + } else if (time > 60) { // mins + Com_sprintf( buf, bufsize, "%d min %d sec", time / 60, time % 60 ); + } else { // secs + Com_sprintf( buf, bufsize, "%d sec", time ); + } +} + +static void UI_DisplayDownloadInfo( const char *downloadName ) { + static char dlText[] = "Downloading:"; + static char etaText[] = "Estimated time left:"; + static char xferText[] = "Transfer rate:"; + + int downloadSize, downloadCount, downloadTime; + char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64]; + int xferRate; + int width, leftWidth; + int style = UI_LEFT|UI_SMALLFONT|UI_DROPSHADOW; + const char *s; + + downloadSize = trap_Cvar_VariableValue( "cl_downloadSize" ); + downloadCount = trap_Cvar_VariableValue( "cl_downloadCount" ); + downloadTime = trap_Cvar_VariableValue( "cl_downloadTime" ); + +#if 0 // bk010104 + fprintf( stderr, "\n\n-----------------------------------------------\n"); + fprintf( stderr, "DB: downloadSize: %16d\n", downloadSize ); + fprintf( stderr, "DB: downloadCount: %16d\n", downloadCount ); + fprintf( stderr, "DB: downloadTime: %16d\n", downloadTime ); + fprintf( stderr, "DB: UI realtime: %16d\n", uis.realtime ); // bk + fprintf( stderr, "DB: UI frametime: %16d\n", uis.frametime ); // bk +#endif + + leftWidth = width = UI_ProportionalStringWidth( dlText ) * UI_ProportionalSizeScale( style ); + width = UI_ProportionalStringWidth( etaText ) * UI_ProportionalSizeScale( style ); + if (width > leftWidth) leftWidth = width; + width = UI_ProportionalStringWidth( xferText ) * UI_ProportionalSizeScale( style ); + if (width > leftWidth) leftWidth = width; + leftWidth += 16; + + UI_DrawProportionalString( 8, 128, dlText, style, color_white ); + UI_DrawProportionalString( 8, 160, etaText, style, color_white ); + UI_DrawProportionalString( 8, 224, xferText, style, color_white ); + + if (downloadSize > 0) { + s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize ); + } else { + s = downloadName; + } + + UI_DrawProportionalString( leftWidth, 128, s, style, color_white ); + + UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount ); + UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize ); + + if (downloadCount < 4096 || !downloadTime) { + UI_DrawProportionalString( leftWidth, 160, "estimating", style, color_white ); + UI_DrawProportionalString( leftWidth, 192, + va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); + } else { + // bk010108 + //float elapsedTime = (float)(uis.realtime - downloadTime); // current - start (msecs) + //elapsedTime = elapsedTime * 0.001f; // in seconds + //if ( elapsedTime <= 0.0f ) elapsedTime == 0.0f; + if ( (uis.realtime - downloadTime) / 1000) { + xferRate = downloadCount / ((uis.realtime - downloadTime) / 1000); + //xferRate = (int)( ((float)downloadCount) / elapsedTime); + } else { + xferRate = 0; + } + + //fprintf( stderr, "DB: elapsedTime: %16.8f\n", elapsedTime ); // bk + //fprintf( stderr, "DB: xferRate: %16d\n", xferRate ); // bk + + UI_ReadableSize( xferRateBuf, sizeof xferRateBuf, xferRate ); + + // Extrapolate estimated completion time + if (downloadSize && xferRate) { + int n = downloadSize / xferRate; // estimated time for entire d/l in secs + + // We do it in K (/1024) because we'd overflow around 4MB + n = (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000; + + UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf, n ); // bk010104 + //(n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000); + + UI_DrawProportionalString( leftWidth, 160, + dlTimeBuf, style, color_white ); + UI_DrawProportionalString( leftWidth, 192, + va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); + } else { + UI_DrawProportionalString( leftWidth, 160, + "estimating", style, color_white ); + if (downloadSize) { + UI_DrawProportionalString( leftWidth, 192, + va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); + } else { + UI_DrawProportionalString( leftWidth, 192, + va("(%s copied)", dlSizeBuf), style, color_white ); + } + } + + if (xferRate) { + UI_DrawProportionalString( leftWidth, 224, + va("%s/Sec", xferRateBuf), style, color_white ); + } + } +} + +/* +======================== +UI_DrawConnectScreen + +This will also be overlaid on the cgame info screen during loading +to prevent it from blinking away too rapidly on local or lan games. +======================== +*/ +void UI_DrawConnectScreen( qboolean overlay ) { + char *s; + uiClientState_t cstate; + char info[MAX_INFO_VALUE]; + + Menu_Cache(); + + if ( !overlay ) { + // draw the dialog background + UI_SetColor( color_white ); + UI_DrawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.menuBackShader ); + } + + // see what information we should display + trap_GetClientState( &cstate ); + + info[0] = '\0'; + if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) { + UI_DrawProportionalString( 320, 16, va( "Loading %s", Info_ValueForKey( info, "mapname" ) ), UI_BIGFONT|UI_CENTER|UI_DROPSHADOW, color_white ); + } + + UI_DrawProportionalString( 320, 64, va("Connecting to %s", cstate.servername), UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); + //UI_DrawProportionalString( 320, 96, "Press Esc to abort", UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); + + // display global MOTD at bottom + UI_DrawProportionalString( SCREEN_WIDTH/2, SCREEN_HEIGHT-32, + Info_ValueForKey( cstate.updateInfoString, "motd" ), UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); + + // print any server info (server full, bad version, etc) + if ( cstate.connState < CA_CONNECTED ) { + UI_DrawProportionalString_AutoWrapped( 320, 192, 630, 20, cstate.messageString, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); + } + +#if 0 + // display password field + if ( passwordNeeded ) { + s_ingame_menu.x = SCREEN_WIDTH * 0.50 - 128; + s_ingame_menu.nitems = 0; + s_ingame_menu.wrapAround = qtrue; + + passwordField.generic.type = MTYPE_FIELD; + passwordField.generic.name = "Password:"; + passwordField.generic.callback = 0; + passwordField.generic.x = 10; + passwordField.generic.y = 180; + Field_Clear( &passwordField.field ); + passwordField.width = 256; + passwordField.field.widthInChars = 16; + Q_strncpyz( passwordField.field.buffer, Cvar_VariableString("password"), + sizeof(passwordField.field.buffer) ); + + Menu_AddItem( &s_ingame_menu, ( void * ) &s_customize_player_action ); + + MField_Draw( &passwordField ); + } +#endif + + if ( lastConnState > cstate.connState ) { + lastLoadingText[0] = '\0'; + } + lastConnState = cstate.connState; + + switch ( cstate.connState ) { + case CA_CONNECTING: + s = va("Awaiting challenge...%i", cstate.connectPacketCount); + break; + case CA_CHALLENGING: + s = va("Awaiting connection...%i", cstate.connectPacketCount); + break; + case CA_CONNECTED: { + char downloadName[MAX_INFO_VALUE]; + + trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) ); + if (*downloadName) { + UI_DisplayDownloadInfo( downloadName ); + return; + } + } + s = "Awaiting gamestate..."; + break; + case CA_LOADING: + return; + case CA_PRIMED: + return; + default: + return; + } + + UI_DrawProportionalString( 320, 128, s, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, color_white ); + + // password required / connection rejected information goes here +} + + +/* +=================== +UI_KeyConnect +=================== +*/ +void UI_KeyConnect( int key ) { + if ( key == K_ESCAPE ) { + trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); + return; + } +} diff --git a/code/q3_ui/ui_controls2.c b/code/q3_ui/ui_controls2.c index f6dc59f..dd21087 100755 --- a/code/q3_ui/ui_controls2.c +++ b/code/q3_ui/ui_controls2.c @@ -1,1667 +1,1667 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -CONTROLS MENU - -======================================================================= -*/ - - -#include "ui_local.h" - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" - - -typedef struct { - char *command; - char *label; - int id; - int anim; - int defaultbind1; - int defaultbind2; - int bind1; - int bind2; -} bind_t; - -typedef struct -{ - char* name; - float defaultvalue; - float value; -} configcvar_t; - -#define SAVE_NOOP 0 -#define SAVE_YES 1 -#define SAVE_NO 2 -#define SAVE_CANCEL 3 - -// control sections -#define C_MOVEMENT 0 -#define C_LOOKING 1 -#define C_WEAPONS 2 -#define C_MISC 3 -#define C_MAX 4 - -#define ID_MOVEMENT 100 -#define ID_LOOKING 101 -#define ID_WEAPONS 102 -#define ID_MISC 103 -#define ID_DEFAULTS 104 -#define ID_BACK 105 -#define ID_SAVEANDEXIT 106 -#define ID_EXIT 107 - -// bindable actions -#define ID_SHOWSCORES 0 -#define ID_USEITEM 1 -#define ID_SPEED 2 -#define ID_FORWARD 3 -#define ID_BACKPEDAL 4 -#define ID_MOVELEFT 5 -#define ID_MOVERIGHT 6 -#define ID_MOVEUP 7 -#define ID_MOVEDOWN 8 -#define ID_LEFT 9 -#define ID_RIGHT 10 -#define ID_STRAFE 11 -#define ID_LOOKUP 12 -#define ID_LOOKDOWN 13 -#define ID_MOUSELOOK 14 -#define ID_CENTERVIEW 15 -#define ID_ZOOMVIEW 16 -#define ID_WEAPON1 17 -#define ID_WEAPON2 18 -#define ID_WEAPON3 19 -#define ID_WEAPON4 20 -#define ID_WEAPON5 21 -#define ID_WEAPON6 22 -#define ID_WEAPON7 23 -#define ID_WEAPON8 24 -#define ID_WEAPON9 25 -#define ID_ATTACK 26 -#define ID_WEAPPREV 27 -#define ID_WEAPNEXT 28 -#define ID_GESTURE 29 -#define ID_CHAT 30 -#define ID_CHAT2 31 -#define ID_CHAT3 32 -#define ID_CHAT4 33 - -// all others -#define ID_FREELOOK 34 -#define ID_INVERTMOUSE 35 -#define ID_ALWAYSRUN 36 -#define ID_AUTOSWITCH 37 -#define ID_MOUSESPEED 38 -#define ID_JOYENABLE 39 -#define ID_JOYTHRESHOLD 40 -#define ID_SMOOTHMOUSE 41 - -#define ANIM_IDLE 0 -#define ANIM_RUN 1 -#define ANIM_WALK 2 -#define ANIM_BACK 3 -#define ANIM_JUMP 4 -#define ANIM_CROUCH 5 -#define ANIM_STEPLEFT 6 -#define ANIM_STEPRIGHT 7 -#define ANIM_TURNLEFT 8 -#define ANIM_TURNRIGHT 9 -#define ANIM_LOOKUP 10 -#define ANIM_LOOKDOWN 11 -#define ANIM_WEAPON1 12 -#define ANIM_WEAPON2 13 -#define ANIM_WEAPON3 14 -#define ANIM_WEAPON4 15 -#define ANIM_WEAPON5 16 -#define ANIM_WEAPON6 17 -#define ANIM_WEAPON7 18 -#define ANIM_WEAPON8 19 -#define ANIM_WEAPON9 20 -#define ANIM_WEAPON10 21 -#define ANIM_ATTACK 22 -#define ANIM_GESTURE 23 -#define ANIM_DIE 24 -#define ANIM_CHAT 25 - -typedef struct -{ - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - menubitmap_s player; - - menutext_s movement; - menutext_s looking; - menutext_s weapons; - menutext_s misc; - - menuaction_s walkforward; - menuaction_s backpedal; - menuaction_s stepleft; - menuaction_s stepright; - menuaction_s moveup; - menuaction_s movedown; - menuaction_s turnleft; - menuaction_s turnright; - menuaction_s sidestep; - menuaction_s run; - menuaction_s machinegun; - menuaction_s chainsaw; - menuaction_s shotgun; - menuaction_s grenadelauncher; - menuaction_s rocketlauncher; - menuaction_s lightning; - menuaction_s railgun; - menuaction_s plasma; - menuaction_s bfg; - menuaction_s attack; - menuaction_s prevweapon; - menuaction_s nextweapon; - menuaction_s lookup; - menuaction_s lookdown; - menuaction_s mouselook; - menuradiobutton_s freelook; - menuaction_s centerview; - menuaction_s zoomview; - menuaction_s gesture; - menuradiobutton_s invertmouse; - menuslider_s sensitivity; - menuradiobutton_s smoothmouse; - menuradiobutton_s alwaysrun; - menuaction_s showscores; - menuradiobutton_s autoswitch; - menuaction_s useitem; - playerInfo_t playerinfo; - qboolean changesmade; - menuaction_s chat; - menuaction_s chat2; - menuaction_s chat3; - menuaction_s chat4; - menuradiobutton_s joyenable; - menuslider_s joythreshold; - int section; - qboolean waitingforkey; - char playerModel[64]; - vec3_t playerViewangles; - vec3_t playerMoveangles; - int playerLegs; - int playerTorso; - int playerWeapon; - qboolean playerChat; - - menubitmap_s back; - menutext_s name; -} controls_t; - -static controls_t s_controls; - -static vec4_t controls_binding_color = {1.00f, 0.43f, 0.00f, 1.00f}; // bk: Win32 C4305 - -static bind_t g_bindings[] = -{ - {"+scores", "show scores", ID_SHOWSCORES, ANIM_IDLE, K_TAB, -1, -1, -1}, - {"+button2", "use item", ID_USEITEM, ANIM_IDLE, K_ENTER, -1, -1, -1}, - {"+speed", "run / walk", ID_SPEED, ANIM_RUN, K_SHIFT, -1, -1, -1}, - {"+forward", "walk forward", ID_FORWARD, ANIM_WALK, K_UPARROW, -1, -1, -1}, - {"+back", "backpedal", ID_BACKPEDAL, ANIM_BACK, K_DOWNARROW, -1, -1, -1}, - {"+moveleft", "step left", ID_MOVELEFT, ANIM_STEPLEFT, ',', -1, -1, -1}, - {"+moveright", "step right", ID_MOVERIGHT, ANIM_STEPRIGHT, '.', -1, -1, -1}, - {"+moveup", "up / jump", ID_MOVEUP, ANIM_JUMP, K_SPACE, -1, -1, -1}, - {"+movedown", "down / crouch", ID_MOVEDOWN, ANIM_CROUCH, 'c', -1, -1, -1}, - {"+left", "turn left", ID_LEFT, ANIM_TURNLEFT, K_LEFTARROW, -1, -1, -1}, - {"+right", "turn right", ID_RIGHT, ANIM_TURNRIGHT, K_RIGHTARROW, -1, -1, -1}, - {"+strafe", "sidestep / turn", ID_STRAFE, ANIM_IDLE, K_ALT, -1, -1, -1}, - {"+lookup", "look up", ID_LOOKUP, ANIM_LOOKUP, K_PGDN, -1, -1, -1}, - {"+lookdown", "look down", ID_LOOKDOWN, ANIM_LOOKDOWN, K_DEL, -1, -1, -1}, - {"+mlook", "mouse look", ID_MOUSELOOK, ANIM_IDLE, '/', -1, -1, -1}, - {"centerview", "center view", ID_CENTERVIEW, ANIM_IDLE, K_END, -1, -1, -1}, - {"+zoom", "zoom view", ID_ZOOMVIEW, ANIM_IDLE, -1, -1, -1, -1}, - {"weapon 1", "gauntlet", ID_WEAPON1, ANIM_WEAPON1, '1', -1, -1, -1}, - {"weapon 2", "machinegun", ID_WEAPON2, ANIM_WEAPON2, '2', -1, -1, -1}, - {"weapon 3", "shotgun", ID_WEAPON3, ANIM_WEAPON3, '3', -1, -1, -1}, - {"weapon 4", "grenade launcher", ID_WEAPON4, ANIM_WEAPON4, '4', -1, -1, -1}, - {"weapon 5", "rocket launcher", ID_WEAPON5, ANIM_WEAPON5, '5', -1, -1, -1}, - {"weapon 6", "lightning", ID_WEAPON6, ANIM_WEAPON6, '6', -1, -1, -1}, - {"weapon 7", "railgun", ID_WEAPON7, ANIM_WEAPON7, '7', -1, -1, -1}, - {"weapon 8", "plasma gun", ID_WEAPON8, ANIM_WEAPON8, '8', -1, -1, -1}, - {"weapon 9", "BFG", ID_WEAPON9, ANIM_WEAPON9, '9', -1, -1, -1}, - {"+attack", "attack", ID_ATTACK, ANIM_ATTACK, K_CTRL, -1, -1, -1}, - {"weapprev", "prev weapon", ID_WEAPPREV, ANIM_IDLE, '[', -1, -1, -1}, - {"weapnext", "next weapon", ID_WEAPNEXT, ANIM_IDLE, ']', -1, -1, -1}, - {"+button3", "gesture", ID_GESTURE, ANIM_GESTURE, K_MOUSE3, -1, -1, -1}, - {"messagemode", "chat", ID_CHAT, ANIM_CHAT, 't', -1, -1, -1}, - {"messagemode2", "chat - team", ID_CHAT2, ANIM_CHAT, -1, -1, -1, -1}, - {"messagemode3", "chat - target", ID_CHAT3, ANIM_CHAT, -1, -1, -1, -1}, - {"messagemode4", "chat - attacker", ID_CHAT4, ANIM_CHAT, -1, -1, -1, -1}, - {(char*)NULL, (char*)NULL, 0, 0, -1, -1, -1, -1}, -}; - -static configcvar_t g_configcvars[] = -{ - {"cl_run", 0, 0}, - {"m_pitch", 0, 0}, - {"cg_autoswitch", 0, 0}, - {"sensitivity", 0, 0}, - {"in_joystick", 0, 0}, - {"joy_threshold", 0, 0}, - {"m_filter", 0, 0}, - {"cl_freelook", 0, 0}, - {NULL, 0, 0} -}; - -static menucommon_s *g_movement_controls[] = -{ - (menucommon_s *)&s_controls.alwaysrun, - (menucommon_s *)&s_controls.run, - (menucommon_s *)&s_controls.walkforward, - (menucommon_s *)&s_controls.backpedal, - (menucommon_s *)&s_controls.stepleft, - (menucommon_s *)&s_controls.stepright, - (menucommon_s *)&s_controls.moveup, - (menucommon_s *)&s_controls.movedown, - (menucommon_s *)&s_controls.turnleft, - (menucommon_s *)&s_controls.turnright, - (menucommon_s *)&s_controls.sidestep, - NULL -}; - -static menucommon_s *g_weapons_controls[] = { - (menucommon_s *)&s_controls.attack, - (menucommon_s *)&s_controls.nextweapon, - (menucommon_s *)&s_controls.prevweapon, - (menucommon_s *)&s_controls.autoswitch, - (menucommon_s *)&s_controls.chainsaw, - (menucommon_s *)&s_controls.machinegun, - (menucommon_s *)&s_controls.shotgun, - (menucommon_s *)&s_controls.grenadelauncher, - (menucommon_s *)&s_controls.rocketlauncher, - (menucommon_s *)&s_controls.lightning, - (menucommon_s *)&s_controls.railgun, - (menucommon_s *)&s_controls.plasma, - (menucommon_s *)&s_controls.bfg, - NULL, -}; - -static menucommon_s *g_looking_controls[] = { - (menucommon_s *)&s_controls.sensitivity, - (menucommon_s *)&s_controls.smoothmouse, - (menucommon_s *)&s_controls.invertmouse, - (menucommon_s *)&s_controls.lookup, - (menucommon_s *)&s_controls.lookdown, - (menucommon_s *)&s_controls.mouselook, - (menucommon_s *)&s_controls.freelook, - (menucommon_s *)&s_controls.centerview, - (menucommon_s *)&s_controls.zoomview, - (menucommon_s *)&s_controls.joyenable, - (menucommon_s *)&s_controls.joythreshold, - NULL, -}; - -static menucommon_s *g_misc_controls[] = { - (menucommon_s *)&s_controls.showscores, - (menucommon_s *)&s_controls.useitem, - (menucommon_s *)&s_controls.gesture, - (menucommon_s *)&s_controls.chat, - (menucommon_s *)&s_controls.chat2, - (menucommon_s *)&s_controls.chat3, - (menucommon_s *)&s_controls.chat4, - NULL, -}; - -static menucommon_s **g_controls[] = { - g_movement_controls, - g_looking_controls, - g_weapons_controls, - g_misc_controls, -}; - -/* -================= -Controls_InitCvars -================= -*/ -static void Controls_InitCvars( void ) -{ - int i; - configcvar_t* cvarptr; - - cvarptr = g_configcvars; - for (i=0; ;i++,cvarptr++) - { - if (!cvarptr->name) - break; - - // get current value - cvarptr->value = trap_Cvar_VariableValue( cvarptr->name ); - - // get default value - trap_Cvar_Reset( cvarptr->name ); - cvarptr->defaultvalue = trap_Cvar_VariableValue( cvarptr->name ); - - // restore current value - trap_Cvar_SetValue( cvarptr->name, cvarptr->value ); - } -} - -/* -================= -Controls_GetCvarDefault -================= -*/ -static float Controls_GetCvarDefault( char* name ) -{ - configcvar_t* cvarptr; - int i; - - cvarptr = g_configcvars; - for (i=0; ;i++,cvarptr++) - { - if (!cvarptr->name) - return (0); - - if (!strcmp(cvarptr->name,name)) - break; - } - - return (cvarptr->defaultvalue); -} - -/* -================= -Controls_GetCvarValue -================= -*/ -static float Controls_GetCvarValue( char* name ) -{ - configcvar_t* cvarptr; - int i; - - cvarptr = g_configcvars; - for (i=0; ;i++,cvarptr++) - { - if (!cvarptr->name) - return (0); - - if (!strcmp(cvarptr->name,name)) - break; - } - - return (cvarptr->value); -} - - -/* -================= -Controls_UpdateModel -================= -*/ -static void Controls_UpdateModel( int anim ) { - VectorClear( s_controls.playerViewangles ); - VectorClear( s_controls.playerMoveangles ); - s_controls.playerViewangles[YAW] = 180 - 30; - s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW]; - s_controls.playerLegs = LEGS_IDLE; - s_controls.playerTorso = TORSO_STAND; - s_controls.playerWeapon = -1; - s_controls.playerChat = qfalse; - - switch( anim ) { - case ANIM_RUN: - s_controls.playerLegs = LEGS_RUN; - break; - - case ANIM_WALK: - s_controls.playerLegs = LEGS_WALK; - break; - - case ANIM_BACK: - s_controls.playerLegs = LEGS_BACK; - break; - - case ANIM_JUMP: - s_controls.playerLegs = LEGS_JUMP; - break; - - case ANIM_CROUCH: - s_controls.playerLegs = LEGS_IDLECR; - break; - - case ANIM_TURNLEFT: - s_controls.playerViewangles[YAW] += 90; - break; - - case ANIM_TURNRIGHT: - s_controls.playerViewangles[YAW] -= 90; - break; - - case ANIM_STEPLEFT: - s_controls.playerLegs = LEGS_WALK; - s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] + 90; - break; - - case ANIM_STEPRIGHT: - s_controls.playerLegs = LEGS_WALK; - s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] - 90; - break; - - case ANIM_LOOKUP: - s_controls.playerViewangles[PITCH] = -45; - break; - - case ANIM_LOOKDOWN: - s_controls.playerViewangles[PITCH] = 45; - break; - - case ANIM_WEAPON1: - s_controls.playerWeapon = WP_GAUNTLET; - break; - - case ANIM_WEAPON2: - s_controls.playerWeapon = WP_MACHINEGUN; - break; - - case ANIM_WEAPON3: - s_controls.playerWeapon = WP_SHOTGUN; - break; - - case ANIM_WEAPON4: - s_controls.playerWeapon = WP_GRENADE_LAUNCHER; - break; - - case ANIM_WEAPON5: - s_controls.playerWeapon = WP_ROCKET_LAUNCHER; - break; - - case ANIM_WEAPON6: - s_controls.playerWeapon = WP_LIGHTNING; - break; - - case ANIM_WEAPON7: - s_controls.playerWeapon = WP_RAILGUN; - break; - - case ANIM_WEAPON8: - s_controls.playerWeapon = WP_PLASMAGUN; - break; - - case ANIM_WEAPON9: - s_controls.playerWeapon = WP_BFG; - break; - - case ANIM_WEAPON10: - s_controls.playerWeapon = WP_GRAPPLING_HOOK; - break; - - case ANIM_ATTACK: - s_controls.playerTorso = TORSO_ATTACK; - break; - - case ANIM_GESTURE: - s_controls.playerTorso = TORSO_GESTURE; - break; - - case ANIM_DIE: - s_controls.playerLegs = BOTH_DEATH1; - s_controls.playerTorso = BOTH_DEATH1; - s_controls.playerWeapon = WP_NONE; - break; - - case ANIM_CHAT: - s_controls.playerChat = qtrue; - break; - - default: - break; - } - - UI_PlayerInfo_SetInfo( &s_controls.playerinfo, s_controls.playerLegs, s_controls.playerTorso, s_controls.playerViewangles, s_controls.playerMoveangles, s_controls.playerWeapon, s_controls.playerChat ); -} - - -/* -================= -Controls_Update -================= -*/ -static void Controls_Update( void ) { - int i; - int j; - int y; - menucommon_s **controls; - menucommon_s *control; - - // disable all controls in all groups - for( i = 0; i < C_MAX; i++ ) { - controls = g_controls[i]; - // bk001204 - parentheses - for( j = 0; (control = controls[j]) ; j++ ) { - control->flags |= (QMF_HIDDEN|QMF_INACTIVE); - } - } - - controls = g_controls[s_controls.section]; - - // enable controls in active group (and count number of items for vertical centering) - // bk001204 - parentheses - for( j = 0; (control = controls[j]) ; j++ ) { - control->flags &= ~(QMF_GRAYED|QMF_HIDDEN|QMF_INACTIVE); - } - - // position controls - y = ( SCREEN_HEIGHT - j * SMALLCHAR_HEIGHT ) / 2; - // bk001204 - parentheses - for( j = 0; (control = controls[j]) ; j++, y += SMALLCHAR_HEIGHT ) { - control->x = 320; - control->y = y; - control->left = 320 - 19*SMALLCHAR_WIDTH; - control->right = 320 + 21*SMALLCHAR_WIDTH; - control->top = y; - control->bottom = y + SMALLCHAR_HEIGHT; - } - - if( s_controls.waitingforkey ) { - // disable everybody - for( i = 0; i < s_controls.menu.nitems; i++ ) { - ((menucommon_s*)(s_controls.menu.items[i]))->flags |= QMF_GRAYED; - } - - // enable action item - ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->flags &= ~QMF_GRAYED; - - // don't gray out player's name - s_controls.name.generic.flags &= ~QMF_GRAYED; - - return; - } - - // enable everybody - for( i = 0; i < s_controls.menu.nitems; i++ ) { - ((menucommon_s*)(s_controls.menu.items[i]))->flags &= ~QMF_GRAYED; - } - - // makes sure flags are right on the group selection controls - s_controls.looking.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - s_controls.movement.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - s_controls.weapons.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - s_controls.misc.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - - s_controls.looking.generic.flags |= QMF_PULSEIFFOCUS; - s_controls.movement.generic.flags |= QMF_PULSEIFFOCUS; - s_controls.weapons.generic.flags |= QMF_PULSEIFFOCUS; - s_controls.misc.generic.flags |= QMF_PULSEIFFOCUS; - - // set buttons - switch( s_controls.section ) { - case C_MOVEMENT: - s_controls.movement.generic.flags &= ~QMF_PULSEIFFOCUS; - s_controls.movement.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - break; - - case C_LOOKING: - s_controls.looking.generic.flags &= ~QMF_PULSEIFFOCUS; - s_controls.looking.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - break; - - case C_WEAPONS: - s_controls.weapons.generic.flags &= ~QMF_PULSEIFFOCUS; - s_controls.weapons.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - break; - - case C_MISC: - s_controls.misc.generic.flags &= ~QMF_PULSEIFFOCUS; - s_controls.misc.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); - break; - } -} - - -/* -================= -Controls_DrawKeyBinding -================= -*/ -static void Controls_DrawKeyBinding( void *self ) -{ - menuaction_s* a; - int x; - int y; - int b1; - int b2; - qboolean c; - char name[32]; - char name2[32]; - - a = (menuaction_s*) self; - - x = a->generic.x; - y = a->generic.y; - - c = (Menu_ItemAtCursor( a->generic.parent ) == a); - - b1 = g_bindings[a->generic.id].bind1; - if (b1 == -1) - strcpy(name,"???"); - else - { - trap_Key_KeynumToStringBuf( b1, name, 32 ); - Q_strupr(name); - - b2 = g_bindings[a->generic.id].bind2; - if (b2 != -1) - { - trap_Key_KeynumToStringBuf( b2, name2, 32 ); - Q_strupr(name2); - - strcat( name, " or " ); - strcat( name, name2 ); - } - } - - if (c) - { - UI_FillRect( a->generic.left, a->generic.top, a->generic.right-a->generic.left+1, a->generic.bottom-a->generic.top+1, listbar_color ); - - UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_highlight ); - UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT|UI_PULSE, text_color_highlight ); - - if (s_controls.waitingforkey) - { - UI_DrawChar( x, y, '=', UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight); - UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Waiting for new key ... ESCAPE to cancel", UI_SMALLFONT|UI_CENTER|UI_PULSE, colorWhite ); - } - else - { - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight); - UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.78, "Press ENTER or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite ); - UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.82, "Press BACKSPACE to clear", UI_SMALLFONT|UI_CENTER, colorWhite ); - } - } - else - { - if (a->generic.flags & QMF_GRAYED) - { - UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_disabled ); - UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, text_color_disabled ); - } - else - { - UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, controls_binding_color ); - UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, controls_binding_color ); - } - } -} - -/* -================= -Controls_StatusBar -================= -*/ -static void Controls_StatusBar( void *self ) -{ - UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Use Arrow Keys or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite ); -} - - -/* -================= -Controls_DrawPlayer -================= -*/ -static void Controls_DrawPlayer( void *self ) { - menubitmap_s *b; - char buf[MAX_QPATH]; - - trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) ); - if ( strcmp( buf, s_controls.playerModel ) != 0 ) { - UI_PlayerInfo_SetModel( &s_controls.playerinfo, buf ); - strcpy( s_controls.playerModel, buf ); - Controls_UpdateModel( ANIM_IDLE ); - } - - b = (menubitmap_s*) self; - UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_controls.playerinfo, uis.realtime/2 ); -} - - -/* -================= -Controls_GetKeyAssignment -================= -*/ -static void Controls_GetKeyAssignment (char *command, int *twokeys) -{ - int count; - int j; - char b[256]; - - twokeys[0] = twokeys[1] = -1; - count = 0; - - for ( j = 0; j < 256; j++ ) - { - trap_Key_GetBindingBuf( j, b, 256 ); - if ( *b == 0 ) { - continue; - } - if ( !Q_stricmp( b, command ) ) { - twokeys[count] = j; - count++; - if (count == 2) - break; - } - } -} - -/* -================= -Controls_GetConfig -================= -*/ -static void Controls_GetConfig( void ) -{ - int i; - int twokeys[2]; - bind_t* bindptr; - - // put the bindings into a local store - bindptr = g_bindings; - - // iterate each command, get its numeric binding - for (i=0; ;i++,bindptr++) - { - if (!bindptr->label) - break; - - Controls_GetKeyAssignment(bindptr->command, twokeys); - - bindptr->bind1 = twokeys[0]; - bindptr->bind2 = twokeys[1]; - } - - s_controls.invertmouse.curvalue = Controls_GetCvarValue( "m_pitch" ) < 0; - s_controls.smoothmouse.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "m_filter" ) ); - s_controls.alwaysrun.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_run" ) ); - s_controls.autoswitch.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cg_autoswitch" ) ); - s_controls.sensitivity.curvalue = UI_ClampCvar( 2, 30, Controls_GetCvarValue( "sensitivity" ) ); - s_controls.joyenable.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "in_joystick" ) ); - s_controls.joythreshold.curvalue = UI_ClampCvar( 0.05f, 0.75f, Controls_GetCvarValue( "joy_threshold" ) ); - s_controls.freelook.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_freelook" ) ); -} - -/* -================= -Controls_SetConfig -================= -*/ -static void Controls_SetConfig( void ) -{ - int i; - bind_t* bindptr; - - // set the bindings from the local store - bindptr = g_bindings; - - // iterate each command, get its numeric binding - for (i=0; ;i++,bindptr++) - { - if (!bindptr->label) - break; - - if (bindptr->bind1 != -1) - { - trap_Key_SetBinding( bindptr->bind1, bindptr->command ); - - if (bindptr->bind2 != -1) - trap_Key_SetBinding( bindptr->bind2, bindptr->command ); - } - } - - if ( s_controls.invertmouse.curvalue ) - trap_Cvar_SetValue( "m_pitch", -fabs( trap_Cvar_VariableValue( "m_pitch" ) ) ); - else - trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) ); - - trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue ); - trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue ); - trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue ); - trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue ); - trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue ); - trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue ); - trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue ); - trap_Cmd_ExecuteText( EXEC_APPEND, "in_restart\n" ); -} - -/* -================= -Controls_SetDefaults -================= -*/ -static void Controls_SetDefaults( void ) -{ - int i; - bind_t* bindptr; - - // set the bindings from the local store - bindptr = g_bindings; - - // iterate each command, set its default binding - for (i=0; ;i++,bindptr++) - { - if (!bindptr->label) - break; - - bindptr->bind1 = bindptr->defaultbind1; - bindptr->bind2 = bindptr->defaultbind2; - } - - s_controls.invertmouse.curvalue = Controls_GetCvarDefault( "m_pitch" ) < 0; - s_controls.smoothmouse.curvalue = Controls_GetCvarDefault( "m_filter" ); - s_controls.alwaysrun.curvalue = Controls_GetCvarDefault( "cl_run" ); - s_controls.autoswitch.curvalue = Controls_GetCvarDefault( "cg_autoswitch" ); - s_controls.sensitivity.curvalue = Controls_GetCvarDefault( "sensitivity" ); - s_controls.joyenable.curvalue = Controls_GetCvarDefault( "in_joystick" ); - s_controls.joythreshold.curvalue = Controls_GetCvarDefault( "joy_threshold" ); - s_controls.freelook.curvalue = Controls_GetCvarDefault( "cl_freelook" ); -} - -/* -================= -Controls_MenuKey -================= -*/ -static sfxHandle_t Controls_MenuKey( int key ) -{ - int id; - int i; - qboolean found; - bind_t* bindptr; - found = qfalse; - - if (!s_controls.waitingforkey) - { - switch (key) - { - case K_BACKSPACE: - case K_DEL: - case K_KP_DEL: - key = -1; - break; - - case K_MOUSE2: - case K_ESCAPE: - if (s_controls.changesmade) - Controls_SetConfig(); - goto ignorekey; - - default: - goto ignorekey; - } - } - else - { - if (key & K_CHAR_FLAG) - goto ignorekey; - - switch (key) - { - case K_ESCAPE: - s_controls.waitingforkey = qfalse; - Controls_Update(); - return (menu_out_sound); - - case '`': - goto ignorekey; - } - } - - s_controls.changesmade = qtrue; - - if (key != -1) - { - // remove from any other bind - bindptr = g_bindings; - for (i=0; ;i++,bindptr++) - { - if (!bindptr->label) - break; - - if (bindptr->bind2 == key) - bindptr->bind2 = -1; - - if (bindptr->bind1 == key) - { - bindptr->bind1 = bindptr->bind2; - bindptr->bind2 = -1; - } - } - } - - // assign key to local store - id = ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->id; - bindptr = g_bindings; - for (i=0; ;i++,bindptr++) - { - if (!bindptr->label) - break; - - if (bindptr->id == id) - { - found = qtrue; - if (key == -1) - { - if( bindptr->bind1 != -1 ) { - trap_Key_SetBinding( bindptr->bind1, "" ); - bindptr->bind1 = -1; - } - if( bindptr->bind2 != -1 ) { - trap_Key_SetBinding( bindptr->bind2, "" ); - bindptr->bind2 = -1; - } - } - else if (bindptr->bind1 == -1) { - bindptr->bind1 = key; - } - else if (bindptr->bind1 != key && bindptr->bind2 == -1) { - bindptr->bind2 = key; - } - else - { - trap_Key_SetBinding( bindptr->bind1, "" ); - trap_Key_SetBinding( bindptr->bind2, "" ); - bindptr->bind1 = key; - bindptr->bind2 = -1; - } - break; - } - } - - s_controls.waitingforkey = qfalse; - - if (found) - { - Controls_Update(); - return (menu_out_sound); - } - -ignorekey: - return Menu_DefaultKey( &s_controls.menu, key ); -} - -/* -================= -Controls_ResetDefaults_Action -================= -*/ -static void Controls_ResetDefaults_Action( qboolean result ) { - if( !result ) { - return; - } - - s_controls.changesmade = qtrue; - Controls_SetDefaults(); - Controls_Update(); -} - -/* -================= -Controls_ResetDefaults_Draw -================= -*/ -static void Controls_ResetDefaults_Draw( void ) { - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This will reset all", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "controls to their default values.", UI_CENTER|UI_SMALLFONT, color_yellow ); -} - -/* -================= -Controls_MenuEvent -================= -*/ -static void Controls_MenuEvent( void* ptr, int event ) -{ - switch (((menucommon_s*)ptr)->id) - { - case ID_MOVEMENT: - if (event == QM_ACTIVATED) - { - s_controls.section = C_MOVEMENT; - Controls_Update(); - } - break; - - case ID_LOOKING: - if (event == QM_ACTIVATED) - { - s_controls.section = C_LOOKING; - Controls_Update(); - } - break; - - case ID_WEAPONS: - if (event == QM_ACTIVATED) - { - s_controls.section = C_WEAPONS; - Controls_Update(); - } - break; - - case ID_MISC: - if (event == QM_ACTIVATED) - { - s_controls.section = C_MISC; - Controls_Update(); - } - break; - - case ID_DEFAULTS: - if (event == QM_ACTIVATED) - { - UI_ConfirmMenu( "SET TO DEFAULTS?", Controls_ResetDefaults_Draw, Controls_ResetDefaults_Action ); - } - break; - - case ID_BACK: - if (event == QM_ACTIVATED) - { - if (s_controls.changesmade) - Controls_SetConfig(); - UI_PopMenu(); - } - break; - - case ID_SAVEANDEXIT: - if (event == QM_ACTIVATED) - { - Controls_SetConfig(); - UI_PopMenu(); - } - break; - - case ID_EXIT: - if (event == QM_ACTIVATED) - { - UI_PopMenu(); - } - break; - - case ID_FREELOOK: - case ID_MOUSESPEED: - case ID_INVERTMOUSE: - case ID_SMOOTHMOUSE: - case ID_ALWAYSRUN: - case ID_AUTOSWITCH: - case ID_JOYENABLE: - case ID_JOYTHRESHOLD: - if (event == QM_ACTIVATED) - { - s_controls.changesmade = qtrue; - } - break; - } -} - -/* -================= -Controls_ActionEvent -================= -*/ -static void Controls_ActionEvent( void* ptr, int event ) -{ - if (event == QM_LOSTFOCUS) - { - Controls_UpdateModel( ANIM_IDLE ); - } - else if (event == QM_GOTFOCUS) - { - Controls_UpdateModel( g_bindings[((menucommon_s*)ptr)->id].anim ); - } - else if ((event == QM_ACTIVATED) && !s_controls.waitingforkey) - { - s_controls.waitingforkey = 1; - Controls_Update(); - } -} - -/* -================= -Controls_InitModel -================= -*/ -static void Controls_InitModel( void ) -{ - memset( &s_controls.playerinfo, 0, sizeof(playerInfo_t) ); - - UI_PlayerInfo_SetModel( &s_controls.playerinfo, UI_Cvar_VariableString( "model" ) ); - - Controls_UpdateModel( ANIM_IDLE ); -} - -/* -================= -Controls_InitWeapons -================= -*/ -static void Controls_InitWeapons( void ) { - gitem_t * item; - - for ( item = bg_itemlist + 1 ; item->classname ; item++ ) { - if ( item->giType != IT_WEAPON ) { - continue; - } - trap_R_RegisterModel( item->world_model[0] ); - } -} - -/* -================= -Controls_MenuInit -================= -*/ -static void Controls_MenuInit( void ) -{ - static char playername[32]; - - // zero set all our globals - memset( &s_controls, 0 ,sizeof(controls_t) ); - - Controls_Cache(); - - s_controls.menu.key = Controls_MenuKey; - s_controls.menu.wrapAround = qtrue; - s_controls.menu.fullscreen = qtrue; - - s_controls.banner.generic.type = MTYPE_BTEXT; - s_controls.banner.generic.flags = QMF_CENTER_JUSTIFY; - s_controls.banner.generic.x = 320; - s_controls.banner.generic.y = 16; - s_controls.banner.string = "CONTROLS"; - s_controls.banner.color = color_white; - s_controls.banner.style = UI_CENTER; - - s_controls.framel.generic.type = MTYPE_BITMAP; - s_controls.framel.generic.name = ART_FRAMEL; - s_controls.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_controls.framel.generic.x = 0; - s_controls.framel.generic.y = 78; - s_controls.framel.width = 256; - s_controls.framel.height = 329; - - s_controls.framer.generic.type = MTYPE_BITMAP; - s_controls.framer.generic.name = ART_FRAMER; - s_controls.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_controls.framer.generic.x = 376; - s_controls.framer.generic.y = 76; - s_controls.framer.width = 256; - s_controls.framer.height = 334; - - s_controls.looking.generic.type = MTYPE_PTEXT; - s_controls.looking.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_controls.looking.generic.id = ID_LOOKING; - s_controls.looking.generic.callback = Controls_MenuEvent; - s_controls.looking.generic.x = 152; - s_controls.looking.generic.y = 240 - 2 * PROP_HEIGHT; - s_controls.looking.string = "LOOK"; - s_controls.looking.style = UI_RIGHT; - s_controls.looking.color = color_red; - - s_controls.movement.generic.type = MTYPE_PTEXT; - s_controls.movement.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_controls.movement.generic.id = ID_MOVEMENT; - s_controls.movement.generic.callback = Controls_MenuEvent; - s_controls.movement.generic.x = 152; - s_controls.movement.generic.y = 240 - PROP_HEIGHT; - s_controls.movement.string = "MOVE"; - s_controls.movement.style = UI_RIGHT; - s_controls.movement.color = color_red; - - s_controls.weapons.generic.type = MTYPE_PTEXT; - s_controls.weapons.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_controls.weapons.generic.id = ID_WEAPONS; - s_controls.weapons.generic.callback = Controls_MenuEvent; - s_controls.weapons.generic.x = 152; - s_controls.weapons.generic.y = 240; - s_controls.weapons.string = "SHOOT"; - s_controls.weapons.style = UI_RIGHT; - s_controls.weapons.color = color_red; - - s_controls.misc.generic.type = MTYPE_PTEXT; - s_controls.misc.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_controls.misc.generic.id = ID_MISC; - s_controls.misc.generic.callback = Controls_MenuEvent; - s_controls.misc.generic.x = 152; - s_controls.misc.generic.y = 240 + PROP_HEIGHT; - s_controls.misc.string = "MISC"; - s_controls.misc.style = UI_RIGHT; - s_controls.misc.color = color_red; - - s_controls.back.generic.type = MTYPE_BITMAP; - s_controls.back.generic.name = ART_BACK0; - s_controls.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_controls.back.generic.x = 0; - s_controls.back.generic.y = 480-64; - s_controls.back.generic.id = ID_BACK; - s_controls.back.generic.callback = Controls_MenuEvent; - s_controls.back.width = 128; - s_controls.back.height = 64; - s_controls.back.focuspic = ART_BACK1; - - s_controls.player.generic.type = MTYPE_BITMAP; - s_controls.player.generic.flags = QMF_INACTIVE; - s_controls.player.generic.ownerdraw = Controls_DrawPlayer; - s_controls.player.generic.x = 400; - s_controls.player.generic.y = -40; - s_controls.player.width = 32*10; - s_controls.player.height = 56*10; - - s_controls.walkforward.generic.type = MTYPE_ACTION; - s_controls.walkforward.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.walkforward.generic.callback = Controls_ActionEvent; - s_controls.walkforward.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.walkforward.generic.id = ID_FORWARD; - - s_controls.backpedal.generic.type = MTYPE_ACTION; - s_controls.backpedal.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.backpedal.generic.callback = Controls_ActionEvent; - s_controls.backpedal.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.backpedal.generic.id = ID_BACKPEDAL; - - s_controls.stepleft.generic.type = MTYPE_ACTION; - s_controls.stepleft.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.stepleft.generic.callback = Controls_ActionEvent; - s_controls.stepleft.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.stepleft.generic.id = ID_MOVELEFT; - - s_controls.stepright.generic.type = MTYPE_ACTION; - s_controls.stepright.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.stepright.generic.callback = Controls_ActionEvent; - s_controls.stepright.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.stepright.generic.id = ID_MOVERIGHT; - - s_controls.moveup.generic.type = MTYPE_ACTION; - s_controls.moveup.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.moveup.generic.callback = Controls_ActionEvent; - s_controls.moveup.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.moveup.generic.id = ID_MOVEUP; - - s_controls.movedown.generic.type = MTYPE_ACTION; - s_controls.movedown.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.movedown.generic.callback = Controls_ActionEvent; - s_controls.movedown.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.movedown.generic.id = ID_MOVEDOWN; - - s_controls.turnleft.generic.type = MTYPE_ACTION; - s_controls.turnleft.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.turnleft.generic.callback = Controls_ActionEvent; - s_controls.turnleft.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.turnleft.generic.id = ID_LEFT; - - s_controls.turnright.generic.type = MTYPE_ACTION; - s_controls.turnright.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.turnright.generic.callback = Controls_ActionEvent; - s_controls.turnright.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.turnright.generic.id = ID_RIGHT; - - s_controls.sidestep.generic.type = MTYPE_ACTION; - s_controls.sidestep.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.sidestep.generic.callback = Controls_ActionEvent; - s_controls.sidestep.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.sidestep.generic.id = ID_STRAFE; - - s_controls.run.generic.type = MTYPE_ACTION; - s_controls.run.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.run.generic.callback = Controls_ActionEvent; - s_controls.run.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.run.generic.id = ID_SPEED; - - s_controls.chainsaw.generic.type = MTYPE_ACTION; - s_controls.chainsaw.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.chainsaw.generic.callback = Controls_ActionEvent; - s_controls.chainsaw.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.chainsaw.generic.id = ID_WEAPON1; - - s_controls.machinegun.generic.type = MTYPE_ACTION; - s_controls.machinegun.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.machinegun.generic.callback = Controls_ActionEvent; - s_controls.machinegun.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.machinegun.generic.id = ID_WEAPON2; - - s_controls.shotgun.generic.type = MTYPE_ACTION; - s_controls.shotgun.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.shotgun.generic.callback = Controls_ActionEvent; - s_controls.shotgun.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.shotgun.generic.id = ID_WEAPON3; - - s_controls.grenadelauncher.generic.type = MTYPE_ACTION; - s_controls.grenadelauncher.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.grenadelauncher.generic.callback = Controls_ActionEvent; - s_controls.grenadelauncher.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.grenadelauncher.generic.id = ID_WEAPON4; - - s_controls.rocketlauncher.generic.type = MTYPE_ACTION; - s_controls.rocketlauncher.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.rocketlauncher.generic.callback = Controls_ActionEvent; - s_controls.rocketlauncher.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.rocketlauncher.generic.id = ID_WEAPON5; - - s_controls.lightning.generic.type = MTYPE_ACTION; - s_controls.lightning.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.lightning.generic.callback = Controls_ActionEvent; - s_controls.lightning.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.lightning.generic.id = ID_WEAPON6; - - s_controls.railgun.generic.type = MTYPE_ACTION; - s_controls.railgun.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.railgun.generic.callback = Controls_ActionEvent; - s_controls.railgun.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.railgun.generic.id = ID_WEAPON7; - - s_controls.plasma.generic.type = MTYPE_ACTION; - s_controls.plasma.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.plasma.generic.callback = Controls_ActionEvent; - s_controls.plasma.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.plasma.generic.id = ID_WEAPON8; - - s_controls.bfg.generic.type = MTYPE_ACTION; - s_controls.bfg.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.bfg.generic.callback = Controls_ActionEvent; - s_controls.bfg.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.bfg.generic.id = ID_WEAPON9; - - s_controls.attack.generic.type = MTYPE_ACTION; - s_controls.attack.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.attack.generic.callback = Controls_ActionEvent; - s_controls.attack.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.attack.generic.id = ID_ATTACK; - - s_controls.prevweapon.generic.type = MTYPE_ACTION; - s_controls.prevweapon.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.prevweapon.generic.callback = Controls_ActionEvent; - s_controls.prevweapon.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.prevweapon.generic.id = ID_WEAPPREV; - - s_controls.nextweapon.generic.type = MTYPE_ACTION; - s_controls.nextweapon.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.nextweapon.generic.callback = Controls_ActionEvent; - s_controls.nextweapon.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.nextweapon.generic.id = ID_WEAPNEXT; - - s_controls.lookup.generic.type = MTYPE_ACTION; - s_controls.lookup.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.lookup.generic.callback = Controls_ActionEvent; - s_controls.lookup.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.lookup.generic.id = ID_LOOKUP; - - s_controls.lookdown.generic.type = MTYPE_ACTION; - s_controls.lookdown.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.lookdown.generic.callback = Controls_ActionEvent; - s_controls.lookdown.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.lookdown.generic.id = ID_LOOKDOWN; - - s_controls.mouselook.generic.type = MTYPE_ACTION; - s_controls.mouselook.generic.flags = QMF_LEFT_JUSTIFY|QMF_HIGHLIGHT_IF_FOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.mouselook.generic.callback = Controls_ActionEvent; - s_controls.mouselook.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.mouselook.generic.id = ID_MOUSELOOK; - - s_controls.freelook.generic.type = MTYPE_RADIOBUTTON; - s_controls.freelook.generic.flags = QMF_SMALLFONT; - s_controls.freelook.generic.x = SCREEN_WIDTH/2; - s_controls.freelook.generic.name = "free look"; - s_controls.freelook.generic.id = ID_FREELOOK; - s_controls.freelook.generic.callback = Controls_MenuEvent; - s_controls.freelook.generic.statusbar = Controls_StatusBar; - - s_controls.centerview.generic.type = MTYPE_ACTION; - s_controls.centerview.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.centerview.generic.callback = Controls_ActionEvent; - s_controls.centerview.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.centerview.generic.id = ID_CENTERVIEW; - - s_controls.zoomview.generic.type = MTYPE_ACTION; - s_controls.zoomview.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.zoomview.generic.callback = Controls_ActionEvent; - s_controls.zoomview.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.zoomview.generic.id = ID_ZOOMVIEW; - - s_controls.useitem.generic.type = MTYPE_ACTION; - s_controls.useitem.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.useitem.generic.callback = Controls_ActionEvent; - s_controls.useitem.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.useitem.generic.id = ID_USEITEM; - - s_controls.showscores.generic.type = MTYPE_ACTION; - s_controls.showscores.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.showscores.generic.callback = Controls_ActionEvent; - s_controls.showscores.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.showscores.generic.id = ID_SHOWSCORES; - - s_controls.invertmouse.generic.type = MTYPE_RADIOBUTTON; - s_controls.invertmouse.generic.flags = QMF_SMALLFONT; - s_controls.invertmouse.generic.x = SCREEN_WIDTH/2; - s_controls.invertmouse.generic.name = "invert mouse"; - s_controls.invertmouse.generic.id = ID_INVERTMOUSE; - s_controls.invertmouse.generic.callback = Controls_MenuEvent; - s_controls.invertmouse.generic.statusbar = Controls_StatusBar; - - s_controls.smoothmouse.generic.type = MTYPE_RADIOBUTTON; - s_controls.smoothmouse.generic.flags = QMF_SMALLFONT; - s_controls.smoothmouse.generic.x = SCREEN_WIDTH/2; - s_controls.smoothmouse.generic.name = "smooth mouse"; - s_controls.smoothmouse.generic.id = ID_SMOOTHMOUSE; - s_controls.smoothmouse.generic.callback = Controls_MenuEvent; - s_controls.smoothmouse.generic.statusbar = Controls_StatusBar; - - s_controls.alwaysrun.generic.type = MTYPE_RADIOBUTTON; - s_controls.alwaysrun.generic.flags = QMF_SMALLFONT; - s_controls.alwaysrun.generic.x = SCREEN_WIDTH/2; - s_controls.alwaysrun.generic.name = "always run"; - s_controls.alwaysrun.generic.id = ID_ALWAYSRUN; - s_controls.alwaysrun.generic.callback = Controls_MenuEvent; - s_controls.alwaysrun.generic.statusbar = Controls_StatusBar; - - s_controls.autoswitch.generic.type = MTYPE_RADIOBUTTON; - s_controls.autoswitch.generic.flags = QMF_SMALLFONT; - s_controls.autoswitch.generic.x = SCREEN_WIDTH/2; - s_controls.autoswitch.generic.name = "autoswitch weapons"; - s_controls.autoswitch.generic.id = ID_AUTOSWITCH; - s_controls.autoswitch.generic.callback = Controls_MenuEvent; - s_controls.autoswitch.generic.statusbar = Controls_StatusBar; - - s_controls.sensitivity.generic.type = MTYPE_SLIDER; - s_controls.sensitivity.generic.x = SCREEN_WIDTH/2; - s_controls.sensitivity.generic.flags = QMF_SMALLFONT; - s_controls.sensitivity.generic.name = "mouse speed"; - s_controls.sensitivity.generic.id = ID_MOUSESPEED; - s_controls.sensitivity.generic.callback = Controls_MenuEvent; - s_controls.sensitivity.minvalue = 2; - s_controls.sensitivity.maxvalue = 30; - s_controls.sensitivity.generic.statusbar = Controls_StatusBar; - - s_controls.gesture.generic.type = MTYPE_ACTION; - s_controls.gesture.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.gesture.generic.callback = Controls_ActionEvent; - s_controls.gesture.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.gesture.generic.id = ID_GESTURE; - - s_controls.chat.generic.type = MTYPE_ACTION; - s_controls.chat.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.chat.generic.callback = Controls_ActionEvent; - s_controls.chat.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.chat.generic.id = ID_CHAT; - - s_controls.chat2.generic.type = MTYPE_ACTION; - s_controls.chat2.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.chat2.generic.callback = Controls_ActionEvent; - s_controls.chat2.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.chat2.generic.id = ID_CHAT2; - - s_controls.chat3.generic.type = MTYPE_ACTION; - s_controls.chat3.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.chat3.generic.callback = Controls_ActionEvent; - s_controls.chat3.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.chat3.generic.id = ID_CHAT3; - - s_controls.chat4.generic.type = MTYPE_ACTION; - s_controls.chat4.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; - s_controls.chat4.generic.callback = Controls_ActionEvent; - s_controls.chat4.generic.ownerdraw = Controls_DrawKeyBinding; - s_controls.chat4.generic.id = ID_CHAT4; - - s_controls.joyenable.generic.type = MTYPE_RADIOBUTTON; - s_controls.joyenable.generic.flags = QMF_SMALLFONT; - s_controls.joyenable.generic.x = SCREEN_WIDTH/2; - s_controls.joyenable.generic.name = "joystick"; - s_controls.joyenable.generic.id = ID_JOYENABLE; - s_controls.joyenable.generic.callback = Controls_MenuEvent; - s_controls.joyenable.generic.statusbar = Controls_StatusBar; - - s_controls.joythreshold.generic.type = MTYPE_SLIDER; - s_controls.joythreshold.generic.x = SCREEN_WIDTH/2; - s_controls.joythreshold.generic.flags = QMF_SMALLFONT; - s_controls.joythreshold.generic.name = "joystick threshold"; - s_controls.joythreshold.generic.id = ID_JOYTHRESHOLD; - s_controls.joythreshold.generic.callback = Controls_MenuEvent; - s_controls.joythreshold.minvalue = 0.05f; - s_controls.joythreshold.maxvalue = 0.75f; - s_controls.joythreshold.generic.statusbar = Controls_StatusBar; - - s_controls.name.generic.type = MTYPE_PTEXT; - s_controls.name.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE; - s_controls.name.generic.x = 320; - s_controls.name.generic.y = 440; - s_controls.name.string = playername; - s_controls.name.style = UI_CENTER; - s_controls.name.color = text_color_normal; - - Menu_AddItem( &s_controls.menu, &s_controls.banner ); - Menu_AddItem( &s_controls.menu, &s_controls.framel ); - Menu_AddItem( &s_controls.menu, &s_controls.framer ); - Menu_AddItem( &s_controls.menu, &s_controls.player ); - Menu_AddItem( &s_controls.menu, &s_controls.name ); - - Menu_AddItem( &s_controls.menu, &s_controls.looking ); - Menu_AddItem( &s_controls.menu, &s_controls.movement ); - Menu_AddItem( &s_controls.menu, &s_controls.weapons ); - Menu_AddItem( &s_controls.menu, &s_controls.misc ); - - Menu_AddItem( &s_controls.menu, &s_controls.sensitivity ); - Menu_AddItem( &s_controls.menu, &s_controls.smoothmouse ); - Menu_AddItem( &s_controls.menu, &s_controls.invertmouse ); - Menu_AddItem( &s_controls.menu, &s_controls.lookup ); - Menu_AddItem( &s_controls.menu, &s_controls.lookdown ); - Menu_AddItem( &s_controls.menu, &s_controls.mouselook ); - Menu_AddItem( &s_controls.menu, &s_controls.freelook ); - Menu_AddItem( &s_controls.menu, &s_controls.centerview ); - Menu_AddItem( &s_controls.menu, &s_controls.zoomview ); - Menu_AddItem( &s_controls.menu, &s_controls.joyenable ); - Menu_AddItem( &s_controls.menu, &s_controls.joythreshold ); - - Menu_AddItem( &s_controls.menu, &s_controls.alwaysrun ); - Menu_AddItem( &s_controls.menu, &s_controls.run ); - Menu_AddItem( &s_controls.menu, &s_controls.walkforward ); - Menu_AddItem( &s_controls.menu, &s_controls.backpedal ); - Menu_AddItem( &s_controls.menu, &s_controls.stepleft ); - Menu_AddItem( &s_controls.menu, &s_controls.stepright ); - Menu_AddItem( &s_controls.menu, &s_controls.moveup ); - Menu_AddItem( &s_controls.menu, &s_controls.movedown ); - Menu_AddItem( &s_controls.menu, &s_controls.turnleft ); - Menu_AddItem( &s_controls.menu, &s_controls.turnright ); - Menu_AddItem( &s_controls.menu, &s_controls.sidestep ); - - Menu_AddItem( &s_controls.menu, &s_controls.attack ); - Menu_AddItem( &s_controls.menu, &s_controls.nextweapon ); - Menu_AddItem( &s_controls.menu, &s_controls.prevweapon ); - Menu_AddItem( &s_controls.menu, &s_controls.autoswitch ); - Menu_AddItem( &s_controls.menu, &s_controls.chainsaw ); - Menu_AddItem( &s_controls.menu, &s_controls.machinegun ); - Menu_AddItem( &s_controls.menu, &s_controls.shotgun ); - Menu_AddItem( &s_controls.menu, &s_controls.grenadelauncher ); - Menu_AddItem( &s_controls.menu, &s_controls.rocketlauncher ); - Menu_AddItem( &s_controls.menu, &s_controls.lightning ); - Menu_AddItem( &s_controls.menu, &s_controls.railgun ); - Menu_AddItem( &s_controls.menu, &s_controls.plasma ); - Menu_AddItem( &s_controls.menu, &s_controls.bfg ); - - Menu_AddItem( &s_controls.menu, &s_controls.showscores ); - Menu_AddItem( &s_controls.menu, &s_controls.useitem ); - Menu_AddItem( &s_controls.menu, &s_controls.gesture ); - Menu_AddItem( &s_controls.menu, &s_controls.chat ); - Menu_AddItem( &s_controls.menu, &s_controls.chat2 ); - Menu_AddItem( &s_controls.menu, &s_controls.chat3 ); - Menu_AddItem( &s_controls.menu, &s_controls.chat4 ); - - Menu_AddItem( &s_controls.menu, &s_controls.back ); - - trap_Cvar_VariableStringBuffer( "name", s_controls.name.string, 16 ); - Q_CleanStr( s_controls.name.string ); - - // initialize the configurable cvars - Controls_InitCvars(); - - // initialize the current config - Controls_GetConfig(); - - // intialize the model - Controls_InitModel(); - - // intialize the weapons - Controls_InitWeapons (); - - // initial default section - s_controls.section = C_LOOKING; - - // update the ui - Controls_Update(); -} - - -/* -================= -Controls_Cache -================= -*/ -void Controls_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); -} - - -/* -================= -UI_ControlsMenu -================= -*/ -void UI_ControlsMenu( void ) { - Controls_MenuInit(); - UI_PushMenu( &s_controls.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +CONTROLS MENU + +======================================================================= +*/ + + +#include "ui_local.h" + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" + + +typedef struct { + char *command; + char *label; + int id; + int anim; + int defaultbind1; + int defaultbind2; + int bind1; + int bind2; +} bind_t; + +typedef struct +{ + char* name; + float defaultvalue; + float value; +} configcvar_t; + +#define SAVE_NOOP 0 +#define SAVE_YES 1 +#define SAVE_NO 2 +#define SAVE_CANCEL 3 + +// control sections +#define C_MOVEMENT 0 +#define C_LOOKING 1 +#define C_WEAPONS 2 +#define C_MISC 3 +#define C_MAX 4 + +#define ID_MOVEMENT 100 +#define ID_LOOKING 101 +#define ID_WEAPONS 102 +#define ID_MISC 103 +#define ID_DEFAULTS 104 +#define ID_BACK 105 +#define ID_SAVEANDEXIT 106 +#define ID_EXIT 107 + +// bindable actions +#define ID_SHOWSCORES 0 +#define ID_USEITEM 1 +#define ID_SPEED 2 +#define ID_FORWARD 3 +#define ID_BACKPEDAL 4 +#define ID_MOVELEFT 5 +#define ID_MOVERIGHT 6 +#define ID_MOVEUP 7 +#define ID_MOVEDOWN 8 +#define ID_LEFT 9 +#define ID_RIGHT 10 +#define ID_STRAFE 11 +#define ID_LOOKUP 12 +#define ID_LOOKDOWN 13 +#define ID_MOUSELOOK 14 +#define ID_CENTERVIEW 15 +#define ID_ZOOMVIEW 16 +#define ID_WEAPON1 17 +#define ID_WEAPON2 18 +#define ID_WEAPON3 19 +#define ID_WEAPON4 20 +#define ID_WEAPON5 21 +#define ID_WEAPON6 22 +#define ID_WEAPON7 23 +#define ID_WEAPON8 24 +#define ID_WEAPON9 25 +#define ID_ATTACK 26 +#define ID_WEAPPREV 27 +#define ID_WEAPNEXT 28 +#define ID_GESTURE 29 +#define ID_CHAT 30 +#define ID_CHAT2 31 +#define ID_CHAT3 32 +#define ID_CHAT4 33 + +// all others +#define ID_FREELOOK 34 +#define ID_INVERTMOUSE 35 +#define ID_ALWAYSRUN 36 +#define ID_AUTOSWITCH 37 +#define ID_MOUSESPEED 38 +#define ID_JOYENABLE 39 +#define ID_JOYTHRESHOLD 40 +#define ID_SMOOTHMOUSE 41 + +#define ANIM_IDLE 0 +#define ANIM_RUN 1 +#define ANIM_WALK 2 +#define ANIM_BACK 3 +#define ANIM_JUMP 4 +#define ANIM_CROUCH 5 +#define ANIM_STEPLEFT 6 +#define ANIM_STEPRIGHT 7 +#define ANIM_TURNLEFT 8 +#define ANIM_TURNRIGHT 9 +#define ANIM_LOOKUP 10 +#define ANIM_LOOKDOWN 11 +#define ANIM_WEAPON1 12 +#define ANIM_WEAPON2 13 +#define ANIM_WEAPON3 14 +#define ANIM_WEAPON4 15 +#define ANIM_WEAPON5 16 +#define ANIM_WEAPON6 17 +#define ANIM_WEAPON7 18 +#define ANIM_WEAPON8 19 +#define ANIM_WEAPON9 20 +#define ANIM_WEAPON10 21 +#define ANIM_ATTACK 22 +#define ANIM_GESTURE 23 +#define ANIM_DIE 24 +#define ANIM_CHAT 25 + +typedef struct +{ + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + menubitmap_s player; + + menutext_s movement; + menutext_s looking; + menutext_s weapons; + menutext_s misc; + + menuaction_s walkforward; + menuaction_s backpedal; + menuaction_s stepleft; + menuaction_s stepright; + menuaction_s moveup; + menuaction_s movedown; + menuaction_s turnleft; + menuaction_s turnright; + menuaction_s sidestep; + menuaction_s run; + menuaction_s machinegun; + menuaction_s chainsaw; + menuaction_s shotgun; + menuaction_s grenadelauncher; + menuaction_s rocketlauncher; + menuaction_s lightning; + menuaction_s railgun; + menuaction_s plasma; + menuaction_s bfg; + menuaction_s attack; + menuaction_s prevweapon; + menuaction_s nextweapon; + menuaction_s lookup; + menuaction_s lookdown; + menuaction_s mouselook; + menuradiobutton_s freelook; + menuaction_s centerview; + menuaction_s zoomview; + menuaction_s gesture; + menuradiobutton_s invertmouse; + menuslider_s sensitivity; + menuradiobutton_s smoothmouse; + menuradiobutton_s alwaysrun; + menuaction_s showscores; + menuradiobutton_s autoswitch; + menuaction_s useitem; + playerInfo_t playerinfo; + qboolean changesmade; + menuaction_s chat; + menuaction_s chat2; + menuaction_s chat3; + menuaction_s chat4; + menuradiobutton_s joyenable; + menuslider_s joythreshold; + int section; + qboolean waitingforkey; + char playerModel[64]; + vec3_t playerViewangles; + vec3_t playerMoveangles; + int playerLegs; + int playerTorso; + int playerWeapon; + qboolean playerChat; + + menubitmap_s back; + menutext_s name; +} controls_t; + +static controls_t s_controls; + +static vec4_t controls_binding_color = {1.00f, 0.43f, 0.00f, 1.00f}; // bk: Win32 C4305 + +static bind_t g_bindings[] = +{ + {"+scores", "show scores", ID_SHOWSCORES, ANIM_IDLE, K_TAB, -1, -1, -1}, + {"+button2", "use item", ID_USEITEM, ANIM_IDLE, K_ENTER, -1, -1, -1}, + {"+speed", "run / walk", ID_SPEED, ANIM_RUN, K_SHIFT, -1, -1, -1}, + {"+forward", "walk forward", ID_FORWARD, ANIM_WALK, K_UPARROW, -1, -1, -1}, + {"+back", "backpedal", ID_BACKPEDAL, ANIM_BACK, K_DOWNARROW, -1, -1, -1}, + {"+moveleft", "step left", ID_MOVELEFT, ANIM_STEPLEFT, ',', -1, -1, -1}, + {"+moveright", "step right", ID_MOVERIGHT, ANIM_STEPRIGHT, '.', -1, -1, -1}, + {"+moveup", "up / jump", ID_MOVEUP, ANIM_JUMP, K_SPACE, -1, -1, -1}, + {"+movedown", "down / crouch", ID_MOVEDOWN, ANIM_CROUCH, 'c', -1, -1, -1}, + {"+left", "turn left", ID_LEFT, ANIM_TURNLEFT, K_LEFTARROW, -1, -1, -1}, + {"+right", "turn right", ID_RIGHT, ANIM_TURNRIGHT, K_RIGHTARROW, -1, -1, -1}, + {"+strafe", "sidestep / turn", ID_STRAFE, ANIM_IDLE, K_ALT, -1, -1, -1}, + {"+lookup", "look up", ID_LOOKUP, ANIM_LOOKUP, K_PGDN, -1, -1, -1}, + {"+lookdown", "look down", ID_LOOKDOWN, ANIM_LOOKDOWN, K_DEL, -1, -1, -1}, + {"+mlook", "mouse look", ID_MOUSELOOK, ANIM_IDLE, '/', -1, -1, -1}, + {"centerview", "center view", ID_CENTERVIEW, ANIM_IDLE, K_END, -1, -1, -1}, + {"+zoom", "zoom view", ID_ZOOMVIEW, ANIM_IDLE, -1, -1, -1, -1}, + {"weapon 1", "gauntlet", ID_WEAPON1, ANIM_WEAPON1, '1', -1, -1, -1}, + {"weapon 2", "machinegun", ID_WEAPON2, ANIM_WEAPON2, '2', -1, -1, -1}, + {"weapon 3", "shotgun", ID_WEAPON3, ANIM_WEAPON3, '3', -1, -1, -1}, + {"weapon 4", "grenade launcher", ID_WEAPON4, ANIM_WEAPON4, '4', -1, -1, -1}, + {"weapon 5", "rocket launcher", ID_WEAPON5, ANIM_WEAPON5, '5', -1, -1, -1}, + {"weapon 6", "lightning", ID_WEAPON6, ANIM_WEAPON6, '6', -1, -1, -1}, + {"weapon 7", "railgun", ID_WEAPON7, ANIM_WEAPON7, '7', -1, -1, -1}, + {"weapon 8", "plasma gun", ID_WEAPON8, ANIM_WEAPON8, '8', -1, -1, -1}, + {"weapon 9", "BFG", ID_WEAPON9, ANIM_WEAPON9, '9', -1, -1, -1}, + {"+attack", "attack", ID_ATTACK, ANIM_ATTACK, K_CTRL, -1, -1, -1}, + {"weapprev", "prev weapon", ID_WEAPPREV, ANIM_IDLE, '[', -1, -1, -1}, + {"weapnext", "next weapon", ID_WEAPNEXT, ANIM_IDLE, ']', -1, -1, -1}, + {"+button3", "gesture", ID_GESTURE, ANIM_GESTURE, K_MOUSE3, -1, -1, -1}, + {"messagemode", "chat", ID_CHAT, ANIM_CHAT, 't', -1, -1, -1}, + {"messagemode2", "chat - team", ID_CHAT2, ANIM_CHAT, -1, -1, -1, -1}, + {"messagemode3", "chat - target", ID_CHAT3, ANIM_CHAT, -1, -1, -1, -1}, + {"messagemode4", "chat - attacker", ID_CHAT4, ANIM_CHAT, -1, -1, -1, -1}, + {(char*)NULL, (char*)NULL, 0, 0, -1, -1, -1, -1}, +}; + +static configcvar_t g_configcvars[] = +{ + {"cl_run", 0, 0}, + {"m_pitch", 0, 0}, + {"cg_autoswitch", 0, 0}, + {"sensitivity", 0, 0}, + {"in_joystick", 0, 0}, + {"joy_threshold", 0, 0}, + {"m_filter", 0, 0}, + {"cl_freelook", 0, 0}, + {NULL, 0, 0} +}; + +static menucommon_s *g_movement_controls[] = +{ + (menucommon_s *)&s_controls.alwaysrun, + (menucommon_s *)&s_controls.run, + (menucommon_s *)&s_controls.walkforward, + (menucommon_s *)&s_controls.backpedal, + (menucommon_s *)&s_controls.stepleft, + (menucommon_s *)&s_controls.stepright, + (menucommon_s *)&s_controls.moveup, + (menucommon_s *)&s_controls.movedown, + (menucommon_s *)&s_controls.turnleft, + (menucommon_s *)&s_controls.turnright, + (menucommon_s *)&s_controls.sidestep, + NULL +}; + +static menucommon_s *g_weapons_controls[] = { + (menucommon_s *)&s_controls.attack, + (menucommon_s *)&s_controls.nextweapon, + (menucommon_s *)&s_controls.prevweapon, + (menucommon_s *)&s_controls.autoswitch, + (menucommon_s *)&s_controls.chainsaw, + (menucommon_s *)&s_controls.machinegun, + (menucommon_s *)&s_controls.shotgun, + (menucommon_s *)&s_controls.grenadelauncher, + (menucommon_s *)&s_controls.rocketlauncher, + (menucommon_s *)&s_controls.lightning, + (menucommon_s *)&s_controls.railgun, + (menucommon_s *)&s_controls.plasma, + (menucommon_s *)&s_controls.bfg, + NULL, +}; + +static menucommon_s *g_looking_controls[] = { + (menucommon_s *)&s_controls.sensitivity, + (menucommon_s *)&s_controls.smoothmouse, + (menucommon_s *)&s_controls.invertmouse, + (menucommon_s *)&s_controls.lookup, + (menucommon_s *)&s_controls.lookdown, + (menucommon_s *)&s_controls.mouselook, + (menucommon_s *)&s_controls.freelook, + (menucommon_s *)&s_controls.centerview, + (menucommon_s *)&s_controls.zoomview, + (menucommon_s *)&s_controls.joyenable, + (menucommon_s *)&s_controls.joythreshold, + NULL, +}; + +static menucommon_s *g_misc_controls[] = { + (menucommon_s *)&s_controls.showscores, + (menucommon_s *)&s_controls.useitem, + (menucommon_s *)&s_controls.gesture, + (menucommon_s *)&s_controls.chat, + (menucommon_s *)&s_controls.chat2, + (menucommon_s *)&s_controls.chat3, + (menucommon_s *)&s_controls.chat4, + NULL, +}; + +static menucommon_s **g_controls[] = { + g_movement_controls, + g_looking_controls, + g_weapons_controls, + g_misc_controls, +}; + +/* +================= +Controls_InitCvars +================= +*/ +static void Controls_InitCvars( void ) +{ + int i; + configcvar_t* cvarptr; + + cvarptr = g_configcvars; + for (i=0; ;i++,cvarptr++) + { + if (!cvarptr->name) + break; + + // get current value + cvarptr->value = trap_Cvar_VariableValue( cvarptr->name ); + + // get default value + trap_Cvar_Reset( cvarptr->name ); + cvarptr->defaultvalue = trap_Cvar_VariableValue( cvarptr->name ); + + // restore current value + trap_Cvar_SetValue( cvarptr->name, cvarptr->value ); + } +} + +/* +================= +Controls_GetCvarDefault +================= +*/ +static float Controls_GetCvarDefault( char* name ) +{ + configcvar_t* cvarptr; + int i; + + cvarptr = g_configcvars; + for (i=0; ;i++,cvarptr++) + { + if (!cvarptr->name) + return (0); + + if (!strcmp(cvarptr->name,name)) + break; + } + + return (cvarptr->defaultvalue); +} + +/* +================= +Controls_GetCvarValue +================= +*/ +static float Controls_GetCvarValue( char* name ) +{ + configcvar_t* cvarptr; + int i; + + cvarptr = g_configcvars; + for (i=0; ;i++,cvarptr++) + { + if (!cvarptr->name) + return (0); + + if (!strcmp(cvarptr->name,name)) + break; + } + + return (cvarptr->value); +} + + +/* +================= +Controls_UpdateModel +================= +*/ +static void Controls_UpdateModel( int anim ) { + VectorClear( s_controls.playerViewangles ); + VectorClear( s_controls.playerMoveangles ); + s_controls.playerViewangles[YAW] = 180 - 30; + s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW]; + s_controls.playerLegs = LEGS_IDLE; + s_controls.playerTorso = TORSO_STAND; + s_controls.playerWeapon = -1; + s_controls.playerChat = qfalse; + + switch( anim ) { + case ANIM_RUN: + s_controls.playerLegs = LEGS_RUN; + break; + + case ANIM_WALK: + s_controls.playerLegs = LEGS_WALK; + break; + + case ANIM_BACK: + s_controls.playerLegs = LEGS_BACK; + break; + + case ANIM_JUMP: + s_controls.playerLegs = LEGS_JUMP; + break; + + case ANIM_CROUCH: + s_controls.playerLegs = LEGS_IDLECR; + break; + + case ANIM_TURNLEFT: + s_controls.playerViewangles[YAW] += 90; + break; + + case ANIM_TURNRIGHT: + s_controls.playerViewangles[YAW] -= 90; + break; + + case ANIM_STEPLEFT: + s_controls.playerLegs = LEGS_WALK; + s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] + 90; + break; + + case ANIM_STEPRIGHT: + s_controls.playerLegs = LEGS_WALK; + s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] - 90; + break; + + case ANIM_LOOKUP: + s_controls.playerViewangles[PITCH] = -45; + break; + + case ANIM_LOOKDOWN: + s_controls.playerViewangles[PITCH] = 45; + break; + + case ANIM_WEAPON1: + s_controls.playerWeapon = WP_GAUNTLET; + break; + + case ANIM_WEAPON2: + s_controls.playerWeapon = WP_MACHINEGUN; + break; + + case ANIM_WEAPON3: + s_controls.playerWeapon = WP_SHOTGUN; + break; + + case ANIM_WEAPON4: + s_controls.playerWeapon = WP_GRENADE_LAUNCHER; + break; + + case ANIM_WEAPON5: + s_controls.playerWeapon = WP_ROCKET_LAUNCHER; + break; + + case ANIM_WEAPON6: + s_controls.playerWeapon = WP_LIGHTNING; + break; + + case ANIM_WEAPON7: + s_controls.playerWeapon = WP_RAILGUN; + break; + + case ANIM_WEAPON8: + s_controls.playerWeapon = WP_PLASMAGUN; + break; + + case ANIM_WEAPON9: + s_controls.playerWeapon = WP_BFG; + break; + + case ANIM_WEAPON10: + s_controls.playerWeapon = WP_GRAPPLING_HOOK; + break; + + case ANIM_ATTACK: + s_controls.playerTorso = TORSO_ATTACK; + break; + + case ANIM_GESTURE: + s_controls.playerTorso = TORSO_GESTURE; + break; + + case ANIM_DIE: + s_controls.playerLegs = BOTH_DEATH1; + s_controls.playerTorso = BOTH_DEATH1; + s_controls.playerWeapon = WP_NONE; + break; + + case ANIM_CHAT: + s_controls.playerChat = qtrue; + break; + + default: + break; + } + + UI_PlayerInfo_SetInfo( &s_controls.playerinfo, s_controls.playerLegs, s_controls.playerTorso, s_controls.playerViewangles, s_controls.playerMoveangles, s_controls.playerWeapon, s_controls.playerChat ); +} + + +/* +================= +Controls_Update +================= +*/ +static void Controls_Update( void ) { + int i; + int j; + int y; + menucommon_s **controls; + menucommon_s *control; + + // disable all controls in all groups + for( i = 0; i < C_MAX; i++ ) { + controls = g_controls[i]; + // bk001204 - parentheses + for( j = 0; (control = controls[j]) ; j++ ) { + control->flags |= (QMF_HIDDEN|QMF_INACTIVE); + } + } + + controls = g_controls[s_controls.section]; + + // enable controls in active group (and count number of items for vertical centering) + // bk001204 - parentheses + for( j = 0; (control = controls[j]) ; j++ ) { + control->flags &= ~(QMF_GRAYED|QMF_HIDDEN|QMF_INACTIVE); + } + + // position controls + y = ( SCREEN_HEIGHT - j * SMALLCHAR_HEIGHT ) / 2; + // bk001204 - parentheses + for( j = 0; (control = controls[j]) ; j++, y += SMALLCHAR_HEIGHT ) { + control->x = 320; + control->y = y; + control->left = 320 - 19*SMALLCHAR_WIDTH; + control->right = 320 + 21*SMALLCHAR_WIDTH; + control->top = y; + control->bottom = y + SMALLCHAR_HEIGHT; + } + + if( s_controls.waitingforkey ) { + // disable everybody + for( i = 0; i < s_controls.menu.nitems; i++ ) { + ((menucommon_s*)(s_controls.menu.items[i]))->flags |= QMF_GRAYED; + } + + // enable action item + ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->flags &= ~QMF_GRAYED; + + // don't gray out player's name + s_controls.name.generic.flags &= ~QMF_GRAYED; + + return; + } + + // enable everybody + for( i = 0; i < s_controls.menu.nitems; i++ ) { + ((menucommon_s*)(s_controls.menu.items[i]))->flags &= ~QMF_GRAYED; + } + + // makes sure flags are right on the group selection controls + s_controls.looking.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + s_controls.movement.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + s_controls.weapons.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + s_controls.misc.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + + s_controls.looking.generic.flags |= QMF_PULSEIFFOCUS; + s_controls.movement.generic.flags |= QMF_PULSEIFFOCUS; + s_controls.weapons.generic.flags |= QMF_PULSEIFFOCUS; + s_controls.misc.generic.flags |= QMF_PULSEIFFOCUS; + + // set buttons + switch( s_controls.section ) { + case C_MOVEMENT: + s_controls.movement.generic.flags &= ~QMF_PULSEIFFOCUS; + s_controls.movement.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + break; + + case C_LOOKING: + s_controls.looking.generic.flags &= ~QMF_PULSEIFFOCUS; + s_controls.looking.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + break; + + case C_WEAPONS: + s_controls.weapons.generic.flags &= ~QMF_PULSEIFFOCUS; + s_controls.weapons.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + break; + + case C_MISC: + s_controls.misc.generic.flags &= ~QMF_PULSEIFFOCUS; + s_controls.misc.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS); + break; + } +} + + +/* +================= +Controls_DrawKeyBinding +================= +*/ +static void Controls_DrawKeyBinding( void *self ) +{ + menuaction_s* a; + int x; + int y; + int b1; + int b2; + qboolean c; + char name[32]; + char name2[32]; + + a = (menuaction_s*) self; + + x = a->generic.x; + y = a->generic.y; + + c = (Menu_ItemAtCursor( a->generic.parent ) == a); + + b1 = g_bindings[a->generic.id].bind1; + if (b1 == -1) + strcpy(name,"???"); + else + { + trap_Key_KeynumToStringBuf( b1, name, 32 ); + Q_strupr(name); + + b2 = g_bindings[a->generic.id].bind2; + if (b2 != -1) + { + trap_Key_KeynumToStringBuf( b2, name2, 32 ); + Q_strupr(name2); + + strcat( name, " or " ); + strcat( name, name2 ); + } + } + + if (c) + { + UI_FillRect( a->generic.left, a->generic.top, a->generic.right-a->generic.left+1, a->generic.bottom-a->generic.top+1, listbar_color ); + + UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_highlight ); + UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT|UI_PULSE, text_color_highlight ); + + if (s_controls.waitingforkey) + { + UI_DrawChar( x, y, '=', UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight); + UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Waiting for new key ... ESCAPE to cancel", UI_SMALLFONT|UI_CENTER|UI_PULSE, colorWhite ); + } + else + { + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight); + UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.78, "Press ENTER or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite ); + UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.82, "Press BACKSPACE to clear", UI_SMALLFONT|UI_CENTER, colorWhite ); + } + } + else + { + if (a->generic.flags & QMF_GRAYED) + { + UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_disabled ); + UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, text_color_disabled ); + } + else + { + UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, controls_binding_color ); + UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, controls_binding_color ); + } + } +} + +/* +================= +Controls_StatusBar +================= +*/ +static void Controls_StatusBar( void *self ) +{ + UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Use Arrow Keys or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite ); +} + + +/* +================= +Controls_DrawPlayer +================= +*/ +static void Controls_DrawPlayer( void *self ) { + menubitmap_s *b; + char buf[MAX_QPATH]; + + trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) ); + if ( strcmp( buf, s_controls.playerModel ) != 0 ) { + UI_PlayerInfo_SetModel( &s_controls.playerinfo, buf ); + strcpy( s_controls.playerModel, buf ); + Controls_UpdateModel( ANIM_IDLE ); + } + + b = (menubitmap_s*) self; + UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_controls.playerinfo, uis.realtime/2 ); +} + + +/* +================= +Controls_GetKeyAssignment +================= +*/ +static void Controls_GetKeyAssignment (char *command, int *twokeys) +{ + int count; + int j; + char b[256]; + + twokeys[0] = twokeys[1] = -1; + count = 0; + + for ( j = 0; j < 256; j++ ) + { + trap_Key_GetBindingBuf( j, b, 256 ); + if ( *b == 0 ) { + continue; + } + if ( !Q_stricmp( b, command ) ) { + twokeys[count] = j; + count++; + if (count == 2) + break; + } + } +} + +/* +================= +Controls_GetConfig +================= +*/ +static void Controls_GetConfig( void ) +{ + int i; + int twokeys[2]; + bind_t* bindptr; + + // put the bindings into a local store + bindptr = g_bindings; + + // iterate each command, get its numeric binding + for (i=0; ;i++,bindptr++) + { + if (!bindptr->label) + break; + + Controls_GetKeyAssignment(bindptr->command, twokeys); + + bindptr->bind1 = twokeys[0]; + bindptr->bind2 = twokeys[1]; + } + + s_controls.invertmouse.curvalue = Controls_GetCvarValue( "m_pitch" ) < 0; + s_controls.smoothmouse.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "m_filter" ) ); + s_controls.alwaysrun.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_run" ) ); + s_controls.autoswitch.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cg_autoswitch" ) ); + s_controls.sensitivity.curvalue = UI_ClampCvar( 2, 30, Controls_GetCvarValue( "sensitivity" ) ); + s_controls.joyenable.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "in_joystick" ) ); + s_controls.joythreshold.curvalue = UI_ClampCvar( 0.05f, 0.75f, Controls_GetCvarValue( "joy_threshold" ) ); + s_controls.freelook.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_freelook" ) ); +} + +/* +================= +Controls_SetConfig +================= +*/ +static void Controls_SetConfig( void ) +{ + int i; + bind_t* bindptr; + + // set the bindings from the local store + bindptr = g_bindings; + + // iterate each command, get its numeric binding + for (i=0; ;i++,bindptr++) + { + if (!bindptr->label) + break; + + if (bindptr->bind1 != -1) + { + trap_Key_SetBinding( bindptr->bind1, bindptr->command ); + + if (bindptr->bind2 != -1) + trap_Key_SetBinding( bindptr->bind2, bindptr->command ); + } + } + + if ( s_controls.invertmouse.curvalue ) + trap_Cvar_SetValue( "m_pitch", -fabs( trap_Cvar_VariableValue( "m_pitch" ) ) ); + else + trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) ); + + trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue ); + trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue ); + trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue ); + trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue ); + trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue ); + trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue ); + trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue ); + trap_Cmd_ExecuteText( EXEC_APPEND, "in_restart\n" ); +} + +/* +================= +Controls_SetDefaults +================= +*/ +static void Controls_SetDefaults( void ) +{ + int i; + bind_t* bindptr; + + // set the bindings from the local store + bindptr = g_bindings; + + // iterate each command, set its default binding + for (i=0; ;i++,bindptr++) + { + if (!bindptr->label) + break; + + bindptr->bind1 = bindptr->defaultbind1; + bindptr->bind2 = bindptr->defaultbind2; + } + + s_controls.invertmouse.curvalue = Controls_GetCvarDefault( "m_pitch" ) < 0; + s_controls.smoothmouse.curvalue = Controls_GetCvarDefault( "m_filter" ); + s_controls.alwaysrun.curvalue = Controls_GetCvarDefault( "cl_run" ); + s_controls.autoswitch.curvalue = Controls_GetCvarDefault( "cg_autoswitch" ); + s_controls.sensitivity.curvalue = Controls_GetCvarDefault( "sensitivity" ); + s_controls.joyenable.curvalue = Controls_GetCvarDefault( "in_joystick" ); + s_controls.joythreshold.curvalue = Controls_GetCvarDefault( "joy_threshold" ); + s_controls.freelook.curvalue = Controls_GetCvarDefault( "cl_freelook" ); +} + +/* +================= +Controls_MenuKey +================= +*/ +static sfxHandle_t Controls_MenuKey( int key ) +{ + int id; + int i; + qboolean found; + bind_t* bindptr; + found = qfalse; + + if (!s_controls.waitingforkey) + { + switch (key) + { + case K_BACKSPACE: + case K_DEL: + case K_KP_DEL: + key = -1; + break; + + case K_MOUSE2: + case K_ESCAPE: + if (s_controls.changesmade) + Controls_SetConfig(); + goto ignorekey; + + default: + goto ignorekey; + } + } + else + { + if (key & K_CHAR_FLAG) + goto ignorekey; + + switch (key) + { + case K_ESCAPE: + s_controls.waitingforkey = qfalse; + Controls_Update(); + return (menu_out_sound); + + case '`': + goto ignorekey; + } + } + + s_controls.changesmade = qtrue; + + if (key != -1) + { + // remove from any other bind + bindptr = g_bindings; + for (i=0; ;i++,bindptr++) + { + if (!bindptr->label) + break; + + if (bindptr->bind2 == key) + bindptr->bind2 = -1; + + if (bindptr->bind1 == key) + { + bindptr->bind1 = bindptr->bind2; + bindptr->bind2 = -1; + } + } + } + + // assign key to local store + id = ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->id; + bindptr = g_bindings; + for (i=0; ;i++,bindptr++) + { + if (!bindptr->label) + break; + + if (bindptr->id == id) + { + found = qtrue; + if (key == -1) + { + if( bindptr->bind1 != -1 ) { + trap_Key_SetBinding( bindptr->bind1, "" ); + bindptr->bind1 = -1; + } + if( bindptr->bind2 != -1 ) { + trap_Key_SetBinding( bindptr->bind2, "" ); + bindptr->bind2 = -1; + } + } + else if (bindptr->bind1 == -1) { + bindptr->bind1 = key; + } + else if (bindptr->bind1 != key && bindptr->bind2 == -1) { + bindptr->bind2 = key; + } + else + { + trap_Key_SetBinding( bindptr->bind1, "" ); + trap_Key_SetBinding( bindptr->bind2, "" ); + bindptr->bind1 = key; + bindptr->bind2 = -1; + } + break; + } + } + + s_controls.waitingforkey = qfalse; + + if (found) + { + Controls_Update(); + return (menu_out_sound); + } + +ignorekey: + return Menu_DefaultKey( &s_controls.menu, key ); +} + +/* +================= +Controls_ResetDefaults_Action +================= +*/ +static void Controls_ResetDefaults_Action( qboolean result ) { + if( !result ) { + return; + } + + s_controls.changesmade = qtrue; + Controls_SetDefaults(); + Controls_Update(); +} + +/* +================= +Controls_ResetDefaults_Draw +================= +*/ +static void Controls_ResetDefaults_Draw( void ) { + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This will reset all", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "controls to their default values.", UI_CENTER|UI_SMALLFONT, color_yellow ); +} + +/* +================= +Controls_MenuEvent +================= +*/ +static void Controls_MenuEvent( void* ptr, int event ) +{ + switch (((menucommon_s*)ptr)->id) + { + case ID_MOVEMENT: + if (event == QM_ACTIVATED) + { + s_controls.section = C_MOVEMENT; + Controls_Update(); + } + break; + + case ID_LOOKING: + if (event == QM_ACTIVATED) + { + s_controls.section = C_LOOKING; + Controls_Update(); + } + break; + + case ID_WEAPONS: + if (event == QM_ACTIVATED) + { + s_controls.section = C_WEAPONS; + Controls_Update(); + } + break; + + case ID_MISC: + if (event == QM_ACTIVATED) + { + s_controls.section = C_MISC; + Controls_Update(); + } + break; + + case ID_DEFAULTS: + if (event == QM_ACTIVATED) + { + UI_ConfirmMenu( "SET TO DEFAULTS?", Controls_ResetDefaults_Draw, Controls_ResetDefaults_Action ); + } + break; + + case ID_BACK: + if (event == QM_ACTIVATED) + { + if (s_controls.changesmade) + Controls_SetConfig(); + UI_PopMenu(); + } + break; + + case ID_SAVEANDEXIT: + if (event == QM_ACTIVATED) + { + Controls_SetConfig(); + UI_PopMenu(); + } + break; + + case ID_EXIT: + if (event == QM_ACTIVATED) + { + UI_PopMenu(); + } + break; + + case ID_FREELOOK: + case ID_MOUSESPEED: + case ID_INVERTMOUSE: + case ID_SMOOTHMOUSE: + case ID_ALWAYSRUN: + case ID_AUTOSWITCH: + case ID_JOYENABLE: + case ID_JOYTHRESHOLD: + if (event == QM_ACTIVATED) + { + s_controls.changesmade = qtrue; + } + break; + } +} + +/* +================= +Controls_ActionEvent +================= +*/ +static void Controls_ActionEvent( void* ptr, int event ) +{ + if (event == QM_LOSTFOCUS) + { + Controls_UpdateModel( ANIM_IDLE ); + } + else if (event == QM_GOTFOCUS) + { + Controls_UpdateModel( g_bindings[((menucommon_s*)ptr)->id].anim ); + } + else if ((event == QM_ACTIVATED) && !s_controls.waitingforkey) + { + s_controls.waitingforkey = 1; + Controls_Update(); + } +} + +/* +================= +Controls_InitModel +================= +*/ +static void Controls_InitModel( void ) +{ + memset( &s_controls.playerinfo, 0, sizeof(playerInfo_t) ); + + UI_PlayerInfo_SetModel( &s_controls.playerinfo, UI_Cvar_VariableString( "model" ) ); + + Controls_UpdateModel( ANIM_IDLE ); +} + +/* +================= +Controls_InitWeapons +================= +*/ +static void Controls_InitWeapons( void ) { + gitem_t * item; + + for ( item = bg_itemlist + 1 ; item->classname ; item++ ) { + if ( item->giType != IT_WEAPON ) { + continue; + } + trap_R_RegisterModel( item->world_model[0] ); + } +} + +/* +================= +Controls_MenuInit +================= +*/ +static void Controls_MenuInit( void ) +{ + static char playername[32]; + + // zero set all our globals + memset( &s_controls, 0 ,sizeof(controls_t) ); + + Controls_Cache(); + + s_controls.menu.key = Controls_MenuKey; + s_controls.menu.wrapAround = qtrue; + s_controls.menu.fullscreen = qtrue; + + s_controls.banner.generic.type = MTYPE_BTEXT; + s_controls.banner.generic.flags = QMF_CENTER_JUSTIFY; + s_controls.banner.generic.x = 320; + s_controls.banner.generic.y = 16; + s_controls.banner.string = "CONTROLS"; + s_controls.banner.color = color_white; + s_controls.banner.style = UI_CENTER; + + s_controls.framel.generic.type = MTYPE_BITMAP; + s_controls.framel.generic.name = ART_FRAMEL; + s_controls.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_controls.framel.generic.x = 0; + s_controls.framel.generic.y = 78; + s_controls.framel.width = 256; + s_controls.framel.height = 329; + + s_controls.framer.generic.type = MTYPE_BITMAP; + s_controls.framer.generic.name = ART_FRAMER; + s_controls.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_controls.framer.generic.x = 376; + s_controls.framer.generic.y = 76; + s_controls.framer.width = 256; + s_controls.framer.height = 334; + + s_controls.looking.generic.type = MTYPE_PTEXT; + s_controls.looking.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_controls.looking.generic.id = ID_LOOKING; + s_controls.looking.generic.callback = Controls_MenuEvent; + s_controls.looking.generic.x = 152; + s_controls.looking.generic.y = 240 - 2 * PROP_HEIGHT; + s_controls.looking.string = "LOOK"; + s_controls.looking.style = UI_RIGHT; + s_controls.looking.color = color_red; + + s_controls.movement.generic.type = MTYPE_PTEXT; + s_controls.movement.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_controls.movement.generic.id = ID_MOVEMENT; + s_controls.movement.generic.callback = Controls_MenuEvent; + s_controls.movement.generic.x = 152; + s_controls.movement.generic.y = 240 - PROP_HEIGHT; + s_controls.movement.string = "MOVE"; + s_controls.movement.style = UI_RIGHT; + s_controls.movement.color = color_red; + + s_controls.weapons.generic.type = MTYPE_PTEXT; + s_controls.weapons.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_controls.weapons.generic.id = ID_WEAPONS; + s_controls.weapons.generic.callback = Controls_MenuEvent; + s_controls.weapons.generic.x = 152; + s_controls.weapons.generic.y = 240; + s_controls.weapons.string = "SHOOT"; + s_controls.weapons.style = UI_RIGHT; + s_controls.weapons.color = color_red; + + s_controls.misc.generic.type = MTYPE_PTEXT; + s_controls.misc.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_controls.misc.generic.id = ID_MISC; + s_controls.misc.generic.callback = Controls_MenuEvent; + s_controls.misc.generic.x = 152; + s_controls.misc.generic.y = 240 + PROP_HEIGHT; + s_controls.misc.string = "MISC"; + s_controls.misc.style = UI_RIGHT; + s_controls.misc.color = color_red; + + s_controls.back.generic.type = MTYPE_BITMAP; + s_controls.back.generic.name = ART_BACK0; + s_controls.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_controls.back.generic.x = 0; + s_controls.back.generic.y = 480-64; + s_controls.back.generic.id = ID_BACK; + s_controls.back.generic.callback = Controls_MenuEvent; + s_controls.back.width = 128; + s_controls.back.height = 64; + s_controls.back.focuspic = ART_BACK1; + + s_controls.player.generic.type = MTYPE_BITMAP; + s_controls.player.generic.flags = QMF_INACTIVE; + s_controls.player.generic.ownerdraw = Controls_DrawPlayer; + s_controls.player.generic.x = 400; + s_controls.player.generic.y = -40; + s_controls.player.width = 32*10; + s_controls.player.height = 56*10; + + s_controls.walkforward.generic.type = MTYPE_ACTION; + s_controls.walkforward.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.walkforward.generic.callback = Controls_ActionEvent; + s_controls.walkforward.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.walkforward.generic.id = ID_FORWARD; + + s_controls.backpedal.generic.type = MTYPE_ACTION; + s_controls.backpedal.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.backpedal.generic.callback = Controls_ActionEvent; + s_controls.backpedal.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.backpedal.generic.id = ID_BACKPEDAL; + + s_controls.stepleft.generic.type = MTYPE_ACTION; + s_controls.stepleft.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.stepleft.generic.callback = Controls_ActionEvent; + s_controls.stepleft.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.stepleft.generic.id = ID_MOVELEFT; + + s_controls.stepright.generic.type = MTYPE_ACTION; + s_controls.stepright.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.stepright.generic.callback = Controls_ActionEvent; + s_controls.stepright.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.stepright.generic.id = ID_MOVERIGHT; + + s_controls.moveup.generic.type = MTYPE_ACTION; + s_controls.moveup.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.moveup.generic.callback = Controls_ActionEvent; + s_controls.moveup.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.moveup.generic.id = ID_MOVEUP; + + s_controls.movedown.generic.type = MTYPE_ACTION; + s_controls.movedown.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.movedown.generic.callback = Controls_ActionEvent; + s_controls.movedown.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.movedown.generic.id = ID_MOVEDOWN; + + s_controls.turnleft.generic.type = MTYPE_ACTION; + s_controls.turnleft.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.turnleft.generic.callback = Controls_ActionEvent; + s_controls.turnleft.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.turnleft.generic.id = ID_LEFT; + + s_controls.turnright.generic.type = MTYPE_ACTION; + s_controls.turnright.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.turnright.generic.callback = Controls_ActionEvent; + s_controls.turnright.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.turnright.generic.id = ID_RIGHT; + + s_controls.sidestep.generic.type = MTYPE_ACTION; + s_controls.sidestep.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.sidestep.generic.callback = Controls_ActionEvent; + s_controls.sidestep.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.sidestep.generic.id = ID_STRAFE; + + s_controls.run.generic.type = MTYPE_ACTION; + s_controls.run.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.run.generic.callback = Controls_ActionEvent; + s_controls.run.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.run.generic.id = ID_SPEED; + + s_controls.chainsaw.generic.type = MTYPE_ACTION; + s_controls.chainsaw.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.chainsaw.generic.callback = Controls_ActionEvent; + s_controls.chainsaw.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.chainsaw.generic.id = ID_WEAPON1; + + s_controls.machinegun.generic.type = MTYPE_ACTION; + s_controls.machinegun.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.machinegun.generic.callback = Controls_ActionEvent; + s_controls.machinegun.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.machinegun.generic.id = ID_WEAPON2; + + s_controls.shotgun.generic.type = MTYPE_ACTION; + s_controls.shotgun.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.shotgun.generic.callback = Controls_ActionEvent; + s_controls.shotgun.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.shotgun.generic.id = ID_WEAPON3; + + s_controls.grenadelauncher.generic.type = MTYPE_ACTION; + s_controls.grenadelauncher.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.grenadelauncher.generic.callback = Controls_ActionEvent; + s_controls.grenadelauncher.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.grenadelauncher.generic.id = ID_WEAPON4; + + s_controls.rocketlauncher.generic.type = MTYPE_ACTION; + s_controls.rocketlauncher.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.rocketlauncher.generic.callback = Controls_ActionEvent; + s_controls.rocketlauncher.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.rocketlauncher.generic.id = ID_WEAPON5; + + s_controls.lightning.generic.type = MTYPE_ACTION; + s_controls.lightning.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.lightning.generic.callback = Controls_ActionEvent; + s_controls.lightning.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.lightning.generic.id = ID_WEAPON6; + + s_controls.railgun.generic.type = MTYPE_ACTION; + s_controls.railgun.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.railgun.generic.callback = Controls_ActionEvent; + s_controls.railgun.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.railgun.generic.id = ID_WEAPON7; + + s_controls.plasma.generic.type = MTYPE_ACTION; + s_controls.plasma.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.plasma.generic.callback = Controls_ActionEvent; + s_controls.plasma.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.plasma.generic.id = ID_WEAPON8; + + s_controls.bfg.generic.type = MTYPE_ACTION; + s_controls.bfg.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.bfg.generic.callback = Controls_ActionEvent; + s_controls.bfg.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.bfg.generic.id = ID_WEAPON9; + + s_controls.attack.generic.type = MTYPE_ACTION; + s_controls.attack.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.attack.generic.callback = Controls_ActionEvent; + s_controls.attack.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.attack.generic.id = ID_ATTACK; + + s_controls.prevweapon.generic.type = MTYPE_ACTION; + s_controls.prevweapon.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.prevweapon.generic.callback = Controls_ActionEvent; + s_controls.prevweapon.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.prevweapon.generic.id = ID_WEAPPREV; + + s_controls.nextweapon.generic.type = MTYPE_ACTION; + s_controls.nextweapon.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.nextweapon.generic.callback = Controls_ActionEvent; + s_controls.nextweapon.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.nextweapon.generic.id = ID_WEAPNEXT; + + s_controls.lookup.generic.type = MTYPE_ACTION; + s_controls.lookup.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.lookup.generic.callback = Controls_ActionEvent; + s_controls.lookup.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.lookup.generic.id = ID_LOOKUP; + + s_controls.lookdown.generic.type = MTYPE_ACTION; + s_controls.lookdown.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.lookdown.generic.callback = Controls_ActionEvent; + s_controls.lookdown.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.lookdown.generic.id = ID_LOOKDOWN; + + s_controls.mouselook.generic.type = MTYPE_ACTION; + s_controls.mouselook.generic.flags = QMF_LEFT_JUSTIFY|QMF_HIGHLIGHT_IF_FOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.mouselook.generic.callback = Controls_ActionEvent; + s_controls.mouselook.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.mouselook.generic.id = ID_MOUSELOOK; + + s_controls.freelook.generic.type = MTYPE_RADIOBUTTON; + s_controls.freelook.generic.flags = QMF_SMALLFONT; + s_controls.freelook.generic.x = SCREEN_WIDTH/2; + s_controls.freelook.generic.name = "free look"; + s_controls.freelook.generic.id = ID_FREELOOK; + s_controls.freelook.generic.callback = Controls_MenuEvent; + s_controls.freelook.generic.statusbar = Controls_StatusBar; + + s_controls.centerview.generic.type = MTYPE_ACTION; + s_controls.centerview.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.centerview.generic.callback = Controls_ActionEvent; + s_controls.centerview.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.centerview.generic.id = ID_CENTERVIEW; + + s_controls.zoomview.generic.type = MTYPE_ACTION; + s_controls.zoomview.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.zoomview.generic.callback = Controls_ActionEvent; + s_controls.zoomview.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.zoomview.generic.id = ID_ZOOMVIEW; + + s_controls.useitem.generic.type = MTYPE_ACTION; + s_controls.useitem.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.useitem.generic.callback = Controls_ActionEvent; + s_controls.useitem.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.useitem.generic.id = ID_USEITEM; + + s_controls.showscores.generic.type = MTYPE_ACTION; + s_controls.showscores.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.showscores.generic.callback = Controls_ActionEvent; + s_controls.showscores.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.showscores.generic.id = ID_SHOWSCORES; + + s_controls.invertmouse.generic.type = MTYPE_RADIOBUTTON; + s_controls.invertmouse.generic.flags = QMF_SMALLFONT; + s_controls.invertmouse.generic.x = SCREEN_WIDTH/2; + s_controls.invertmouse.generic.name = "invert mouse"; + s_controls.invertmouse.generic.id = ID_INVERTMOUSE; + s_controls.invertmouse.generic.callback = Controls_MenuEvent; + s_controls.invertmouse.generic.statusbar = Controls_StatusBar; + + s_controls.smoothmouse.generic.type = MTYPE_RADIOBUTTON; + s_controls.smoothmouse.generic.flags = QMF_SMALLFONT; + s_controls.smoothmouse.generic.x = SCREEN_WIDTH/2; + s_controls.smoothmouse.generic.name = "smooth mouse"; + s_controls.smoothmouse.generic.id = ID_SMOOTHMOUSE; + s_controls.smoothmouse.generic.callback = Controls_MenuEvent; + s_controls.smoothmouse.generic.statusbar = Controls_StatusBar; + + s_controls.alwaysrun.generic.type = MTYPE_RADIOBUTTON; + s_controls.alwaysrun.generic.flags = QMF_SMALLFONT; + s_controls.alwaysrun.generic.x = SCREEN_WIDTH/2; + s_controls.alwaysrun.generic.name = "always run"; + s_controls.alwaysrun.generic.id = ID_ALWAYSRUN; + s_controls.alwaysrun.generic.callback = Controls_MenuEvent; + s_controls.alwaysrun.generic.statusbar = Controls_StatusBar; + + s_controls.autoswitch.generic.type = MTYPE_RADIOBUTTON; + s_controls.autoswitch.generic.flags = QMF_SMALLFONT; + s_controls.autoswitch.generic.x = SCREEN_WIDTH/2; + s_controls.autoswitch.generic.name = "autoswitch weapons"; + s_controls.autoswitch.generic.id = ID_AUTOSWITCH; + s_controls.autoswitch.generic.callback = Controls_MenuEvent; + s_controls.autoswitch.generic.statusbar = Controls_StatusBar; + + s_controls.sensitivity.generic.type = MTYPE_SLIDER; + s_controls.sensitivity.generic.x = SCREEN_WIDTH/2; + s_controls.sensitivity.generic.flags = QMF_SMALLFONT; + s_controls.sensitivity.generic.name = "mouse speed"; + s_controls.sensitivity.generic.id = ID_MOUSESPEED; + s_controls.sensitivity.generic.callback = Controls_MenuEvent; + s_controls.sensitivity.minvalue = 2; + s_controls.sensitivity.maxvalue = 30; + s_controls.sensitivity.generic.statusbar = Controls_StatusBar; + + s_controls.gesture.generic.type = MTYPE_ACTION; + s_controls.gesture.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.gesture.generic.callback = Controls_ActionEvent; + s_controls.gesture.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.gesture.generic.id = ID_GESTURE; + + s_controls.chat.generic.type = MTYPE_ACTION; + s_controls.chat.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.chat.generic.callback = Controls_ActionEvent; + s_controls.chat.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.chat.generic.id = ID_CHAT; + + s_controls.chat2.generic.type = MTYPE_ACTION; + s_controls.chat2.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.chat2.generic.callback = Controls_ActionEvent; + s_controls.chat2.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.chat2.generic.id = ID_CHAT2; + + s_controls.chat3.generic.type = MTYPE_ACTION; + s_controls.chat3.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.chat3.generic.callback = Controls_ActionEvent; + s_controls.chat3.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.chat3.generic.id = ID_CHAT3; + + s_controls.chat4.generic.type = MTYPE_ACTION; + s_controls.chat4.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN; + s_controls.chat4.generic.callback = Controls_ActionEvent; + s_controls.chat4.generic.ownerdraw = Controls_DrawKeyBinding; + s_controls.chat4.generic.id = ID_CHAT4; + + s_controls.joyenable.generic.type = MTYPE_RADIOBUTTON; + s_controls.joyenable.generic.flags = QMF_SMALLFONT; + s_controls.joyenable.generic.x = SCREEN_WIDTH/2; + s_controls.joyenable.generic.name = "joystick"; + s_controls.joyenable.generic.id = ID_JOYENABLE; + s_controls.joyenable.generic.callback = Controls_MenuEvent; + s_controls.joyenable.generic.statusbar = Controls_StatusBar; + + s_controls.joythreshold.generic.type = MTYPE_SLIDER; + s_controls.joythreshold.generic.x = SCREEN_WIDTH/2; + s_controls.joythreshold.generic.flags = QMF_SMALLFONT; + s_controls.joythreshold.generic.name = "joystick threshold"; + s_controls.joythreshold.generic.id = ID_JOYTHRESHOLD; + s_controls.joythreshold.generic.callback = Controls_MenuEvent; + s_controls.joythreshold.minvalue = 0.05f; + s_controls.joythreshold.maxvalue = 0.75f; + s_controls.joythreshold.generic.statusbar = Controls_StatusBar; + + s_controls.name.generic.type = MTYPE_PTEXT; + s_controls.name.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE; + s_controls.name.generic.x = 320; + s_controls.name.generic.y = 440; + s_controls.name.string = playername; + s_controls.name.style = UI_CENTER; + s_controls.name.color = text_color_normal; + + Menu_AddItem( &s_controls.menu, &s_controls.banner ); + Menu_AddItem( &s_controls.menu, &s_controls.framel ); + Menu_AddItem( &s_controls.menu, &s_controls.framer ); + Menu_AddItem( &s_controls.menu, &s_controls.player ); + Menu_AddItem( &s_controls.menu, &s_controls.name ); + + Menu_AddItem( &s_controls.menu, &s_controls.looking ); + Menu_AddItem( &s_controls.menu, &s_controls.movement ); + Menu_AddItem( &s_controls.menu, &s_controls.weapons ); + Menu_AddItem( &s_controls.menu, &s_controls.misc ); + + Menu_AddItem( &s_controls.menu, &s_controls.sensitivity ); + Menu_AddItem( &s_controls.menu, &s_controls.smoothmouse ); + Menu_AddItem( &s_controls.menu, &s_controls.invertmouse ); + Menu_AddItem( &s_controls.menu, &s_controls.lookup ); + Menu_AddItem( &s_controls.menu, &s_controls.lookdown ); + Menu_AddItem( &s_controls.menu, &s_controls.mouselook ); + Menu_AddItem( &s_controls.menu, &s_controls.freelook ); + Menu_AddItem( &s_controls.menu, &s_controls.centerview ); + Menu_AddItem( &s_controls.menu, &s_controls.zoomview ); + Menu_AddItem( &s_controls.menu, &s_controls.joyenable ); + Menu_AddItem( &s_controls.menu, &s_controls.joythreshold ); + + Menu_AddItem( &s_controls.menu, &s_controls.alwaysrun ); + Menu_AddItem( &s_controls.menu, &s_controls.run ); + Menu_AddItem( &s_controls.menu, &s_controls.walkforward ); + Menu_AddItem( &s_controls.menu, &s_controls.backpedal ); + Menu_AddItem( &s_controls.menu, &s_controls.stepleft ); + Menu_AddItem( &s_controls.menu, &s_controls.stepright ); + Menu_AddItem( &s_controls.menu, &s_controls.moveup ); + Menu_AddItem( &s_controls.menu, &s_controls.movedown ); + Menu_AddItem( &s_controls.menu, &s_controls.turnleft ); + Menu_AddItem( &s_controls.menu, &s_controls.turnright ); + Menu_AddItem( &s_controls.menu, &s_controls.sidestep ); + + Menu_AddItem( &s_controls.menu, &s_controls.attack ); + Menu_AddItem( &s_controls.menu, &s_controls.nextweapon ); + Menu_AddItem( &s_controls.menu, &s_controls.prevweapon ); + Menu_AddItem( &s_controls.menu, &s_controls.autoswitch ); + Menu_AddItem( &s_controls.menu, &s_controls.chainsaw ); + Menu_AddItem( &s_controls.menu, &s_controls.machinegun ); + Menu_AddItem( &s_controls.menu, &s_controls.shotgun ); + Menu_AddItem( &s_controls.menu, &s_controls.grenadelauncher ); + Menu_AddItem( &s_controls.menu, &s_controls.rocketlauncher ); + Menu_AddItem( &s_controls.menu, &s_controls.lightning ); + Menu_AddItem( &s_controls.menu, &s_controls.railgun ); + Menu_AddItem( &s_controls.menu, &s_controls.plasma ); + Menu_AddItem( &s_controls.menu, &s_controls.bfg ); + + Menu_AddItem( &s_controls.menu, &s_controls.showscores ); + Menu_AddItem( &s_controls.menu, &s_controls.useitem ); + Menu_AddItem( &s_controls.menu, &s_controls.gesture ); + Menu_AddItem( &s_controls.menu, &s_controls.chat ); + Menu_AddItem( &s_controls.menu, &s_controls.chat2 ); + Menu_AddItem( &s_controls.menu, &s_controls.chat3 ); + Menu_AddItem( &s_controls.menu, &s_controls.chat4 ); + + Menu_AddItem( &s_controls.menu, &s_controls.back ); + + trap_Cvar_VariableStringBuffer( "name", s_controls.name.string, 16 ); + Q_CleanStr( s_controls.name.string ); + + // initialize the configurable cvars + Controls_InitCvars(); + + // initialize the current config + Controls_GetConfig(); + + // intialize the model + Controls_InitModel(); + + // intialize the weapons + Controls_InitWeapons (); + + // initial default section + s_controls.section = C_LOOKING; + + // update the ui + Controls_Update(); +} + + +/* +================= +Controls_Cache +================= +*/ +void Controls_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); +} + + +/* +================= +UI_ControlsMenu +================= +*/ +void UI_ControlsMenu( void ) { + Controls_MenuInit(); + UI_PushMenu( &s_controls.menu ); +} diff --git a/code/q3_ui/ui_credits.c b/code/q3_ui/ui_credits.c index 266e00b..acb482b 100755 --- a/code/q3_ui/ui_credits.c +++ b/code/q3_ui/ui_credits.c @@ -1,129 +1,129 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -CREDITS - -======================================================================= -*/ - - -#include "ui_local.h" - - -typedef struct { - menuframework_s menu; -} creditsmenu_t; - -static creditsmenu_t s_credits; - - -/* -================= -UI_CreditMenu_Key -================= -*/ -static sfxHandle_t UI_CreditMenu_Key( int key ) { - if( key & K_CHAR_FLAG ) { - return 0; - } - - trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" ); - return 0; -} - - -/* -=============== -UI_CreditMenu_Draw -=============== -*/ -static void UI_CreditMenu_Draw( void ) { - int y; - - y = 12; - UI_DrawProportionalString( 320, y, "id Software is:", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Programming", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "John Carmack, Robert A. Duffy, Jim Dose'", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Art", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Adrian Carmack, Kevin Cloud,", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Kenneth Scott, Seneca Menard, Fred Nilsson", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Game Designer", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Graeme Devine", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Level Design", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Tim Willits, Christian Antkow, Paul Jaquays", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "CEO", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Todd Hollenshead", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Director of Business Development", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Marty Stratton", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Biz Assist and id Mom", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Donna Jackson", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Development Assistance", UI_CENTER|UI_SMALLFONT, color_white ); - y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawProportionalString( 320, y, "Eric Webb", UI_CENTER|UI_SMALLFONT, color_white ); - - y += 1.35 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; - UI_DrawString( 320, y, "To order: 1-800-idgames www.quake3arena.com www.idsoftware.com", UI_CENTER|UI_SMALLFONT, color_red ); - y += SMALLCHAR_HEIGHT; - UI_DrawString( 320, y, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color_red ); -} - - -/* -=============== -UI_CreditMenu -=============== -*/ -void UI_CreditMenu( void ) { - memset( &s_credits, 0 ,sizeof(s_credits) ); - - s_credits.menu.draw = UI_CreditMenu_Draw; - s_credits.menu.key = UI_CreditMenu_Key; - s_credits.menu.fullscreen = qtrue; - UI_PushMenu ( &s_credits.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +CREDITS + +======================================================================= +*/ + + +#include "ui_local.h" + + +typedef struct { + menuframework_s menu; +} creditsmenu_t; + +static creditsmenu_t s_credits; + + +/* +================= +UI_CreditMenu_Key +================= +*/ +static sfxHandle_t UI_CreditMenu_Key( int key ) { + if( key & K_CHAR_FLAG ) { + return 0; + } + + trap_Cmd_ExecuteText( EXEC_APPEND, "quit\n" ); + return 0; +} + + +/* +=============== +UI_CreditMenu_Draw +=============== +*/ +static void UI_CreditMenu_Draw( void ) { + int y; + + y = 12; + UI_DrawProportionalString( 320, y, "id Software is:", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Programming", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "John Carmack, Robert A. Duffy, Jim Dose'", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Art", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Adrian Carmack, Kevin Cloud,", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Kenneth Scott, Seneca Menard, Fred Nilsson", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Game Designer", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Graeme Devine", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Level Design", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Tim Willits, Christian Antkow, Paul Jaquays", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "CEO", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Todd Hollenshead", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Director of Business Development", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Marty Stratton", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Biz Assist and id Mom", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Donna Jackson", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.42 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Development Assistance", UI_CENTER|UI_SMALLFONT, color_white ); + y += PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawProportionalString( 320, y, "Eric Webb", UI_CENTER|UI_SMALLFONT, color_white ); + + y += 1.35 * PROP_HEIGHT * PROP_SMALL_SIZE_SCALE; + UI_DrawString( 320, y, "To order: 1-800-idgames www.quake3arena.com www.idsoftware.com", UI_CENTER|UI_SMALLFONT, color_red ); + y += SMALLCHAR_HEIGHT; + UI_DrawString( 320, y, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color_red ); +} + + +/* +=============== +UI_CreditMenu +=============== +*/ +void UI_CreditMenu( void ) { + memset( &s_credits, 0 ,sizeof(s_credits) ); + + s_credits.menu.draw = UI_CreditMenu_Draw; + s_credits.menu.key = UI_CreditMenu_Key; + s_credits.menu.fullscreen = qtrue; + UI_PushMenu ( &s_credits.menu ); +} diff --git a/code/q3_ui/ui_demo2.c b/code/q3_ui/ui_demo2.c index 57b5955..f6f6f66 100755 --- a/code/q3_ui/ui_demo2.c +++ b/code/q3_ui/ui_demo2.c @@ -1,291 +1,291 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -DEMOS MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_GO0 "menu/art/play_0" -#define ART_GO1 "menu/art/play_1" -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_ARROWS "menu/art/arrows_horz_0" -#define ART_ARROWLEFT "menu/art/arrows_horz_left" -#define ART_ARROWRIGHT "menu/art/arrows_horz_right" - -#define MAX_DEMOS 128 -#define NAMEBUFSIZE ( MAX_DEMOS * 16 ) - -#define ID_BACK 10 -#define ID_GO 11 -#define ID_LIST 12 -#define ID_RIGHT 13 -#define ID_LEFT 14 - -#define ARROWS_WIDTH 128 -#define ARROWS_HEIGHT 48 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menulist_s list; - - menubitmap_s arrows; - menubitmap_s left; - menubitmap_s right; - menubitmap_s back; - menubitmap_s go; - - int numDemos; - char names[NAMEBUFSIZE]; - char *demolist[MAX_DEMOS]; -} demos_t; - -static demos_t s_demos; - - -/* -=============== -Demos_MenuEvent -=============== -*/ -static void Demos_MenuEvent( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_GO: - UI_ForceMenuOff (); - trap_Cmd_ExecuteText( EXEC_APPEND, va( "demo %s\n", - s_demos.list.itemnames[s_demos.list.curvalue]) ); - break; - - case ID_BACK: - UI_PopMenu(); - break; - - case ID_LEFT: - ScrollList_Key( &s_demos.list, K_LEFTARROW ); - break; - - case ID_RIGHT: - ScrollList_Key( &s_demos.list, K_RIGHTARROW ); - break; - } -} - - -/* -================= -UI_DemosMenu_Key -================= -*/ -static sfxHandle_t UI_DemosMenu_Key( int key ) { - menucommon_s *item; - - item = Menu_ItemAtCursor( &s_demos.menu ); - - return Menu_DefaultKey( &s_demos.menu, key ); -} - - -/* -=============== -Demos_MenuInit -=============== -*/ -static void Demos_MenuInit( void ) { - int i; - int len; - char *demoname, extension[32]; - - memset( &s_demos, 0 ,sizeof(demos_t) ); - s_demos.menu.key = UI_DemosMenu_Key; - - Demos_Cache(); - - s_demos.menu.fullscreen = qtrue; - s_demos.menu.wrapAround = qtrue; - - s_demos.banner.generic.type = MTYPE_BTEXT; - s_demos.banner.generic.x = 320; - s_demos.banner.generic.y = 16; - s_demos.banner.string = "DEMOS"; - s_demos.banner.color = color_white; - s_demos.banner.style = UI_CENTER; - - s_demos.framel.generic.type = MTYPE_BITMAP; - s_demos.framel.generic.name = ART_FRAMEL; - s_demos.framel.generic.flags = QMF_INACTIVE; - s_demos.framel.generic.x = 0; - s_demos.framel.generic.y = 78; - s_demos.framel.width = 256; - s_demos.framel.height = 329; - - s_demos.framer.generic.type = MTYPE_BITMAP; - s_demos.framer.generic.name = ART_FRAMER; - s_demos.framer.generic.flags = QMF_INACTIVE; - s_demos.framer.generic.x = 376; - s_demos.framer.generic.y = 76; - s_demos.framer.width = 256; - s_demos.framer.height = 334; - - s_demos.arrows.generic.type = MTYPE_BITMAP; - s_demos.arrows.generic.name = ART_ARROWS; - s_demos.arrows.generic.flags = QMF_INACTIVE; - s_demos.arrows.generic.x = 320-ARROWS_WIDTH/2; - s_demos.arrows.generic.y = 400; - s_demos.arrows.width = ARROWS_WIDTH; - s_demos.arrows.height = ARROWS_HEIGHT; - - s_demos.left.generic.type = MTYPE_BITMAP; - s_demos.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - s_demos.left.generic.x = 320-ARROWS_WIDTH/2; - s_demos.left.generic.y = 400; - s_demos.left.generic.id = ID_LEFT; - s_demos.left.generic.callback = Demos_MenuEvent; - s_demos.left.width = ARROWS_WIDTH/2; - s_demos.left.height = ARROWS_HEIGHT; - s_demos.left.focuspic = ART_ARROWLEFT; - - s_demos.right.generic.type = MTYPE_BITMAP; - s_demos.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - s_demos.right.generic.x = 320; - s_demos.right.generic.y = 400; - s_demos.right.generic.id = ID_RIGHT; - s_demos.right.generic.callback = Demos_MenuEvent; - s_demos.right.width = ARROWS_WIDTH/2; - s_demos.right.height = ARROWS_HEIGHT; - s_demos.right.focuspic = ART_ARROWRIGHT; - - s_demos.back.generic.type = MTYPE_BITMAP; - s_demos.back.generic.name = ART_BACK0; - s_demos.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_demos.back.generic.id = ID_BACK; - s_demos.back.generic.callback = Demos_MenuEvent; - s_demos.back.generic.x = 0; - s_demos.back.generic.y = 480-64; - s_demos.back.width = 128; - s_demos.back.height = 64; - s_demos.back.focuspic = ART_BACK1; - - s_demos.go.generic.type = MTYPE_BITMAP; - s_demos.go.generic.name = ART_GO0; - s_demos.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_demos.go.generic.id = ID_GO; - s_demos.go.generic.callback = Demos_MenuEvent; - s_demos.go.generic.x = 640; - s_demos.go.generic.y = 480-64; - s_demos.go.width = 128; - s_demos.go.height = 64; - s_demos.go.focuspic = ART_GO1; - - s_demos.list.generic.type = MTYPE_SCROLLLIST; - s_demos.list.generic.flags = QMF_PULSEIFFOCUS; - s_demos.list.generic.callback = Demos_MenuEvent; - s_demos.list.generic.id = ID_LIST; - s_demos.list.generic.x = 118; - s_demos.list.generic.y = 130; - s_demos.list.width = 16; - s_demos.list.height = 14; - Com_sprintf(extension, sizeof(extension), "dm_%d", (int)trap_Cvar_VariableValue( "protocol" ) ); - s_demos.list.numitems = trap_FS_GetFileList( "demos", extension, s_demos.names, NAMEBUFSIZE ); - s_demos.list.itemnames = (const char **)s_demos.demolist; - s_demos.list.columns = 3; - - if (!s_demos.list.numitems) { - strcpy( s_demos.names, "No Demos Found." ); - s_demos.list.numitems = 1; - - //degenerate case, not selectable - s_demos.go.generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - else if (s_demos.list.numitems > MAX_DEMOS) - s_demos.list.numitems = MAX_DEMOS; - - demoname = s_demos.names; - for ( i = 0; i < s_demos.list.numitems; i++ ) { - s_demos.list.itemnames[i] = demoname; - - // strip extension - len = strlen( demoname ); - if (!Q_stricmp(demoname + len - 4,".dm3")) - demoname[len-4] = '\0'; - - Q_strupr(demoname); - - demoname += len + 1; - } - - Menu_AddItem( &s_demos.menu, &s_demos.banner ); - Menu_AddItem( &s_demos.menu, &s_demos.framel ); - Menu_AddItem( &s_demos.menu, &s_demos.framer ); - Menu_AddItem( &s_demos.menu, &s_demos.list ); - Menu_AddItem( &s_demos.menu, &s_demos.arrows ); - Menu_AddItem( &s_demos.menu, &s_demos.left ); - Menu_AddItem( &s_demos.menu, &s_demos.right ); - Menu_AddItem( &s_demos.menu, &s_demos.back ); - Menu_AddItem( &s_demos.menu, &s_demos.go ); -} - -/* -================= -Demos_Cache -================= -*/ -void Demos_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_GO0 ); - trap_R_RegisterShaderNoMip( ART_GO1 ); - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_ARROWS ); - trap_R_RegisterShaderNoMip( ART_ARROWLEFT ); - trap_R_RegisterShaderNoMip( ART_ARROWRIGHT ); -} - -/* -=============== -UI_DemosMenu -=============== -*/ -void UI_DemosMenu( void ) { - Demos_MenuInit(); - UI_PushMenu( &s_demos.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +DEMOS MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_GO0 "menu/art/play_0" +#define ART_GO1 "menu/art/play_1" +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_ARROWS "menu/art/arrows_horz_0" +#define ART_ARROWLEFT "menu/art/arrows_horz_left" +#define ART_ARROWRIGHT "menu/art/arrows_horz_right" + +#define MAX_DEMOS 128 +#define NAMEBUFSIZE ( MAX_DEMOS * 16 ) + +#define ID_BACK 10 +#define ID_GO 11 +#define ID_LIST 12 +#define ID_RIGHT 13 +#define ID_LEFT 14 + +#define ARROWS_WIDTH 128 +#define ARROWS_HEIGHT 48 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menulist_s list; + + menubitmap_s arrows; + menubitmap_s left; + menubitmap_s right; + menubitmap_s back; + menubitmap_s go; + + int numDemos; + char names[NAMEBUFSIZE]; + char *demolist[MAX_DEMOS]; +} demos_t; + +static demos_t s_demos; + + +/* +=============== +Demos_MenuEvent +=============== +*/ +static void Demos_MenuEvent( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_GO: + UI_ForceMenuOff (); + trap_Cmd_ExecuteText( EXEC_APPEND, va( "demo %s\n", + s_demos.list.itemnames[s_demos.list.curvalue]) ); + break; + + case ID_BACK: + UI_PopMenu(); + break; + + case ID_LEFT: + ScrollList_Key( &s_demos.list, K_LEFTARROW ); + break; + + case ID_RIGHT: + ScrollList_Key( &s_demos.list, K_RIGHTARROW ); + break; + } +} + + +/* +================= +UI_DemosMenu_Key +================= +*/ +static sfxHandle_t UI_DemosMenu_Key( int key ) { + menucommon_s *item; + + item = Menu_ItemAtCursor( &s_demos.menu ); + + return Menu_DefaultKey( &s_demos.menu, key ); +} + + +/* +=============== +Demos_MenuInit +=============== +*/ +static void Demos_MenuInit( void ) { + int i; + int len; + char *demoname, extension[32]; + + memset( &s_demos, 0 ,sizeof(demos_t) ); + s_demos.menu.key = UI_DemosMenu_Key; + + Demos_Cache(); + + s_demos.menu.fullscreen = qtrue; + s_demos.menu.wrapAround = qtrue; + + s_demos.banner.generic.type = MTYPE_BTEXT; + s_demos.banner.generic.x = 320; + s_demos.banner.generic.y = 16; + s_demos.banner.string = "DEMOS"; + s_demos.banner.color = color_white; + s_demos.banner.style = UI_CENTER; + + s_demos.framel.generic.type = MTYPE_BITMAP; + s_demos.framel.generic.name = ART_FRAMEL; + s_demos.framel.generic.flags = QMF_INACTIVE; + s_demos.framel.generic.x = 0; + s_demos.framel.generic.y = 78; + s_demos.framel.width = 256; + s_demos.framel.height = 329; + + s_demos.framer.generic.type = MTYPE_BITMAP; + s_demos.framer.generic.name = ART_FRAMER; + s_demos.framer.generic.flags = QMF_INACTIVE; + s_demos.framer.generic.x = 376; + s_demos.framer.generic.y = 76; + s_demos.framer.width = 256; + s_demos.framer.height = 334; + + s_demos.arrows.generic.type = MTYPE_BITMAP; + s_demos.arrows.generic.name = ART_ARROWS; + s_demos.arrows.generic.flags = QMF_INACTIVE; + s_demos.arrows.generic.x = 320-ARROWS_WIDTH/2; + s_demos.arrows.generic.y = 400; + s_demos.arrows.width = ARROWS_WIDTH; + s_demos.arrows.height = ARROWS_HEIGHT; + + s_demos.left.generic.type = MTYPE_BITMAP; + s_demos.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + s_demos.left.generic.x = 320-ARROWS_WIDTH/2; + s_demos.left.generic.y = 400; + s_demos.left.generic.id = ID_LEFT; + s_demos.left.generic.callback = Demos_MenuEvent; + s_demos.left.width = ARROWS_WIDTH/2; + s_demos.left.height = ARROWS_HEIGHT; + s_demos.left.focuspic = ART_ARROWLEFT; + + s_demos.right.generic.type = MTYPE_BITMAP; + s_demos.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + s_demos.right.generic.x = 320; + s_demos.right.generic.y = 400; + s_demos.right.generic.id = ID_RIGHT; + s_demos.right.generic.callback = Demos_MenuEvent; + s_demos.right.width = ARROWS_WIDTH/2; + s_demos.right.height = ARROWS_HEIGHT; + s_demos.right.focuspic = ART_ARROWRIGHT; + + s_demos.back.generic.type = MTYPE_BITMAP; + s_demos.back.generic.name = ART_BACK0; + s_demos.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_demos.back.generic.id = ID_BACK; + s_demos.back.generic.callback = Demos_MenuEvent; + s_demos.back.generic.x = 0; + s_demos.back.generic.y = 480-64; + s_demos.back.width = 128; + s_demos.back.height = 64; + s_demos.back.focuspic = ART_BACK1; + + s_demos.go.generic.type = MTYPE_BITMAP; + s_demos.go.generic.name = ART_GO0; + s_demos.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_demos.go.generic.id = ID_GO; + s_demos.go.generic.callback = Demos_MenuEvent; + s_demos.go.generic.x = 640; + s_demos.go.generic.y = 480-64; + s_demos.go.width = 128; + s_demos.go.height = 64; + s_demos.go.focuspic = ART_GO1; + + s_demos.list.generic.type = MTYPE_SCROLLLIST; + s_demos.list.generic.flags = QMF_PULSEIFFOCUS; + s_demos.list.generic.callback = Demos_MenuEvent; + s_demos.list.generic.id = ID_LIST; + s_demos.list.generic.x = 118; + s_demos.list.generic.y = 130; + s_demos.list.width = 16; + s_demos.list.height = 14; + Com_sprintf(extension, sizeof(extension), "dm_%d", (int)trap_Cvar_VariableValue( "protocol" ) ); + s_demos.list.numitems = trap_FS_GetFileList( "demos", extension, s_demos.names, NAMEBUFSIZE ); + s_demos.list.itemnames = (const char **)s_demos.demolist; + s_demos.list.columns = 3; + + if (!s_demos.list.numitems) { + strcpy( s_demos.names, "No Demos Found." ); + s_demos.list.numitems = 1; + + //degenerate case, not selectable + s_demos.go.generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + else if (s_demos.list.numitems > MAX_DEMOS) + s_demos.list.numitems = MAX_DEMOS; + + demoname = s_demos.names; + for ( i = 0; i < s_demos.list.numitems; i++ ) { + s_demos.list.itemnames[i] = demoname; + + // strip extension + len = strlen( demoname ); + if (!Q_stricmp(demoname + len - 4,".dm3")) + demoname[len-4] = '\0'; + + Q_strupr(demoname); + + demoname += len + 1; + } + + Menu_AddItem( &s_demos.menu, &s_demos.banner ); + Menu_AddItem( &s_demos.menu, &s_demos.framel ); + Menu_AddItem( &s_demos.menu, &s_demos.framer ); + Menu_AddItem( &s_demos.menu, &s_demos.list ); + Menu_AddItem( &s_demos.menu, &s_demos.arrows ); + Menu_AddItem( &s_demos.menu, &s_demos.left ); + Menu_AddItem( &s_demos.menu, &s_demos.right ); + Menu_AddItem( &s_demos.menu, &s_demos.back ); + Menu_AddItem( &s_demos.menu, &s_demos.go ); +} + +/* +================= +Demos_Cache +================= +*/ +void Demos_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_GO0 ); + trap_R_RegisterShaderNoMip( ART_GO1 ); + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_ARROWS ); + trap_R_RegisterShaderNoMip( ART_ARROWLEFT ); + trap_R_RegisterShaderNoMip( ART_ARROWRIGHT ); +} + +/* +=============== +UI_DemosMenu +=============== +*/ +void UI_DemosMenu( void ) { + Demos_MenuInit(); + UI_PushMenu( &s_demos.menu ); +} diff --git a/code/q3_ui/ui_display.c b/code/q3_ui/ui_display.c index 9a8a49f..ba4f320 100755 --- a/code/q3_ui/ui_display.c +++ b/code/q3_ui/ui_display.c @@ -1,265 +1,265 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -DISPLAY OPTIONS MENU - -======================================================================= -*/ - -#include "ui_local.h" - - -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" - -#define ID_GRAPHICS 10 -#define ID_DISPLAY 11 -#define ID_SOUND 12 -#define ID_NETWORK 13 -#define ID_BRIGHTNESS 14 -#define ID_SCREENSIZE 15 -#define ID_BACK 16 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menutext_s graphics; - menutext_s display; - menutext_s sound; - menutext_s network; - - menuslider_s brightness; - menuslider_s screensize; - - menubitmap_s back; -} displayOptionsInfo_t; - -static displayOptionsInfo_t displayOptionsInfo; - - -/* -================= -UI_DisplayOptionsMenu_Event -================= -*/ -static void UI_DisplayOptionsMenu_Event( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_GRAPHICS: - UI_PopMenu(); - UI_GraphicsOptionsMenu(); - break; - - case ID_DISPLAY: - break; - - case ID_SOUND: - UI_PopMenu(); - UI_SoundOptionsMenu(); - break; - - case ID_NETWORK: - UI_PopMenu(); - UI_NetworkOptionsMenu(); - break; - - case ID_BRIGHTNESS: - trap_Cvar_SetValue( "r_gamma", displayOptionsInfo.brightness.curvalue / 10.0f ); - break; - - case ID_SCREENSIZE: - trap_Cvar_SetValue( "cg_viewsize", displayOptionsInfo.screensize.curvalue * 10 ); - break; - - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -UI_DisplayOptionsMenu_Init -=============== -*/ -static void UI_DisplayOptionsMenu_Init( void ) { - int y; - - memset( &displayOptionsInfo, 0, sizeof(displayOptionsInfo) ); - - UI_DisplayOptionsMenu_Cache(); - displayOptionsInfo.menu.wrapAround = qtrue; - displayOptionsInfo.menu.fullscreen = qtrue; - - displayOptionsInfo.banner.generic.type = MTYPE_BTEXT; - displayOptionsInfo.banner.generic.flags = QMF_CENTER_JUSTIFY; - displayOptionsInfo.banner.generic.x = 320; - displayOptionsInfo.banner.generic.y = 16; - displayOptionsInfo.banner.string = "SYSTEM SETUP"; - displayOptionsInfo.banner.color = color_white; - displayOptionsInfo.banner.style = UI_CENTER; - - displayOptionsInfo.framel.generic.type = MTYPE_BITMAP; - displayOptionsInfo.framel.generic.name = ART_FRAMEL; - displayOptionsInfo.framel.generic.flags = QMF_INACTIVE; - displayOptionsInfo.framel.generic.x = 0; - displayOptionsInfo.framel.generic.y = 78; - displayOptionsInfo.framel.width = 256; - displayOptionsInfo.framel.height = 329; - - displayOptionsInfo.framer.generic.type = MTYPE_BITMAP; - displayOptionsInfo.framer.generic.name = ART_FRAMER; - displayOptionsInfo.framer.generic.flags = QMF_INACTIVE; - displayOptionsInfo.framer.generic.x = 376; - displayOptionsInfo.framer.generic.y = 76; - displayOptionsInfo.framer.width = 256; - displayOptionsInfo.framer.height = 334; - - displayOptionsInfo.graphics.generic.type = MTYPE_PTEXT; - displayOptionsInfo.graphics.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - displayOptionsInfo.graphics.generic.id = ID_GRAPHICS; - displayOptionsInfo.graphics.generic.callback = UI_DisplayOptionsMenu_Event; - displayOptionsInfo.graphics.generic.x = 216; - displayOptionsInfo.graphics.generic.y = 240 - 2 * PROP_HEIGHT; - displayOptionsInfo.graphics.string = "GRAPHICS"; - displayOptionsInfo.graphics.style = UI_RIGHT; - displayOptionsInfo.graphics.color = color_red; - - displayOptionsInfo.display.generic.type = MTYPE_PTEXT; - displayOptionsInfo.display.generic.flags = QMF_RIGHT_JUSTIFY; - displayOptionsInfo.display.generic.id = ID_DISPLAY; - displayOptionsInfo.display.generic.callback = UI_DisplayOptionsMenu_Event; - displayOptionsInfo.display.generic.x = 216; - displayOptionsInfo.display.generic.y = 240 - PROP_HEIGHT; - displayOptionsInfo.display.string = "DISPLAY"; - displayOptionsInfo.display.style = UI_RIGHT; - displayOptionsInfo.display.color = color_red; - - displayOptionsInfo.sound.generic.type = MTYPE_PTEXT; - displayOptionsInfo.sound.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - displayOptionsInfo.sound.generic.id = ID_SOUND; - displayOptionsInfo.sound.generic.callback = UI_DisplayOptionsMenu_Event; - displayOptionsInfo.sound.generic.x = 216; - displayOptionsInfo.sound.generic.y = 240; - displayOptionsInfo.sound.string = "SOUND"; - displayOptionsInfo.sound.style = UI_RIGHT; - displayOptionsInfo.sound.color = color_red; - - displayOptionsInfo.network.generic.type = MTYPE_PTEXT; - displayOptionsInfo.network.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - displayOptionsInfo.network.generic.id = ID_NETWORK; - displayOptionsInfo.network.generic.callback = UI_DisplayOptionsMenu_Event; - displayOptionsInfo.network.generic.x = 216; - displayOptionsInfo.network.generic.y = 240 + PROP_HEIGHT; - displayOptionsInfo.network.string = "NETWORK"; - displayOptionsInfo.network.style = UI_RIGHT; - displayOptionsInfo.network.color = color_red; - - y = 240 - 1 * (BIGCHAR_HEIGHT+2); - displayOptionsInfo.brightness.generic.type = MTYPE_SLIDER; - displayOptionsInfo.brightness.generic.name = "Brightness:"; - displayOptionsInfo.brightness.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - displayOptionsInfo.brightness.generic.callback = UI_DisplayOptionsMenu_Event; - displayOptionsInfo.brightness.generic.id = ID_BRIGHTNESS; - displayOptionsInfo.brightness.generic.x = 400; - displayOptionsInfo.brightness.generic.y = y; - displayOptionsInfo.brightness.minvalue = 5; - displayOptionsInfo.brightness.maxvalue = 20; - if( !uis.glconfig.deviceSupportsGamma ) { - displayOptionsInfo.brightness.generic.flags |= QMF_GRAYED; - } - - y += BIGCHAR_HEIGHT+2; - displayOptionsInfo.screensize.generic.type = MTYPE_SLIDER; - displayOptionsInfo.screensize.generic.name = "Screen Size:"; - displayOptionsInfo.screensize.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - displayOptionsInfo.screensize.generic.callback = UI_DisplayOptionsMenu_Event; - displayOptionsInfo.screensize.generic.id = ID_SCREENSIZE; - displayOptionsInfo.screensize.generic.x = 400; - displayOptionsInfo.screensize.generic.y = y; - displayOptionsInfo.screensize.minvalue = 3; - displayOptionsInfo.screensize.maxvalue = 10; - - displayOptionsInfo.back.generic.type = MTYPE_BITMAP; - displayOptionsInfo.back.generic.name = ART_BACK0; - displayOptionsInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - displayOptionsInfo.back.generic.callback = UI_DisplayOptionsMenu_Event; - displayOptionsInfo.back.generic.id = ID_BACK; - displayOptionsInfo.back.generic.x = 0; - displayOptionsInfo.back.generic.y = 480-64; - displayOptionsInfo.back.width = 128; - displayOptionsInfo.back.height = 64; - displayOptionsInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.banner ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.framel ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.framer ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.graphics ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.display ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.sound ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.network ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.brightness ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.screensize ); - Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.back ); - - displayOptionsInfo.brightness.curvalue = trap_Cvar_VariableValue("r_gamma") * 10; - displayOptionsInfo.screensize.curvalue = trap_Cvar_VariableValue( "cg_viewsize")/10; -} - - -/* -=============== -UI_DisplayOptionsMenu_Cache -=============== -*/ -void UI_DisplayOptionsMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); -} - - -/* -=============== -UI_DisplayOptionsMenu -=============== -*/ -void UI_DisplayOptionsMenu( void ) { - UI_DisplayOptionsMenu_Init(); - UI_PushMenu( &displayOptionsInfo.menu ); - Menu_SetCursorToItem( &displayOptionsInfo.menu, &displayOptionsInfo.display ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +DISPLAY OPTIONS MENU + +======================================================================= +*/ + +#include "ui_local.h" + + +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" + +#define ID_GRAPHICS 10 +#define ID_DISPLAY 11 +#define ID_SOUND 12 +#define ID_NETWORK 13 +#define ID_BRIGHTNESS 14 +#define ID_SCREENSIZE 15 +#define ID_BACK 16 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menutext_s graphics; + menutext_s display; + menutext_s sound; + menutext_s network; + + menuslider_s brightness; + menuslider_s screensize; + + menubitmap_s back; +} displayOptionsInfo_t; + +static displayOptionsInfo_t displayOptionsInfo; + + +/* +================= +UI_DisplayOptionsMenu_Event +================= +*/ +static void UI_DisplayOptionsMenu_Event( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_GRAPHICS: + UI_PopMenu(); + UI_GraphicsOptionsMenu(); + break; + + case ID_DISPLAY: + break; + + case ID_SOUND: + UI_PopMenu(); + UI_SoundOptionsMenu(); + break; + + case ID_NETWORK: + UI_PopMenu(); + UI_NetworkOptionsMenu(); + break; + + case ID_BRIGHTNESS: + trap_Cvar_SetValue( "r_gamma", displayOptionsInfo.brightness.curvalue / 10.0f ); + break; + + case ID_SCREENSIZE: + trap_Cvar_SetValue( "cg_viewsize", displayOptionsInfo.screensize.curvalue * 10 ); + break; + + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +UI_DisplayOptionsMenu_Init +=============== +*/ +static void UI_DisplayOptionsMenu_Init( void ) { + int y; + + memset( &displayOptionsInfo, 0, sizeof(displayOptionsInfo) ); + + UI_DisplayOptionsMenu_Cache(); + displayOptionsInfo.menu.wrapAround = qtrue; + displayOptionsInfo.menu.fullscreen = qtrue; + + displayOptionsInfo.banner.generic.type = MTYPE_BTEXT; + displayOptionsInfo.banner.generic.flags = QMF_CENTER_JUSTIFY; + displayOptionsInfo.banner.generic.x = 320; + displayOptionsInfo.banner.generic.y = 16; + displayOptionsInfo.banner.string = "SYSTEM SETUP"; + displayOptionsInfo.banner.color = color_white; + displayOptionsInfo.banner.style = UI_CENTER; + + displayOptionsInfo.framel.generic.type = MTYPE_BITMAP; + displayOptionsInfo.framel.generic.name = ART_FRAMEL; + displayOptionsInfo.framel.generic.flags = QMF_INACTIVE; + displayOptionsInfo.framel.generic.x = 0; + displayOptionsInfo.framel.generic.y = 78; + displayOptionsInfo.framel.width = 256; + displayOptionsInfo.framel.height = 329; + + displayOptionsInfo.framer.generic.type = MTYPE_BITMAP; + displayOptionsInfo.framer.generic.name = ART_FRAMER; + displayOptionsInfo.framer.generic.flags = QMF_INACTIVE; + displayOptionsInfo.framer.generic.x = 376; + displayOptionsInfo.framer.generic.y = 76; + displayOptionsInfo.framer.width = 256; + displayOptionsInfo.framer.height = 334; + + displayOptionsInfo.graphics.generic.type = MTYPE_PTEXT; + displayOptionsInfo.graphics.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + displayOptionsInfo.graphics.generic.id = ID_GRAPHICS; + displayOptionsInfo.graphics.generic.callback = UI_DisplayOptionsMenu_Event; + displayOptionsInfo.graphics.generic.x = 216; + displayOptionsInfo.graphics.generic.y = 240 - 2 * PROP_HEIGHT; + displayOptionsInfo.graphics.string = "GRAPHICS"; + displayOptionsInfo.graphics.style = UI_RIGHT; + displayOptionsInfo.graphics.color = color_red; + + displayOptionsInfo.display.generic.type = MTYPE_PTEXT; + displayOptionsInfo.display.generic.flags = QMF_RIGHT_JUSTIFY; + displayOptionsInfo.display.generic.id = ID_DISPLAY; + displayOptionsInfo.display.generic.callback = UI_DisplayOptionsMenu_Event; + displayOptionsInfo.display.generic.x = 216; + displayOptionsInfo.display.generic.y = 240 - PROP_HEIGHT; + displayOptionsInfo.display.string = "DISPLAY"; + displayOptionsInfo.display.style = UI_RIGHT; + displayOptionsInfo.display.color = color_red; + + displayOptionsInfo.sound.generic.type = MTYPE_PTEXT; + displayOptionsInfo.sound.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + displayOptionsInfo.sound.generic.id = ID_SOUND; + displayOptionsInfo.sound.generic.callback = UI_DisplayOptionsMenu_Event; + displayOptionsInfo.sound.generic.x = 216; + displayOptionsInfo.sound.generic.y = 240; + displayOptionsInfo.sound.string = "SOUND"; + displayOptionsInfo.sound.style = UI_RIGHT; + displayOptionsInfo.sound.color = color_red; + + displayOptionsInfo.network.generic.type = MTYPE_PTEXT; + displayOptionsInfo.network.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + displayOptionsInfo.network.generic.id = ID_NETWORK; + displayOptionsInfo.network.generic.callback = UI_DisplayOptionsMenu_Event; + displayOptionsInfo.network.generic.x = 216; + displayOptionsInfo.network.generic.y = 240 + PROP_HEIGHT; + displayOptionsInfo.network.string = "NETWORK"; + displayOptionsInfo.network.style = UI_RIGHT; + displayOptionsInfo.network.color = color_red; + + y = 240 - 1 * (BIGCHAR_HEIGHT+2); + displayOptionsInfo.brightness.generic.type = MTYPE_SLIDER; + displayOptionsInfo.brightness.generic.name = "Brightness:"; + displayOptionsInfo.brightness.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + displayOptionsInfo.brightness.generic.callback = UI_DisplayOptionsMenu_Event; + displayOptionsInfo.brightness.generic.id = ID_BRIGHTNESS; + displayOptionsInfo.brightness.generic.x = 400; + displayOptionsInfo.brightness.generic.y = y; + displayOptionsInfo.brightness.minvalue = 5; + displayOptionsInfo.brightness.maxvalue = 20; + if( !uis.glconfig.deviceSupportsGamma ) { + displayOptionsInfo.brightness.generic.flags |= QMF_GRAYED; + } + + y += BIGCHAR_HEIGHT+2; + displayOptionsInfo.screensize.generic.type = MTYPE_SLIDER; + displayOptionsInfo.screensize.generic.name = "Screen Size:"; + displayOptionsInfo.screensize.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + displayOptionsInfo.screensize.generic.callback = UI_DisplayOptionsMenu_Event; + displayOptionsInfo.screensize.generic.id = ID_SCREENSIZE; + displayOptionsInfo.screensize.generic.x = 400; + displayOptionsInfo.screensize.generic.y = y; + displayOptionsInfo.screensize.minvalue = 3; + displayOptionsInfo.screensize.maxvalue = 10; + + displayOptionsInfo.back.generic.type = MTYPE_BITMAP; + displayOptionsInfo.back.generic.name = ART_BACK0; + displayOptionsInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + displayOptionsInfo.back.generic.callback = UI_DisplayOptionsMenu_Event; + displayOptionsInfo.back.generic.id = ID_BACK; + displayOptionsInfo.back.generic.x = 0; + displayOptionsInfo.back.generic.y = 480-64; + displayOptionsInfo.back.width = 128; + displayOptionsInfo.back.height = 64; + displayOptionsInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.banner ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.framel ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.framer ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.graphics ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.display ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.sound ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.network ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.brightness ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.screensize ); + Menu_AddItem( &displayOptionsInfo.menu, ( void * ) &displayOptionsInfo.back ); + + displayOptionsInfo.brightness.curvalue = trap_Cvar_VariableValue("r_gamma") * 10; + displayOptionsInfo.screensize.curvalue = trap_Cvar_VariableValue( "cg_viewsize")/10; +} + + +/* +=============== +UI_DisplayOptionsMenu_Cache +=============== +*/ +void UI_DisplayOptionsMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); +} + + +/* +=============== +UI_DisplayOptionsMenu +=============== +*/ +void UI_DisplayOptionsMenu( void ) { + UI_DisplayOptionsMenu_Init(); + UI_PushMenu( &displayOptionsInfo.menu ); + Menu_SetCursorToItem( &displayOptionsInfo.menu, &displayOptionsInfo.display ); +} diff --git a/code/q3_ui/ui_gameinfo.c b/code/q3_ui/ui_gameinfo.c index 29beddd..b73a18f 100755 --- a/code/q3_ui/ui_gameinfo.c +++ b/code/q3_ui/ui_gameinfo.c @@ -1,820 +1,820 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -// -// gameinfo.c -// - -#include "ui_local.h" - - -// -// arena and bot info -// - -#define POOLSIZE 128 * 1024 - -int ui_numBots; -static char *ui_botInfos[MAX_BOTS]; - -static int ui_numArenas; -static char *ui_arenaInfos[MAX_ARENAS]; - -static int ui_numSinglePlayerArenas; -static int ui_numSpecialSinglePlayerArenas; - -static char memoryPool[POOLSIZE]; -static int allocPoint, outOfMemory; - - -/* -=============== -UI_Alloc -=============== -*/ -void *UI_Alloc( int size ) { - char *p; - - if ( allocPoint + size > POOLSIZE ) { - outOfMemory = qtrue; - return NULL; - } - - p = &memoryPool[allocPoint]; - - allocPoint += ( size + 31 ) & ~31; - - return p; -} - -/* -=============== -UI_InitMemory -=============== -*/ -void UI_InitMemory( void ) { - allocPoint = 0; - outOfMemory = qfalse; -} - -/* -=============== -UI_ParseInfos -=============== -*/ -int UI_ParseInfos( char *buf, int max, char *infos[] ) { - char *token; - int count; - char key[MAX_TOKEN_CHARS]; - char info[MAX_INFO_STRING]; - - count = 0; - - while ( 1 ) { - token = COM_Parse( &buf ); - if ( !token[0] ) { - break; - } - if ( strcmp( token, "{" ) ) { - Com_Printf( "Missing { in info file\n" ); - break; - } - - if ( count == max ) { - Com_Printf( "Max infos exceeded\n" ); - break; - } - - info[0] = '\0'; - while ( 1 ) { - token = COM_ParseExt( &buf, qtrue ); - if ( !token[0] ) { - Com_Printf( "Unexpected end of info file\n" ); - break; - } - if ( !strcmp( token, "}" ) ) { - break; - } - Q_strncpyz( key, token, sizeof( key ) ); - - token = COM_ParseExt( &buf, qfalse ); - if ( !token[0] ) { - strcpy( token, "" ); - } - Info_SetValueForKey( info, key, token ); - } - //NOTE: extra space for arena number - infos[count] = UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1); - if (infos[count]) { - strcpy(infos[count], info); - count++; - } - } - return count; -} - -/* -=============== -UI_LoadArenasFromFile -=============== -*/ -static void UI_LoadArenasFromFile( char *filename ) { - int len; - fileHandle_t f; - char buf[MAX_ARENAS_TEXT]; - - len = trap_FS_FOpenFile( filename, &f, FS_READ ); - if ( !f ) { - trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); - return; - } - if ( len >= MAX_ARENAS_TEXT ) { - trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) ); - trap_FS_FCloseFile( f ); - return; - } - - trap_FS_Read( buf, len, f ); - buf[len] = 0; - trap_FS_FCloseFile( f ); - - ui_numArenas += UI_ParseInfos( buf, MAX_ARENAS - ui_numArenas, &ui_arenaInfos[ui_numArenas] ); -} - -/* -=============== -UI_LoadArenas -=============== -*/ -static void UI_LoadArenas( void ) { - int numdirs; - vmCvar_t arenasFile; - char filename[128]; - char dirlist[1024]; - char* dirptr; - int i, n; - int dirlen; - char *type; - char *tag; - int singlePlayerNum, specialNum, otherNum; - - ui_numArenas = 0; - - trap_Cvar_Register( &arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM ); - if( *arenasFile.string ) { - UI_LoadArenasFromFile(arenasFile.string); - } - else { - UI_LoadArenasFromFile("scripts/arenas.txt"); - } - - // get all arenas from .arena files - numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024 ); - dirptr = dirlist; - for (i = 0; i < numdirs; i++, dirptr += dirlen+1) { - dirlen = strlen(dirptr); - strcpy(filename, "scripts/"); - strcat(filename, dirptr); - UI_LoadArenasFromFile(filename); - } - trap_Print( va( "%i arenas parsed\n", ui_numArenas ) ); - if (outOfMemory) trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all arenas\n"); - - // set initial numbers - for( n = 0; n < ui_numArenas; n++ ) { - Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", n ) ); - } - - // go through and count single players levels - ui_numSinglePlayerArenas = 0; - ui_numSpecialSinglePlayerArenas = 0; - for( n = 0; n < ui_numArenas; n++ ) { - // determine type - type = Info_ValueForKey( ui_arenaInfos[n], "type" ); - - // if no type specified, it will be treated as "ffa" - if( !*type ) { - continue; - } - - if( strstr( type, "single" ) ) { - // check for special single player arenas (training, final) - tag = Info_ValueForKey( ui_arenaInfos[n], "special" ); - if( *tag ) { - ui_numSpecialSinglePlayerArenas++; - continue; - } - - ui_numSinglePlayerArenas++; - } - } - - n = ui_numSinglePlayerArenas % ARENAS_PER_TIER; - if( n != 0 ) { - ui_numSinglePlayerArenas -= n; - trap_Print( va( "%i arenas ignored to make count divisible by %i\n", n, ARENAS_PER_TIER ) ); - } - - // go through once more and assign number to the levels - singlePlayerNum = 0; - specialNum = singlePlayerNum + ui_numSinglePlayerArenas; - otherNum = specialNum + ui_numSpecialSinglePlayerArenas; - for( n = 0; n < ui_numArenas; n++ ) { - // determine type - type = Info_ValueForKey( ui_arenaInfos[n], "type" ); - - // if no type specified, it will be treated as "ffa" - if( *type ) { - if( strstr( type, "single" ) ) { - // check for special single player arenas (training, final) - tag = Info_ValueForKey( ui_arenaInfos[n], "special" ); - if( *tag ) { - Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", specialNum++ ) ); - continue; - } - - Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", singlePlayerNum++ ) ); - continue; - } - } - - Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", otherNum++ ) ); - } -} - -/* -=============== -UI_GetArenaInfoByNumber -=============== -*/ -const char *UI_GetArenaInfoByNumber( int num ) { - int n; - char *value; - - if( num < 0 || num >= ui_numArenas ) { - trap_Print( va( S_COLOR_RED "Invalid arena number: %i\n", num ) ); - return NULL; - } - - for( n = 0; n < ui_numArenas; n++ ) { - value = Info_ValueForKey( ui_arenaInfos[n], "num" ); - if( *value && atoi(value) == num ) { - return ui_arenaInfos[n]; - } - } - - return NULL; -} - - -/* -=============== -UI_GetArenaInfoByNumber -=============== -*/ -const char *UI_GetArenaInfoByMap( const char *map ) { - int n; - - for( n = 0; n < ui_numArenas; n++ ) { - if( Q_stricmp( Info_ValueForKey( ui_arenaInfos[n], "map" ), map ) == 0 ) { - return ui_arenaInfos[n]; - } - } - - return NULL; -} - - -/* -=============== -UI_GetSpecialArenaInfo -=============== -*/ -const char *UI_GetSpecialArenaInfo( const char *tag ) { - int n; - - for( n = 0; n < ui_numArenas; n++ ) { - if( Q_stricmp( Info_ValueForKey( ui_arenaInfos[n], "special" ), tag ) == 0 ) { - return ui_arenaInfos[n]; - } - } - - return NULL; -} - -/* -=============== -UI_LoadBotsFromFile -=============== -*/ -static void UI_LoadBotsFromFile( char *filename ) { - int len; - fileHandle_t f; - char buf[MAX_BOTS_TEXT]; - - len = trap_FS_FOpenFile( filename, &f, FS_READ ); - if ( !f ) { - trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); - return; - } - if ( len >= MAX_BOTS_TEXT ) { - trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) ); - trap_FS_FCloseFile( f ); - return; - } - - trap_FS_Read( buf, len, f ); - buf[len] = 0; - trap_FS_FCloseFile( f ); - - ui_numBots += UI_ParseInfos( buf, MAX_BOTS - ui_numBots, &ui_botInfos[ui_numBots] ); - if (outOfMemory) trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all bots\n"); -} - -/* -=============== -UI_LoadBots -=============== -*/ -static void UI_LoadBots( void ) { - vmCvar_t botsFile; - int numdirs; - char filename[128]; - char dirlist[1024]; - char* dirptr; - int i; - int dirlen; - - ui_numBots = 0; - - trap_Cvar_Register( &botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM ); - if( *botsFile.string ) { - UI_LoadBotsFromFile(botsFile.string); - } - else { - UI_LoadBotsFromFile("scripts/bots.txt"); - } - - // get all bots from .bot files - numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024 ); - dirptr = dirlist; - for (i = 0; i < numdirs; i++, dirptr += dirlen+1) { - dirlen = strlen(dirptr); - strcpy(filename, "scripts/"); - strcat(filename, dirptr); - UI_LoadBotsFromFile(filename); - } - trap_Print( va( "%i bots parsed\n", ui_numBots ) ); -} - - -/* -=============== -UI_GetBotInfoByNumber -=============== -*/ -char *UI_GetBotInfoByNumber( int num ) { - if( num < 0 || num >= ui_numBots ) { - trap_Print( va( S_COLOR_RED "Invalid bot number: %i\n", num ) ); - return NULL; - } - return ui_botInfos[num]; -} - - -/* -=============== -UI_GetBotInfoByName -=============== -*/ -char *UI_GetBotInfoByName( const char *name ) { - int n; - char *value; - - for ( n = 0; n < ui_numBots ; n++ ) { - value = Info_ValueForKey( ui_botInfos[n], "name" ); - if ( !Q_stricmp( value, name ) ) { - return ui_botInfos[n]; - } - } - - return NULL; -} - - -// -// single player game info -// - -/* -=============== -UI_GetBestScore - -Returns the player's best finish on a given level, 0 if the have not played the level -=============== -*/ -void UI_GetBestScore( int level, int *score, int *skill ) { - int n; - int skillScore; - int bestScore; - int bestScoreSkill; - char arenaKey[16]; - char scores[MAX_INFO_VALUE]; - - if( !score || !skill ) { - return; - } - - if( level < 0 || level > ui_numArenas ) { - return; - } - - bestScore = 0; - bestScoreSkill = 0; - - for( n = 1; n <= 5; n++ ) { - trap_Cvar_VariableStringBuffer( va( "g_spScores%i", n ), scores, MAX_INFO_VALUE ); - - Com_sprintf( arenaKey, sizeof( arenaKey ), "l%i", level ); - skillScore = atoi( Info_ValueForKey( scores, arenaKey ) ); - - if( skillScore < 1 || skillScore > 8 ) { - continue; - } - - if( !bestScore || skillScore <= bestScore ) { - bestScore = skillScore; - bestScoreSkill = n; - } - } - - *score = bestScore; - *skill = bestScoreSkill; -} - - -/* -=============== -UI_SetBestScore - -Set the player's best finish for a level -=============== -*/ -void UI_SetBestScore( int level, int score ) { - int skill; - int oldScore; - char arenaKey[16]; - char scores[MAX_INFO_VALUE]; - - // validate score - if( score < 1 || score > 8 ) { - return; - } - - // validate skill - skill = (int)trap_Cvar_VariableValue( "g_spSkill" ); - if( skill < 1 || skill > 5 ) { - return; - } - - // get scores - trap_Cvar_VariableStringBuffer( va( "g_spScores%i", skill ), scores, MAX_INFO_VALUE ); - - // see if this is better - Com_sprintf( arenaKey, sizeof( arenaKey ), "l%i", level ); - oldScore = atoi( Info_ValueForKey( scores, arenaKey ) ); - if( oldScore && oldScore <= score ) { - return; - } - - // update scores - Info_SetValueForKey( scores, arenaKey, va( "%i", score ) ); - trap_Cvar_Set( va( "g_spScores%i", skill ), scores ); -} - - -/* -=============== -UI_LogAwardData -=============== -*/ -void UI_LogAwardData( int award, int data ) { - char key[16]; - char awardData[MAX_INFO_VALUE]; - int oldValue; - - if( data == 0 ) { - return; - } - - if( award > AWARD_PERFECT ) { - trap_Print( va( S_COLOR_RED "Bad award %i in UI_LogAwardData\n", award ) ); - return; - } - - trap_Cvar_VariableStringBuffer( "g_spAwards", awardData, sizeof(awardData) ); - - Com_sprintf( key, sizeof(key), "a%i", award ); - oldValue = atoi( Info_ValueForKey( awardData, key ) ); - - Info_SetValueForKey( awardData, key, va( "%i", oldValue + data ) ); - trap_Cvar_Set( "g_spAwards", awardData ); -} - - -/* -=============== -UI_GetAwardLevel -=============== -*/ -int UI_GetAwardLevel( int award ) { - char key[16]; - char awardData[MAX_INFO_VALUE]; - - trap_Cvar_VariableStringBuffer( "g_spAwards", awardData, sizeof(awardData) ); - - Com_sprintf( key, sizeof(key), "a%i", award ); - return atoi( Info_ValueForKey( awardData, key ) ); -} - - -/* -=============== -UI_TierCompleted -=============== -*/ -int UI_TierCompleted( int levelWon ) { - int level; - int n; - int tier; - int score; - int skill; - const char *info; - - tier = levelWon / ARENAS_PER_TIER; - level = tier * ARENAS_PER_TIER; - - if( tier == UI_GetNumSPTiers() ) { - info = UI_GetSpecialArenaInfo( "training" ); - if( levelWon == atoi( Info_ValueForKey( info, "num" ) ) ) { - return 0; - } - info = UI_GetSpecialArenaInfo( "final" ); - if( !info || levelWon == atoi( Info_ValueForKey( info, "num" ) ) ) { - return tier + 1; - } - return -1; - } - - for( n = 0; n < ARENAS_PER_TIER; n++, level++ ) { - UI_GetBestScore( level, &score, &skill ); - if ( score != 1 ) { - return -1; - } - } - return tier + 1; -} - - -/* -=============== -UI_ShowTierVideo -=============== -*/ -qboolean UI_ShowTierVideo( int tier ) { - char key[16]; - char videos[MAX_INFO_VALUE]; - - if( tier <= 0 ) { - return qfalse; - } - - trap_Cvar_VariableStringBuffer( "g_spVideos", videos, sizeof(videos) ); - - Com_sprintf( key, sizeof(key), "tier%i", tier ); - if( atoi( Info_ValueForKey( videos, key ) ) ) { - return qfalse; - } - - Info_SetValueForKey( videos, key, va( "%i", 1 ) ); - trap_Cvar_Set( "g_spVideos", videos ); - - return qtrue; -} - - -/* -=============== -UI_CanShowTierVideo -=============== -*/ -qboolean UI_CanShowTierVideo( int tier ) { - char key[16]; - char videos[MAX_INFO_VALUE]; - - if( !tier ) { - return qfalse; - } - - if( uis.demoversion && tier != 8 ) { - return qfalse; - } - - trap_Cvar_VariableStringBuffer( "g_spVideos", videos, sizeof(videos) ); - - Com_sprintf( key, sizeof(key), "tier%i", tier ); - if( atoi( Info_ValueForKey( videos, key ) ) ) { - return qtrue; - } - - return qfalse; -} - - -/* -=============== -UI_GetCurrentGame - -Returns the next level the player has not won -=============== -*/ -int UI_GetCurrentGame( void ) { - int level; - int rank; - int skill; - const char *info; - - info = UI_GetSpecialArenaInfo( "training" ); - if( info ) { - level = atoi( Info_ValueForKey( info, "num" ) ); - UI_GetBestScore( level, &rank, &skill ); - if ( !rank || rank > 1 ) { - return level; - } - } - - for( level = 0; level < ui_numSinglePlayerArenas; level++ ) { - UI_GetBestScore( level, &rank, &skill ); - if ( !rank || rank > 1 ) { - return level; - } - } - - info = UI_GetSpecialArenaInfo( "final" ); - if( !info ) { - return -1; - } - return atoi( Info_ValueForKey( info, "num" ) ); -} - - -/* -=============== -UI_NewGame - -Clears the scores and sets the difficutly level -=============== -*/ -void UI_NewGame( void ) { - trap_Cvar_Set( "g_spScores1", "" ); - trap_Cvar_Set( "g_spScores2", "" ); - trap_Cvar_Set( "g_spScores3", "" ); - trap_Cvar_Set( "g_spScores4", "" ); - trap_Cvar_Set( "g_spScores5", "" ); - trap_Cvar_Set( "g_spAwards", "" ); - trap_Cvar_Set( "g_spVideos", "" ); -} - - -/* -=============== -UI_GetNumArenas -=============== -*/ -int UI_GetNumArenas( void ) { - return ui_numArenas; -} - - -/* -=============== -UI_GetNumSPArenas -=============== -*/ -int UI_GetNumSPArenas( void ) { - return ui_numSinglePlayerArenas; -} - - -/* -=============== -UI_GetNumSPTiers -=============== -*/ -int UI_GetNumSPTiers( void ) { - return ui_numSinglePlayerArenas / ARENAS_PER_TIER; -} - - -/* -=============== -UI_GetNumBots -=============== -*/ -int UI_GetNumBots( void ) { - return ui_numBots; -} - - -/* -=============== -UI_SPUnlock_f -=============== -*/ -void UI_SPUnlock_f( void ) { - char arenaKey[16]; - char scores[MAX_INFO_VALUE]; - int level; - int tier; - - // get scores for skill 1 - trap_Cvar_VariableStringBuffer( "g_spScores1", scores, MAX_INFO_VALUE ); - - // update scores - for( level = 0; level < ui_numSinglePlayerArenas + ui_numSpecialSinglePlayerArenas; level++ ) { - Com_sprintf( arenaKey, sizeof( arenaKey ), "l%i", level ); - Info_SetValueForKey( scores, arenaKey, "1" ); - } - trap_Cvar_Set( "g_spScores1", scores ); - - // unlock cinematics - for( tier = 1; tier <= 8; tier++ ) { - UI_ShowTierVideo( tier ); - } - - trap_Print( "All levels unlocked at skill level 1\n" ); - - UI_SPLevelMenu_ReInit(); -} - - -/* -=============== -UI_SPUnlockMedals_f -=============== -*/ -void UI_SPUnlockMedals_f( void ) { - int n; - char key[16]; - char awardData[MAX_INFO_VALUE]; - - trap_Cvar_VariableStringBuffer( "g_spAwards", awardData, MAX_INFO_VALUE ); - - for( n = 0; n < 6; n++ ) { - Com_sprintf( key, sizeof(key), "a%i", n ); - Info_SetValueForKey( awardData, key, "100" ); - } - - trap_Cvar_Set( "g_spAwards", awardData ); - - trap_Print( "All levels unlocked at 100\n" ); -} - - -/* -=============== -UI_InitGameinfo -=============== -*/ -void UI_InitGameinfo( void ) { - - UI_InitMemory(); - UI_LoadArenas(); - UI_LoadBots(); - - if( (trap_Cvar_VariableValue( "fs_restrict" )) || (ui_numSpecialSinglePlayerArenas == 0 && ui_numSinglePlayerArenas == 4) ) { - uis.demoversion = qtrue; - } - else { - uis.demoversion = qfalse; - } -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +// +// gameinfo.c +// + +#include "ui_local.h" + + +// +// arena and bot info +// + +#define POOLSIZE 128 * 1024 + +int ui_numBots; +static char *ui_botInfos[MAX_BOTS]; + +static int ui_numArenas; +static char *ui_arenaInfos[MAX_ARENAS]; + +static int ui_numSinglePlayerArenas; +static int ui_numSpecialSinglePlayerArenas; + +static char memoryPool[POOLSIZE]; +static int allocPoint, outOfMemory; + + +/* +=============== +UI_Alloc +=============== +*/ +void *UI_Alloc( int size ) { + char *p; + + if ( allocPoint + size > POOLSIZE ) { + outOfMemory = qtrue; + return NULL; + } + + p = &memoryPool[allocPoint]; + + allocPoint += ( size + 31 ) & ~31; + + return p; +} + +/* +=============== +UI_InitMemory +=============== +*/ +void UI_InitMemory( void ) { + allocPoint = 0; + outOfMemory = qfalse; +} + +/* +=============== +UI_ParseInfos +=============== +*/ +int UI_ParseInfos( char *buf, int max, char *infos[] ) { + char *token; + int count; + char key[MAX_TOKEN_CHARS]; + char info[MAX_INFO_STRING]; + + count = 0; + + while ( 1 ) { + token = COM_Parse( &buf ); + if ( !token[0] ) { + break; + } + if ( strcmp( token, "{" ) ) { + Com_Printf( "Missing { in info file\n" ); + break; + } + + if ( count == max ) { + Com_Printf( "Max infos exceeded\n" ); + break; + } + + info[0] = '\0'; + while ( 1 ) { + token = COM_ParseExt( &buf, qtrue ); + if ( !token[0] ) { + Com_Printf( "Unexpected end of info file\n" ); + break; + } + if ( !strcmp( token, "}" ) ) { + break; + } + Q_strncpyz( key, token, sizeof( key ) ); + + token = COM_ParseExt( &buf, qfalse ); + if ( !token[0] ) { + strcpy( token, "" ); + } + Info_SetValueForKey( info, key, token ); + } + //NOTE: extra space for arena number + infos[count] = UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1); + if (infos[count]) { + strcpy(infos[count], info); + count++; + } + } + return count; +} + +/* +=============== +UI_LoadArenasFromFile +=============== +*/ +static void UI_LoadArenasFromFile( char *filename ) { + int len; + fileHandle_t f; + char buf[MAX_ARENAS_TEXT]; + + len = trap_FS_FOpenFile( filename, &f, FS_READ ); + if ( !f ) { + trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); + return; + } + if ( len >= MAX_ARENAS_TEXT ) { + trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) ); + trap_FS_FCloseFile( f ); + return; + } + + trap_FS_Read( buf, len, f ); + buf[len] = 0; + trap_FS_FCloseFile( f ); + + ui_numArenas += UI_ParseInfos( buf, MAX_ARENAS - ui_numArenas, &ui_arenaInfos[ui_numArenas] ); +} + +/* +=============== +UI_LoadArenas +=============== +*/ +static void UI_LoadArenas( void ) { + int numdirs; + vmCvar_t arenasFile; + char filename[128]; + char dirlist[1024]; + char* dirptr; + int i, n; + int dirlen; + char *type; + char *tag; + int singlePlayerNum, specialNum, otherNum; + + ui_numArenas = 0; + + trap_Cvar_Register( &arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM ); + if( *arenasFile.string ) { + UI_LoadArenasFromFile(arenasFile.string); + } + else { + UI_LoadArenasFromFile("scripts/arenas.txt"); + } + + // get all arenas from .arena files + numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024 ); + dirptr = dirlist; + for (i = 0; i < numdirs; i++, dirptr += dirlen+1) { + dirlen = strlen(dirptr); + strcpy(filename, "scripts/"); + strcat(filename, dirptr); + UI_LoadArenasFromFile(filename); + } + trap_Print( va( "%i arenas parsed\n", ui_numArenas ) ); + if (outOfMemory) trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all arenas\n"); + + // set initial numbers + for( n = 0; n < ui_numArenas; n++ ) { + Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", n ) ); + } + + // go through and count single players levels + ui_numSinglePlayerArenas = 0; + ui_numSpecialSinglePlayerArenas = 0; + for( n = 0; n < ui_numArenas; n++ ) { + // determine type + type = Info_ValueForKey( ui_arenaInfos[n], "type" ); + + // if no type specified, it will be treated as "ffa" + if( !*type ) { + continue; + } + + if( strstr( type, "single" ) ) { + // check for special single player arenas (training, final) + tag = Info_ValueForKey( ui_arenaInfos[n], "special" ); + if( *tag ) { + ui_numSpecialSinglePlayerArenas++; + continue; + } + + ui_numSinglePlayerArenas++; + } + } + + n = ui_numSinglePlayerArenas % ARENAS_PER_TIER; + if( n != 0 ) { + ui_numSinglePlayerArenas -= n; + trap_Print( va( "%i arenas ignored to make count divisible by %i\n", n, ARENAS_PER_TIER ) ); + } + + // go through once more and assign number to the levels + singlePlayerNum = 0; + specialNum = singlePlayerNum + ui_numSinglePlayerArenas; + otherNum = specialNum + ui_numSpecialSinglePlayerArenas; + for( n = 0; n < ui_numArenas; n++ ) { + // determine type + type = Info_ValueForKey( ui_arenaInfos[n], "type" ); + + // if no type specified, it will be treated as "ffa" + if( *type ) { + if( strstr( type, "single" ) ) { + // check for special single player arenas (training, final) + tag = Info_ValueForKey( ui_arenaInfos[n], "special" ); + if( *tag ) { + Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", specialNum++ ) ); + continue; + } + + Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", singlePlayerNum++ ) ); + continue; + } + } + + Info_SetValueForKey( ui_arenaInfos[n], "num", va( "%i", otherNum++ ) ); + } +} + +/* +=============== +UI_GetArenaInfoByNumber +=============== +*/ +const char *UI_GetArenaInfoByNumber( int num ) { + int n; + char *value; + + if( num < 0 || num >= ui_numArenas ) { + trap_Print( va( S_COLOR_RED "Invalid arena number: %i\n", num ) ); + return NULL; + } + + for( n = 0; n < ui_numArenas; n++ ) { + value = Info_ValueForKey( ui_arenaInfos[n], "num" ); + if( *value && atoi(value) == num ) { + return ui_arenaInfos[n]; + } + } + + return NULL; +} + + +/* +=============== +UI_GetArenaInfoByNumber +=============== +*/ +const char *UI_GetArenaInfoByMap( const char *map ) { + int n; + + for( n = 0; n < ui_numArenas; n++ ) { + if( Q_stricmp( Info_ValueForKey( ui_arenaInfos[n], "map" ), map ) == 0 ) { + return ui_arenaInfos[n]; + } + } + + return NULL; +} + + +/* +=============== +UI_GetSpecialArenaInfo +=============== +*/ +const char *UI_GetSpecialArenaInfo( const char *tag ) { + int n; + + for( n = 0; n < ui_numArenas; n++ ) { + if( Q_stricmp( Info_ValueForKey( ui_arenaInfos[n], "special" ), tag ) == 0 ) { + return ui_arenaInfos[n]; + } + } + + return NULL; +} + +/* +=============== +UI_LoadBotsFromFile +=============== +*/ +static void UI_LoadBotsFromFile( char *filename ) { + int len; + fileHandle_t f; + char buf[MAX_BOTS_TEXT]; + + len = trap_FS_FOpenFile( filename, &f, FS_READ ); + if ( !f ) { + trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); + return; + } + if ( len >= MAX_BOTS_TEXT ) { + trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) ); + trap_FS_FCloseFile( f ); + return; + } + + trap_FS_Read( buf, len, f ); + buf[len] = 0; + trap_FS_FCloseFile( f ); + + ui_numBots += UI_ParseInfos( buf, MAX_BOTS - ui_numBots, &ui_botInfos[ui_numBots] ); + if (outOfMemory) trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all bots\n"); +} + +/* +=============== +UI_LoadBots +=============== +*/ +static void UI_LoadBots( void ) { + vmCvar_t botsFile; + int numdirs; + char filename[128]; + char dirlist[1024]; + char* dirptr; + int i; + int dirlen; + + ui_numBots = 0; + + trap_Cvar_Register( &botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM ); + if( *botsFile.string ) { + UI_LoadBotsFromFile(botsFile.string); + } + else { + UI_LoadBotsFromFile("scripts/bots.txt"); + } + + // get all bots from .bot files + numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024 ); + dirptr = dirlist; + for (i = 0; i < numdirs; i++, dirptr += dirlen+1) { + dirlen = strlen(dirptr); + strcpy(filename, "scripts/"); + strcat(filename, dirptr); + UI_LoadBotsFromFile(filename); + } + trap_Print( va( "%i bots parsed\n", ui_numBots ) ); +} + + +/* +=============== +UI_GetBotInfoByNumber +=============== +*/ +char *UI_GetBotInfoByNumber( int num ) { + if( num < 0 || num >= ui_numBots ) { + trap_Print( va( S_COLOR_RED "Invalid bot number: %i\n", num ) ); + return NULL; + } + return ui_botInfos[num]; +} + + +/* +=============== +UI_GetBotInfoByName +=============== +*/ +char *UI_GetBotInfoByName( const char *name ) { + int n; + char *value; + + for ( n = 0; n < ui_numBots ; n++ ) { + value = Info_ValueForKey( ui_botInfos[n], "name" ); + if ( !Q_stricmp( value, name ) ) { + return ui_botInfos[n]; + } + } + + return NULL; +} + + +// +// single player game info +// + +/* +=============== +UI_GetBestScore + +Returns the player's best finish on a given level, 0 if the have not played the level +=============== +*/ +void UI_GetBestScore( int level, int *score, int *skill ) { + int n; + int skillScore; + int bestScore; + int bestScoreSkill; + char arenaKey[16]; + char scores[MAX_INFO_VALUE]; + + if( !score || !skill ) { + return; + } + + if( level < 0 || level > ui_numArenas ) { + return; + } + + bestScore = 0; + bestScoreSkill = 0; + + for( n = 1; n <= 5; n++ ) { + trap_Cvar_VariableStringBuffer( va( "g_spScores%i", n ), scores, MAX_INFO_VALUE ); + + Com_sprintf( arenaKey, sizeof( arenaKey ), "l%i", level ); + skillScore = atoi( Info_ValueForKey( scores, arenaKey ) ); + + if( skillScore < 1 || skillScore > 8 ) { + continue; + } + + if( !bestScore || skillScore <= bestScore ) { + bestScore = skillScore; + bestScoreSkill = n; + } + } + + *score = bestScore; + *skill = bestScoreSkill; +} + + +/* +=============== +UI_SetBestScore + +Set the player's best finish for a level +=============== +*/ +void UI_SetBestScore( int level, int score ) { + int skill; + int oldScore; + char arenaKey[16]; + char scores[MAX_INFO_VALUE]; + + // validate score + if( score < 1 || score > 8 ) { + return; + } + + // validate skill + skill = (int)trap_Cvar_VariableValue( "g_spSkill" ); + if( skill < 1 || skill > 5 ) { + return; + } + + // get scores + trap_Cvar_VariableStringBuffer( va( "g_spScores%i", skill ), scores, MAX_INFO_VALUE ); + + // see if this is better + Com_sprintf( arenaKey, sizeof( arenaKey ), "l%i", level ); + oldScore = atoi( Info_ValueForKey( scores, arenaKey ) ); + if( oldScore && oldScore <= score ) { + return; + } + + // update scores + Info_SetValueForKey( scores, arenaKey, va( "%i", score ) ); + trap_Cvar_Set( va( "g_spScores%i", skill ), scores ); +} + + +/* +=============== +UI_LogAwardData +=============== +*/ +void UI_LogAwardData( int award, int data ) { + char key[16]; + char awardData[MAX_INFO_VALUE]; + int oldValue; + + if( data == 0 ) { + return; + } + + if( award > AWARD_PERFECT ) { + trap_Print( va( S_COLOR_RED "Bad award %i in UI_LogAwardData\n", award ) ); + return; + } + + trap_Cvar_VariableStringBuffer( "g_spAwards", awardData, sizeof(awardData) ); + + Com_sprintf( key, sizeof(key), "a%i", award ); + oldValue = atoi( Info_ValueForKey( awardData, key ) ); + + Info_SetValueForKey( awardData, key, va( "%i", oldValue + data ) ); + trap_Cvar_Set( "g_spAwards", awardData ); +} + + +/* +=============== +UI_GetAwardLevel +=============== +*/ +int UI_GetAwardLevel( int award ) { + char key[16]; + char awardData[MAX_INFO_VALUE]; + + trap_Cvar_VariableStringBuffer( "g_spAwards", awardData, sizeof(awardData) ); + + Com_sprintf( key, sizeof(key), "a%i", award ); + return atoi( Info_ValueForKey( awardData, key ) ); +} + + +/* +=============== +UI_TierCompleted +=============== +*/ +int UI_TierCompleted( int levelWon ) { + int level; + int n; + int tier; + int score; + int skill; + const char *info; + + tier = levelWon / ARENAS_PER_TIER; + level = tier * ARENAS_PER_TIER; + + if( tier == UI_GetNumSPTiers() ) { + info = UI_GetSpecialArenaInfo( "training" ); + if( levelWon == atoi( Info_ValueForKey( info, "num" ) ) ) { + return 0; + } + info = UI_GetSpecialArenaInfo( "final" ); + if( !info || levelWon == atoi( Info_ValueForKey( info, "num" ) ) ) { + return tier + 1; + } + return -1; + } + + for( n = 0; n < ARENAS_PER_TIER; n++, level++ ) { + UI_GetBestScore( level, &score, &skill ); + if ( score != 1 ) { + return -1; + } + } + return tier + 1; +} + + +/* +=============== +UI_ShowTierVideo +=============== +*/ +qboolean UI_ShowTierVideo( int tier ) { + char key[16]; + char videos[MAX_INFO_VALUE]; + + if( tier <= 0 ) { + return qfalse; + } + + trap_Cvar_VariableStringBuffer( "g_spVideos", videos, sizeof(videos) ); + + Com_sprintf( key, sizeof(key), "tier%i", tier ); + if( atoi( Info_ValueForKey( videos, key ) ) ) { + return qfalse; + } + + Info_SetValueForKey( videos, key, va( "%i", 1 ) ); + trap_Cvar_Set( "g_spVideos", videos ); + + return qtrue; +} + + +/* +=============== +UI_CanShowTierVideo +=============== +*/ +qboolean UI_CanShowTierVideo( int tier ) { + char key[16]; + char videos[MAX_INFO_VALUE]; + + if( !tier ) { + return qfalse; + } + + if( uis.demoversion && tier != 8 ) { + return qfalse; + } + + trap_Cvar_VariableStringBuffer( "g_spVideos", videos, sizeof(videos) ); + + Com_sprintf( key, sizeof(key), "tier%i", tier ); + if( atoi( Info_ValueForKey( videos, key ) ) ) { + return qtrue; + } + + return qfalse; +} + + +/* +=============== +UI_GetCurrentGame + +Returns the next level the player has not won +=============== +*/ +int UI_GetCurrentGame( void ) { + int level; + int rank; + int skill; + const char *info; + + info = UI_GetSpecialArenaInfo( "training" ); + if( info ) { + level = atoi( Info_ValueForKey( info, "num" ) ); + UI_GetBestScore( level, &rank, &skill ); + if ( !rank || rank > 1 ) { + return level; + } + } + + for( level = 0; level < ui_numSinglePlayerArenas; level++ ) { + UI_GetBestScore( level, &rank, &skill ); + if ( !rank || rank > 1 ) { + return level; + } + } + + info = UI_GetSpecialArenaInfo( "final" ); + if( !info ) { + return -1; + } + return atoi( Info_ValueForKey( info, "num" ) ); +} + + +/* +=============== +UI_NewGame + +Clears the scores and sets the difficutly level +=============== +*/ +void UI_NewGame( void ) { + trap_Cvar_Set( "g_spScores1", "" ); + trap_Cvar_Set( "g_spScores2", "" ); + trap_Cvar_Set( "g_spScores3", "" ); + trap_Cvar_Set( "g_spScores4", "" ); + trap_Cvar_Set( "g_spScores5", "" ); + trap_Cvar_Set( "g_spAwards", "" ); + trap_Cvar_Set( "g_spVideos", "" ); +} + + +/* +=============== +UI_GetNumArenas +=============== +*/ +int UI_GetNumArenas( void ) { + return ui_numArenas; +} + + +/* +=============== +UI_GetNumSPArenas +=============== +*/ +int UI_GetNumSPArenas( void ) { + return ui_numSinglePlayerArenas; +} + + +/* +=============== +UI_GetNumSPTiers +=============== +*/ +int UI_GetNumSPTiers( void ) { + return ui_numSinglePlayerArenas / ARENAS_PER_TIER; +} + + +/* +=============== +UI_GetNumBots +=============== +*/ +int UI_GetNumBots( void ) { + return ui_numBots; +} + + +/* +=============== +UI_SPUnlock_f +=============== +*/ +void UI_SPUnlock_f( void ) { + char arenaKey[16]; + char scores[MAX_INFO_VALUE]; + int level; + int tier; + + // get scores for skill 1 + trap_Cvar_VariableStringBuffer( "g_spScores1", scores, MAX_INFO_VALUE ); + + // update scores + for( level = 0; level < ui_numSinglePlayerArenas + ui_numSpecialSinglePlayerArenas; level++ ) { + Com_sprintf( arenaKey, sizeof( arenaKey ), "l%i", level ); + Info_SetValueForKey( scores, arenaKey, "1" ); + } + trap_Cvar_Set( "g_spScores1", scores ); + + // unlock cinematics + for( tier = 1; tier <= 8; tier++ ) { + UI_ShowTierVideo( tier ); + } + + trap_Print( "All levels unlocked at skill level 1\n" ); + + UI_SPLevelMenu_ReInit(); +} + + +/* +=============== +UI_SPUnlockMedals_f +=============== +*/ +void UI_SPUnlockMedals_f( void ) { + int n; + char key[16]; + char awardData[MAX_INFO_VALUE]; + + trap_Cvar_VariableStringBuffer( "g_spAwards", awardData, MAX_INFO_VALUE ); + + for( n = 0; n < 6; n++ ) { + Com_sprintf( key, sizeof(key), "a%i", n ); + Info_SetValueForKey( awardData, key, "100" ); + } + + trap_Cvar_Set( "g_spAwards", awardData ); + + trap_Print( "All levels unlocked at 100\n" ); +} + + +/* +=============== +UI_InitGameinfo +=============== +*/ +void UI_InitGameinfo( void ) { + + UI_InitMemory(); + UI_LoadArenas(); + UI_LoadBots(); + + if( (trap_Cvar_VariableValue( "fs_restrict" )) || (ui_numSpecialSinglePlayerArenas == 0 && ui_numSinglePlayerArenas == 4) ) { + uis.demoversion = qtrue; + } + else { + uis.demoversion = qfalse; + } +} diff --git a/code/q3_ui/ui_ingame.c b/code/q3_ui/ui_ingame.c index c5c6b06..9b58c11 100755 --- a/code/q3_ui/ui_ingame.c +++ b/code/q3_ui/ui_ingame.c @@ -1,349 +1,349 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -INGAME MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define INGAME_FRAME "menu/art/addbotframe" -//#define INGAME_FRAME "menu/art/cut_frame" -#define INGAME_MENU_VERTICAL_SPACING 28 - -#define ID_TEAM 10 -#define ID_ADDBOTS 11 -#define ID_REMOVEBOTS 12 -#define ID_SETUP 13 -#define ID_SERVERINFO 14 -#define ID_LEAVEARENA 15 -#define ID_RESTART 16 -#define ID_QUIT 17 -#define ID_RESUME 18 -#define ID_TEAMORDERS 19 - - -typedef struct { - menuframework_s menu; - - menubitmap_s frame; - menutext_s team; - menutext_s setup; - menutext_s server; - menutext_s leave; - menutext_s restart; - menutext_s addbots; - menutext_s removebots; - menutext_s teamorders; - menutext_s quit; - menutext_s resume; -} ingamemenu_t; - -static ingamemenu_t s_ingame; - - -/* -================= -InGame_RestartAction -================= -*/ -static void InGame_RestartAction( qboolean result ) { - if( !result ) { - return; - } - - UI_PopMenu(); - trap_Cmd_ExecuteText( EXEC_APPEND, "map_restart 0\n" ); -} - - -/* -================= -InGame_QuitAction -================= -*/ -static void InGame_QuitAction( qboolean result ) { - if( !result ) { - return; - } - UI_PopMenu(); - UI_CreditMenu(); -} - - -/* -================= -InGame_Event -================= -*/ -void InGame_Event( void *ptr, int notification ) { - if( notification != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_TEAM: - UI_TeamMainMenu(); - break; - - case ID_SETUP: - UI_SetupMenu(); - break; - - case ID_LEAVEARENA: - trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); - break; - - case ID_RESTART: - UI_ConfirmMenu( "RESTART ARENA?", (voidfunc_f)NULL, InGame_RestartAction ); - break; - - case ID_QUIT: - UI_ConfirmMenu( "EXIT GAME?", (voidfunc_f)NULL, InGame_QuitAction ); - break; - - case ID_SERVERINFO: - UI_ServerInfoMenu(); - break; - - case ID_ADDBOTS: - UI_AddBotsMenu(); - break; - - case ID_REMOVEBOTS: - UI_RemoveBotsMenu(); - break; - - case ID_TEAMORDERS: - UI_TeamOrdersMenu(); - break; - - case ID_RESUME: - UI_PopMenu(); - break; - } -} - - -/* -================= -InGame_MenuInit -================= -*/ -void InGame_MenuInit( void ) { - int y; - uiClientState_t cs; - char info[MAX_INFO_STRING]; - int team; - - memset( &s_ingame, 0 ,sizeof(ingamemenu_t) ); - - InGame_Cache(); - - s_ingame.menu.wrapAround = qtrue; - s_ingame.menu.fullscreen = qfalse; - - s_ingame.frame.generic.type = MTYPE_BITMAP; - s_ingame.frame.generic.flags = QMF_INACTIVE; - s_ingame.frame.generic.name = INGAME_FRAME; - s_ingame.frame.generic.x = 320-233;//142; - s_ingame.frame.generic.y = 240-166;//118; - s_ingame.frame.width = 466;//359; - s_ingame.frame.height = 332;//256; - - //y = 96; - y = 88; - s_ingame.team.generic.type = MTYPE_PTEXT; - s_ingame.team.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.team.generic.x = 320; - s_ingame.team.generic.y = y; - s_ingame.team.generic.id = ID_TEAM; - s_ingame.team.generic.callback = InGame_Event; - s_ingame.team.string = "START"; - s_ingame.team.color = color_red; - s_ingame.team.style = UI_CENTER|UI_SMALLFONT; - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.addbots.generic.type = MTYPE_PTEXT; - s_ingame.addbots.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.addbots.generic.x = 320; - s_ingame.addbots.generic.y = y; - s_ingame.addbots.generic.id = ID_ADDBOTS; - s_ingame.addbots.generic.callback = InGame_Event; - s_ingame.addbots.string = "ADD BOTS"; - s_ingame.addbots.color = color_red; - s_ingame.addbots.style = UI_CENTER|UI_SMALLFONT; - if( !trap_Cvar_VariableValue( "sv_running" ) || !trap_Cvar_VariableValue( "bot_enable" ) || (trap_Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER)) { - s_ingame.addbots.generic.flags |= QMF_GRAYED; - } - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.removebots.generic.type = MTYPE_PTEXT; - s_ingame.removebots.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.removebots.generic.x = 320; - s_ingame.removebots.generic.y = y; - s_ingame.removebots.generic.id = ID_REMOVEBOTS; - s_ingame.removebots.generic.callback = InGame_Event; - s_ingame.removebots.string = "REMOVE BOTS"; - s_ingame.removebots.color = color_red; - s_ingame.removebots.style = UI_CENTER|UI_SMALLFONT; - if( !trap_Cvar_VariableValue( "sv_running" ) || !trap_Cvar_VariableValue( "bot_enable" ) || (trap_Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER)) { - s_ingame.removebots.generic.flags |= QMF_GRAYED; - } - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.teamorders.generic.type = MTYPE_PTEXT; - s_ingame.teamorders.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.teamorders.generic.x = 320; - s_ingame.teamorders.generic.y = y; - s_ingame.teamorders.generic.id = ID_TEAMORDERS; - s_ingame.teamorders.generic.callback = InGame_Event; - s_ingame.teamorders.string = "TEAM ORDERS"; - s_ingame.teamorders.color = color_red; - s_ingame.teamorders.style = UI_CENTER|UI_SMALLFONT; - if( !(trap_Cvar_VariableValue( "g_gametype" ) >= GT_TEAM) ) { - s_ingame.teamorders.generic.flags |= QMF_GRAYED; - } - else { - trap_GetClientState( &cs ); - trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); - team = atoi( Info_ValueForKey( info, "t" ) ); - if( team == TEAM_SPECTATOR ) { - s_ingame.teamorders.generic.flags |= QMF_GRAYED; - } - } - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.setup.generic.type = MTYPE_PTEXT; - s_ingame.setup.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.setup.generic.x = 320; - s_ingame.setup.generic.y = y; - s_ingame.setup.generic.id = ID_SETUP; - s_ingame.setup.generic.callback = InGame_Event; - s_ingame.setup.string = "SETUP"; - s_ingame.setup.color = color_red; - s_ingame.setup.style = UI_CENTER|UI_SMALLFONT; - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.server.generic.type = MTYPE_PTEXT; - s_ingame.server.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.server.generic.x = 320; - s_ingame.server.generic.y = y; - s_ingame.server.generic.id = ID_SERVERINFO; - s_ingame.server.generic.callback = InGame_Event; - s_ingame.server.string = "SERVER INFO"; - s_ingame.server.color = color_red; - s_ingame.server.style = UI_CENTER|UI_SMALLFONT; - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.restart.generic.type = MTYPE_PTEXT; - s_ingame.restart.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.restart.generic.x = 320; - s_ingame.restart.generic.y = y; - s_ingame.restart.generic.id = ID_RESTART; - s_ingame.restart.generic.callback = InGame_Event; - s_ingame.restart.string = "RESTART ARENA"; - s_ingame.restart.color = color_red; - s_ingame.restart.style = UI_CENTER|UI_SMALLFONT; - if( !trap_Cvar_VariableValue( "sv_running" ) ) { - s_ingame.restart.generic.flags |= QMF_GRAYED; - } - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.resume.generic.type = MTYPE_PTEXT; - s_ingame.resume.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.resume.generic.x = 320; - s_ingame.resume.generic.y = y; - s_ingame.resume.generic.id = ID_RESUME; - s_ingame.resume.generic.callback = InGame_Event; - s_ingame.resume.string = "RESUME GAME"; - s_ingame.resume.color = color_red; - s_ingame.resume.style = UI_CENTER|UI_SMALLFONT; - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.leave.generic.type = MTYPE_PTEXT; - s_ingame.leave.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.leave.generic.x = 320; - s_ingame.leave.generic.y = y; - s_ingame.leave.generic.id = ID_LEAVEARENA; - s_ingame.leave.generic.callback = InGame_Event; - s_ingame.leave.string = "LEAVE ARENA"; - s_ingame.leave.color = color_red; - s_ingame.leave.style = UI_CENTER|UI_SMALLFONT; - - y += INGAME_MENU_VERTICAL_SPACING; - s_ingame.quit.generic.type = MTYPE_PTEXT; - s_ingame.quit.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_ingame.quit.generic.x = 320; - s_ingame.quit.generic.y = y; - s_ingame.quit.generic.id = ID_QUIT; - s_ingame.quit.generic.callback = InGame_Event; - s_ingame.quit.string = "EXIT GAME"; - s_ingame.quit.color = color_red; - s_ingame.quit.style = UI_CENTER|UI_SMALLFONT; - - Menu_AddItem( &s_ingame.menu, &s_ingame.frame ); - Menu_AddItem( &s_ingame.menu, &s_ingame.team ); - Menu_AddItem( &s_ingame.menu, &s_ingame.addbots ); - Menu_AddItem( &s_ingame.menu, &s_ingame.removebots ); - Menu_AddItem( &s_ingame.menu, &s_ingame.teamorders ); - Menu_AddItem( &s_ingame.menu, &s_ingame.setup ); - Menu_AddItem( &s_ingame.menu, &s_ingame.server ); - Menu_AddItem( &s_ingame.menu, &s_ingame.restart ); - Menu_AddItem( &s_ingame.menu, &s_ingame.resume ); - Menu_AddItem( &s_ingame.menu, &s_ingame.leave ); - Menu_AddItem( &s_ingame.menu, &s_ingame.quit ); -} - - -/* -================= -InGame_Cache -================= -*/ -void InGame_Cache( void ) { - trap_R_RegisterShaderNoMip( INGAME_FRAME ); -} - - -/* -================= -UI_InGameMenu -================= -*/ -void UI_InGameMenu( void ) { - // force as top level menu - uis.menusp = 0; - - // set menu cursor to a nice location - uis.cursorx = 319; - uis.cursory = 80; - - InGame_MenuInit(); - UI_PushMenu( &s_ingame.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +INGAME MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define INGAME_FRAME "menu/art/addbotframe" +//#define INGAME_FRAME "menu/art/cut_frame" +#define INGAME_MENU_VERTICAL_SPACING 28 + +#define ID_TEAM 10 +#define ID_ADDBOTS 11 +#define ID_REMOVEBOTS 12 +#define ID_SETUP 13 +#define ID_SERVERINFO 14 +#define ID_LEAVEARENA 15 +#define ID_RESTART 16 +#define ID_QUIT 17 +#define ID_RESUME 18 +#define ID_TEAMORDERS 19 + + +typedef struct { + menuframework_s menu; + + menubitmap_s frame; + menutext_s team; + menutext_s setup; + menutext_s server; + menutext_s leave; + menutext_s restart; + menutext_s addbots; + menutext_s removebots; + menutext_s teamorders; + menutext_s quit; + menutext_s resume; +} ingamemenu_t; + +static ingamemenu_t s_ingame; + + +/* +================= +InGame_RestartAction +================= +*/ +static void InGame_RestartAction( qboolean result ) { + if( !result ) { + return; + } + + UI_PopMenu(); + trap_Cmd_ExecuteText( EXEC_APPEND, "map_restart 0\n" ); +} + + +/* +================= +InGame_QuitAction +================= +*/ +static void InGame_QuitAction( qboolean result ) { + if( !result ) { + return; + } + UI_PopMenu(); + UI_CreditMenu(); +} + + +/* +================= +InGame_Event +================= +*/ +void InGame_Event( void *ptr, int notification ) { + if( notification != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_TEAM: + UI_TeamMainMenu(); + break; + + case ID_SETUP: + UI_SetupMenu(); + break; + + case ID_LEAVEARENA: + trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); + break; + + case ID_RESTART: + UI_ConfirmMenu( "RESTART ARENA?", (voidfunc_f)NULL, InGame_RestartAction ); + break; + + case ID_QUIT: + UI_ConfirmMenu( "EXIT GAME?", (voidfunc_f)NULL, InGame_QuitAction ); + break; + + case ID_SERVERINFO: + UI_ServerInfoMenu(); + break; + + case ID_ADDBOTS: + UI_AddBotsMenu(); + break; + + case ID_REMOVEBOTS: + UI_RemoveBotsMenu(); + break; + + case ID_TEAMORDERS: + UI_TeamOrdersMenu(); + break; + + case ID_RESUME: + UI_PopMenu(); + break; + } +} + + +/* +================= +InGame_MenuInit +================= +*/ +void InGame_MenuInit( void ) { + int y; + uiClientState_t cs; + char info[MAX_INFO_STRING]; + int team; + + memset( &s_ingame, 0 ,sizeof(ingamemenu_t) ); + + InGame_Cache(); + + s_ingame.menu.wrapAround = qtrue; + s_ingame.menu.fullscreen = qfalse; + + s_ingame.frame.generic.type = MTYPE_BITMAP; + s_ingame.frame.generic.flags = QMF_INACTIVE; + s_ingame.frame.generic.name = INGAME_FRAME; + s_ingame.frame.generic.x = 320-233;//142; + s_ingame.frame.generic.y = 240-166;//118; + s_ingame.frame.width = 466;//359; + s_ingame.frame.height = 332;//256; + + //y = 96; + y = 88; + s_ingame.team.generic.type = MTYPE_PTEXT; + s_ingame.team.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.team.generic.x = 320; + s_ingame.team.generic.y = y; + s_ingame.team.generic.id = ID_TEAM; + s_ingame.team.generic.callback = InGame_Event; + s_ingame.team.string = "START"; + s_ingame.team.color = color_red; + s_ingame.team.style = UI_CENTER|UI_SMALLFONT; + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.addbots.generic.type = MTYPE_PTEXT; + s_ingame.addbots.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.addbots.generic.x = 320; + s_ingame.addbots.generic.y = y; + s_ingame.addbots.generic.id = ID_ADDBOTS; + s_ingame.addbots.generic.callback = InGame_Event; + s_ingame.addbots.string = "ADD BOTS"; + s_ingame.addbots.color = color_red; + s_ingame.addbots.style = UI_CENTER|UI_SMALLFONT; + if( !trap_Cvar_VariableValue( "sv_running" ) || !trap_Cvar_VariableValue( "bot_enable" ) || (trap_Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER)) { + s_ingame.addbots.generic.flags |= QMF_GRAYED; + } + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.removebots.generic.type = MTYPE_PTEXT; + s_ingame.removebots.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.removebots.generic.x = 320; + s_ingame.removebots.generic.y = y; + s_ingame.removebots.generic.id = ID_REMOVEBOTS; + s_ingame.removebots.generic.callback = InGame_Event; + s_ingame.removebots.string = "REMOVE BOTS"; + s_ingame.removebots.color = color_red; + s_ingame.removebots.style = UI_CENTER|UI_SMALLFONT; + if( !trap_Cvar_VariableValue( "sv_running" ) || !trap_Cvar_VariableValue( "bot_enable" ) || (trap_Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER)) { + s_ingame.removebots.generic.flags |= QMF_GRAYED; + } + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.teamorders.generic.type = MTYPE_PTEXT; + s_ingame.teamorders.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.teamorders.generic.x = 320; + s_ingame.teamorders.generic.y = y; + s_ingame.teamorders.generic.id = ID_TEAMORDERS; + s_ingame.teamorders.generic.callback = InGame_Event; + s_ingame.teamorders.string = "TEAM ORDERS"; + s_ingame.teamorders.color = color_red; + s_ingame.teamorders.style = UI_CENTER|UI_SMALLFONT; + if( !(trap_Cvar_VariableValue( "g_gametype" ) >= GT_TEAM) ) { + s_ingame.teamorders.generic.flags |= QMF_GRAYED; + } + else { + trap_GetClientState( &cs ); + trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); + team = atoi( Info_ValueForKey( info, "t" ) ); + if( team == TEAM_SPECTATOR ) { + s_ingame.teamorders.generic.flags |= QMF_GRAYED; + } + } + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.setup.generic.type = MTYPE_PTEXT; + s_ingame.setup.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.setup.generic.x = 320; + s_ingame.setup.generic.y = y; + s_ingame.setup.generic.id = ID_SETUP; + s_ingame.setup.generic.callback = InGame_Event; + s_ingame.setup.string = "SETUP"; + s_ingame.setup.color = color_red; + s_ingame.setup.style = UI_CENTER|UI_SMALLFONT; + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.server.generic.type = MTYPE_PTEXT; + s_ingame.server.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.server.generic.x = 320; + s_ingame.server.generic.y = y; + s_ingame.server.generic.id = ID_SERVERINFO; + s_ingame.server.generic.callback = InGame_Event; + s_ingame.server.string = "SERVER INFO"; + s_ingame.server.color = color_red; + s_ingame.server.style = UI_CENTER|UI_SMALLFONT; + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.restart.generic.type = MTYPE_PTEXT; + s_ingame.restart.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.restart.generic.x = 320; + s_ingame.restart.generic.y = y; + s_ingame.restart.generic.id = ID_RESTART; + s_ingame.restart.generic.callback = InGame_Event; + s_ingame.restart.string = "RESTART ARENA"; + s_ingame.restart.color = color_red; + s_ingame.restart.style = UI_CENTER|UI_SMALLFONT; + if( !trap_Cvar_VariableValue( "sv_running" ) ) { + s_ingame.restart.generic.flags |= QMF_GRAYED; + } + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.resume.generic.type = MTYPE_PTEXT; + s_ingame.resume.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.resume.generic.x = 320; + s_ingame.resume.generic.y = y; + s_ingame.resume.generic.id = ID_RESUME; + s_ingame.resume.generic.callback = InGame_Event; + s_ingame.resume.string = "RESUME GAME"; + s_ingame.resume.color = color_red; + s_ingame.resume.style = UI_CENTER|UI_SMALLFONT; + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.leave.generic.type = MTYPE_PTEXT; + s_ingame.leave.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.leave.generic.x = 320; + s_ingame.leave.generic.y = y; + s_ingame.leave.generic.id = ID_LEAVEARENA; + s_ingame.leave.generic.callback = InGame_Event; + s_ingame.leave.string = "LEAVE ARENA"; + s_ingame.leave.color = color_red; + s_ingame.leave.style = UI_CENTER|UI_SMALLFONT; + + y += INGAME_MENU_VERTICAL_SPACING; + s_ingame.quit.generic.type = MTYPE_PTEXT; + s_ingame.quit.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_ingame.quit.generic.x = 320; + s_ingame.quit.generic.y = y; + s_ingame.quit.generic.id = ID_QUIT; + s_ingame.quit.generic.callback = InGame_Event; + s_ingame.quit.string = "EXIT GAME"; + s_ingame.quit.color = color_red; + s_ingame.quit.style = UI_CENTER|UI_SMALLFONT; + + Menu_AddItem( &s_ingame.menu, &s_ingame.frame ); + Menu_AddItem( &s_ingame.menu, &s_ingame.team ); + Menu_AddItem( &s_ingame.menu, &s_ingame.addbots ); + Menu_AddItem( &s_ingame.menu, &s_ingame.removebots ); + Menu_AddItem( &s_ingame.menu, &s_ingame.teamorders ); + Menu_AddItem( &s_ingame.menu, &s_ingame.setup ); + Menu_AddItem( &s_ingame.menu, &s_ingame.server ); + Menu_AddItem( &s_ingame.menu, &s_ingame.restart ); + Menu_AddItem( &s_ingame.menu, &s_ingame.resume ); + Menu_AddItem( &s_ingame.menu, &s_ingame.leave ); + Menu_AddItem( &s_ingame.menu, &s_ingame.quit ); +} + + +/* +================= +InGame_Cache +================= +*/ +void InGame_Cache( void ) { + trap_R_RegisterShaderNoMip( INGAME_FRAME ); +} + + +/* +================= +UI_InGameMenu +================= +*/ +void UI_InGameMenu( void ) { + // force as top level menu + uis.menusp = 0; + + // set menu cursor to a nice location + uis.cursorx = 319; + uis.cursory = 80; + + InGame_MenuInit(); + UI_PushMenu( &s_ingame.menu ); +} diff --git a/code/q3_ui/ui_loadconfig.c b/code/q3_ui/ui_loadconfig.c index 24aff9f..7d5e5f1 100755 --- a/code/q3_ui/ui_loadconfig.c +++ b/code/q3_ui/ui_loadconfig.c @@ -1,274 +1,274 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -============================================================================= - -LOAD CONFIG MENU - -============================================================================= -*/ - -#include "ui_local.h" - - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FIGHT0 "menu/art/load_0" -#define ART_FIGHT1 "menu/art/load_1" -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_ARROWS "menu/art/arrows_horz_0" -#define ART_ARROWLEFT "menu/art/arrows_horz_left" -#define ART_ARROWRIGHT "menu/art/arrows_horz_right" - -#define MAX_CONFIGS 128 -#define NAMEBUFSIZE ( MAX_CONFIGS * 16 ) - -#define ID_BACK 10 -#define ID_GO 11 -#define ID_LIST 12 -#define ID_LEFT 13 -#define ID_RIGHT 14 - -#define ARROWS_WIDTH 128 -#define ARROWS_HEIGHT 48 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menulist_s list; - - menubitmap_s arrows; - menubitmap_s left; - menubitmap_s right; - menubitmap_s back; - menubitmap_s go; - - char names[NAMEBUFSIZE]; - char* configlist[MAX_CONFIGS]; -} configs_t; - -static configs_t s_configs; - - -/* -=============== -LoadConfig_MenuEvent -=============== -*/ -static void LoadConfig_MenuEvent( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch ( ((menucommon_s*)ptr)->id ) { - case ID_GO: - trap_Cmd_ExecuteText( EXEC_APPEND, va( "exec %s\n", s_configs.list.itemnames[s_configs.list.curvalue] ) ); - UI_PopMenu(); - break; - - case ID_BACK: - UI_PopMenu(); - break; - - case ID_LEFT: - ScrollList_Key( &s_configs.list, K_LEFTARROW ); - break; - - case ID_RIGHT: - ScrollList_Key( &s_configs.list, K_RIGHTARROW ); - break; - } -} - - -/* -=============== -LoadConfig_MenuInit -=============== -*/ -static void LoadConfig_MenuInit( void ) { - int i; - int len; - char *configname; - - UI_LoadConfig_Cache(); - - memset( &s_configs, 0 ,sizeof(configs_t) ); - s_configs.menu.wrapAround = qtrue; - s_configs.menu.fullscreen = qtrue; - - s_configs.banner.generic.type = MTYPE_BTEXT; - s_configs.banner.generic.x = 320; - s_configs.banner.generic.y = 16; - s_configs.banner.string = "LOAD CONFIG"; - s_configs.banner.color = color_white; - s_configs.banner.style = UI_CENTER; - - s_configs.framel.generic.type = MTYPE_BITMAP; - s_configs.framel.generic.name = ART_FRAMEL; - s_configs.framel.generic.flags = QMF_INACTIVE; - s_configs.framel.generic.x = 0; - s_configs.framel.generic.y = 78; - s_configs.framel.width = 256; - s_configs.framel.height = 329; - - s_configs.framer.generic.type = MTYPE_BITMAP; - s_configs.framer.generic.name = ART_FRAMER; - s_configs.framer.generic.flags = QMF_INACTIVE; - s_configs.framer.generic.x = 376; - s_configs.framer.generic.y = 76; - s_configs.framer.width = 256; - s_configs.framer.height = 334; - - s_configs.arrows.generic.type = MTYPE_BITMAP; - s_configs.arrows.generic.name = ART_ARROWS; - s_configs.arrows.generic.flags = QMF_INACTIVE; - s_configs.arrows.generic.x = 320-ARROWS_WIDTH/2; - s_configs.arrows.generic.y = 400; - s_configs.arrows.width = ARROWS_WIDTH; - s_configs.arrows.height = ARROWS_HEIGHT; - - s_configs.left.generic.type = MTYPE_BITMAP; - s_configs.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - s_configs.left.generic.x = 320-ARROWS_WIDTH/2; - s_configs.left.generic.y = 400; - s_configs.left.generic.id = ID_LEFT; - s_configs.left.generic.callback = LoadConfig_MenuEvent; - s_configs.left.width = ARROWS_WIDTH/2; - s_configs.left.height = ARROWS_HEIGHT; - s_configs.left.focuspic = ART_ARROWLEFT; - - s_configs.right.generic.type = MTYPE_BITMAP; - s_configs.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - s_configs.right.generic.x = 320; - s_configs.right.generic.y = 400; - s_configs.right.generic.id = ID_RIGHT; - s_configs.right.generic.callback = LoadConfig_MenuEvent; - s_configs.right.width = ARROWS_WIDTH/2; - s_configs.right.height = ARROWS_HEIGHT; - s_configs.right.focuspic = ART_ARROWRIGHT; - - s_configs.back.generic.type = MTYPE_BITMAP; - s_configs.back.generic.name = ART_BACK0; - s_configs.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_configs.back.generic.id = ID_BACK; - s_configs.back.generic.callback = LoadConfig_MenuEvent; - s_configs.back.generic.x = 0; - s_configs.back.generic.y = 480-64; - s_configs.back.width = 128; - s_configs.back.height = 64; - s_configs.back.focuspic = ART_BACK1; - - s_configs.go.generic.type = MTYPE_BITMAP; - s_configs.go.generic.name = ART_FIGHT0; - s_configs.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_configs.go.generic.id = ID_GO; - s_configs.go.generic.callback = LoadConfig_MenuEvent; - s_configs.go.generic.x = 640; - s_configs.go.generic.y = 480-64; - s_configs.go.width = 128; - s_configs.go.height = 64; - s_configs.go.focuspic = ART_FIGHT1; - - // scan for configs - s_configs.list.generic.type = MTYPE_SCROLLLIST; - s_configs.list.generic.flags = QMF_PULSEIFFOCUS; - s_configs.list.generic.callback = LoadConfig_MenuEvent; - s_configs.list.generic.id = ID_LIST; - s_configs.list.generic.x = 118; - s_configs.list.generic.y = 130; - s_configs.list.width = 16; - s_configs.list.height = 14; - s_configs.list.numitems = trap_FS_GetFileList( "", "cfg", s_configs.names, NAMEBUFSIZE ); - s_configs.list.itemnames = (const char **)s_configs.configlist; - s_configs.list.columns = 3; - - if (!s_configs.list.numitems) { - strcpy(s_configs.names,"No Files Found."); - s_configs.list.numitems = 1; - - //degenerate case, not selectable - s_configs.go.generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - else if (s_configs.list.numitems > MAX_CONFIGS) - s_configs.list.numitems = MAX_CONFIGS; - - configname = s_configs.names; - for ( i = 0; i < s_configs.list.numitems; i++ ) { - s_configs.list.itemnames[i] = configname; - - // strip extension - len = strlen( configname ); - if (!Q_stricmp(configname + len - 4,".cfg")) - configname[len-4] = '\0'; - - Q_strupr(configname); - - configname += len + 1; - } - - Menu_AddItem( &s_configs.menu, &s_configs.banner ); - Menu_AddItem( &s_configs.menu, &s_configs.framel ); - Menu_AddItem( &s_configs.menu, &s_configs.framer ); - Menu_AddItem( &s_configs.menu, &s_configs.list ); - Menu_AddItem( &s_configs.menu, &s_configs.arrows ); - Menu_AddItem( &s_configs.menu, &s_configs.left ); - Menu_AddItem( &s_configs.menu, &s_configs.right ); - Menu_AddItem( &s_configs.menu, &s_configs.back ); - Menu_AddItem( &s_configs.menu, &s_configs.go ); -} - -/* -================= -UI_LoadConfig_Cache -================= -*/ -void UI_LoadConfig_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FIGHT0 ); - trap_R_RegisterShaderNoMip( ART_FIGHT1 ); - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_ARROWS ); - trap_R_RegisterShaderNoMip( ART_ARROWLEFT ); - trap_R_RegisterShaderNoMip( ART_ARROWRIGHT ); -} - - -/* -=============== -UI_LoadConfigMenu -=============== -*/ -void UI_LoadConfigMenu( void ) { - LoadConfig_MenuInit(); - UI_PushMenu( &s_configs.menu ); -} - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +============================================================================= + +LOAD CONFIG MENU + +============================================================================= +*/ + +#include "ui_local.h" + + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FIGHT0 "menu/art/load_0" +#define ART_FIGHT1 "menu/art/load_1" +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_ARROWS "menu/art/arrows_horz_0" +#define ART_ARROWLEFT "menu/art/arrows_horz_left" +#define ART_ARROWRIGHT "menu/art/arrows_horz_right" + +#define MAX_CONFIGS 128 +#define NAMEBUFSIZE ( MAX_CONFIGS * 16 ) + +#define ID_BACK 10 +#define ID_GO 11 +#define ID_LIST 12 +#define ID_LEFT 13 +#define ID_RIGHT 14 + +#define ARROWS_WIDTH 128 +#define ARROWS_HEIGHT 48 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menulist_s list; + + menubitmap_s arrows; + menubitmap_s left; + menubitmap_s right; + menubitmap_s back; + menubitmap_s go; + + char names[NAMEBUFSIZE]; + char* configlist[MAX_CONFIGS]; +} configs_t; + +static configs_t s_configs; + + +/* +=============== +LoadConfig_MenuEvent +=============== +*/ +static void LoadConfig_MenuEvent( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch ( ((menucommon_s*)ptr)->id ) { + case ID_GO: + trap_Cmd_ExecuteText( EXEC_APPEND, va( "exec %s\n", s_configs.list.itemnames[s_configs.list.curvalue] ) ); + UI_PopMenu(); + break; + + case ID_BACK: + UI_PopMenu(); + break; + + case ID_LEFT: + ScrollList_Key( &s_configs.list, K_LEFTARROW ); + break; + + case ID_RIGHT: + ScrollList_Key( &s_configs.list, K_RIGHTARROW ); + break; + } +} + + +/* +=============== +LoadConfig_MenuInit +=============== +*/ +static void LoadConfig_MenuInit( void ) { + int i; + int len; + char *configname; + + UI_LoadConfig_Cache(); + + memset( &s_configs, 0 ,sizeof(configs_t) ); + s_configs.menu.wrapAround = qtrue; + s_configs.menu.fullscreen = qtrue; + + s_configs.banner.generic.type = MTYPE_BTEXT; + s_configs.banner.generic.x = 320; + s_configs.banner.generic.y = 16; + s_configs.banner.string = "LOAD CONFIG"; + s_configs.banner.color = color_white; + s_configs.banner.style = UI_CENTER; + + s_configs.framel.generic.type = MTYPE_BITMAP; + s_configs.framel.generic.name = ART_FRAMEL; + s_configs.framel.generic.flags = QMF_INACTIVE; + s_configs.framel.generic.x = 0; + s_configs.framel.generic.y = 78; + s_configs.framel.width = 256; + s_configs.framel.height = 329; + + s_configs.framer.generic.type = MTYPE_BITMAP; + s_configs.framer.generic.name = ART_FRAMER; + s_configs.framer.generic.flags = QMF_INACTIVE; + s_configs.framer.generic.x = 376; + s_configs.framer.generic.y = 76; + s_configs.framer.width = 256; + s_configs.framer.height = 334; + + s_configs.arrows.generic.type = MTYPE_BITMAP; + s_configs.arrows.generic.name = ART_ARROWS; + s_configs.arrows.generic.flags = QMF_INACTIVE; + s_configs.arrows.generic.x = 320-ARROWS_WIDTH/2; + s_configs.arrows.generic.y = 400; + s_configs.arrows.width = ARROWS_WIDTH; + s_configs.arrows.height = ARROWS_HEIGHT; + + s_configs.left.generic.type = MTYPE_BITMAP; + s_configs.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + s_configs.left.generic.x = 320-ARROWS_WIDTH/2; + s_configs.left.generic.y = 400; + s_configs.left.generic.id = ID_LEFT; + s_configs.left.generic.callback = LoadConfig_MenuEvent; + s_configs.left.width = ARROWS_WIDTH/2; + s_configs.left.height = ARROWS_HEIGHT; + s_configs.left.focuspic = ART_ARROWLEFT; + + s_configs.right.generic.type = MTYPE_BITMAP; + s_configs.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + s_configs.right.generic.x = 320; + s_configs.right.generic.y = 400; + s_configs.right.generic.id = ID_RIGHT; + s_configs.right.generic.callback = LoadConfig_MenuEvent; + s_configs.right.width = ARROWS_WIDTH/2; + s_configs.right.height = ARROWS_HEIGHT; + s_configs.right.focuspic = ART_ARROWRIGHT; + + s_configs.back.generic.type = MTYPE_BITMAP; + s_configs.back.generic.name = ART_BACK0; + s_configs.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_configs.back.generic.id = ID_BACK; + s_configs.back.generic.callback = LoadConfig_MenuEvent; + s_configs.back.generic.x = 0; + s_configs.back.generic.y = 480-64; + s_configs.back.width = 128; + s_configs.back.height = 64; + s_configs.back.focuspic = ART_BACK1; + + s_configs.go.generic.type = MTYPE_BITMAP; + s_configs.go.generic.name = ART_FIGHT0; + s_configs.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_configs.go.generic.id = ID_GO; + s_configs.go.generic.callback = LoadConfig_MenuEvent; + s_configs.go.generic.x = 640; + s_configs.go.generic.y = 480-64; + s_configs.go.width = 128; + s_configs.go.height = 64; + s_configs.go.focuspic = ART_FIGHT1; + + // scan for configs + s_configs.list.generic.type = MTYPE_SCROLLLIST; + s_configs.list.generic.flags = QMF_PULSEIFFOCUS; + s_configs.list.generic.callback = LoadConfig_MenuEvent; + s_configs.list.generic.id = ID_LIST; + s_configs.list.generic.x = 118; + s_configs.list.generic.y = 130; + s_configs.list.width = 16; + s_configs.list.height = 14; + s_configs.list.numitems = trap_FS_GetFileList( "", "cfg", s_configs.names, NAMEBUFSIZE ); + s_configs.list.itemnames = (const char **)s_configs.configlist; + s_configs.list.columns = 3; + + if (!s_configs.list.numitems) { + strcpy(s_configs.names,"No Files Found."); + s_configs.list.numitems = 1; + + //degenerate case, not selectable + s_configs.go.generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + else if (s_configs.list.numitems > MAX_CONFIGS) + s_configs.list.numitems = MAX_CONFIGS; + + configname = s_configs.names; + for ( i = 0; i < s_configs.list.numitems; i++ ) { + s_configs.list.itemnames[i] = configname; + + // strip extension + len = strlen( configname ); + if (!Q_stricmp(configname + len - 4,".cfg")) + configname[len-4] = '\0'; + + Q_strupr(configname); + + configname += len + 1; + } + + Menu_AddItem( &s_configs.menu, &s_configs.banner ); + Menu_AddItem( &s_configs.menu, &s_configs.framel ); + Menu_AddItem( &s_configs.menu, &s_configs.framer ); + Menu_AddItem( &s_configs.menu, &s_configs.list ); + Menu_AddItem( &s_configs.menu, &s_configs.arrows ); + Menu_AddItem( &s_configs.menu, &s_configs.left ); + Menu_AddItem( &s_configs.menu, &s_configs.right ); + Menu_AddItem( &s_configs.menu, &s_configs.back ); + Menu_AddItem( &s_configs.menu, &s_configs.go ); +} + +/* +================= +UI_LoadConfig_Cache +================= +*/ +void UI_LoadConfig_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FIGHT0 ); + trap_R_RegisterShaderNoMip( ART_FIGHT1 ); + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_ARROWS ); + trap_R_RegisterShaderNoMip( ART_ARROWLEFT ); + trap_R_RegisterShaderNoMip( ART_ARROWRIGHT ); +} + + +/* +=============== +UI_LoadConfigMenu +=============== +*/ +void UI_LoadConfigMenu( void ) { + LoadConfig_MenuInit(); + UI_PushMenu( &s_configs.menu ); +} + diff --git a/code/q3_ui/ui_local.h b/code/q3_ui/ui_local.h index 71ea0de..5d66770 100755 --- a/code/q3_ui/ui_local.h +++ b/code/q3_ui/ui_local.h @@ -1,800 +1,800 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#ifndef __UI_LOCAL_H__ -#define __UI_LOCAL_H__ - -#include "../game/q_shared.h" -#include "../cgame/tr_types.h" -//NOTE: include the ui_public.h from the new UI -#include "../ui/ui_public.h" // bk001205 - yes, do have to use this -//redefine to old API version -#undef UI_API_VERSION -#define UI_API_VERSION 4 -#include "keycodes.h" -#include "../game/bg_public.h" - -typedef void (*voidfunc_f)(void); - -extern vmCvar_t ui_ffa_fraglimit; -extern vmCvar_t ui_ffa_timelimit; - -extern vmCvar_t ui_tourney_fraglimit; -extern vmCvar_t ui_tourney_timelimit; - -extern vmCvar_t ui_team_fraglimit; -extern vmCvar_t ui_team_timelimit; -extern vmCvar_t ui_team_friendly; - -extern vmCvar_t ui_ctf_capturelimit; -extern vmCvar_t ui_ctf_timelimit; -extern vmCvar_t ui_ctf_friendly; - -extern vmCvar_t ui_arenasFile; -extern vmCvar_t ui_botsFile; -extern vmCvar_t ui_spScores1; -extern vmCvar_t ui_spScores2; -extern vmCvar_t ui_spScores3; -extern vmCvar_t ui_spScores4; -extern vmCvar_t ui_spScores5; -extern vmCvar_t ui_spAwards; -extern vmCvar_t ui_spVideos; -extern vmCvar_t ui_spSkill; - -extern vmCvar_t ui_spSelection; - -extern vmCvar_t ui_browserMaster; -extern vmCvar_t ui_browserGameType; -extern vmCvar_t ui_browserSortKey; -extern vmCvar_t ui_browserShowFull; -extern vmCvar_t ui_browserShowEmpty; - -extern vmCvar_t ui_brassTime; -extern vmCvar_t ui_drawCrosshair; -extern vmCvar_t ui_drawCrosshairNames; -extern vmCvar_t ui_marks; - -extern vmCvar_t ui_server1; -extern vmCvar_t ui_server2; -extern vmCvar_t ui_server3; -extern vmCvar_t ui_server4; -extern vmCvar_t ui_server5; -extern vmCvar_t ui_server6; -extern vmCvar_t ui_server7; -extern vmCvar_t ui_server8; -extern vmCvar_t ui_server9; -extern vmCvar_t ui_server10; -extern vmCvar_t ui_server11; -extern vmCvar_t ui_server12; -extern vmCvar_t ui_server13; -extern vmCvar_t ui_server14; -extern vmCvar_t ui_server15; -extern vmCvar_t ui_server16; - -extern vmCvar_t ui_cdkey; -extern vmCvar_t ui_cdkeychecked; - - -// -// ui_qmenu.c -// - -#define RCOLUMN_OFFSET ( BIGCHAR_WIDTH ) -#define LCOLUMN_OFFSET (-BIGCHAR_WIDTH ) - -#define SLIDER_RANGE 10 -#define MAX_EDIT_LINE 256 - -#define MAX_MENUDEPTH 8 -#define MAX_MENUITEMS 64 - -#define MTYPE_NULL 0 -#define MTYPE_SLIDER 1 -#define MTYPE_ACTION 2 -#define MTYPE_SPINCONTROL 3 -#define MTYPE_FIELD 4 -#define MTYPE_RADIOBUTTON 5 -#define MTYPE_BITMAP 6 -#define MTYPE_TEXT 7 -#define MTYPE_SCROLLLIST 8 -#define MTYPE_PTEXT 9 -#define MTYPE_BTEXT 10 - -#define QMF_BLINK 0x00000001 -#define QMF_SMALLFONT 0x00000002 -#define QMF_LEFT_JUSTIFY 0x00000004 -#define QMF_CENTER_JUSTIFY 0x00000008 -#define QMF_RIGHT_JUSTIFY 0x00000010 -#define QMF_NUMBERSONLY 0x00000020 // edit field is only numbers -#define QMF_HIGHLIGHT 0x00000040 -#define QMF_HIGHLIGHT_IF_FOCUS 0x00000080 // steady focus -#define QMF_PULSEIFFOCUS 0x00000100 // pulse if focus -#define QMF_HASMOUSEFOCUS 0x00000200 -#define QMF_NOONOFFTEXT 0x00000400 -#define QMF_MOUSEONLY 0x00000800 // only mouse input allowed -#define QMF_HIDDEN 0x00001000 // skips drawing -#define QMF_GRAYED 0x00002000 // grays and disables -#define QMF_INACTIVE 0x00004000 // disables any input -#define QMF_NODEFAULTINIT 0x00008000 // skip default initialization -#define QMF_OWNERDRAW 0x00010000 -#define QMF_PULSE 0x00020000 -#define QMF_LOWERCASE 0x00040000 // edit field is all lower case -#define QMF_UPPERCASE 0x00080000 // edit field is all upper case -#define QMF_SILENT 0x00100000 - -// callback notifications -#define QM_GOTFOCUS 1 -#define QM_LOSTFOCUS 2 -#define QM_ACTIVATED 3 - -typedef struct _tag_menuframework -{ - int cursor; - int cursor_prev; - - int nitems; - void *items[MAX_MENUITEMS]; - - void (*draw) (void); - sfxHandle_t (*key) (int key); - - qboolean wrapAround; - qboolean fullscreen; - qboolean showlogo; -} menuframework_s; - -typedef struct -{ - int type; - const char *name; - int id; - int x, y; - int left; - int top; - int right; - int bottom; - menuframework_s *parent; - int menuPosition; - unsigned flags; - - void (*callback)( void *self, int event ); - void (*statusbar)( void *self ); - void (*ownerdraw)( void *self ); -} menucommon_s; - -typedef struct { - int cursor; - int scroll; - int widthInChars; - char buffer[MAX_EDIT_LINE]; - int maxchars; -} mfield_t; - -typedef struct -{ - menucommon_s generic; - mfield_t field; -} menufield_s; - -typedef struct -{ - menucommon_s generic; - - float minvalue; - float maxvalue; - float curvalue; - - float range; -} menuslider_s; - -typedef struct -{ - menucommon_s generic; - - int oldvalue; - int curvalue; - int numitems; - int top; - - const char **itemnames; - - int width; - int height; - int columns; - int seperation; -} menulist_s; - -typedef struct -{ - menucommon_s generic; -} menuaction_s; - -typedef struct -{ - menucommon_s generic; - int curvalue; -} menuradiobutton_s; - -typedef struct -{ - menucommon_s generic; - char* focuspic; - char* errorpic; - qhandle_t shader; - qhandle_t focusshader; - int width; - int height; - float* focuscolor; -} menubitmap_s; - -typedef struct -{ - menucommon_s generic; - char* string; - int style; - float* color; -} menutext_s; - -extern void Menu_Cache( void ); -extern void Menu_Focus( menucommon_s *m ); -extern void Menu_AddItem( menuframework_s *menu, void *item ); -extern void Menu_AdjustCursor( menuframework_s *menu, int dir ); -extern void Menu_Draw( menuframework_s *menu ); -extern void *Menu_ItemAtCursor( menuframework_s *m ); -extern sfxHandle_t Menu_ActivateItem( menuframework_s *s, menucommon_s* item ); -extern void Menu_SetCursor( menuframework_s *s, int cursor ); -extern void Menu_SetCursorToItem( menuframework_s *m, void* ptr ); -extern sfxHandle_t Menu_DefaultKey( menuframework_s *s, int key ); -extern void Bitmap_Init( menubitmap_s *b ); -extern void Bitmap_Draw( menubitmap_s *b ); -extern void ScrollList_Draw( menulist_s *l ); -extern sfxHandle_t ScrollList_Key( menulist_s *l, int key ); -extern sfxHandle_t menu_in_sound; -extern sfxHandle_t menu_move_sound; -extern sfxHandle_t menu_out_sound; -extern sfxHandle_t menu_buzz_sound; -extern sfxHandle_t menu_null_sound; -extern sfxHandle_t weaponChangeSound; -extern vec4_t menu_text_color; -extern vec4_t menu_grayed_color; -extern vec4_t menu_dark_color; -extern vec4_t menu_highlight_color; -extern vec4_t menu_red_color; -extern vec4_t menu_black_color; -extern vec4_t menu_dim_color; -extern vec4_t color_black; -extern vec4_t color_white; -extern vec4_t color_yellow; -extern vec4_t color_blue; -extern vec4_t color_orange; -extern vec4_t color_red; -extern vec4_t color_dim; -extern vec4_t name_color; -extern vec4_t list_color; -extern vec4_t listbar_color; -extern vec4_t text_color_disabled; -extern vec4_t text_color_normal; -extern vec4_t text_color_highlight; - -extern char *ui_medalNames[]; -extern char *ui_medalPicNames[]; -extern char *ui_medalSounds[]; - -// -// ui_mfield.c -// -extern void MField_Clear( mfield_t *edit ); -extern void MField_KeyDownEvent( mfield_t *edit, int key ); -extern void MField_CharEvent( mfield_t *edit, int ch ); -extern void MField_Draw( mfield_t *edit, int x, int y, int style, vec4_t color ); -extern void MenuField_Init( menufield_s* m ); -extern void MenuField_Draw( menufield_s *f ); -extern sfxHandle_t MenuField_Key( menufield_s* m, int* key ); - -// -// ui_menu.c -// -extern void MainMenu_Cache( void ); -extern void UI_MainMenu(void); -extern void UI_RegisterCvars( void ); -extern void UI_UpdateCvars( void ); - -// -// ui_credits.c -// -extern void UI_CreditMenu( void ); - -// -// ui_ingame.c -// -extern void InGame_Cache( void ); -extern void UI_InGameMenu(void); - -// -// ui_confirm.c -// -extern void ConfirmMenu_Cache( void ); -extern void UI_ConfirmMenu( const char *question, void (*draw)( void ), void (*action)( qboolean result ) ); -extern void UI_ConfirmMenu_Style( const char *question, int style, void (*draw)( void ), void (*action)( qboolean result ) ); -extern void UI_Message( const char **lines ); - -// -// ui_setup.c -// -extern void UI_SetupMenu_Cache( void ); -extern void UI_SetupMenu(void); - -// -// ui_team.c -// -extern void UI_TeamMainMenu( void ); -extern void TeamMain_Cache( void ); - -// -// ui_connect.c -// -extern void UI_DrawConnectScreen( qboolean overlay ); - -// -// ui_controls2.c -// -extern void UI_ControlsMenu( void ); -extern void Controls_Cache( void ); - -// -// ui_demo2.c -// -extern void UI_DemosMenu( void ); -extern void Demos_Cache( void ); - -// -// ui_cinematics.c -// -extern void UI_CinematicsMenu( void ); -extern void UI_CinematicsMenu_f( void ); -extern void UI_CinematicsMenu_Cache( void ); - -// -// ui_mods.c -// -extern void UI_ModsMenu( void ); -extern void UI_ModsMenu_Cache( void ); - -// -// ui_cdkey.c -// -extern void UI_CDKeyMenu( void ); -extern void UI_CDKeyMenu_Cache( void ); -extern void UI_CDKeyMenu_f( void ); - -// -// ui_playermodel.c -// -extern void UI_PlayerModelMenu( void ); -extern void PlayerModel_Cache( void ); - -// -// ui_playersettings.c -// -extern void UI_PlayerSettingsMenu( void ); -extern void PlayerSettings_Cache( void ); - -// -// ui_preferences.c -// -extern void UI_PreferencesMenu( void ); -extern void Preferences_Cache( void ); - -// -// ui_specifyleague.c -// -extern void UI_SpecifyLeagueMenu( void ); -extern void SpecifyLeague_Cache( void ); - -// -// ui_specifyserver.c -// -extern void UI_SpecifyServerMenu( void ); -extern void SpecifyServer_Cache( void ); - -// -// ui_servers2.c -// -#define MAX_FAVORITESERVERS 16 - -extern void UI_ArenaServersMenu( void ); -extern void ArenaServers_Cache( void ); - -// -// ui_startserver.c -// -extern void UI_StartServerMenu( qboolean multiplayer ); -extern void StartServer_Cache( void ); -extern void ServerOptions_Cache( void ); -extern void UI_BotSelectMenu( char *bot ); -extern void UI_BotSelectMenu_Cache( void ); - -// -// ui_serverinfo.c -// -extern void UI_ServerInfoMenu( void ); -extern void ServerInfo_Cache( void ); - -// -// ui_video.c -// -extern void UI_GraphicsOptionsMenu( void ); -extern void GraphicsOptions_Cache( void ); -extern void DriverInfo_Cache( void ); - -// -// ui_players.c -// - -//FIXME ripped from cg_local.h -typedef struct { - int oldFrame; - int oldFrameTime; // time when ->oldFrame was exactly on - - int frame; - int frameTime; // time when ->frame will be exactly on - - float backlerp; - - float yawAngle; - qboolean yawing; - float pitchAngle; - qboolean pitching; - - int animationNumber; // may include ANIM_TOGGLEBIT - animation_t *animation; - int animationTime; // time when the first frame of the animation will be exact -} lerpFrame_t; - -typedef struct { - // model info - qhandle_t legsModel; - qhandle_t legsSkin; - lerpFrame_t legs; - - qhandle_t torsoModel; - qhandle_t torsoSkin; - lerpFrame_t torso; - - qhandle_t headModel; - qhandle_t headSkin; - - animation_t animations[MAX_ANIMATIONS]; - - qhandle_t weaponModel; - qhandle_t barrelModel; - qhandle_t flashModel; - vec3_t flashDlightColor; - int muzzleFlashTime; - - // currently in use drawing parms - vec3_t viewAngles; - vec3_t moveAngles; - weapon_t currentWeapon; - int legsAnim; - int torsoAnim; - - // animation vars - weapon_t weapon; - weapon_t lastWeapon; - weapon_t pendingWeapon; - int weaponTimer; - int pendingLegsAnim; - int torsoAnimationTimer; - - int pendingTorsoAnim; - int legsAnimationTimer; - - qboolean chat; - qboolean newModel; - - qboolean barrelSpinning; - float barrelAngle; - int barrelTime; - - int realWeapon; -} playerInfo_t; - -void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ); -void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model ); -void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNum, qboolean chat ); -qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName ); - -// -// ui_atoms.c -// -typedef struct { - int frametime; - int realtime; - int cursorx; - int cursory; - int menusp; - menuframework_s* activemenu; - menuframework_s* stack[MAX_MENUDEPTH]; - glconfig_t glconfig; - qboolean debug; - qhandle_t whiteShader; - qhandle_t menuBackShader; - qhandle_t menuBackNoLogoShader; - qhandle_t charset; - qhandle_t charsetProp; - qhandle_t charsetPropGlow; - qhandle_t charsetPropB; - qhandle_t cursor; - qhandle_t rb_on; - qhandle_t rb_off; - float scale; - float bias; - qboolean demoversion; - qboolean firstdraw; -} uiStatic_t; - -extern void UI_Init( void ); -extern void UI_Shutdown( void ); -extern void UI_KeyEvent( int key, int down ); -extern void UI_MouseEvent( int dx, int dy ); -extern void UI_Refresh( int realtime ); -extern qboolean UI_ConsoleCommand( int realTime ); -extern float UI_ClampCvar( float min, float max, float value ); -extern void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ); -extern void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ); -extern void UI_FillRect( float x, float y, float width, float height, const float *color ); -extern void UI_DrawRect( float x, float y, float width, float height, const float *color ); -extern void UI_UpdateScreen( void ); -extern void UI_SetColor( const float *rgba ); -extern void UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t); -extern void UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color ); -extern float UI_ProportionalSizeScale( int style ); -extern void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ); -extern void UI_DrawProportionalString_AutoWrapped( int x, int ystart, int xmax, int ystep, const char* str, int style, vec4_t color ); -extern int UI_ProportionalStringWidth( const char* str ); -extern void UI_DrawString( int x, int y, const char* str, int style, vec4_t color ); -extern void UI_DrawChar( int x, int y, int ch, int style, vec4_t color ); -extern qboolean UI_CursorInRect (int x, int y, int width, int height); -extern void UI_AdjustFrom640( float *x, float *y, float *w, float *h ); -extern void UI_DrawTextBox (int x, int y, int width, int lines); -extern qboolean UI_IsFullscreen( void ); -extern void UI_SetActiveMenu( uiMenuCommand_t menu ); -extern void UI_PushMenu ( menuframework_s *menu ); -extern void UI_PopMenu (void); -extern void UI_ForceMenuOff (void); -extern char *UI_Argv( int arg ); -extern char *UI_Cvar_VariableString( const char *var_name ); -extern void UI_Refresh( int time ); -extern void UI_StartDemoLoop( void ); -extern qboolean m_entersound; -extern uiStatic_t uis; - -// -// ui_spLevel.c -// -void UI_SPLevelMenu_Cache( void ); -void UI_SPLevelMenu( void ); -void UI_SPLevelMenu_f( void ); -void UI_SPLevelMenu_ReInit( void ); - -// -// ui_spArena.c -// -void UI_SPArena_Start( const char *arenaInfo ); - -// -// ui_spPostgame.c -// -void UI_SPPostgameMenu_Cache( void ); -void UI_SPPostgameMenu_f( void ); - -// -// ui_spSkill.c -// -void UI_SPSkillMenu( const char *arenaInfo ); -void UI_SPSkillMenu_Cache( void ); - -// -// ui_syscalls.c -// -void trap_Print( const char *string ); -void trap_Error( const char *string ); -int trap_Milliseconds( void ); -void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ); -void trap_Cvar_Update( vmCvar_t *vmCvar ); -void trap_Cvar_Set( const char *var_name, const char *value ); -float trap_Cvar_VariableValue( const char *var_name ); -void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); -void trap_Cvar_SetValue( const char *var_name, float value ); -void trap_Cvar_Reset( const char *name ); -void trap_Cvar_Create( const char *var_name, const char *var_value, int flags ); -void trap_Cvar_InfoStringBuffer( int bit, char *buffer, int bufsize ); -int trap_Argc( void ); -void trap_Argv( int n, char *buffer, int bufferLength ); -void trap_Cmd_ExecuteText( int exec_when, const char *text ); // don't use EXEC_NOW! -int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ); -void trap_FS_Read( void *buffer, int len, fileHandle_t f ); -void trap_FS_Write( const void *buffer, int len, fileHandle_t f ); -void trap_FS_FCloseFile( fileHandle_t f ); -int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize ); -int trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t -qhandle_t trap_R_RegisterModel( const char *name ); -qhandle_t trap_R_RegisterSkin( const char *name ); -qhandle_t trap_R_RegisterShaderNoMip( const char *name ); -void trap_R_ClearScene( void ); -void trap_R_AddRefEntityToScene( const refEntity_t *re ); -void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ); -void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ); -void trap_R_RenderScene( const refdef_t *fd ); -void trap_R_SetColor( const float *rgba ); -void trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader ); -void trap_UpdateScreen( void ); -int trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName ); -void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ); -sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ); -void trap_Key_KeynumToStringBuf( int keynum, char *buf, int buflen ); -void trap_Key_GetBindingBuf( int keynum, char *buf, int buflen ); -void trap_Key_SetBinding( int keynum, const char *binding ); -qboolean trap_Key_IsDown( int keynum ); -qboolean trap_Key_GetOverstrikeMode( void ); -void trap_Key_SetOverstrikeMode( qboolean state ); -void trap_Key_ClearStates( void ); -int trap_Key_GetCatcher( void ); -void trap_Key_SetCatcher( int catcher ); -void trap_GetClipboardData( char *buf, int bufsize ); -void trap_GetClientState( uiClientState_t *state ); -void trap_GetGlconfig( glconfig_t *glconfig ); -int trap_GetConfigString( int index, char* buff, int buffsize ); -int trap_LAN_GetServerCount( int source ); -void trap_LAN_GetServerAddressString( int source, int n, char *buf, int buflen ); -void trap_LAN_GetServerInfo( int source, int n, char *buf, int buflen ); -int trap_LAN_GetPingQueueCount( void ); -int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen ); -void trap_LAN_ClearPing( int n ); -void trap_LAN_GetPing( int n, char *buf, int buflen, int *pingtime ); -void trap_LAN_GetPingInfo( int n, char *buf, int buflen ); -int trap_MemoryRemaining( void ); -void trap_GetCDKey( char *buf, int buflen ); -void trap_SetCDKey( char *buf ); - -qboolean trap_VerifyCDKey( const char *key, const char *chksum); // bk001208 - RC4 - -void trap_SetPbClStatus( int status ); - -// -// ui_addbots.c -// -void UI_AddBots_Cache( void ); -void UI_AddBotsMenu( void ); - -// -// ui_removebots.c -// -void UI_RemoveBots_Cache( void ); -void UI_RemoveBotsMenu( void ); - -// -// ui_teamorders.c -// -extern void UI_TeamOrdersMenu( void ); -extern void UI_TeamOrdersMenu_f( void ); -extern void UI_TeamOrdersMenu_Cache( void ); - -// -// ui_loadconfig.c -// -void UI_LoadConfig_Cache( void ); -void UI_LoadConfigMenu( void ); - -// -// ui_saveconfig.c -// -void UI_SaveConfigMenu_Cache( void ); -void UI_SaveConfigMenu( void ); - -// -// ui_display.c -// -void UI_DisplayOptionsMenu_Cache( void ); -void UI_DisplayOptionsMenu( void ); - -// -// ui_sound.c -// -void UI_SoundOptionsMenu_Cache( void ); -void UI_SoundOptionsMenu( void ); - -// -// ui_network.c -// -void UI_NetworkOptionsMenu_Cache( void ); -void UI_NetworkOptionsMenu( void ); - -// -// ui_gameinfo.c -// -typedef enum { - AWARD_ACCURACY, - AWARD_IMPRESSIVE, - AWARD_EXCELLENT, - AWARD_GAUNTLET, - AWARD_FRAGS, - AWARD_PERFECT -} awardType_t; - -const char *UI_GetArenaInfoByNumber( int num ); -const char *UI_GetArenaInfoByMap( const char *map ); -const char *UI_GetSpecialArenaInfo( const char *tag ); -int UI_GetNumArenas( void ); -int UI_GetNumSPArenas( void ); -int UI_GetNumSPTiers( void ); - -char *UI_GetBotInfoByNumber( int num ); -char *UI_GetBotInfoByName( const char *name ); -int UI_GetNumBots( void ); - -void UI_GetBestScore( int level, int *score, int *skill ); -void UI_SetBestScore( int level, int score ); -int UI_TierCompleted( int levelWon ); -qboolean UI_ShowTierVideo( int tier ); -qboolean UI_CanShowTierVideo( int tier ); -int UI_GetCurrentGame( void ); -void UI_NewGame( void ); -void UI_LogAwardData( int award, int data ); -int UI_GetAwardLevel( int award ); - -void UI_SPUnlock_f( void ); -void UI_SPUnlockMedals_f( void ); - -void UI_InitGameinfo( void ); - -//GRank - -// -// ui_rankings.c -// -void Rankings_DrawText( void* self ); -void Rankings_DrawName( void* self ); -void Rankings_DrawPassword( void* self ); -void Rankings_Cache( void ); -void UI_RankingsMenu( void ); - -// -// ui_login.c -// -void Login_Cache( void ); -void UI_LoginMenu( void ); - -// -// ui_signup.c -// -void Signup_Cache( void ); -void UI_SignupMenu( void ); - -// -// ui_rankstatus.c -// -void RankStatus_Cache( void ); -void UI_RankStatusMenu( void ); - -#endif +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#ifndef __UI_LOCAL_H__ +#define __UI_LOCAL_H__ + +#include "../game/q_shared.h" +#include "../cgame/tr_types.h" +//NOTE: include the ui_public.h from the new UI +#include "../ui/ui_public.h" // bk001205 - yes, do have to use this +//redefine to old API version +#undef UI_API_VERSION +#define UI_API_VERSION 4 +#include "keycodes.h" +#include "../game/bg_public.h" + +typedef void (*voidfunc_f)(void); + +extern vmCvar_t ui_ffa_fraglimit; +extern vmCvar_t ui_ffa_timelimit; + +extern vmCvar_t ui_tourney_fraglimit; +extern vmCvar_t ui_tourney_timelimit; + +extern vmCvar_t ui_team_fraglimit; +extern vmCvar_t ui_team_timelimit; +extern vmCvar_t ui_team_friendly; + +extern vmCvar_t ui_ctf_capturelimit; +extern vmCvar_t ui_ctf_timelimit; +extern vmCvar_t ui_ctf_friendly; + +extern vmCvar_t ui_arenasFile; +extern vmCvar_t ui_botsFile; +extern vmCvar_t ui_spScores1; +extern vmCvar_t ui_spScores2; +extern vmCvar_t ui_spScores3; +extern vmCvar_t ui_spScores4; +extern vmCvar_t ui_spScores5; +extern vmCvar_t ui_spAwards; +extern vmCvar_t ui_spVideos; +extern vmCvar_t ui_spSkill; + +extern vmCvar_t ui_spSelection; + +extern vmCvar_t ui_browserMaster; +extern vmCvar_t ui_browserGameType; +extern vmCvar_t ui_browserSortKey; +extern vmCvar_t ui_browserShowFull; +extern vmCvar_t ui_browserShowEmpty; + +extern vmCvar_t ui_brassTime; +extern vmCvar_t ui_drawCrosshair; +extern vmCvar_t ui_drawCrosshairNames; +extern vmCvar_t ui_marks; + +extern vmCvar_t ui_server1; +extern vmCvar_t ui_server2; +extern vmCvar_t ui_server3; +extern vmCvar_t ui_server4; +extern vmCvar_t ui_server5; +extern vmCvar_t ui_server6; +extern vmCvar_t ui_server7; +extern vmCvar_t ui_server8; +extern vmCvar_t ui_server9; +extern vmCvar_t ui_server10; +extern vmCvar_t ui_server11; +extern vmCvar_t ui_server12; +extern vmCvar_t ui_server13; +extern vmCvar_t ui_server14; +extern vmCvar_t ui_server15; +extern vmCvar_t ui_server16; + +extern vmCvar_t ui_cdkey; +extern vmCvar_t ui_cdkeychecked; + + +// +// ui_qmenu.c +// + +#define RCOLUMN_OFFSET ( BIGCHAR_WIDTH ) +#define LCOLUMN_OFFSET (-BIGCHAR_WIDTH ) + +#define SLIDER_RANGE 10 +#define MAX_EDIT_LINE 256 + +#define MAX_MENUDEPTH 8 +#define MAX_MENUITEMS 64 + +#define MTYPE_NULL 0 +#define MTYPE_SLIDER 1 +#define MTYPE_ACTION 2 +#define MTYPE_SPINCONTROL 3 +#define MTYPE_FIELD 4 +#define MTYPE_RADIOBUTTON 5 +#define MTYPE_BITMAP 6 +#define MTYPE_TEXT 7 +#define MTYPE_SCROLLLIST 8 +#define MTYPE_PTEXT 9 +#define MTYPE_BTEXT 10 + +#define QMF_BLINK 0x00000001 +#define QMF_SMALLFONT 0x00000002 +#define QMF_LEFT_JUSTIFY 0x00000004 +#define QMF_CENTER_JUSTIFY 0x00000008 +#define QMF_RIGHT_JUSTIFY 0x00000010 +#define QMF_NUMBERSONLY 0x00000020 // edit field is only numbers +#define QMF_HIGHLIGHT 0x00000040 +#define QMF_HIGHLIGHT_IF_FOCUS 0x00000080 // steady focus +#define QMF_PULSEIFFOCUS 0x00000100 // pulse if focus +#define QMF_HASMOUSEFOCUS 0x00000200 +#define QMF_NOONOFFTEXT 0x00000400 +#define QMF_MOUSEONLY 0x00000800 // only mouse input allowed +#define QMF_HIDDEN 0x00001000 // skips drawing +#define QMF_GRAYED 0x00002000 // grays and disables +#define QMF_INACTIVE 0x00004000 // disables any input +#define QMF_NODEFAULTINIT 0x00008000 // skip default initialization +#define QMF_OWNERDRAW 0x00010000 +#define QMF_PULSE 0x00020000 +#define QMF_LOWERCASE 0x00040000 // edit field is all lower case +#define QMF_UPPERCASE 0x00080000 // edit field is all upper case +#define QMF_SILENT 0x00100000 + +// callback notifications +#define QM_GOTFOCUS 1 +#define QM_LOSTFOCUS 2 +#define QM_ACTIVATED 3 + +typedef struct _tag_menuframework +{ + int cursor; + int cursor_prev; + + int nitems; + void *items[MAX_MENUITEMS]; + + void (*draw) (void); + sfxHandle_t (*key) (int key); + + qboolean wrapAround; + qboolean fullscreen; + qboolean showlogo; +} menuframework_s; + +typedef struct +{ + int type; + const char *name; + int id; + int x, y; + int left; + int top; + int right; + int bottom; + menuframework_s *parent; + int menuPosition; + unsigned flags; + + void (*callback)( void *self, int event ); + void (*statusbar)( void *self ); + void (*ownerdraw)( void *self ); +} menucommon_s; + +typedef struct { + int cursor; + int scroll; + int widthInChars; + char buffer[MAX_EDIT_LINE]; + int maxchars; +} mfield_t; + +typedef struct +{ + menucommon_s generic; + mfield_t field; +} menufield_s; + +typedef struct +{ + menucommon_s generic; + + float minvalue; + float maxvalue; + float curvalue; + + float range; +} menuslider_s; + +typedef struct +{ + menucommon_s generic; + + int oldvalue; + int curvalue; + int numitems; + int top; + + const char **itemnames; + + int width; + int height; + int columns; + int seperation; +} menulist_s; + +typedef struct +{ + menucommon_s generic; +} menuaction_s; + +typedef struct +{ + menucommon_s generic; + int curvalue; +} menuradiobutton_s; + +typedef struct +{ + menucommon_s generic; + char* focuspic; + char* errorpic; + qhandle_t shader; + qhandle_t focusshader; + int width; + int height; + float* focuscolor; +} menubitmap_s; + +typedef struct +{ + menucommon_s generic; + char* string; + int style; + float* color; +} menutext_s; + +extern void Menu_Cache( void ); +extern void Menu_Focus( menucommon_s *m ); +extern void Menu_AddItem( menuframework_s *menu, void *item ); +extern void Menu_AdjustCursor( menuframework_s *menu, int dir ); +extern void Menu_Draw( menuframework_s *menu ); +extern void *Menu_ItemAtCursor( menuframework_s *m ); +extern sfxHandle_t Menu_ActivateItem( menuframework_s *s, menucommon_s* item ); +extern void Menu_SetCursor( menuframework_s *s, int cursor ); +extern void Menu_SetCursorToItem( menuframework_s *m, void* ptr ); +extern sfxHandle_t Menu_DefaultKey( menuframework_s *s, int key ); +extern void Bitmap_Init( menubitmap_s *b ); +extern void Bitmap_Draw( menubitmap_s *b ); +extern void ScrollList_Draw( menulist_s *l ); +extern sfxHandle_t ScrollList_Key( menulist_s *l, int key ); +extern sfxHandle_t menu_in_sound; +extern sfxHandle_t menu_move_sound; +extern sfxHandle_t menu_out_sound; +extern sfxHandle_t menu_buzz_sound; +extern sfxHandle_t menu_null_sound; +extern sfxHandle_t weaponChangeSound; +extern vec4_t menu_text_color; +extern vec4_t menu_grayed_color; +extern vec4_t menu_dark_color; +extern vec4_t menu_highlight_color; +extern vec4_t menu_red_color; +extern vec4_t menu_black_color; +extern vec4_t menu_dim_color; +extern vec4_t color_black; +extern vec4_t color_white; +extern vec4_t color_yellow; +extern vec4_t color_blue; +extern vec4_t color_orange; +extern vec4_t color_red; +extern vec4_t color_dim; +extern vec4_t name_color; +extern vec4_t list_color; +extern vec4_t listbar_color; +extern vec4_t text_color_disabled; +extern vec4_t text_color_normal; +extern vec4_t text_color_highlight; + +extern char *ui_medalNames[]; +extern char *ui_medalPicNames[]; +extern char *ui_medalSounds[]; + +// +// ui_mfield.c +// +extern void MField_Clear( mfield_t *edit ); +extern void MField_KeyDownEvent( mfield_t *edit, int key ); +extern void MField_CharEvent( mfield_t *edit, int ch ); +extern void MField_Draw( mfield_t *edit, int x, int y, int style, vec4_t color ); +extern void MenuField_Init( menufield_s* m ); +extern void MenuField_Draw( menufield_s *f ); +extern sfxHandle_t MenuField_Key( menufield_s* m, int* key ); + +// +// ui_menu.c +// +extern void MainMenu_Cache( void ); +extern void UI_MainMenu(void); +extern void UI_RegisterCvars( void ); +extern void UI_UpdateCvars( void ); + +// +// ui_credits.c +// +extern void UI_CreditMenu( void ); + +// +// ui_ingame.c +// +extern void InGame_Cache( void ); +extern void UI_InGameMenu(void); + +// +// ui_confirm.c +// +extern void ConfirmMenu_Cache( void ); +extern void UI_ConfirmMenu( const char *question, void (*draw)( void ), void (*action)( qboolean result ) ); +extern void UI_ConfirmMenu_Style( const char *question, int style, void (*draw)( void ), void (*action)( qboolean result ) ); +extern void UI_Message( const char **lines ); + +// +// ui_setup.c +// +extern void UI_SetupMenu_Cache( void ); +extern void UI_SetupMenu(void); + +// +// ui_team.c +// +extern void UI_TeamMainMenu( void ); +extern void TeamMain_Cache( void ); + +// +// ui_connect.c +// +extern void UI_DrawConnectScreen( qboolean overlay ); + +// +// ui_controls2.c +// +extern void UI_ControlsMenu( void ); +extern void Controls_Cache( void ); + +// +// ui_demo2.c +// +extern void UI_DemosMenu( void ); +extern void Demos_Cache( void ); + +// +// ui_cinematics.c +// +extern void UI_CinematicsMenu( void ); +extern void UI_CinematicsMenu_f( void ); +extern void UI_CinematicsMenu_Cache( void ); + +// +// ui_mods.c +// +extern void UI_ModsMenu( void ); +extern void UI_ModsMenu_Cache( void ); + +// +// ui_cdkey.c +// +extern void UI_CDKeyMenu( void ); +extern void UI_CDKeyMenu_Cache( void ); +extern void UI_CDKeyMenu_f( void ); + +// +// ui_playermodel.c +// +extern void UI_PlayerModelMenu( void ); +extern void PlayerModel_Cache( void ); + +// +// ui_playersettings.c +// +extern void UI_PlayerSettingsMenu( void ); +extern void PlayerSettings_Cache( void ); + +// +// ui_preferences.c +// +extern void UI_PreferencesMenu( void ); +extern void Preferences_Cache( void ); + +// +// ui_specifyleague.c +// +extern void UI_SpecifyLeagueMenu( void ); +extern void SpecifyLeague_Cache( void ); + +// +// ui_specifyserver.c +// +extern void UI_SpecifyServerMenu( void ); +extern void SpecifyServer_Cache( void ); + +// +// ui_servers2.c +// +#define MAX_FAVORITESERVERS 16 + +extern void UI_ArenaServersMenu( void ); +extern void ArenaServers_Cache( void ); + +// +// ui_startserver.c +// +extern void UI_StartServerMenu( qboolean multiplayer ); +extern void StartServer_Cache( void ); +extern void ServerOptions_Cache( void ); +extern void UI_BotSelectMenu( char *bot ); +extern void UI_BotSelectMenu_Cache( void ); + +// +// ui_serverinfo.c +// +extern void UI_ServerInfoMenu( void ); +extern void ServerInfo_Cache( void ); + +// +// ui_video.c +// +extern void UI_GraphicsOptionsMenu( void ); +extern void GraphicsOptions_Cache( void ); +extern void DriverInfo_Cache( void ); + +// +// ui_players.c +// + +//FIXME ripped from cg_local.h +typedef struct { + int oldFrame; + int oldFrameTime; // time when ->oldFrame was exactly on + + int frame; + int frameTime; // time when ->frame will be exactly on + + float backlerp; + + float yawAngle; + qboolean yawing; + float pitchAngle; + qboolean pitching; + + int animationNumber; // may include ANIM_TOGGLEBIT + animation_t *animation; + int animationTime; // time when the first frame of the animation will be exact +} lerpFrame_t; + +typedef struct { + // model info + qhandle_t legsModel; + qhandle_t legsSkin; + lerpFrame_t legs; + + qhandle_t torsoModel; + qhandle_t torsoSkin; + lerpFrame_t torso; + + qhandle_t headModel; + qhandle_t headSkin; + + animation_t animations[MAX_ANIMATIONS]; + + qhandle_t weaponModel; + qhandle_t barrelModel; + qhandle_t flashModel; + vec3_t flashDlightColor; + int muzzleFlashTime; + + // currently in use drawing parms + vec3_t viewAngles; + vec3_t moveAngles; + weapon_t currentWeapon; + int legsAnim; + int torsoAnim; + + // animation vars + weapon_t weapon; + weapon_t lastWeapon; + weapon_t pendingWeapon; + int weaponTimer; + int pendingLegsAnim; + int torsoAnimationTimer; + + int pendingTorsoAnim; + int legsAnimationTimer; + + qboolean chat; + qboolean newModel; + + qboolean barrelSpinning; + float barrelAngle; + int barrelTime; + + int realWeapon; +} playerInfo_t; + +void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ); +void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model ); +void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNum, qboolean chat ); +qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName ); + +// +// ui_atoms.c +// +typedef struct { + int frametime; + int realtime; + int cursorx; + int cursory; + int menusp; + menuframework_s* activemenu; + menuframework_s* stack[MAX_MENUDEPTH]; + glconfig_t glconfig; + qboolean debug; + qhandle_t whiteShader; + qhandle_t menuBackShader; + qhandle_t menuBackNoLogoShader; + qhandle_t charset; + qhandle_t charsetProp; + qhandle_t charsetPropGlow; + qhandle_t charsetPropB; + qhandle_t cursor; + qhandle_t rb_on; + qhandle_t rb_off; + float scale; + float bias; + qboolean demoversion; + qboolean firstdraw; +} uiStatic_t; + +extern void UI_Init( void ); +extern void UI_Shutdown( void ); +extern void UI_KeyEvent( int key, int down ); +extern void UI_MouseEvent( int dx, int dy ); +extern void UI_Refresh( int realtime ); +extern qboolean UI_ConsoleCommand( int realTime ); +extern float UI_ClampCvar( float min, float max, float value ); +extern void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ); +extern void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ); +extern void UI_FillRect( float x, float y, float width, float height, const float *color ); +extern void UI_DrawRect( float x, float y, float width, float height, const float *color ); +extern void UI_UpdateScreen( void ); +extern void UI_SetColor( const float *rgba ); +extern void UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t); +extern void UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color ); +extern float UI_ProportionalSizeScale( int style ); +extern void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ); +extern void UI_DrawProportionalString_AutoWrapped( int x, int ystart, int xmax, int ystep, const char* str, int style, vec4_t color ); +extern int UI_ProportionalStringWidth( const char* str ); +extern void UI_DrawString( int x, int y, const char* str, int style, vec4_t color ); +extern void UI_DrawChar( int x, int y, int ch, int style, vec4_t color ); +extern qboolean UI_CursorInRect (int x, int y, int width, int height); +extern void UI_AdjustFrom640( float *x, float *y, float *w, float *h ); +extern void UI_DrawTextBox (int x, int y, int width, int lines); +extern qboolean UI_IsFullscreen( void ); +extern void UI_SetActiveMenu( uiMenuCommand_t menu ); +extern void UI_PushMenu ( menuframework_s *menu ); +extern void UI_PopMenu (void); +extern void UI_ForceMenuOff (void); +extern char *UI_Argv( int arg ); +extern char *UI_Cvar_VariableString( const char *var_name ); +extern void UI_Refresh( int time ); +extern void UI_StartDemoLoop( void ); +extern qboolean m_entersound; +extern uiStatic_t uis; + +// +// ui_spLevel.c +// +void UI_SPLevelMenu_Cache( void ); +void UI_SPLevelMenu( void ); +void UI_SPLevelMenu_f( void ); +void UI_SPLevelMenu_ReInit( void ); + +// +// ui_spArena.c +// +void UI_SPArena_Start( const char *arenaInfo ); + +// +// ui_spPostgame.c +// +void UI_SPPostgameMenu_Cache( void ); +void UI_SPPostgameMenu_f( void ); + +// +// ui_spSkill.c +// +void UI_SPSkillMenu( const char *arenaInfo ); +void UI_SPSkillMenu_Cache( void ); + +// +// ui_syscalls.c +// +void trap_Print( const char *string ); +void trap_Error( const char *string ); +int trap_Milliseconds( void ); +void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags ); +void trap_Cvar_Update( vmCvar_t *vmCvar ); +void trap_Cvar_Set( const char *var_name, const char *value ); +float trap_Cvar_VariableValue( const char *var_name ); +void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); +void trap_Cvar_SetValue( const char *var_name, float value ); +void trap_Cvar_Reset( const char *name ); +void trap_Cvar_Create( const char *var_name, const char *var_value, int flags ); +void trap_Cvar_InfoStringBuffer( int bit, char *buffer, int bufsize ); +int trap_Argc( void ); +void trap_Argv( int n, char *buffer, int bufferLength ); +void trap_Cmd_ExecuteText( int exec_when, const char *text ); // don't use EXEC_NOW! +int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ); +void trap_FS_Read( void *buffer, int len, fileHandle_t f ); +void trap_FS_Write( const void *buffer, int len, fileHandle_t f ); +void trap_FS_FCloseFile( fileHandle_t f ); +int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize ); +int trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t +qhandle_t trap_R_RegisterModel( const char *name ); +qhandle_t trap_R_RegisterSkin( const char *name ); +qhandle_t trap_R_RegisterShaderNoMip( const char *name ); +void trap_R_ClearScene( void ); +void trap_R_AddRefEntityToScene( const refEntity_t *re ); +void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ); +void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ); +void trap_R_RenderScene( const refdef_t *fd ); +void trap_R_SetColor( const float *rgba ); +void trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader ); +void trap_UpdateScreen( void ); +int trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName ); +void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ); +sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ); +void trap_Key_KeynumToStringBuf( int keynum, char *buf, int buflen ); +void trap_Key_GetBindingBuf( int keynum, char *buf, int buflen ); +void trap_Key_SetBinding( int keynum, const char *binding ); +qboolean trap_Key_IsDown( int keynum ); +qboolean trap_Key_GetOverstrikeMode( void ); +void trap_Key_SetOverstrikeMode( qboolean state ); +void trap_Key_ClearStates( void ); +int trap_Key_GetCatcher( void ); +void trap_Key_SetCatcher( int catcher ); +void trap_GetClipboardData( char *buf, int bufsize ); +void trap_GetClientState( uiClientState_t *state ); +void trap_GetGlconfig( glconfig_t *glconfig ); +int trap_GetConfigString( int index, char* buff, int buffsize ); +int trap_LAN_GetServerCount( int source ); +void trap_LAN_GetServerAddressString( int source, int n, char *buf, int buflen ); +void trap_LAN_GetServerInfo( int source, int n, char *buf, int buflen ); +int trap_LAN_GetPingQueueCount( void ); +int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen ); +void trap_LAN_ClearPing( int n ); +void trap_LAN_GetPing( int n, char *buf, int buflen, int *pingtime ); +void trap_LAN_GetPingInfo( int n, char *buf, int buflen ); +int trap_MemoryRemaining( void ); +void trap_GetCDKey( char *buf, int buflen ); +void trap_SetCDKey( char *buf ); + +qboolean trap_VerifyCDKey( const char *key, const char *chksum); // bk001208 - RC4 + +void trap_SetPbClStatus( int status ); + +// +// ui_addbots.c +// +void UI_AddBots_Cache( void ); +void UI_AddBotsMenu( void ); + +// +// ui_removebots.c +// +void UI_RemoveBots_Cache( void ); +void UI_RemoveBotsMenu( void ); + +// +// ui_teamorders.c +// +extern void UI_TeamOrdersMenu( void ); +extern void UI_TeamOrdersMenu_f( void ); +extern void UI_TeamOrdersMenu_Cache( void ); + +// +// ui_loadconfig.c +// +void UI_LoadConfig_Cache( void ); +void UI_LoadConfigMenu( void ); + +// +// ui_saveconfig.c +// +void UI_SaveConfigMenu_Cache( void ); +void UI_SaveConfigMenu( void ); + +// +// ui_display.c +// +void UI_DisplayOptionsMenu_Cache( void ); +void UI_DisplayOptionsMenu( void ); + +// +// ui_sound.c +// +void UI_SoundOptionsMenu_Cache( void ); +void UI_SoundOptionsMenu( void ); + +// +// ui_network.c +// +void UI_NetworkOptionsMenu_Cache( void ); +void UI_NetworkOptionsMenu( void ); + +// +// ui_gameinfo.c +// +typedef enum { + AWARD_ACCURACY, + AWARD_IMPRESSIVE, + AWARD_EXCELLENT, + AWARD_GAUNTLET, + AWARD_FRAGS, + AWARD_PERFECT +} awardType_t; + +const char *UI_GetArenaInfoByNumber( int num ); +const char *UI_GetArenaInfoByMap( const char *map ); +const char *UI_GetSpecialArenaInfo( const char *tag ); +int UI_GetNumArenas( void ); +int UI_GetNumSPArenas( void ); +int UI_GetNumSPTiers( void ); + +char *UI_GetBotInfoByNumber( int num ); +char *UI_GetBotInfoByName( const char *name ); +int UI_GetNumBots( void ); + +void UI_GetBestScore( int level, int *score, int *skill ); +void UI_SetBestScore( int level, int score ); +int UI_TierCompleted( int levelWon ); +qboolean UI_ShowTierVideo( int tier ); +qboolean UI_CanShowTierVideo( int tier ); +int UI_GetCurrentGame( void ); +void UI_NewGame( void ); +void UI_LogAwardData( int award, int data ); +int UI_GetAwardLevel( int award ); + +void UI_SPUnlock_f( void ); +void UI_SPUnlockMedals_f( void ); + +void UI_InitGameinfo( void ); + +//GRank + +// +// ui_rankings.c +// +void Rankings_DrawText( void* self ); +void Rankings_DrawName( void* self ); +void Rankings_DrawPassword( void* self ); +void Rankings_Cache( void ); +void UI_RankingsMenu( void ); + +// +// ui_login.c +// +void Login_Cache( void ); +void UI_LoginMenu( void ); + +// +// ui_signup.c +// +void Signup_Cache( void ); +void UI_SignupMenu( void ); + +// +// ui_rankstatus.c +// +void RankStatus_Cache( void ); +void UI_RankStatusMenu( void ); + +#endif diff --git a/code/q3_ui/ui_login.c b/code/q3_ui/ui_login.c index 86b7584..650f385 100755 --- a/code/q3_ui/ui_login.c +++ b/code/q3_ui/ui_login.c @@ -1,208 +1,208 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -// -// ui_login.c -// - -#include "ui_local.h" - - -#define LOGIN_FRAME "menu/art/cut_frame" - -#define ID_NAME 100 -#define ID_NAME_BOX 101 -#define ID_PASSWORD 102 -#define ID_PASSWORD_BOX 103 -#define ID_LOGIN 104 -#define ID_CANCEL 105 - - -typedef struct -{ - menuframework_s menu; - menubitmap_s frame; - menutext_s name; - menufield_s name_box; - menutext_s password; - menufield_s password_box; - menutext_s login; - menutext_s cancel; -} login_t; - -static login_t s_login; - -static menuframework_s s_login_menu; -static menuaction_s s_login_login; -static menuaction_s s_login_cancel; - -static vec4_t s_login_color_prompt = {1.00, 0.43, 0.00, 1.00}; - -/* -=============== -Login_MenuEvent -=============== -*/ -static void Login_MenuEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_LOGIN: - // set name `` - //trap_Cvar_Set( "name", s_login.name_box.field.buffer ); - /* - trap_Cvar_Set( "rank_name", s_login.name_box.field.buffer ); - trap_Cvar_Set( "rank_pwd", s_login.password_box.field.buffer ); - */ - - // login - trap_CL_UI_RankUserLogin( - s_login.name_box.field.buffer, - s_login.password_box.field.buffer ); - - UI_ForceMenuOff(); - break; - - case ID_CANCEL: - UI_PopMenu(); - break; - } -} - - -/* -=============== -Login_MenuInit -=============== -*/ -void Login_MenuInit( void ) { - int y; - - memset( &s_login, 0, sizeof(s_login) ); - - Login_Cache(); - - s_login.menu.wrapAround = qtrue; - s_login.menu.fullscreen = qfalse; - - s_login.frame.generic.type = MTYPE_BITMAP; - s_login.frame.generic.flags = QMF_INACTIVE; - s_login.frame.generic.name = LOGIN_FRAME; - s_login.frame.generic.x = 142; //320-233; - s_login.frame.generic.y = 118; //240-166; - s_login.frame.width = 359; //466; - s_login.frame.height = 256; //332; - - y = 214; - - s_login.name.generic.type = MTYPE_PTEXT; - s_login.name.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; - s_login.name.generic.id = ID_NAME; - s_login.name.generic.x = 310; - s_login.name.generic.y = y; - s_login.name.string = "NAME"; - s_login.name.style = UI_RIGHT|UI_SMALLFONT; - s_login.name.color = s_login_color_prompt; - - s_login.name_box.generic.type = MTYPE_FIELD; - s_login.name_box.generic.ownerdraw = Rankings_DrawName; - s_login.name_box.generic.name = ""; - s_login.name_box.generic.flags = 0; - s_login.name_box.generic.x = 330; - s_login.name_box.generic.y = y; - s_login.name_box.field.widthInChars = 16; - s_login.name_box.field.maxchars = 16; - y += 20; - - s_login.password.generic.type = MTYPE_PTEXT; - s_login.password.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; - s_login.password.generic.id = ID_PASSWORD; - s_login.password.generic.x = 310; - s_login.password.generic.y = y; - s_login.password.string = "PASSWORD"; - s_login.password.style = UI_RIGHT|UI_SMALLFONT; - s_login.password.color = s_login_color_prompt; - - s_login.password_box.generic.type = MTYPE_FIELD; - s_login.password_box.generic.ownerdraw = Rankings_DrawPassword; - s_login.password_box.generic.name = ""; - s_login.password_box.generic.flags = 0; - s_login.password_box.generic.x = 330; - s_login.password_box.generic.y = y; - s_login.password_box.field.widthInChars = 16; - s_login.password_box.field.maxchars = 16; - y += 40; - - s_login.login.generic.type = MTYPE_PTEXT; - s_login.login.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_login.login.generic.id = ID_LOGIN; - s_login.login.generic.callback = Login_MenuEvent; - s_login.login.generic.x = 310; - s_login.login.generic.y = y; - s_login.login.string = "LOGIN"; - s_login.login.style = UI_RIGHT|UI_SMALLFONT; - s_login.login.color = colorRed; - - s_login.cancel.generic.type = MTYPE_PTEXT; - s_login.cancel.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_login.cancel.generic.id = ID_CANCEL; - s_login.cancel.generic.callback = Login_MenuEvent; - s_login.cancel.generic.x = 330; - s_login.cancel.generic.y = y; - s_login.cancel.string = "CANCEL"; - s_login.cancel.style = UI_LEFT|UI_SMALLFONT; - s_login.cancel.color = colorRed; - y += 20; - - Menu_AddItem( &s_login.menu, (void*) &s_login.frame ); - Menu_AddItem( &s_login.menu, (void*) &s_login.name ); - Menu_AddItem( &s_login.menu, (void*) &s_login.name_box ); - Menu_AddItem( &s_login.menu, (void*) &s_login.password ); - Menu_AddItem( &s_login.menu, (void*) &s_login.password_box ); - Menu_AddItem( &s_login.menu, (void*) &s_login.login ); - Menu_AddItem( &s_login.menu, (void*) &s_login.cancel ); -} - - -/* -=============== -Login_Cache -=============== -*/ -void Login_Cache( void ) { - trap_R_RegisterShaderNoMip( LOGIN_FRAME ); -} - - -/* -=============== -UI_LoginMenu -=============== -*/ -void UI_LoginMenu( void ) { - Login_MenuInit(); - UI_PushMenu ( &s_login.menu ); -} - - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +// +// ui_login.c +// + +#include "ui_local.h" + + +#define LOGIN_FRAME "menu/art/cut_frame" + +#define ID_NAME 100 +#define ID_NAME_BOX 101 +#define ID_PASSWORD 102 +#define ID_PASSWORD_BOX 103 +#define ID_LOGIN 104 +#define ID_CANCEL 105 + + +typedef struct +{ + menuframework_s menu; + menubitmap_s frame; + menutext_s name; + menufield_s name_box; + menutext_s password; + menufield_s password_box; + menutext_s login; + menutext_s cancel; +} login_t; + +static login_t s_login; + +static menuframework_s s_login_menu; +static menuaction_s s_login_login; +static menuaction_s s_login_cancel; + +static vec4_t s_login_color_prompt = {1.00, 0.43, 0.00, 1.00}; + +/* +=============== +Login_MenuEvent +=============== +*/ +static void Login_MenuEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_LOGIN: + // set name `` + //trap_Cvar_Set( "name", s_login.name_box.field.buffer ); + /* + trap_Cvar_Set( "rank_name", s_login.name_box.field.buffer ); + trap_Cvar_Set( "rank_pwd", s_login.password_box.field.buffer ); + */ + + // login + trap_CL_UI_RankUserLogin( + s_login.name_box.field.buffer, + s_login.password_box.field.buffer ); + + UI_ForceMenuOff(); + break; + + case ID_CANCEL: + UI_PopMenu(); + break; + } +} + + +/* +=============== +Login_MenuInit +=============== +*/ +void Login_MenuInit( void ) { + int y; + + memset( &s_login, 0, sizeof(s_login) ); + + Login_Cache(); + + s_login.menu.wrapAround = qtrue; + s_login.menu.fullscreen = qfalse; + + s_login.frame.generic.type = MTYPE_BITMAP; + s_login.frame.generic.flags = QMF_INACTIVE; + s_login.frame.generic.name = LOGIN_FRAME; + s_login.frame.generic.x = 142; //320-233; + s_login.frame.generic.y = 118; //240-166; + s_login.frame.width = 359; //466; + s_login.frame.height = 256; //332; + + y = 214; + + s_login.name.generic.type = MTYPE_PTEXT; + s_login.name.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; + s_login.name.generic.id = ID_NAME; + s_login.name.generic.x = 310; + s_login.name.generic.y = y; + s_login.name.string = "NAME"; + s_login.name.style = UI_RIGHT|UI_SMALLFONT; + s_login.name.color = s_login_color_prompt; + + s_login.name_box.generic.type = MTYPE_FIELD; + s_login.name_box.generic.ownerdraw = Rankings_DrawName; + s_login.name_box.generic.name = ""; + s_login.name_box.generic.flags = 0; + s_login.name_box.generic.x = 330; + s_login.name_box.generic.y = y; + s_login.name_box.field.widthInChars = 16; + s_login.name_box.field.maxchars = 16; + y += 20; + + s_login.password.generic.type = MTYPE_PTEXT; + s_login.password.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; + s_login.password.generic.id = ID_PASSWORD; + s_login.password.generic.x = 310; + s_login.password.generic.y = y; + s_login.password.string = "PASSWORD"; + s_login.password.style = UI_RIGHT|UI_SMALLFONT; + s_login.password.color = s_login_color_prompt; + + s_login.password_box.generic.type = MTYPE_FIELD; + s_login.password_box.generic.ownerdraw = Rankings_DrawPassword; + s_login.password_box.generic.name = ""; + s_login.password_box.generic.flags = 0; + s_login.password_box.generic.x = 330; + s_login.password_box.generic.y = y; + s_login.password_box.field.widthInChars = 16; + s_login.password_box.field.maxchars = 16; + y += 40; + + s_login.login.generic.type = MTYPE_PTEXT; + s_login.login.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_login.login.generic.id = ID_LOGIN; + s_login.login.generic.callback = Login_MenuEvent; + s_login.login.generic.x = 310; + s_login.login.generic.y = y; + s_login.login.string = "LOGIN"; + s_login.login.style = UI_RIGHT|UI_SMALLFONT; + s_login.login.color = colorRed; + + s_login.cancel.generic.type = MTYPE_PTEXT; + s_login.cancel.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_login.cancel.generic.id = ID_CANCEL; + s_login.cancel.generic.callback = Login_MenuEvent; + s_login.cancel.generic.x = 330; + s_login.cancel.generic.y = y; + s_login.cancel.string = "CANCEL"; + s_login.cancel.style = UI_LEFT|UI_SMALLFONT; + s_login.cancel.color = colorRed; + y += 20; + + Menu_AddItem( &s_login.menu, (void*) &s_login.frame ); + Menu_AddItem( &s_login.menu, (void*) &s_login.name ); + Menu_AddItem( &s_login.menu, (void*) &s_login.name_box ); + Menu_AddItem( &s_login.menu, (void*) &s_login.password ); + Menu_AddItem( &s_login.menu, (void*) &s_login.password_box ); + Menu_AddItem( &s_login.menu, (void*) &s_login.login ); + Menu_AddItem( &s_login.menu, (void*) &s_login.cancel ); +} + + +/* +=============== +Login_Cache +=============== +*/ +void Login_Cache( void ) { + trap_R_RegisterShaderNoMip( LOGIN_FRAME ); +} + + +/* +=============== +UI_LoginMenu +=============== +*/ +void UI_LoginMenu( void ) { + Login_MenuInit(); + UI_PushMenu ( &s_login.menu ); +} + + diff --git a/code/q3_ui/ui_main.c b/code/q3_ui/ui_main.c index 465e6ec..5107cdc 100755 --- a/code/q3_ui/ui_main.c +++ b/code/q3_ui/ui_main.c @@ -1,249 +1,249 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -USER INTERFACE MAIN - -======================================================================= -*/ - - -#include "ui_local.h" - - -/* -================ -vmMain - -This is the only way control passes into the module. -This must be the very first function compiled into the .qvm file -================ -*/ -int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) { - switch ( command ) { - case UI_GETAPIVERSION: - return UI_API_VERSION; - - case UI_INIT: - UI_Init(); - return 0; - - case UI_SHUTDOWN: - UI_Shutdown(); - return 0; - - case UI_KEY_EVENT: - UI_KeyEvent( arg0, arg1 ); - return 0; - - case UI_MOUSE_EVENT: - UI_MouseEvent( arg0, arg1 ); - return 0; - - case UI_REFRESH: - UI_Refresh( arg0 ); - return 0; - - case UI_IS_FULLSCREEN: - return UI_IsFullscreen(); - - case UI_SET_ACTIVE_MENU: - UI_SetActiveMenu( arg0 ); - return 0; - - case UI_CONSOLE_COMMAND: - return UI_ConsoleCommand(arg0); - - case UI_DRAW_CONNECT_SCREEN: - UI_DrawConnectScreen( arg0 ); - return 0; - case UI_HASUNIQUECDKEY: // mod authors need to observe this - return qtrue; // bk010117 - change this to qfalse for mods! - } - - return -1; -} - - -/* -================ -cvars -================ -*/ - -typedef struct { - vmCvar_t *vmCvar; - char *cvarName; - char *defaultString; - int cvarFlags; -} cvarTable_t; - -vmCvar_t ui_ffa_fraglimit; -vmCvar_t ui_ffa_timelimit; - -vmCvar_t ui_tourney_fraglimit; -vmCvar_t ui_tourney_timelimit; - -vmCvar_t ui_team_fraglimit; -vmCvar_t ui_team_timelimit; -vmCvar_t ui_team_friendly; - -vmCvar_t ui_ctf_capturelimit; -vmCvar_t ui_ctf_timelimit; -vmCvar_t ui_ctf_friendly; - -vmCvar_t ui_arenasFile; -vmCvar_t ui_botsFile; -vmCvar_t ui_spScores1; -vmCvar_t ui_spScores2; -vmCvar_t ui_spScores3; -vmCvar_t ui_spScores4; -vmCvar_t ui_spScores5; -vmCvar_t ui_spAwards; -vmCvar_t ui_spVideos; -vmCvar_t ui_spSkill; - -vmCvar_t ui_spSelection; - -vmCvar_t ui_browserMaster; -vmCvar_t ui_browserGameType; -vmCvar_t ui_browserSortKey; -vmCvar_t ui_browserShowFull; -vmCvar_t ui_browserShowEmpty; - -vmCvar_t ui_brassTime; -vmCvar_t ui_drawCrosshair; -vmCvar_t ui_drawCrosshairNames; -vmCvar_t ui_marks; - -vmCvar_t ui_server1; -vmCvar_t ui_server2; -vmCvar_t ui_server3; -vmCvar_t ui_server4; -vmCvar_t ui_server5; -vmCvar_t ui_server6; -vmCvar_t ui_server7; -vmCvar_t ui_server8; -vmCvar_t ui_server9; -vmCvar_t ui_server10; -vmCvar_t ui_server11; -vmCvar_t ui_server12; -vmCvar_t ui_server13; -vmCvar_t ui_server14; -vmCvar_t ui_server15; -vmCvar_t ui_server16; - -vmCvar_t ui_cdkeychecked; - -// bk001129 - made static to avoid aliasing. -static cvarTable_t cvarTable[] = { - { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE }, - { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", CVAR_ARCHIVE }, - - { &ui_tourney_fraglimit, "ui_tourney_fraglimit", "0", CVAR_ARCHIVE }, - { &ui_tourney_timelimit, "ui_tourney_timelimit", "15", CVAR_ARCHIVE }, - - { &ui_team_fraglimit, "ui_team_fraglimit", "0", CVAR_ARCHIVE }, - { &ui_team_timelimit, "ui_team_timelimit", "20", CVAR_ARCHIVE }, - { &ui_team_friendly, "ui_team_friendly", "1", CVAR_ARCHIVE }, - - { &ui_ctf_capturelimit, "ui_ctf_capturelimit", "8", CVAR_ARCHIVE }, - { &ui_ctf_timelimit, "ui_ctf_timelimit", "30", CVAR_ARCHIVE }, - { &ui_ctf_friendly, "ui_ctf_friendly", "0", CVAR_ARCHIVE }, - - { &ui_arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM }, - { &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM }, - { &ui_spScores1, "g_spScores1", "", CVAR_ARCHIVE | CVAR_ROM }, - { &ui_spScores2, "g_spScores2", "", CVAR_ARCHIVE | CVAR_ROM }, - { &ui_spScores3, "g_spScores3", "", CVAR_ARCHIVE | CVAR_ROM }, - { &ui_spScores4, "g_spScores4", "", CVAR_ARCHIVE | CVAR_ROM }, - { &ui_spScores5, "g_spScores5", "", CVAR_ARCHIVE | CVAR_ROM }, - { &ui_spAwards, "g_spAwards", "", CVAR_ARCHIVE | CVAR_ROM }, - { &ui_spVideos, "g_spVideos", "", CVAR_ARCHIVE | CVAR_ROM }, - { &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE | CVAR_LATCH }, - - { &ui_spSelection, "ui_spSelection", "", CVAR_ROM }, - - { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE }, - { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE }, - { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE }, - { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE }, - { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE }, - - { &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, - { &ui_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, - { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, - { &ui_marks, "cg_marks", "1", CVAR_ARCHIVE }, - - { &ui_server1, "server1", "", CVAR_ARCHIVE }, - { &ui_server2, "server2", "", CVAR_ARCHIVE }, - { &ui_server3, "server3", "", CVAR_ARCHIVE }, - { &ui_server4, "server4", "", CVAR_ARCHIVE }, - { &ui_server5, "server5", "", CVAR_ARCHIVE }, - { &ui_server6, "server6", "", CVAR_ARCHIVE }, - { &ui_server7, "server7", "", CVAR_ARCHIVE }, - { &ui_server8, "server8", "", CVAR_ARCHIVE }, - { &ui_server9, "server9", "", CVAR_ARCHIVE }, - { &ui_server10, "server10", "", CVAR_ARCHIVE }, - { &ui_server11, "server11", "", CVAR_ARCHIVE }, - { &ui_server12, "server12", "", CVAR_ARCHIVE }, - { &ui_server13, "server13", "", CVAR_ARCHIVE }, - { &ui_server14, "server14", "", CVAR_ARCHIVE }, - { &ui_server15, "server15", "", CVAR_ARCHIVE }, - { &ui_server16, "server16", "", CVAR_ARCHIVE }, - - { &ui_cdkeychecked, "ui_cdkeychecked", "0", CVAR_ROM } -}; - -// bk001129 - made static to avoid aliasing -static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]); - - -/* -================= -UI_RegisterCvars -================= -*/ -void UI_RegisterCvars( void ) { - int i; - cvarTable_t *cv; - - for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { - trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags ); - } -} - -/* -================= -UI_UpdateCvars -================= -*/ -void UI_UpdateCvars( void ) { - int i; - cvarTable_t *cv; - - for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { - trap_Cvar_Update( cv->vmCvar ); - } -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +USER INTERFACE MAIN + +======================================================================= +*/ + + +#include "ui_local.h" + + +/* +================ +vmMain + +This is the only way control passes into the module. +This must be the very first function compiled into the .qvm file +================ +*/ +int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) { + switch ( command ) { + case UI_GETAPIVERSION: + return UI_API_VERSION; + + case UI_INIT: + UI_Init(); + return 0; + + case UI_SHUTDOWN: + UI_Shutdown(); + return 0; + + case UI_KEY_EVENT: + UI_KeyEvent( arg0, arg1 ); + return 0; + + case UI_MOUSE_EVENT: + UI_MouseEvent( arg0, arg1 ); + return 0; + + case UI_REFRESH: + UI_Refresh( arg0 ); + return 0; + + case UI_IS_FULLSCREEN: + return UI_IsFullscreen(); + + case UI_SET_ACTIVE_MENU: + UI_SetActiveMenu( arg0 ); + return 0; + + case UI_CONSOLE_COMMAND: + return UI_ConsoleCommand(arg0); + + case UI_DRAW_CONNECT_SCREEN: + UI_DrawConnectScreen( arg0 ); + return 0; + case UI_HASUNIQUECDKEY: // mod authors need to observe this + return qtrue; // bk010117 - change this to qfalse for mods! + } + + return -1; +} + + +/* +================ +cvars +================ +*/ + +typedef struct { + vmCvar_t *vmCvar; + char *cvarName; + char *defaultString; + int cvarFlags; +} cvarTable_t; + +vmCvar_t ui_ffa_fraglimit; +vmCvar_t ui_ffa_timelimit; + +vmCvar_t ui_tourney_fraglimit; +vmCvar_t ui_tourney_timelimit; + +vmCvar_t ui_team_fraglimit; +vmCvar_t ui_team_timelimit; +vmCvar_t ui_team_friendly; + +vmCvar_t ui_ctf_capturelimit; +vmCvar_t ui_ctf_timelimit; +vmCvar_t ui_ctf_friendly; + +vmCvar_t ui_arenasFile; +vmCvar_t ui_botsFile; +vmCvar_t ui_spScores1; +vmCvar_t ui_spScores2; +vmCvar_t ui_spScores3; +vmCvar_t ui_spScores4; +vmCvar_t ui_spScores5; +vmCvar_t ui_spAwards; +vmCvar_t ui_spVideos; +vmCvar_t ui_spSkill; + +vmCvar_t ui_spSelection; + +vmCvar_t ui_browserMaster; +vmCvar_t ui_browserGameType; +vmCvar_t ui_browserSortKey; +vmCvar_t ui_browserShowFull; +vmCvar_t ui_browserShowEmpty; + +vmCvar_t ui_brassTime; +vmCvar_t ui_drawCrosshair; +vmCvar_t ui_drawCrosshairNames; +vmCvar_t ui_marks; + +vmCvar_t ui_server1; +vmCvar_t ui_server2; +vmCvar_t ui_server3; +vmCvar_t ui_server4; +vmCvar_t ui_server5; +vmCvar_t ui_server6; +vmCvar_t ui_server7; +vmCvar_t ui_server8; +vmCvar_t ui_server9; +vmCvar_t ui_server10; +vmCvar_t ui_server11; +vmCvar_t ui_server12; +vmCvar_t ui_server13; +vmCvar_t ui_server14; +vmCvar_t ui_server15; +vmCvar_t ui_server16; + +vmCvar_t ui_cdkeychecked; + +// bk001129 - made static to avoid aliasing. +static cvarTable_t cvarTable[] = { + { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE }, + { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", CVAR_ARCHIVE }, + + { &ui_tourney_fraglimit, "ui_tourney_fraglimit", "0", CVAR_ARCHIVE }, + { &ui_tourney_timelimit, "ui_tourney_timelimit", "15", CVAR_ARCHIVE }, + + { &ui_team_fraglimit, "ui_team_fraglimit", "0", CVAR_ARCHIVE }, + { &ui_team_timelimit, "ui_team_timelimit", "20", CVAR_ARCHIVE }, + { &ui_team_friendly, "ui_team_friendly", "1", CVAR_ARCHIVE }, + + { &ui_ctf_capturelimit, "ui_ctf_capturelimit", "8", CVAR_ARCHIVE }, + { &ui_ctf_timelimit, "ui_ctf_timelimit", "30", CVAR_ARCHIVE }, + { &ui_ctf_friendly, "ui_ctf_friendly", "0", CVAR_ARCHIVE }, + + { &ui_arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM }, + { &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM }, + { &ui_spScores1, "g_spScores1", "", CVAR_ARCHIVE | CVAR_ROM }, + { &ui_spScores2, "g_spScores2", "", CVAR_ARCHIVE | CVAR_ROM }, + { &ui_spScores3, "g_spScores3", "", CVAR_ARCHIVE | CVAR_ROM }, + { &ui_spScores4, "g_spScores4", "", CVAR_ARCHIVE | CVAR_ROM }, + { &ui_spScores5, "g_spScores5", "", CVAR_ARCHIVE | CVAR_ROM }, + { &ui_spAwards, "g_spAwards", "", CVAR_ARCHIVE | CVAR_ROM }, + { &ui_spVideos, "g_spVideos", "", CVAR_ARCHIVE | CVAR_ROM }, + { &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE | CVAR_LATCH }, + + { &ui_spSelection, "ui_spSelection", "", CVAR_ROM }, + + { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE }, + { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE }, + { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE }, + { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE }, + { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE }, + + { &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, + { &ui_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, + { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, + { &ui_marks, "cg_marks", "1", CVAR_ARCHIVE }, + + { &ui_server1, "server1", "", CVAR_ARCHIVE }, + { &ui_server2, "server2", "", CVAR_ARCHIVE }, + { &ui_server3, "server3", "", CVAR_ARCHIVE }, + { &ui_server4, "server4", "", CVAR_ARCHIVE }, + { &ui_server5, "server5", "", CVAR_ARCHIVE }, + { &ui_server6, "server6", "", CVAR_ARCHIVE }, + { &ui_server7, "server7", "", CVAR_ARCHIVE }, + { &ui_server8, "server8", "", CVAR_ARCHIVE }, + { &ui_server9, "server9", "", CVAR_ARCHIVE }, + { &ui_server10, "server10", "", CVAR_ARCHIVE }, + { &ui_server11, "server11", "", CVAR_ARCHIVE }, + { &ui_server12, "server12", "", CVAR_ARCHIVE }, + { &ui_server13, "server13", "", CVAR_ARCHIVE }, + { &ui_server14, "server14", "", CVAR_ARCHIVE }, + { &ui_server15, "server15", "", CVAR_ARCHIVE }, + { &ui_server16, "server16", "", CVAR_ARCHIVE }, + + { &ui_cdkeychecked, "ui_cdkeychecked", "0", CVAR_ROM } +}; + +// bk001129 - made static to avoid aliasing +static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]); + + +/* +================= +UI_RegisterCvars +================= +*/ +void UI_RegisterCvars( void ) { + int i; + cvarTable_t *cv; + + for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { + trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags ); + } +} + +/* +================= +UI_UpdateCvars +================= +*/ +void UI_UpdateCvars( void ) { + int i; + cvarTable_t *cv; + + for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { + trap_Cvar_Update( cv->vmCvar ); + } +} diff --git a/code/q3_ui/ui_menu.c b/code/q3_ui/ui_menu.c index 682c5a8..6722435 100755 --- a/code/q3_ui/ui_menu.c +++ b/code/q3_ui/ui_menu.c @@ -1,419 +1,419 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -MAIN MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ID_SINGLEPLAYER 10 -#define ID_MULTIPLAYER 11 -#define ID_SETUP 12 -#define ID_DEMOS 13 -#define ID_CINEMATICS 14 -#define ID_TEAMARENA 15 -#define ID_MODS 16 -#define ID_EXIT 17 - -#define MAIN_BANNER_MODEL "models/mapobjects/banner/banner5.md3" -#define MAIN_MENU_VERTICAL_SPACING 34 - - -typedef struct { - menuframework_s menu; - - menutext_s singleplayer; - menutext_s multiplayer; - menutext_s setup; - menutext_s demos; - menutext_s cinematics; - menutext_s teamArena; - menutext_s mods; - menutext_s exit; - - qhandle_t bannerModel; -} mainmenu_t; - - -static mainmenu_t s_main; - -typedef struct { - menuframework_s menu; - char errorMessage[4096]; -} errorMessage_t; - -static errorMessage_t s_errorMessage; - -/* -================= -MainMenu_ExitAction -================= -*/ -static void MainMenu_ExitAction( qboolean result ) { - if( !result ) { - return; - } - UI_PopMenu(); - UI_CreditMenu(); -} - - - -/* -================= -Main_MenuEvent -================= -*/ -void Main_MenuEvent (void* ptr, int event) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_SINGLEPLAYER: - UI_SPLevelMenu(); - break; - - case ID_MULTIPLAYER: - UI_ArenaServersMenu(); - break; - - case ID_SETUP: - UI_SetupMenu(); - break; - - case ID_DEMOS: - UI_DemosMenu(); - break; - - case ID_CINEMATICS: - UI_CinematicsMenu(); - break; - - case ID_MODS: - UI_ModsMenu(); - break; - - case ID_TEAMARENA: - trap_Cvar_Set( "fs_game", "missionpack"); - trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); - break; - - case ID_EXIT: - UI_ConfirmMenu( "EXIT GAME?", NULL, MainMenu_ExitAction ); - break; - } -} - - -/* -=============== -MainMenu_Cache -=============== -*/ -void MainMenu_Cache( void ) { - s_main.bannerModel = trap_R_RegisterModel( MAIN_BANNER_MODEL ); -} - -sfxHandle_t ErrorMessage_Key(int key) -{ - trap_Cvar_Set( "com_errorMessage", "" ); - UI_MainMenu(); - return (menu_null_sound); -} - -/* -=============== -Main_MenuDraw -TTimo: this function is common to the main menu and errorMessage menu -=============== -*/ - -static void Main_MenuDraw( void ) { - refdef_t refdef; - refEntity_t ent; - vec3_t origin; - vec3_t angles; - float adjust; - float x, y, w, h; - vec4_t color = {0.5, 0, 0, 1}; - - // setup the refdef - - memset( &refdef, 0, sizeof( refdef ) ); - - refdef.rdflags = RDF_NOWORLDMODEL; - - AxisClear( refdef.viewaxis ); - - x = 0; - y = 0; - w = 640; - h = 120; - UI_AdjustFrom640( &x, &y, &w, &h ); - refdef.x = x; - refdef.y = y; - refdef.width = w; - refdef.height = h; - - adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); - refdef.fov_x = 60 + adjust; - refdef.fov_y = 19.6875 + adjust; - - refdef.time = uis.realtime; - - origin[0] = 300; - origin[1] = 0; - origin[2] = -32; - - trap_R_ClearScene(); - - // add the model - - memset( &ent, 0, sizeof(ent) ); - - adjust = 5.0 * sin( (float)uis.realtime / 5000 ); - VectorSet( angles, 0, 180 + adjust, 0 ); - AnglesToAxis( angles, ent.axis ); - ent.hModel = s_main.bannerModel; - VectorCopy( origin, ent.origin ); - VectorCopy( origin, ent.lightingOrigin ); - ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; - VectorCopy( ent.origin, ent.oldorigin ); - - trap_R_AddRefEntityToScene( &ent ); - - trap_R_RenderScene( &refdef ); - - if (strlen(s_errorMessage.errorMessage)) - { - UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); - } - else - { - // standard menu drawing - Menu_Draw( &s_main.menu ); - } - - if (uis.demoversion) { - UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); - UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); - } else { - UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); - } -} - - -/* -=============== -UI_TeamArenaExists -=============== -*/ -static qboolean UI_TeamArenaExists( void ) { - int numdirs; - char dirlist[2048]; - char *dirptr; - char *descptr; - int i; - int dirlen; - - numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) ); - dirptr = dirlist; - for( i = 0; i < numdirs; i++ ) { - dirlen = strlen( dirptr ) + 1; - descptr = dirptr + dirlen; - if (Q_stricmp(dirptr, "missionpack") == 0) { - return qtrue; - } - dirptr += dirlen + strlen(descptr) + 1; - } - return qfalse; -} - - -/* -=============== -UI_MainMenu - -The main menu only comes up when not in a game, -so make sure that the attract loop server is down -and that local cinematics are killed -=============== -*/ -void UI_MainMenu( void ) { - int y; - qboolean teamArena = qfalse; - int style = UI_CENTER | UI_DROPSHADOW; - - trap_Cvar_Set( "sv_killserver", "1" ); - - if( !uis.demoversion && !ui_cdkeychecked.integer ) { - char key[17]; - - trap_GetCDKey( key, sizeof(key) ); - if( trap_VerifyCDKey( key, NULL ) == qfalse ) { - UI_CDKeyMenu(); - return; - } - } - - memset( &s_main, 0 ,sizeof(mainmenu_t) ); - memset( &s_errorMessage, 0 ,sizeof(errorMessage_t) ); - - // com_errorMessage would need that too - MainMenu_Cache(); - - trap_Cvar_VariableStringBuffer( "com_errorMessage", s_errorMessage.errorMessage, sizeof(s_errorMessage.errorMessage) ); - if (strlen(s_errorMessage.errorMessage)) - { - s_errorMessage.menu.draw = Main_MenuDraw; - s_errorMessage.menu.key = ErrorMessage_Key; - s_errorMessage.menu.fullscreen = qtrue; - s_errorMessage.menu.wrapAround = qtrue; - s_errorMessage.menu.showlogo = qtrue; - - trap_Key_SetCatcher( KEYCATCH_UI ); - uis.menusp = 0; - UI_PushMenu ( &s_errorMessage.menu ); - - return; - } - - s_main.menu.draw = Main_MenuDraw; - s_main.menu.fullscreen = qtrue; - s_main.menu.wrapAround = qtrue; - s_main.menu.showlogo = qtrue; - - y = 134; - s_main.singleplayer.generic.type = MTYPE_PTEXT; - s_main.singleplayer.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.singleplayer.generic.x = 320; - s_main.singleplayer.generic.y = y; - s_main.singleplayer.generic.id = ID_SINGLEPLAYER; - s_main.singleplayer.generic.callback = Main_MenuEvent; - s_main.singleplayer.string = "SINGLE PLAYER"; - s_main.singleplayer.color = color_red; - s_main.singleplayer.style = style; - - y += MAIN_MENU_VERTICAL_SPACING; - s_main.multiplayer.generic.type = MTYPE_PTEXT; - s_main.multiplayer.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.multiplayer.generic.x = 320; - s_main.multiplayer.generic.y = y; - s_main.multiplayer.generic.id = ID_MULTIPLAYER; - s_main.multiplayer.generic.callback = Main_MenuEvent; - s_main.multiplayer.string = "MULTIPLAYER"; - s_main.multiplayer.color = color_red; - s_main.multiplayer.style = style; - - y += MAIN_MENU_VERTICAL_SPACING; - s_main.setup.generic.type = MTYPE_PTEXT; - s_main.setup.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.setup.generic.x = 320; - s_main.setup.generic.y = y; - s_main.setup.generic.id = ID_SETUP; - s_main.setup.generic.callback = Main_MenuEvent; - s_main.setup.string = "SETUP"; - s_main.setup.color = color_red; - s_main.setup.style = style; - - y += MAIN_MENU_VERTICAL_SPACING; - s_main.demos.generic.type = MTYPE_PTEXT; - s_main.demos.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.demos.generic.x = 320; - s_main.demos.generic.y = y; - s_main.demos.generic.id = ID_DEMOS; - s_main.demos.generic.callback = Main_MenuEvent; - s_main.demos.string = "DEMOS"; - s_main.demos.color = color_red; - s_main.demos.style = style; - - y += MAIN_MENU_VERTICAL_SPACING; - s_main.cinematics.generic.type = MTYPE_PTEXT; - s_main.cinematics.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.cinematics.generic.x = 320; - s_main.cinematics.generic.y = y; - s_main.cinematics.generic.id = ID_CINEMATICS; - s_main.cinematics.generic.callback = Main_MenuEvent; - s_main.cinematics.string = "CINEMATICS"; - s_main.cinematics.color = color_red; - s_main.cinematics.style = style; - - if (UI_TeamArenaExists()) { - teamArena = qtrue; - y += MAIN_MENU_VERTICAL_SPACING; - s_main.teamArena.generic.type = MTYPE_PTEXT; - s_main.teamArena.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.teamArena.generic.x = 320; - s_main.teamArena.generic.y = y; - s_main.teamArena.generic.id = ID_TEAMARENA; - s_main.teamArena.generic.callback = Main_MenuEvent; - s_main.teamArena.string = "TEAM ARENA"; - s_main.teamArena.color = color_red; - s_main.teamArena.style = style; - } - - y += MAIN_MENU_VERTICAL_SPACING; - s_main.mods.generic.type = MTYPE_PTEXT; - s_main.mods.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.mods.generic.x = 320; - s_main.mods.generic.y = y; - s_main.mods.generic.id = ID_MODS; - s_main.mods.generic.callback = Main_MenuEvent; - s_main.mods.string = "MODS"; - s_main.mods.color = color_red; - s_main.mods.style = style; - - y += MAIN_MENU_VERTICAL_SPACING; - s_main.exit.generic.type = MTYPE_PTEXT; - s_main.exit.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_main.exit.generic.x = 320; - s_main.exit.generic.y = y; - s_main.exit.generic.id = ID_EXIT; - s_main.exit.generic.callback = Main_MenuEvent; - s_main.exit.string = "EXIT"; - s_main.exit.color = color_red; - s_main.exit.style = style; - - Menu_AddItem( &s_main.menu, &s_main.singleplayer ); - Menu_AddItem( &s_main.menu, &s_main.multiplayer ); - Menu_AddItem( &s_main.menu, &s_main.setup ); - Menu_AddItem( &s_main.menu, &s_main.demos ); - Menu_AddItem( &s_main.menu, &s_main.cinematics ); - if (teamArena) { - Menu_AddItem( &s_main.menu, &s_main.teamArena ); - } - Menu_AddItem( &s_main.menu, &s_main.mods ); - Menu_AddItem( &s_main.menu, &s_main.exit ); - - trap_Key_SetCatcher( KEYCATCH_UI ); - uis.menusp = 0; - UI_PushMenu ( &s_main.menu ); - -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +MAIN MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ID_SINGLEPLAYER 10 +#define ID_MULTIPLAYER 11 +#define ID_SETUP 12 +#define ID_DEMOS 13 +#define ID_CINEMATICS 14 +#define ID_TEAMARENA 15 +#define ID_MODS 16 +#define ID_EXIT 17 + +#define MAIN_BANNER_MODEL "models/mapobjects/banner/banner5.md3" +#define MAIN_MENU_VERTICAL_SPACING 34 + + +typedef struct { + menuframework_s menu; + + menutext_s singleplayer; + menutext_s multiplayer; + menutext_s setup; + menutext_s demos; + menutext_s cinematics; + menutext_s teamArena; + menutext_s mods; + menutext_s exit; + + qhandle_t bannerModel; +} mainmenu_t; + + +static mainmenu_t s_main; + +typedef struct { + menuframework_s menu; + char errorMessage[4096]; +} errorMessage_t; + +static errorMessage_t s_errorMessage; + +/* +================= +MainMenu_ExitAction +================= +*/ +static void MainMenu_ExitAction( qboolean result ) { + if( !result ) { + return; + } + UI_PopMenu(); + UI_CreditMenu(); +} + + + +/* +================= +Main_MenuEvent +================= +*/ +void Main_MenuEvent (void* ptr, int event) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_SINGLEPLAYER: + UI_SPLevelMenu(); + break; + + case ID_MULTIPLAYER: + UI_ArenaServersMenu(); + break; + + case ID_SETUP: + UI_SetupMenu(); + break; + + case ID_DEMOS: + UI_DemosMenu(); + break; + + case ID_CINEMATICS: + UI_CinematicsMenu(); + break; + + case ID_MODS: + UI_ModsMenu(); + break; + + case ID_TEAMARENA: + trap_Cvar_Set( "fs_game", "missionpack"); + trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); + break; + + case ID_EXIT: + UI_ConfirmMenu( "EXIT GAME?", NULL, MainMenu_ExitAction ); + break; + } +} + + +/* +=============== +MainMenu_Cache +=============== +*/ +void MainMenu_Cache( void ) { + s_main.bannerModel = trap_R_RegisterModel( MAIN_BANNER_MODEL ); +} + +sfxHandle_t ErrorMessage_Key(int key) +{ + trap_Cvar_Set( "com_errorMessage", "" ); + UI_MainMenu(); + return (menu_null_sound); +} + +/* +=============== +Main_MenuDraw +TTimo: this function is common to the main menu and errorMessage menu +=============== +*/ + +static void Main_MenuDraw( void ) { + refdef_t refdef; + refEntity_t ent; + vec3_t origin; + vec3_t angles; + float adjust; + float x, y, w, h; + vec4_t color = {0.5, 0, 0, 1}; + + // setup the refdef + + memset( &refdef, 0, sizeof( refdef ) ); + + refdef.rdflags = RDF_NOWORLDMODEL; + + AxisClear( refdef.viewaxis ); + + x = 0; + y = 0; + w = 640; + h = 120; + UI_AdjustFrom640( &x, &y, &w, &h ); + refdef.x = x; + refdef.y = y; + refdef.width = w; + refdef.height = h; + + adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); + refdef.fov_x = 60 + adjust; + refdef.fov_y = 19.6875 + adjust; + + refdef.time = uis.realtime; + + origin[0] = 300; + origin[1] = 0; + origin[2] = -32; + + trap_R_ClearScene(); + + // add the model + + memset( &ent, 0, sizeof(ent) ); + + adjust = 5.0 * sin( (float)uis.realtime / 5000 ); + VectorSet( angles, 0, 180 + adjust, 0 ); + AnglesToAxis( angles, ent.axis ); + ent.hModel = s_main.bannerModel; + VectorCopy( origin, ent.origin ); + VectorCopy( origin, ent.lightingOrigin ); + ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; + VectorCopy( ent.origin, ent.oldorigin ); + + trap_R_AddRefEntityToScene( &ent ); + + trap_R_RenderScene( &refdef ); + + if (strlen(s_errorMessage.errorMessage)) + { + UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); + } + else + { + // standard menu drawing + Menu_Draw( &s_main.menu ); + } + + if (uis.demoversion) { + UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); + UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); + } else { + UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); + } +} + + +/* +=============== +UI_TeamArenaExists +=============== +*/ +static qboolean UI_TeamArenaExists( void ) { + int numdirs; + char dirlist[2048]; + char *dirptr; + char *descptr; + int i; + int dirlen; + + numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) ); + dirptr = dirlist; + for( i = 0; i < numdirs; i++ ) { + dirlen = strlen( dirptr ) + 1; + descptr = dirptr + dirlen; + if (Q_stricmp(dirptr, "missionpack") == 0) { + return qtrue; + } + dirptr += dirlen + strlen(descptr) + 1; + } + return qfalse; +} + + +/* +=============== +UI_MainMenu + +The main menu only comes up when not in a game, +so make sure that the attract loop server is down +and that local cinematics are killed +=============== +*/ +void UI_MainMenu( void ) { + int y; + qboolean teamArena = qfalse; + int style = UI_CENTER | UI_DROPSHADOW; + + trap_Cvar_Set( "sv_killserver", "1" ); + + if( !uis.demoversion && !ui_cdkeychecked.integer ) { + char key[17]; + + trap_GetCDKey( key, sizeof(key) ); + if( trap_VerifyCDKey( key, NULL ) == qfalse ) { + UI_CDKeyMenu(); + return; + } + } + + memset( &s_main, 0 ,sizeof(mainmenu_t) ); + memset( &s_errorMessage, 0 ,sizeof(errorMessage_t) ); + + // com_errorMessage would need that too + MainMenu_Cache(); + + trap_Cvar_VariableStringBuffer( "com_errorMessage", s_errorMessage.errorMessage, sizeof(s_errorMessage.errorMessage) ); + if (strlen(s_errorMessage.errorMessage)) + { + s_errorMessage.menu.draw = Main_MenuDraw; + s_errorMessage.menu.key = ErrorMessage_Key; + s_errorMessage.menu.fullscreen = qtrue; + s_errorMessage.menu.wrapAround = qtrue; + s_errorMessage.menu.showlogo = qtrue; + + trap_Key_SetCatcher( KEYCATCH_UI ); + uis.menusp = 0; + UI_PushMenu ( &s_errorMessage.menu ); + + return; + } + + s_main.menu.draw = Main_MenuDraw; + s_main.menu.fullscreen = qtrue; + s_main.menu.wrapAround = qtrue; + s_main.menu.showlogo = qtrue; + + y = 134; + s_main.singleplayer.generic.type = MTYPE_PTEXT; + s_main.singleplayer.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.singleplayer.generic.x = 320; + s_main.singleplayer.generic.y = y; + s_main.singleplayer.generic.id = ID_SINGLEPLAYER; + s_main.singleplayer.generic.callback = Main_MenuEvent; + s_main.singleplayer.string = "SINGLE PLAYER"; + s_main.singleplayer.color = color_red; + s_main.singleplayer.style = style; + + y += MAIN_MENU_VERTICAL_SPACING; + s_main.multiplayer.generic.type = MTYPE_PTEXT; + s_main.multiplayer.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.multiplayer.generic.x = 320; + s_main.multiplayer.generic.y = y; + s_main.multiplayer.generic.id = ID_MULTIPLAYER; + s_main.multiplayer.generic.callback = Main_MenuEvent; + s_main.multiplayer.string = "MULTIPLAYER"; + s_main.multiplayer.color = color_red; + s_main.multiplayer.style = style; + + y += MAIN_MENU_VERTICAL_SPACING; + s_main.setup.generic.type = MTYPE_PTEXT; + s_main.setup.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.setup.generic.x = 320; + s_main.setup.generic.y = y; + s_main.setup.generic.id = ID_SETUP; + s_main.setup.generic.callback = Main_MenuEvent; + s_main.setup.string = "SETUP"; + s_main.setup.color = color_red; + s_main.setup.style = style; + + y += MAIN_MENU_VERTICAL_SPACING; + s_main.demos.generic.type = MTYPE_PTEXT; + s_main.demos.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.demos.generic.x = 320; + s_main.demos.generic.y = y; + s_main.demos.generic.id = ID_DEMOS; + s_main.demos.generic.callback = Main_MenuEvent; + s_main.demos.string = "DEMOS"; + s_main.demos.color = color_red; + s_main.demos.style = style; + + y += MAIN_MENU_VERTICAL_SPACING; + s_main.cinematics.generic.type = MTYPE_PTEXT; + s_main.cinematics.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.cinematics.generic.x = 320; + s_main.cinematics.generic.y = y; + s_main.cinematics.generic.id = ID_CINEMATICS; + s_main.cinematics.generic.callback = Main_MenuEvent; + s_main.cinematics.string = "CINEMATICS"; + s_main.cinematics.color = color_red; + s_main.cinematics.style = style; + + if (UI_TeamArenaExists()) { + teamArena = qtrue; + y += MAIN_MENU_VERTICAL_SPACING; + s_main.teamArena.generic.type = MTYPE_PTEXT; + s_main.teamArena.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.teamArena.generic.x = 320; + s_main.teamArena.generic.y = y; + s_main.teamArena.generic.id = ID_TEAMARENA; + s_main.teamArena.generic.callback = Main_MenuEvent; + s_main.teamArena.string = "TEAM ARENA"; + s_main.teamArena.color = color_red; + s_main.teamArena.style = style; + } + + y += MAIN_MENU_VERTICAL_SPACING; + s_main.mods.generic.type = MTYPE_PTEXT; + s_main.mods.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.mods.generic.x = 320; + s_main.mods.generic.y = y; + s_main.mods.generic.id = ID_MODS; + s_main.mods.generic.callback = Main_MenuEvent; + s_main.mods.string = "MODS"; + s_main.mods.color = color_red; + s_main.mods.style = style; + + y += MAIN_MENU_VERTICAL_SPACING; + s_main.exit.generic.type = MTYPE_PTEXT; + s_main.exit.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_main.exit.generic.x = 320; + s_main.exit.generic.y = y; + s_main.exit.generic.id = ID_EXIT; + s_main.exit.generic.callback = Main_MenuEvent; + s_main.exit.string = "EXIT"; + s_main.exit.color = color_red; + s_main.exit.style = style; + + Menu_AddItem( &s_main.menu, &s_main.singleplayer ); + Menu_AddItem( &s_main.menu, &s_main.multiplayer ); + Menu_AddItem( &s_main.menu, &s_main.setup ); + Menu_AddItem( &s_main.menu, &s_main.demos ); + Menu_AddItem( &s_main.menu, &s_main.cinematics ); + if (teamArena) { + Menu_AddItem( &s_main.menu, &s_main.teamArena ); + } + Menu_AddItem( &s_main.menu, &s_main.mods ); + Menu_AddItem( &s_main.menu, &s_main.exit ); + + trap_Key_SetCatcher( KEYCATCH_UI ); + uis.menusp = 0; + UI_PushMenu ( &s_main.menu ); + +} diff --git a/code/q3_ui/ui_mfield.c b/code/q3_ui/ui_mfield.c index 927e6c2..b94c515 100755 --- a/code/q3_ui/ui_mfield.c +++ b/code/q3_ui/ui_mfield.c @@ -1,439 +1,439 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -/* -=================== -MField_Draw - -Handles horizontal scrolling and cursor blinking -x, y, are in pixels -=================== -*/ -void MField_Draw( mfield_t *edit, int x, int y, int style, vec4_t color ) { - int len; - int charw; - int drawLen; - int prestep; - int cursorChar; - char str[MAX_STRING_CHARS]; - - drawLen = edit->widthInChars; - len = strlen( edit->buffer ) + 1; - - // guarantee that cursor will be visible - if ( len <= drawLen ) { - prestep = 0; - } else { - if ( edit->scroll + drawLen > len ) { - edit->scroll = len - drawLen; - if ( edit->scroll < 0 ) { - edit->scroll = 0; - } - } - prestep = edit->scroll; - } - - if ( prestep + drawLen > len ) { - drawLen = len - prestep; - } - - // extract characters from the field at - if ( drawLen >= MAX_STRING_CHARS ) { - trap_Error( "drawLen >= MAX_STRING_CHARS" ); - } - memcpy( str, edit->buffer + prestep, drawLen ); - str[ drawLen ] = 0; - - UI_DrawString( x, y, str, style, color ); - - // draw the cursor - if (!(style & UI_PULSE)) { - return; - } - - if ( trap_Key_GetOverstrikeMode() ) { - cursorChar = 11; - } else { - cursorChar = 10; - } - - style &= ~UI_PULSE; - style |= UI_BLINK; - - if (style & UI_SMALLFONT) - { - charw = SMALLCHAR_WIDTH; - } - else if (style & UI_GIANTFONT) - { - charw = GIANTCHAR_WIDTH; - } - else - { - charw = BIGCHAR_WIDTH; - } - - if (style & UI_CENTER) - { - len = strlen(str); - x = x - len*charw/2; - } - else if (style & UI_RIGHT) - { - len = strlen(str); - x = x - len*charw; - } - - UI_DrawChar( x + ( edit->cursor - prestep ) * charw, y, cursorChar, style & ~(UI_CENTER|UI_RIGHT), color ); -} - -/* -================ -MField_Paste -================ -*/ -void MField_Paste( mfield_t *edit ) { - char pasteBuffer[64]; - int pasteLen, i; - - trap_GetClipboardData( pasteBuffer, 64 ); - - // send as if typed, so insert / overstrike works properly - pasteLen = strlen( pasteBuffer ); - for ( i = 0 ; i < pasteLen ; i++ ) { - MField_CharEvent( edit, pasteBuffer[i] ); - } -} - -/* -================= -MField_KeyDownEvent - -Performs the basic line editing functions for the console, -in-game talk, and menu fields - -Key events are used for non-printable characters, others are gotten from char events. -================= -*/ -void MField_KeyDownEvent( mfield_t *edit, int key ) { - int len; - - // shift-insert is paste - if ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && trap_Key_IsDown( K_SHIFT ) ) { - MField_Paste( edit ); - return; - } - - len = strlen( edit->buffer ); - - if ( key == K_DEL || key == K_KP_DEL ) { - if ( edit->cursor < len ) { - memmove( edit->buffer + edit->cursor, - edit->buffer + edit->cursor + 1, len - edit->cursor ); - } - return; - } - - if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW ) - { - if ( edit->cursor < len ) { - edit->cursor++; - } - if ( edit->cursor >= edit->scroll + edit->widthInChars && edit->cursor <= len ) - { - edit->scroll++; - } - return; - } - - if ( key == K_LEFTARROW || key == K_KP_LEFTARROW ) - { - if ( edit->cursor > 0 ) { - edit->cursor--; - } - if ( edit->cursor < edit->scroll ) - { - edit->scroll--; - } - return; - } - - if ( key == K_HOME || key == K_KP_HOME || ( tolower(key) == 'a' && trap_Key_IsDown( K_CTRL ) ) ) { - edit->cursor = 0; - edit->scroll = 0; - return; - } - - if ( key == K_END || key == K_KP_END || ( tolower(key) == 'e' && trap_Key_IsDown( K_CTRL ) ) ) { - edit->cursor = len; - edit->scroll = len - edit->widthInChars + 1; - if (edit->scroll < 0) - edit->scroll = 0; - return; - } - - if ( key == K_INS || key == K_KP_INS ) { - trap_Key_SetOverstrikeMode( !trap_Key_GetOverstrikeMode() ); - return; - } -} - -/* -================== -MField_CharEvent -================== -*/ -void MField_CharEvent( mfield_t *edit, int ch ) { - int len; - - if ( ch == 'v' - 'a' + 1 ) { // ctrl-v is paste - MField_Paste( edit ); - return; - } - - if ( ch == 'c' - 'a' + 1 ) { // ctrl-c clears the field - MField_Clear( edit ); - return; - } - - len = strlen( edit->buffer ); - - if ( ch == 'h' - 'a' + 1 ) { // ctrl-h is backspace - if ( edit->cursor > 0 ) { - memmove( edit->buffer + edit->cursor - 1, - edit->buffer + edit->cursor, len + 1 - edit->cursor ); - edit->cursor--; - if ( edit->cursor < edit->scroll ) - { - edit->scroll--; - } - } - return; - } - - if ( ch == 'a' - 'a' + 1 ) { // ctrl-a is home - edit->cursor = 0; - edit->scroll = 0; - return; - } - - if ( ch == 'e' - 'a' + 1 ) { // ctrl-e is end - edit->cursor = len; - edit->scroll = edit->cursor - edit->widthInChars + 1; - if (edit->scroll < 0) - edit->scroll = 0; - return; - } - - // - // ignore any other non printable chars - // - if ( ch < 32 ) { - return; - } - - if ( !trap_Key_GetOverstrikeMode() ) { - if ((edit->cursor == MAX_EDIT_LINE - 1) || (edit->maxchars && edit->cursor >= edit->maxchars)) - return; - } else { - // insert mode - if (( len == MAX_EDIT_LINE - 1 ) || (edit->maxchars && len >= edit->maxchars)) - return; - memmove( edit->buffer + edit->cursor + 1, edit->buffer + edit->cursor, len + 1 - edit->cursor ); - } - - edit->buffer[edit->cursor] = ch; - if (!edit->maxchars || edit->cursor < edit->maxchars-1) - edit->cursor++; - - if ( edit->cursor >= edit->widthInChars ) - { - edit->scroll++; - } - - if ( edit->cursor == len + 1) { - edit->buffer[edit->cursor] = 0; - } -} - -/* -================== -MField_Clear -================== -*/ -void MField_Clear( mfield_t *edit ) { - edit->buffer[0] = 0; - edit->cursor = 0; - edit->scroll = 0; -} - -/* -================== -MenuField_Init -================== -*/ -void MenuField_Init( menufield_s* m ) { - int l; - int w; - int h; - - MField_Clear( &m->field ); - - if (m->generic.flags & QMF_SMALLFONT) - { - w = SMALLCHAR_WIDTH; - h = SMALLCHAR_HEIGHT; - } - else - { - w = BIGCHAR_WIDTH; - h = BIGCHAR_HEIGHT; - } - - if (m->generic.name) { - l = (strlen( m->generic.name )+1) * w; - } - else { - l = 0; - } - - m->generic.left = m->generic.x - l; - m->generic.top = m->generic.y; - m->generic.right = m->generic.x + w + m->field.widthInChars*w; - m->generic.bottom = m->generic.y + h; -} - -/* -================== -MenuField_Draw -================== -*/ -void MenuField_Draw( menufield_s *f ) -{ - int x; - int y; - int w; - int h; - int style; - qboolean focus; - float *color; - - x = f->generic.x; - y = f->generic.y; - - if (f->generic.flags & QMF_SMALLFONT) - { - w = SMALLCHAR_WIDTH; - h = SMALLCHAR_HEIGHT; - style = UI_SMALLFONT; - } - else - { - w = BIGCHAR_WIDTH; - h = BIGCHAR_HEIGHT; - style = UI_BIGFONT; - } - - if (Menu_ItemAtCursor( f->generic.parent ) == f) { - focus = qtrue; - style |= UI_PULSE; - } - else { - focus = qfalse; - } - - if (f->generic.flags & QMF_GRAYED) - color = text_color_disabled; - else if (focus) - color = text_color_highlight; - else - color = text_color_normal; - - if ( focus ) - { - // draw cursor - UI_FillRect( f->generic.left, f->generic.top, f->generic.right-f->generic.left+1, f->generic.bottom-f->generic.top+1, listbar_color ); - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|style, color); - } - - if ( f->generic.name ) { - UI_DrawString( x - w, y, f->generic.name, style|UI_RIGHT, color ); - } - - MField_Draw( &f->field, x + w, y, style, color ); -} - -/* -================== -MenuField_Key -================== -*/ -sfxHandle_t MenuField_Key( menufield_s* m, int* key ) -{ - int keycode; - - keycode = *key; - - switch ( keycode ) - { - case K_KP_ENTER: - case K_ENTER: - case K_JOY1: - case K_JOY2: - case K_JOY3: - case K_JOY4: - // have enter go to next cursor point - *key = K_TAB; - break; - - case K_TAB: - case K_KP_DOWNARROW: - case K_DOWNARROW: - case K_KP_UPARROW: - case K_UPARROW: - break; - - default: - if ( keycode & K_CHAR_FLAG ) - { - keycode &= ~K_CHAR_FLAG; - - if ((m->generic.flags & QMF_UPPERCASE) && Q_islower( keycode )) - keycode -= 'a' - 'A'; - else if ((m->generic.flags & QMF_LOWERCASE) && Q_isupper( keycode )) - keycode -= 'A' - 'a'; - else if ((m->generic.flags & QMF_NUMBERSONLY) && Q_isalpha( keycode )) - return (menu_buzz_sound); - - MField_CharEvent( &m->field, keycode); - } - else - MField_KeyDownEvent( &m->field, keycode ); - break; - } - - return (0); -} - - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +/* +=================== +MField_Draw + +Handles horizontal scrolling and cursor blinking +x, y, are in pixels +=================== +*/ +void MField_Draw( mfield_t *edit, int x, int y, int style, vec4_t color ) { + int len; + int charw; + int drawLen; + int prestep; + int cursorChar; + char str[MAX_STRING_CHARS]; + + drawLen = edit->widthInChars; + len = strlen( edit->buffer ) + 1; + + // guarantee that cursor will be visible + if ( len <= drawLen ) { + prestep = 0; + } else { + if ( edit->scroll + drawLen > len ) { + edit->scroll = len - drawLen; + if ( edit->scroll < 0 ) { + edit->scroll = 0; + } + } + prestep = edit->scroll; + } + + if ( prestep + drawLen > len ) { + drawLen = len - prestep; + } + + // extract characters from the field at + if ( drawLen >= MAX_STRING_CHARS ) { + trap_Error( "drawLen >= MAX_STRING_CHARS" ); + } + memcpy( str, edit->buffer + prestep, drawLen ); + str[ drawLen ] = 0; + + UI_DrawString( x, y, str, style, color ); + + // draw the cursor + if (!(style & UI_PULSE)) { + return; + } + + if ( trap_Key_GetOverstrikeMode() ) { + cursorChar = 11; + } else { + cursorChar = 10; + } + + style &= ~UI_PULSE; + style |= UI_BLINK; + + if (style & UI_SMALLFONT) + { + charw = SMALLCHAR_WIDTH; + } + else if (style & UI_GIANTFONT) + { + charw = GIANTCHAR_WIDTH; + } + else + { + charw = BIGCHAR_WIDTH; + } + + if (style & UI_CENTER) + { + len = strlen(str); + x = x - len*charw/2; + } + else if (style & UI_RIGHT) + { + len = strlen(str); + x = x - len*charw; + } + + UI_DrawChar( x + ( edit->cursor - prestep ) * charw, y, cursorChar, style & ~(UI_CENTER|UI_RIGHT), color ); +} + +/* +================ +MField_Paste +================ +*/ +void MField_Paste( mfield_t *edit ) { + char pasteBuffer[64]; + int pasteLen, i; + + trap_GetClipboardData( pasteBuffer, 64 ); + + // send as if typed, so insert / overstrike works properly + pasteLen = strlen( pasteBuffer ); + for ( i = 0 ; i < pasteLen ; i++ ) { + MField_CharEvent( edit, pasteBuffer[i] ); + } +} + +/* +================= +MField_KeyDownEvent + +Performs the basic line editing functions for the console, +in-game talk, and menu fields + +Key events are used for non-printable characters, others are gotten from char events. +================= +*/ +void MField_KeyDownEvent( mfield_t *edit, int key ) { + int len; + + // shift-insert is paste + if ( ( ( key == K_INS ) || ( key == K_KP_INS ) ) && trap_Key_IsDown( K_SHIFT ) ) { + MField_Paste( edit ); + return; + } + + len = strlen( edit->buffer ); + + if ( key == K_DEL || key == K_KP_DEL ) { + if ( edit->cursor < len ) { + memmove( edit->buffer + edit->cursor, + edit->buffer + edit->cursor + 1, len - edit->cursor ); + } + return; + } + + if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW ) + { + if ( edit->cursor < len ) { + edit->cursor++; + } + if ( edit->cursor >= edit->scroll + edit->widthInChars && edit->cursor <= len ) + { + edit->scroll++; + } + return; + } + + if ( key == K_LEFTARROW || key == K_KP_LEFTARROW ) + { + if ( edit->cursor > 0 ) { + edit->cursor--; + } + if ( edit->cursor < edit->scroll ) + { + edit->scroll--; + } + return; + } + + if ( key == K_HOME || key == K_KP_HOME || ( tolower(key) == 'a' && trap_Key_IsDown( K_CTRL ) ) ) { + edit->cursor = 0; + edit->scroll = 0; + return; + } + + if ( key == K_END || key == K_KP_END || ( tolower(key) == 'e' && trap_Key_IsDown( K_CTRL ) ) ) { + edit->cursor = len; + edit->scroll = len - edit->widthInChars + 1; + if (edit->scroll < 0) + edit->scroll = 0; + return; + } + + if ( key == K_INS || key == K_KP_INS ) { + trap_Key_SetOverstrikeMode( !trap_Key_GetOverstrikeMode() ); + return; + } +} + +/* +================== +MField_CharEvent +================== +*/ +void MField_CharEvent( mfield_t *edit, int ch ) { + int len; + + if ( ch == 'v' - 'a' + 1 ) { // ctrl-v is paste + MField_Paste( edit ); + return; + } + + if ( ch == 'c' - 'a' + 1 ) { // ctrl-c clears the field + MField_Clear( edit ); + return; + } + + len = strlen( edit->buffer ); + + if ( ch == 'h' - 'a' + 1 ) { // ctrl-h is backspace + if ( edit->cursor > 0 ) { + memmove( edit->buffer + edit->cursor - 1, + edit->buffer + edit->cursor, len + 1 - edit->cursor ); + edit->cursor--; + if ( edit->cursor < edit->scroll ) + { + edit->scroll--; + } + } + return; + } + + if ( ch == 'a' - 'a' + 1 ) { // ctrl-a is home + edit->cursor = 0; + edit->scroll = 0; + return; + } + + if ( ch == 'e' - 'a' + 1 ) { // ctrl-e is end + edit->cursor = len; + edit->scroll = edit->cursor - edit->widthInChars + 1; + if (edit->scroll < 0) + edit->scroll = 0; + return; + } + + // + // ignore any other non printable chars + // + if ( ch < 32 ) { + return; + } + + if ( !trap_Key_GetOverstrikeMode() ) { + if ((edit->cursor == MAX_EDIT_LINE - 1) || (edit->maxchars && edit->cursor >= edit->maxchars)) + return; + } else { + // insert mode + if (( len == MAX_EDIT_LINE - 1 ) || (edit->maxchars && len >= edit->maxchars)) + return; + memmove( edit->buffer + edit->cursor + 1, edit->buffer + edit->cursor, len + 1 - edit->cursor ); + } + + edit->buffer[edit->cursor] = ch; + if (!edit->maxchars || edit->cursor < edit->maxchars-1) + edit->cursor++; + + if ( edit->cursor >= edit->widthInChars ) + { + edit->scroll++; + } + + if ( edit->cursor == len + 1) { + edit->buffer[edit->cursor] = 0; + } +} + +/* +================== +MField_Clear +================== +*/ +void MField_Clear( mfield_t *edit ) { + edit->buffer[0] = 0; + edit->cursor = 0; + edit->scroll = 0; +} + +/* +================== +MenuField_Init +================== +*/ +void MenuField_Init( menufield_s* m ) { + int l; + int w; + int h; + + MField_Clear( &m->field ); + + if (m->generic.flags & QMF_SMALLFONT) + { + w = SMALLCHAR_WIDTH; + h = SMALLCHAR_HEIGHT; + } + else + { + w = BIGCHAR_WIDTH; + h = BIGCHAR_HEIGHT; + } + + if (m->generic.name) { + l = (strlen( m->generic.name )+1) * w; + } + else { + l = 0; + } + + m->generic.left = m->generic.x - l; + m->generic.top = m->generic.y; + m->generic.right = m->generic.x + w + m->field.widthInChars*w; + m->generic.bottom = m->generic.y + h; +} + +/* +================== +MenuField_Draw +================== +*/ +void MenuField_Draw( menufield_s *f ) +{ + int x; + int y; + int w; + int h; + int style; + qboolean focus; + float *color; + + x = f->generic.x; + y = f->generic.y; + + if (f->generic.flags & QMF_SMALLFONT) + { + w = SMALLCHAR_WIDTH; + h = SMALLCHAR_HEIGHT; + style = UI_SMALLFONT; + } + else + { + w = BIGCHAR_WIDTH; + h = BIGCHAR_HEIGHT; + style = UI_BIGFONT; + } + + if (Menu_ItemAtCursor( f->generic.parent ) == f) { + focus = qtrue; + style |= UI_PULSE; + } + else { + focus = qfalse; + } + + if (f->generic.flags & QMF_GRAYED) + color = text_color_disabled; + else if (focus) + color = text_color_highlight; + else + color = text_color_normal; + + if ( focus ) + { + // draw cursor + UI_FillRect( f->generic.left, f->generic.top, f->generic.right-f->generic.left+1, f->generic.bottom-f->generic.top+1, listbar_color ); + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|style, color); + } + + if ( f->generic.name ) { + UI_DrawString( x - w, y, f->generic.name, style|UI_RIGHT, color ); + } + + MField_Draw( &f->field, x + w, y, style, color ); +} + +/* +================== +MenuField_Key +================== +*/ +sfxHandle_t MenuField_Key( menufield_s* m, int* key ) +{ + int keycode; + + keycode = *key; + + switch ( keycode ) + { + case K_KP_ENTER: + case K_ENTER: + case K_JOY1: + case K_JOY2: + case K_JOY3: + case K_JOY4: + // have enter go to next cursor point + *key = K_TAB; + break; + + case K_TAB: + case K_KP_DOWNARROW: + case K_DOWNARROW: + case K_KP_UPARROW: + case K_UPARROW: + break; + + default: + if ( keycode & K_CHAR_FLAG ) + { + keycode &= ~K_CHAR_FLAG; + + if ((m->generic.flags & QMF_UPPERCASE) && Q_islower( keycode )) + keycode -= 'a' - 'A'; + else if ((m->generic.flags & QMF_LOWERCASE) && Q_isupper( keycode )) + keycode -= 'A' - 'a'; + else if ((m->generic.flags & QMF_NUMBERSONLY) && Q_isalpha( keycode )) + return (menu_buzz_sound); + + MField_CharEvent( &m->field, keycode); + } + else + MField_KeyDownEvent( &m->field, keycode ); + break; + } + + return (0); +} + + diff --git a/code/q3_ui/ui_mods.c b/code/q3_ui/ui_mods.c index 2c6b82d..a7d32fb 100755 --- a/code/q3_ui/ui_mods.c +++ b/code/q3_ui/ui_mods.c @@ -1,283 +1,283 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FIGHT0 "menu/art/load_0" -#define ART_FIGHT1 "menu/art/load_1" -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" - -#define MAX_MODS 64 -#define NAMEBUFSIZE ( MAX_MODS * 48 ) -#define GAMEBUFSIZE ( MAX_MODS * 16 ) - -#define ID_BACK 10 -#define ID_GO 11 -#define ID_LIST 12 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menulist_s list; - - menubitmap_s back; - menubitmap_s go; - - char description[NAMEBUFSIZE]; - char fs_game[GAMEBUFSIZE]; - - char *descriptionPtr; - char *fs_gamePtr; - - char *descriptionList[MAX_MODS]; - char *fs_gameList[MAX_MODS]; -} mods_t; - -static mods_t s_mods; - - -/* -=============== -UI_Mods_MenuEvent -=============== -*/ -static void UI_Mods_MenuEvent( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch ( ((menucommon_s*)ptr)->id ) { - case ID_GO: - trap_Cvar_Set( "fs_game", s_mods.fs_gameList[s_mods.list.curvalue] ); - trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); - UI_PopMenu(); - break; - - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -UI_Mods_ParseInfos -=============== -*/ -static void UI_Mods_ParseInfos( char *modDir, char *modDesc ) { - s_mods.fs_gameList[s_mods.list.numitems] = s_mods.fs_gamePtr; - Q_strncpyz( s_mods.fs_gamePtr, modDir, 16 ); - - s_mods.descriptionList[s_mods.list.numitems] = s_mods.descriptionPtr; - Q_strncpyz( s_mods.descriptionPtr, modDesc, 48 ); - - s_mods.list.itemnames[s_mods.list.numitems] = s_mods.descriptionPtr; - s_mods.descriptionPtr += strlen( s_mods.descriptionPtr ) + 1; - s_mods.fs_gamePtr += strlen( s_mods.fs_gamePtr ) + 1; - s_mods.list.numitems++; -} - - -#if 0 // bk001204 - unused -/* -=============== -UI_Mods_LoadModsFromFile -=============== -*/ -static void UI_Mods_LoadModsFromFile( char *filename ) { - int len; - fileHandle_t f; - char buf[1024]; - - len = trap_FS_FOpenFile( filename, &f, FS_READ ); - if ( !f ) { - trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); - return; - } - if ( len >= sizeof(buf) ) { - trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, sizeof(buf) ) ); - trap_FS_FCloseFile( f ); - return; - } - - trap_FS_Read( buf, len, f ); - buf[len] = 0; - trap_FS_FCloseFile( f ); - - len = strlen( filename ); - if( !Q_stricmp(filename + len - 4,".mod") ) { - filename[len-4] = '\0'; - } - - UI_Mods_ParseInfos( filename, buf ); -} -#endif - - -/* -=============== -UI_Mods_LoadMods -=============== -*/ -static void UI_Mods_LoadMods( void ) { - int numdirs; - char dirlist[2048]; - char *dirptr; - char *descptr; - int i; - int dirlen; - - s_mods.list.itemnames = (const char **)s_mods.descriptionList; - s_mods.descriptionPtr = s_mods.description; - s_mods.fs_gamePtr = s_mods.fs_game; - - // always start off with baseq3 - s_mods.list.numitems = 1; - s_mods.list.itemnames[0] = s_mods.descriptionList[0] = "Quake III Arena"; - s_mods.fs_gameList[0] = ""; - - numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) ); - dirptr = dirlist; - for( i = 0; i < numdirs; i++ ) { - dirlen = strlen( dirptr ) + 1; - descptr = dirptr + dirlen; - UI_Mods_ParseInfos( dirptr, descptr); - dirptr += dirlen + strlen(descptr) + 1; - } - - trap_Print( va( "%i mods parsed\n", s_mods.list.numitems ) ); - if (s_mods.list.numitems > MAX_MODS) { - s_mods.list.numitems = MAX_MODS; - } -} - - -/* -=============== -UI_Mods_MenuInit -=============== -*/ -static void UI_Mods_MenuInit( void ) { - UI_ModsMenu_Cache(); - - memset( &s_mods, 0 ,sizeof(mods_t) ); - s_mods.menu.wrapAround = qtrue; - s_mods.menu.fullscreen = qtrue; - - s_mods.banner.generic.type = MTYPE_BTEXT; - s_mods.banner.generic.x = 320; - s_mods.banner.generic.y = 16; - s_mods.banner.string = "MODS"; - s_mods.banner.color = color_white; - s_mods.banner.style = UI_CENTER; - - s_mods.framel.generic.type = MTYPE_BITMAP; - s_mods.framel.generic.name = ART_FRAMEL; - s_mods.framel.generic.flags = QMF_INACTIVE; - s_mods.framel.generic.x = 0; - s_mods.framel.generic.y = 78; - s_mods.framel.width = 256; - s_mods.framel.height = 329; - - s_mods.framer.generic.type = MTYPE_BITMAP; - s_mods.framer.generic.name = ART_FRAMER; - s_mods.framer.generic.flags = QMF_INACTIVE; - s_mods.framer.generic.x = 376; - s_mods.framer.generic.y = 76; - s_mods.framer.width = 256; - s_mods.framer.height = 334; - - s_mods.back.generic.type = MTYPE_BITMAP; - s_mods.back.generic.name = ART_BACK0; - s_mods.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_mods.back.generic.id = ID_BACK; - s_mods.back.generic.callback = UI_Mods_MenuEvent; - s_mods.back.generic.x = 0; - s_mods.back.generic.y = 480-64; - s_mods.back.width = 128; - s_mods.back.height = 64; - s_mods.back.focuspic = ART_BACK1; - - s_mods.go.generic.type = MTYPE_BITMAP; - s_mods.go.generic.name = ART_FIGHT0; - s_mods.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_mods.go.generic.id = ID_GO; - s_mods.go.generic.callback = UI_Mods_MenuEvent; - s_mods.go.generic.x = 640; - s_mods.go.generic.y = 480-64; - s_mods.go.width = 128; - s_mods.go.height = 64; - s_mods.go.focuspic = ART_FIGHT1; - - // scan for mods - s_mods.list.generic.type = MTYPE_SCROLLLIST; - s_mods.list.generic.flags = QMF_PULSEIFFOCUS|QMF_CENTER_JUSTIFY; - s_mods.list.generic.callback = UI_Mods_MenuEvent; - s_mods.list.generic.id = ID_LIST; - s_mods.list.generic.x = 320; - s_mods.list.generic.y = 130; - s_mods.list.width = 48; - s_mods.list.height = 14; - - UI_Mods_LoadMods(); - - Menu_AddItem( &s_mods.menu, &s_mods.banner ); - Menu_AddItem( &s_mods.menu, &s_mods.framel ); - Menu_AddItem( &s_mods.menu, &s_mods.framer ); - Menu_AddItem( &s_mods.menu, &s_mods.list ); - Menu_AddItem( &s_mods.menu, &s_mods.back ); - Menu_AddItem( &s_mods.menu, &s_mods.go ); -} - -/* -================= -UI_Mods_Cache -================= -*/ -void UI_ModsMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FIGHT0 ); - trap_R_RegisterShaderNoMip( ART_FIGHT1 ); - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); -} - - -/* -=============== -UI_ModsMenu -=============== -*/ -void UI_ModsMenu( void ) { - UI_Mods_MenuInit(); - UI_PushMenu( &s_mods.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FIGHT0 "menu/art/load_0" +#define ART_FIGHT1 "menu/art/load_1" +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" + +#define MAX_MODS 64 +#define NAMEBUFSIZE ( MAX_MODS * 48 ) +#define GAMEBUFSIZE ( MAX_MODS * 16 ) + +#define ID_BACK 10 +#define ID_GO 11 +#define ID_LIST 12 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menulist_s list; + + menubitmap_s back; + menubitmap_s go; + + char description[NAMEBUFSIZE]; + char fs_game[GAMEBUFSIZE]; + + char *descriptionPtr; + char *fs_gamePtr; + + char *descriptionList[MAX_MODS]; + char *fs_gameList[MAX_MODS]; +} mods_t; + +static mods_t s_mods; + + +/* +=============== +UI_Mods_MenuEvent +=============== +*/ +static void UI_Mods_MenuEvent( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch ( ((menucommon_s*)ptr)->id ) { + case ID_GO: + trap_Cvar_Set( "fs_game", s_mods.fs_gameList[s_mods.list.curvalue] ); + trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" ); + UI_PopMenu(); + break; + + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +UI_Mods_ParseInfos +=============== +*/ +static void UI_Mods_ParseInfos( char *modDir, char *modDesc ) { + s_mods.fs_gameList[s_mods.list.numitems] = s_mods.fs_gamePtr; + Q_strncpyz( s_mods.fs_gamePtr, modDir, 16 ); + + s_mods.descriptionList[s_mods.list.numitems] = s_mods.descriptionPtr; + Q_strncpyz( s_mods.descriptionPtr, modDesc, 48 ); + + s_mods.list.itemnames[s_mods.list.numitems] = s_mods.descriptionPtr; + s_mods.descriptionPtr += strlen( s_mods.descriptionPtr ) + 1; + s_mods.fs_gamePtr += strlen( s_mods.fs_gamePtr ) + 1; + s_mods.list.numitems++; +} + + +#if 0 // bk001204 - unused +/* +=============== +UI_Mods_LoadModsFromFile +=============== +*/ +static void UI_Mods_LoadModsFromFile( char *filename ) { + int len; + fileHandle_t f; + char buf[1024]; + + len = trap_FS_FOpenFile( filename, &f, FS_READ ); + if ( !f ) { + trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) ); + return; + } + if ( len >= sizeof(buf) ) { + trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, sizeof(buf) ) ); + trap_FS_FCloseFile( f ); + return; + } + + trap_FS_Read( buf, len, f ); + buf[len] = 0; + trap_FS_FCloseFile( f ); + + len = strlen( filename ); + if( !Q_stricmp(filename + len - 4,".mod") ) { + filename[len-4] = '\0'; + } + + UI_Mods_ParseInfos( filename, buf ); +} +#endif + + +/* +=============== +UI_Mods_LoadMods +=============== +*/ +static void UI_Mods_LoadMods( void ) { + int numdirs; + char dirlist[2048]; + char *dirptr; + char *descptr; + int i; + int dirlen; + + s_mods.list.itemnames = (const char **)s_mods.descriptionList; + s_mods.descriptionPtr = s_mods.description; + s_mods.fs_gamePtr = s_mods.fs_game; + + // always start off with baseq3 + s_mods.list.numitems = 1; + s_mods.list.itemnames[0] = s_mods.descriptionList[0] = "Quake III Arena"; + s_mods.fs_gameList[0] = ""; + + numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) ); + dirptr = dirlist; + for( i = 0; i < numdirs; i++ ) { + dirlen = strlen( dirptr ) + 1; + descptr = dirptr + dirlen; + UI_Mods_ParseInfos( dirptr, descptr); + dirptr += dirlen + strlen(descptr) + 1; + } + + trap_Print( va( "%i mods parsed\n", s_mods.list.numitems ) ); + if (s_mods.list.numitems > MAX_MODS) { + s_mods.list.numitems = MAX_MODS; + } +} + + +/* +=============== +UI_Mods_MenuInit +=============== +*/ +static void UI_Mods_MenuInit( void ) { + UI_ModsMenu_Cache(); + + memset( &s_mods, 0 ,sizeof(mods_t) ); + s_mods.menu.wrapAround = qtrue; + s_mods.menu.fullscreen = qtrue; + + s_mods.banner.generic.type = MTYPE_BTEXT; + s_mods.banner.generic.x = 320; + s_mods.banner.generic.y = 16; + s_mods.banner.string = "MODS"; + s_mods.banner.color = color_white; + s_mods.banner.style = UI_CENTER; + + s_mods.framel.generic.type = MTYPE_BITMAP; + s_mods.framel.generic.name = ART_FRAMEL; + s_mods.framel.generic.flags = QMF_INACTIVE; + s_mods.framel.generic.x = 0; + s_mods.framel.generic.y = 78; + s_mods.framel.width = 256; + s_mods.framel.height = 329; + + s_mods.framer.generic.type = MTYPE_BITMAP; + s_mods.framer.generic.name = ART_FRAMER; + s_mods.framer.generic.flags = QMF_INACTIVE; + s_mods.framer.generic.x = 376; + s_mods.framer.generic.y = 76; + s_mods.framer.width = 256; + s_mods.framer.height = 334; + + s_mods.back.generic.type = MTYPE_BITMAP; + s_mods.back.generic.name = ART_BACK0; + s_mods.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_mods.back.generic.id = ID_BACK; + s_mods.back.generic.callback = UI_Mods_MenuEvent; + s_mods.back.generic.x = 0; + s_mods.back.generic.y = 480-64; + s_mods.back.width = 128; + s_mods.back.height = 64; + s_mods.back.focuspic = ART_BACK1; + + s_mods.go.generic.type = MTYPE_BITMAP; + s_mods.go.generic.name = ART_FIGHT0; + s_mods.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_mods.go.generic.id = ID_GO; + s_mods.go.generic.callback = UI_Mods_MenuEvent; + s_mods.go.generic.x = 640; + s_mods.go.generic.y = 480-64; + s_mods.go.width = 128; + s_mods.go.height = 64; + s_mods.go.focuspic = ART_FIGHT1; + + // scan for mods + s_mods.list.generic.type = MTYPE_SCROLLLIST; + s_mods.list.generic.flags = QMF_PULSEIFFOCUS|QMF_CENTER_JUSTIFY; + s_mods.list.generic.callback = UI_Mods_MenuEvent; + s_mods.list.generic.id = ID_LIST; + s_mods.list.generic.x = 320; + s_mods.list.generic.y = 130; + s_mods.list.width = 48; + s_mods.list.height = 14; + + UI_Mods_LoadMods(); + + Menu_AddItem( &s_mods.menu, &s_mods.banner ); + Menu_AddItem( &s_mods.menu, &s_mods.framel ); + Menu_AddItem( &s_mods.menu, &s_mods.framer ); + Menu_AddItem( &s_mods.menu, &s_mods.list ); + Menu_AddItem( &s_mods.menu, &s_mods.back ); + Menu_AddItem( &s_mods.menu, &s_mods.go ); +} + +/* +================= +UI_Mods_Cache +================= +*/ +void UI_ModsMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FIGHT0 ); + trap_R_RegisterShaderNoMip( ART_FIGHT1 ); + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); +} + + +/* +=============== +UI_ModsMenu +=============== +*/ +void UI_ModsMenu( void ) { + UI_Mods_MenuInit(); + UI_PushMenu( &s_mods.menu ); +} diff --git a/code/q3_ui/ui_network.c b/code/q3_ui/ui_network.c index 30019e8..ef047a3 100755 --- a/code/q3_ui/ui_network.c +++ b/code/q3_ui/ui_network.c @@ -1,281 +1,281 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -NETWORK OPTIONS MENU - -======================================================================= -*/ - -#include "ui_local.h" - - -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" - -#define ID_GRAPHICS 10 -#define ID_DISPLAY 11 -#define ID_SOUND 12 -#define ID_NETWORK 13 -#define ID_RATE 14 -#define ID_BACK 15 - - -static const char *rate_items[] = { - "<= 28.8K", - "33.6K", - "56K", - "ISDN", - "LAN/Cable/xDSL", - 0 -}; - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menutext_s graphics; - menutext_s display; - menutext_s sound; - menutext_s network; - - menulist_s rate; - - menubitmap_s back; -} networkOptionsInfo_t; - -static networkOptionsInfo_t networkOptionsInfo; - - -/* -================= -UI_NetworkOptionsMenu_Event -================= -*/ -static void UI_NetworkOptionsMenu_Event( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_GRAPHICS: - UI_PopMenu(); - UI_GraphicsOptionsMenu(); - break; - - case ID_DISPLAY: - UI_PopMenu(); - UI_DisplayOptionsMenu(); - break; - - case ID_SOUND: - UI_PopMenu(); - UI_SoundOptionsMenu(); - break; - - case ID_NETWORK: - break; - - case ID_RATE: - if( networkOptionsInfo.rate.curvalue == 0 ) { - trap_Cvar_SetValue( "rate", 2500 ); - } - else if( networkOptionsInfo.rate.curvalue == 1 ) { - trap_Cvar_SetValue( "rate", 3000 ); - } - else if( networkOptionsInfo.rate.curvalue == 2 ) { - trap_Cvar_SetValue( "rate", 4000 ); - } - else if( networkOptionsInfo.rate.curvalue == 3 ) { - trap_Cvar_SetValue( "rate", 5000 ); - } - else if( networkOptionsInfo.rate.curvalue == 4 ) { - trap_Cvar_SetValue( "rate", 25000 ); - } - break; - - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -UI_NetworkOptionsMenu_Init -=============== -*/ -static void UI_NetworkOptionsMenu_Init( void ) { - int y; - int rate; - - memset( &networkOptionsInfo, 0, sizeof(networkOptionsInfo) ); - - UI_NetworkOptionsMenu_Cache(); - networkOptionsInfo.menu.wrapAround = qtrue; - networkOptionsInfo.menu.fullscreen = qtrue; - - networkOptionsInfo.banner.generic.type = MTYPE_BTEXT; - networkOptionsInfo.banner.generic.flags = QMF_CENTER_JUSTIFY; - networkOptionsInfo.banner.generic.x = 320; - networkOptionsInfo.banner.generic.y = 16; - networkOptionsInfo.banner.string = "SYSTEM SETUP"; - networkOptionsInfo.banner.color = color_white; - networkOptionsInfo.banner.style = UI_CENTER; - - networkOptionsInfo.framel.generic.type = MTYPE_BITMAP; - networkOptionsInfo.framel.generic.name = ART_FRAMEL; - networkOptionsInfo.framel.generic.flags = QMF_INACTIVE; - networkOptionsInfo.framel.generic.x = 0; - networkOptionsInfo.framel.generic.y = 78; - networkOptionsInfo.framel.width = 256; - networkOptionsInfo.framel.height = 329; - - networkOptionsInfo.framer.generic.type = MTYPE_BITMAP; - networkOptionsInfo.framer.generic.name = ART_FRAMER; - networkOptionsInfo.framer.generic.flags = QMF_INACTIVE; - networkOptionsInfo.framer.generic.x = 376; - networkOptionsInfo.framer.generic.y = 76; - networkOptionsInfo.framer.width = 256; - networkOptionsInfo.framer.height = 334; - - networkOptionsInfo.graphics.generic.type = MTYPE_PTEXT; - networkOptionsInfo.graphics.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - networkOptionsInfo.graphics.generic.id = ID_GRAPHICS; - networkOptionsInfo.graphics.generic.callback = UI_NetworkOptionsMenu_Event; - networkOptionsInfo.graphics.generic.x = 216; - networkOptionsInfo.graphics.generic.y = 240 - 2 * PROP_HEIGHT; - networkOptionsInfo.graphics.string = "GRAPHICS"; - networkOptionsInfo.graphics.style = UI_RIGHT; - networkOptionsInfo.graphics.color = color_red; - - networkOptionsInfo.display.generic.type = MTYPE_PTEXT; - networkOptionsInfo.display.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - networkOptionsInfo.display.generic.id = ID_DISPLAY; - networkOptionsInfo.display.generic.callback = UI_NetworkOptionsMenu_Event; - networkOptionsInfo.display.generic.x = 216; - networkOptionsInfo.display.generic.y = 240 - PROP_HEIGHT; - networkOptionsInfo.display.string = "DISPLAY"; - networkOptionsInfo.display.style = UI_RIGHT; - networkOptionsInfo.display.color = color_red; - - networkOptionsInfo.sound.generic.type = MTYPE_PTEXT; - networkOptionsInfo.sound.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - networkOptionsInfo.sound.generic.id = ID_SOUND; - networkOptionsInfo.sound.generic.callback = UI_NetworkOptionsMenu_Event; - networkOptionsInfo.sound.generic.x = 216; - networkOptionsInfo.sound.generic.y = 240; - networkOptionsInfo.sound.string = "SOUND"; - networkOptionsInfo.sound.style = UI_RIGHT; - networkOptionsInfo.sound.color = color_red; - - networkOptionsInfo.network.generic.type = MTYPE_PTEXT; - networkOptionsInfo.network.generic.flags = QMF_RIGHT_JUSTIFY; - networkOptionsInfo.network.generic.id = ID_NETWORK; - networkOptionsInfo.network.generic.callback = UI_NetworkOptionsMenu_Event; - networkOptionsInfo.network.generic.x = 216; - networkOptionsInfo.network.generic.y = 240 + PROP_HEIGHT; - networkOptionsInfo.network.string = "NETWORK"; - networkOptionsInfo.network.style = UI_RIGHT; - networkOptionsInfo.network.color = color_red; - - y = 240 - 1 * (BIGCHAR_HEIGHT+2); - networkOptionsInfo.rate.generic.type = MTYPE_SPINCONTROL; - networkOptionsInfo.rate.generic.name = "Data Rate:"; - networkOptionsInfo.rate.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - networkOptionsInfo.rate.generic.callback = UI_NetworkOptionsMenu_Event; - networkOptionsInfo.rate.generic.id = ID_RATE; - networkOptionsInfo.rate.generic.x = 400; - networkOptionsInfo.rate.generic.y = y; - networkOptionsInfo.rate.itemnames = rate_items; - - networkOptionsInfo.back.generic.type = MTYPE_BITMAP; - networkOptionsInfo.back.generic.name = ART_BACK0; - networkOptionsInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - networkOptionsInfo.back.generic.callback = UI_NetworkOptionsMenu_Event; - networkOptionsInfo.back.generic.id = ID_BACK; - networkOptionsInfo.back.generic.x = 0; - networkOptionsInfo.back.generic.y = 480-64; - networkOptionsInfo.back.width = 128; - networkOptionsInfo.back.height = 64; - networkOptionsInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.banner ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.framel ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.framer ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.graphics ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.display ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.sound ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.network ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.rate ); - Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.back ); - - rate = trap_Cvar_VariableValue( "rate" ); - if( rate <= 2500 ) { - networkOptionsInfo.rate.curvalue = 0; - } - else if( rate <= 3000 ) { - networkOptionsInfo.rate.curvalue = 1; - } - else if( rate <= 4000 ) { - networkOptionsInfo.rate.curvalue = 2; - } - else if( rate <= 5000 ) { - networkOptionsInfo.rate.curvalue = 3; - } - else { - networkOptionsInfo.rate.curvalue = 4; - } -} - - -/* -=============== -UI_NetworkOptionsMenu_Cache -=============== -*/ -void UI_NetworkOptionsMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); -} - - -/* -=============== -UI_NetworkOptionsMenu -=============== -*/ -void UI_NetworkOptionsMenu( void ) { - UI_NetworkOptionsMenu_Init(); - UI_PushMenu( &networkOptionsInfo.menu ); - Menu_SetCursorToItem( &networkOptionsInfo.menu, &networkOptionsInfo.network ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +NETWORK OPTIONS MENU + +======================================================================= +*/ + +#include "ui_local.h" + + +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" + +#define ID_GRAPHICS 10 +#define ID_DISPLAY 11 +#define ID_SOUND 12 +#define ID_NETWORK 13 +#define ID_RATE 14 +#define ID_BACK 15 + + +static const char *rate_items[] = { + "<= 28.8K", + "33.6K", + "56K", + "ISDN", + "LAN/Cable/xDSL", + 0 +}; + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menutext_s graphics; + menutext_s display; + menutext_s sound; + menutext_s network; + + menulist_s rate; + + menubitmap_s back; +} networkOptionsInfo_t; + +static networkOptionsInfo_t networkOptionsInfo; + + +/* +================= +UI_NetworkOptionsMenu_Event +================= +*/ +static void UI_NetworkOptionsMenu_Event( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_GRAPHICS: + UI_PopMenu(); + UI_GraphicsOptionsMenu(); + break; + + case ID_DISPLAY: + UI_PopMenu(); + UI_DisplayOptionsMenu(); + break; + + case ID_SOUND: + UI_PopMenu(); + UI_SoundOptionsMenu(); + break; + + case ID_NETWORK: + break; + + case ID_RATE: + if( networkOptionsInfo.rate.curvalue == 0 ) { + trap_Cvar_SetValue( "rate", 2500 ); + } + else if( networkOptionsInfo.rate.curvalue == 1 ) { + trap_Cvar_SetValue( "rate", 3000 ); + } + else if( networkOptionsInfo.rate.curvalue == 2 ) { + trap_Cvar_SetValue( "rate", 4000 ); + } + else if( networkOptionsInfo.rate.curvalue == 3 ) { + trap_Cvar_SetValue( "rate", 5000 ); + } + else if( networkOptionsInfo.rate.curvalue == 4 ) { + trap_Cvar_SetValue( "rate", 25000 ); + } + break; + + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +UI_NetworkOptionsMenu_Init +=============== +*/ +static void UI_NetworkOptionsMenu_Init( void ) { + int y; + int rate; + + memset( &networkOptionsInfo, 0, sizeof(networkOptionsInfo) ); + + UI_NetworkOptionsMenu_Cache(); + networkOptionsInfo.menu.wrapAround = qtrue; + networkOptionsInfo.menu.fullscreen = qtrue; + + networkOptionsInfo.banner.generic.type = MTYPE_BTEXT; + networkOptionsInfo.banner.generic.flags = QMF_CENTER_JUSTIFY; + networkOptionsInfo.banner.generic.x = 320; + networkOptionsInfo.banner.generic.y = 16; + networkOptionsInfo.banner.string = "SYSTEM SETUP"; + networkOptionsInfo.banner.color = color_white; + networkOptionsInfo.banner.style = UI_CENTER; + + networkOptionsInfo.framel.generic.type = MTYPE_BITMAP; + networkOptionsInfo.framel.generic.name = ART_FRAMEL; + networkOptionsInfo.framel.generic.flags = QMF_INACTIVE; + networkOptionsInfo.framel.generic.x = 0; + networkOptionsInfo.framel.generic.y = 78; + networkOptionsInfo.framel.width = 256; + networkOptionsInfo.framel.height = 329; + + networkOptionsInfo.framer.generic.type = MTYPE_BITMAP; + networkOptionsInfo.framer.generic.name = ART_FRAMER; + networkOptionsInfo.framer.generic.flags = QMF_INACTIVE; + networkOptionsInfo.framer.generic.x = 376; + networkOptionsInfo.framer.generic.y = 76; + networkOptionsInfo.framer.width = 256; + networkOptionsInfo.framer.height = 334; + + networkOptionsInfo.graphics.generic.type = MTYPE_PTEXT; + networkOptionsInfo.graphics.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + networkOptionsInfo.graphics.generic.id = ID_GRAPHICS; + networkOptionsInfo.graphics.generic.callback = UI_NetworkOptionsMenu_Event; + networkOptionsInfo.graphics.generic.x = 216; + networkOptionsInfo.graphics.generic.y = 240 - 2 * PROP_HEIGHT; + networkOptionsInfo.graphics.string = "GRAPHICS"; + networkOptionsInfo.graphics.style = UI_RIGHT; + networkOptionsInfo.graphics.color = color_red; + + networkOptionsInfo.display.generic.type = MTYPE_PTEXT; + networkOptionsInfo.display.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + networkOptionsInfo.display.generic.id = ID_DISPLAY; + networkOptionsInfo.display.generic.callback = UI_NetworkOptionsMenu_Event; + networkOptionsInfo.display.generic.x = 216; + networkOptionsInfo.display.generic.y = 240 - PROP_HEIGHT; + networkOptionsInfo.display.string = "DISPLAY"; + networkOptionsInfo.display.style = UI_RIGHT; + networkOptionsInfo.display.color = color_red; + + networkOptionsInfo.sound.generic.type = MTYPE_PTEXT; + networkOptionsInfo.sound.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + networkOptionsInfo.sound.generic.id = ID_SOUND; + networkOptionsInfo.sound.generic.callback = UI_NetworkOptionsMenu_Event; + networkOptionsInfo.sound.generic.x = 216; + networkOptionsInfo.sound.generic.y = 240; + networkOptionsInfo.sound.string = "SOUND"; + networkOptionsInfo.sound.style = UI_RIGHT; + networkOptionsInfo.sound.color = color_red; + + networkOptionsInfo.network.generic.type = MTYPE_PTEXT; + networkOptionsInfo.network.generic.flags = QMF_RIGHT_JUSTIFY; + networkOptionsInfo.network.generic.id = ID_NETWORK; + networkOptionsInfo.network.generic.callback = UI_NetworkOptionsMenu_Event; + networkOptionsInfo.network.generic.x = 216; + networkOptionsInfo.network.generic.y = 240 + PROP_HEIGHT; + networkOptionsInfo.network.string = "NETWORK"; + networkOptionsInfo.network.style = UI_RIGHT; + networkOptionsInfo.network.color = color_red; + + y = 240 - 1 * (BIGCHAR_HEIGHT+2); + networkOptionsInfo.rate.generic.type = MTYPE_SPINCONTROL; + networkOptionsInfo.rate.generic.name = "Data Rate:"; + networkOptionsInfo.rate.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + networkOptionsInfo.rate.generic.callback = UI_NetworkOptionsMenu_Event; + networkOptionsInfo.rate.generic.id = ID_RATE; + networkOptionsInfo.rate.generic.x = 400; + networkOptionsInfo.rate.generic.y = y; + networkOptionsInfo.rate.itemnames = rate_items; + + networkOptionsInfo.back.generic.type = MTYPE_BITMAP; + networkOptionsInfo.back.generic.name = ART_BACK0; + networkOptionsInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + networkOptionsInfo.back.generic.callback = UI_NetworkOptionsMenu_Event; + networkOptionsInfo.back.generic.id = ID_BACK; + networkOptionsInfo.back.generic.x = 0; + networkOptionsInfo.back.generic.y = 480-64; + networkOptionsInfo.back.width = 128; + networkOptionsInfo.back.height = 64; + networkOptionsInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.banner ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.framel ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.framer ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.graphics ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.display ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.sound ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.network ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.rate ); + Menu_AddItem( &networkOptionsInfo.menu, ( void * ) &networkOptionsInfo.back ); + + rate = trap_Cvar_VariableValue( "rate" ); + if( rate <= 2500 ) { + networkOptionsInfo.rate.curvalue = 0; + } + else if( rate <= 3000 ) { + networkOptionsInfo.rate.curvalue = 1; + } + else if( rate <= 4000 ) { + networkOptionsInfo.rate.curvalue = 2; + } + else if( rate <= 5000 ) { + networkOptionsInfo.rate.curvalue = 3; + } + else { + networkOptionsInfo.rate.curvalue = 4; + } +} + + +/* +=============== +UI_NetworkOptionsMenu_Cache +=============== +*/ +void UI_NetworkOptionsMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); +} + + +/* +=============== +UI_NetworkOptionsMenu +=============== +*/ +void UI_NetworkOptionsMenu( void ) { + UI_NetworkOptionsMenu_Init(); + UI_PushMenu( &networkOptionsInfo.menu ); + Menu_SetCursorToItem( &networkOptionsInfo.menu, &networkOptionsInfo.network ); +} diff --git a/code/q3_ui/ui_options.c b/code/q3_ui/ui_options.c index d65afb0..b2f8993 100755 --- a/code/q3_ui/ui_options.c +++ b/code/q3_ui/ui_options.c @@ -1,229 +1,229 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -/* -======================================================================= - -SYSTEM CONFIGURATION MENU - -======================================================================= -*/ - -#include "ui_local.h" - - -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" - -#define ID_GRAPHICS 10 -#define ID_DISPLAY 11 -#define ID_SOUND 12 -#define ID_NETWORK 13 -#define ID_BACK 14 - -#define VERTICAL_SPACING 34 - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menutext_s graphics; - menutext_s display; - menutext_s sound; - menutext_s network; - menubitmap_s back; -} optionsmenu_t; - -static optionsmenu_t s_options; - - -/* -================= -Options_Event -================= -*/ -static void Options_Event( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_GRAPHICS: - UI_GraphicsOptionsMenu(); - break; - - case ID_DISPLAY: - UI_DisplayOptionsMenu(); - break; - - case ID_SOUND: - UI_SoundOptionsMenu(); - break; - - case ID_NETWORK: - UI_NetworkOptionsMenu(); - break; - - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -SystemConfig_Cache -=============== -*/ -void SystemConfig_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); -} - -/* -=============== -Options_MenuInit -=============== -*/ -void Options_MenuInit( void ) { - int y; - uiClientState_t cstate; - - memset( &s_options, 0, sizeof(optionsmenu_t) ); - - SystemConfig_Cache(); - s_options.menu.wrapAround = qtrue; - - trap_GetClientState( &cstate ); - if ( cstate.connState >= CA_CONNECTED ) { - s_options.menu.fullscreen = qfalse; - } - else { - s_options.menu.fullscreen = qtrue; - } - - s_options.banner.generic.type = MTYPE_BTEXT; - s_options.banner.generic.flags = QMF_CENTER_JUSTIFY; - s_options.banner.generic.x = 320; - s_options.banner.generic.y = 16; - s_options.banner.string = "SYSTEM SETUP"; - s_options.banner.color = color_white; - s_options.banner.style = UI_CENTER; - - s_options.framel.generic.type = MTYPE_BITMAP; - s_options.framel.generic.name = ART_FRAMEL; - s_options.framel.generic.flags = QMF_INACTIVE; - s_options.framel.generic.x = 8; - s_options.framel.generic.y = 76; - s_options.framel.width = 256; - s_options.framel.height = 334; - - s_options.framer.generic.type = MTYPE_BITMAP; - s_options.framer.generic.name = ART_FRAMER; - s_options.framer.generic.flags = QMF_INACTIVE; - s_options.framer.generic.x = 376; - s_options.framer.generic.y = 76; - s_options.framer.width = 256; - s_options.framer.height = 334; - - y = 168; - s_options.graphics.generic.type = MTYPE_PTEXT; - s_options.graphics.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_options.graphics.generic.callback = Options_Event; - s_options.graphics.generic.id = ID_GRAPHICS; - s_options.graphics.generic.x = 320; - s_options.graphics.generic.y = y; - s_options.graphics.string = "GRAPHICS"; - s_options.graphics.color = color_red; - s_options.graphics.style = UI_CENTER; - - y += VERTICAL_SPACING; - s_options.display.generic.type = MTYPE_PTEXT; - s_options.display.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_options.display.generic.callback = Options_Event; - s_options.display.generic.id = ID_DISPLAY; - s_options.display.generic.x = 320; - s_options.display.generic.y = y; - s_options.display.string = "DISPLAY"; - s_options.display.color = color_red; - s_options.display.style = UI_CENTER; - - y += VERTICAL_SPACING; - s_options.sound.generic.type = MTYPE_PTEXT; - s_options.sound.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_options.sound.generic.callback = Options_Event; - s_options.sound.generic.id = ID_SOUND; - s_options.sound.generic.x = 320; - s_options.sound.generic.y = y; - s_options.sound.string = "SOUND"; - s_options.sound.color = color_red; - s_options.sound.style = UI_CENTER; - - y += VERTICAL_SPACING; - s_options.network.generic.type = MTYPE_PTEXT; - s_options.network.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_options.network.generic.callback = Options_Event; - s_options.network.generic.id = ID_NETWORK; - s_options.network.generic.x = 320; - s_options.network.generic.y = y; - s_options.network.string = "NETWORK"; - s_options.network.color = color_red; - s_options.network.style = UI_CENTER; - - s_options.back.generic.type = MTYPE_BITMAP; - s_options.back.generic.name = ART_BACK0; - s_options.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_options.back.generic.callback = Options_Event; - s_options.back.generic.id = ID_BACK; - s_options.back.generic.x = 0; - s_options.back.generic.y = 480-64; - s_options.back.width = 128; - s_options.back.height = 64; - s_options.back.focuspic = ART_BACK1; - - Menu_AddItem( &s_options.menu, ( void * ) &s_options.banner ); - Menu_AddItem( &s_options.menu, ( void * ) &s_options.framel ); - Menu_AddItem( &s_options.menu, ( void * ) &s_options.framer ); - Menu_AddItem( &s_options.menu, ( void * ) &s_options.graphics ); - Menu_AddItem( &s_options.menu, ( void * ) &s_options.display ); - Menu_AddItem( &s_options.menu, ( void * ) &s_options.sound ); - Menu_AddItem( &s_options.menu, ( void * ) &s_options.network ); - Menu_AddItem( &s_options.menu, ( void * ) &s_options.back ); -} - - -/* -=============== -UI_SystemConfigMenu -=============== -*/ -void UI_SystemConfigMenu( void ) { - Options_MenuInit(); - UI_PushMenu ( &s_options.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +/* +======================================================================= + +SYSTEM CONFIGURATION MENU + +======================================================================= +*/ + +#include "ui_local.h" + + +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" + +#define ID_GRAPHICS 10 +#define ID_DISPLAY 11 +#define ID_SOUND 12 +#define ID_NETWORK 13 +#define ID_BACK 14 + +#define VERTICAL_SPACING 34 + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menutext_s graphics; + menutext_s display; + menutext_s sound; + menutext_s network; + menubitmap_s back; +} optionsmenu_t; + +static optionsmenu_t s_options; + + +/* +================= +Options_Event +================= +*/ +static void Options_Event( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_GRAPHICS: + UI_GraphicsOptionsMenu(); + break; + + case ID_DISPLAY: + UI_DisplayOptionsMenu(); + break; + + case ID_SOUND: + UI_SoundOptionsMenu(); + break; + + case ID_NETWORK: + UI_NetworkOptionsMenu(); + break; + + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +SystemConfig_Cache +=============== +*/ +void SystemConfig_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); +} + +/* +=============== +Options_MenuInit +=============== +*/ +void Options_MenuInit( void ) { + int y; + uiClientState_t cstate; + + memset( &s_options, 0, sizeof(optionsmenu_t) ); + + SystemConfig_Cache(); + s_options.menu.wrapAround = qtrue; + + trap_GetClientState( &cstate ); + if ( cstate.connState >= CA_CONNECTED ) { + s_options.menu.fullscreen = qfalse; + } + else { + s_options.menu.fullscreen = qtrue; + } + + s_options.banner.generic.type = MTYPE_BTEXT; + s_options.banner.generic.flags = QMF_CENTER_JUSTIFY; + s_options.banner.generic.x = 320; + s_options.banner.generic.y = 16; + s_options.banner.string = "SYSTEM SETUP"; + s_options.banner.color = color_white; + s_options.banner.style = UI_CENTER; + + s_options.framel.generic.type = MTYPE_BITMAP; + s_options.framel.generic.name = ART_FRAMEL; + s_options.framel.generic.flags = QMF_INACTIVE; + s_options.framel.generic.x = 8; + s_options.framel.generic.y = 76; + s_options.framel.width = 256; + s_options.framel.height = 334; + + s_options.framer.generic.type = MTYPE_BITMAP; + s_options.framer.generic.name = ART_FRAMER; + s_options.framer.generic.flags = QMF_INACTIVE; + s_options.framer.generic.x = 376; + s_options.framer.generic.y = 76; + s_options.framer.width = 256; + s_options.framer.height = 334; + + y = 168; + s_options.graphics.generic.type = MTYPE_PTEXT; + s_options.graphics.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_options.graphics.generic.callback = Options_Event; + s_options.graphics.generic.id = ID_GRAPHICS; + s_options.graphics.generic.x = 320; + s_options.graphics.generic.y = y; + s_options.graphics.string = "GRAPHICS"; + s_options.graphics.color = color_red; + s_options.graphics.style = UI_CENTER; + + y += VERTICAL_SPACING; + s_options.display.generic.type = MTYPE_PTEXT; + s_options.display.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_options.display.generic.callback = Options_Event; + s_options.display.generic.id = ID_DISPLAY; + s_options.display.generic.x = 320; + s_options.display.generic.y = y; + s_options.display.string = "DISPLAY"; + s_options.display.color = color_red; + s_options.display.style = UI_CENTER; + + y += VERTICAL_SPACING; + s_options.sound.generic.type = MTYPE_PTEXT; + s_options.sound.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_options.sound.generic.callback = Options_Event; + s_options.sound.generic.id = ID_SOUND; + s_options.sound.generic.x = 320; + s_options.sound.generic.y = y; + s_options.sound.string = "SOUND"; + s_options.sound.color = color_red; + s_options.sound.style = UI_CENTER; + + y += VERTICAL_SPACING; + s_options.network.generic.type = MTYPE_PTEXT; + s_options.network.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_options.network.generic.callback = Options_Event; + s_options.network.generic.id = ID_NETWORK; + s_options.network.generic.x = 320; + s_options.network.generic.y = y; + s_options.network.string = "NETWORK"; + s_options.network.color = color_red; + s_options.network.style = UI_CENTER; + + s_options.back.generic.type = MTYPE_BITMAP; + s_options.back.generic.name = ART_BACK0; + s_options.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_options.back.generic.callback = Options_Event; + s_options.back.generic.id = ID_BACK; + s_options.back.generic.x = 0; + s_options.back.generic.y = 480-64; + s_options.back.width = 128; + s_options.back.height = 64; + s_options.back.focuspic = ART_BACK1; + + Menu_AddItem( &s_options.menu, ( void * ) &s_options.banner ); + Menu_AddItem( &s_options.menu, ( void * ) &s_options.framel ); + Menu_AddItem( &s_options.menu, ( void * ) &s_options.framer ); + Menu_AddItem( &s_options.menu, ( void * ) &s_options.graphics ); + Menu_AddItem( &s_options.menu, ( void * ) &s_options.display ); + Menu_AddItem( &s_options.menu, ( void * ) &s_options.sound ); + Menu_AddItem( &s_options.menu, ( void * ) &s_options.network ); + Menu_AddItem( &s_options.menu, ( void * ) &s_options.back ); +} + + +/* +=============== +UI_SystemConfigMenu +=============== +*/ +void UI_SystemConfigMenu( void ) { + Options_MenuInit(); + UI_PushMenu ( &s_options.menu ); +} diff --git a/code/q3_ui/ui_playermodel.c b/code/q3_ui/ui_playermodel.c index 316d5ec..444385e 100755 --- a/code/q3_ui/ui_playermodel.c +++ b/code/q3_ui/ui_playermodel.c @@ -1,731 +1,731 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -#define MODEL_BACK0 "menu/art/back_0" -#define MODEL_BACK1 "menu/art/back_1" -#define MODEL_SELECT "menu/art/opponents_select" -#define MODEL_SELECTED "menu/art/opponents_selected" -#define MODEL_FRAMEL "menu/art/frame1_l" -#define MODEL_FRAMER "menu/art/frame1_r" -#define MODEL_PORTS "menu/art/player_models_ports" -#define MODEL_ARROWS "menu/art/gs_arrows_0" -#define MODEL_ARROWSL "menu/art/gs_arrows_l" -#define MODEL_ARROWSR "menu/art/gs_arrows_r" - -#define LOW_MEMORY (5 * 1024 * 1024) - -static char* playermodel_artlist[] = -{ - MODEL_BACK0, - MODEL_BACK1, - MODEL_SELECT, - MODEL_SELECTED, - MODEL_FRAMEL, - MODEL_FRAMER, - MODEL_PORTS, - MODEL_ARROWS, - MODEL_ARROWSL, - MODEL_ARROWSR, - NULL -}; - -#define PLAYERGRID_COLS 4 -#define PLAYERGRID_ROWS 4 -#define MAX_MODELSPERPAGE (PLAYERGRID_ROWS*PLAYERGRID_COLS) - -#define MAX_PLAYERMODELS 256 - -#define ID_PLAYERPIC0 0 -#define ID_PLAYERPIC1 1 -#define ID_PLAYERPIC2 2 -#define ID_PLAYERPIC3 3 -#define ID_PLAYERPIC4 4 -#define ID_PLAYERPIC5 5 -#define ID_PLAYERPIC6 6 -#define ID_PLAYERPIC7 7 -#define ID_PLAYERPIC8 8 -#define ID_PLAYERPIC9 9 -#define ID_PLAYERPIC10 10 -#define ID_PLAYERPIC11 11 -#define ID_PLAYERPIC12 12 -#define ID_PLAYERPIC13 13 -#define ID_PLAYERPIC14 14 -#define ID_PLAYERPIC15 15 -#define ID_PREVPAGE 100 -#define ID_NEXTPAGE 101 -#define ID_BACK 102 - -typedef struct -{ - menuframework_s menu; - menubitmap_s pics[MAX_MODELSPERPAGE]; - menubitmap_s picbuttons[MAX_MODELSPERPAGE]; - menubitmap_s framel; - menubitmap_s framer; - menubitmap_s ports; - menutext_s banner; - menubitmap_s back; - menubitmap_s player; - menubitmap_s arrows; - menubitmap_s left; - menubitmap_s right; - menutext_s modelname; - menutext_s skinname; - menutext_s playername; - playerInfo_t playerinfo; - int nummodels; - char modelnames[MAX_PLAYERMODELS][128]; - int modelpage; - int numpages; - char modelskin[64]; - int selectedmodel; -} playermodel_t; - -static playermodel_t s_playermodel; - -/* -================= -PlayerModel_UpdateGrid -================= -*/ -static void PlayerModel_UpdateGrid( void ) -{ - int i; - int j; - - j = s_playermodel.modelpage * MAX_MODELSPERPAGE; - for (i=0; i 1) - { - if (s_playermodel.modelpage > 0) - s_playermodel.left.generic.flags &= ~QMF_INACTIVE; - else - s_playermodel.left.generic.flags |= QMF_INACTIVE; - - if (s_playermodel.modelpage < s_playermodel.numpages-1) - s_playermodel.right.generic.flags &= ~QMF_INACTIVE; - else - s_playermodel.right.generic.flags |= QMF_INACTIVE; - } - else - { - // hide left/right markers - s_playermodel.left.generic.flags |= QMF_INACTIVE; - s_playermodel.right.generic.flags |= QMF_INACTIVE; - } -} - -/* -================= -PlayerModel_UpdateModel -================= -*/ -static void PlayerModel_UpdateModel( void ) -{ - vec3_t viewangles; - vec3_t moveangles; - - memset( &s_playermodel.playerinfo, 0, sizeof(playerInfo_t) ); - - viewangles[YAW] = 180 - 30; - viewangles[PITCH] = 0; - viewangles[ROLL] = 0; - VectorClear( moveangles ); - - UI_PlayerInfo_SetModel( &s_playermodel.playerinfo, s_playermodel.modelskin ); - UI_PlayerInfo_SetInfo( &s_playermodel.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, moveangles, WP_MACHINEGUN, qfalse ); -} - -/* -================= -PlayerModel_SaveChanges -================= -*/ -static void PlayerModel_SaveChanges( void ) -{ - trap_Cvar_Set( "model", s_playermodel.modelskin ); - trap_Cvar_Set( "headmodel", s_playermodel.modelskin ); - trap_Cvar_Set( "team_model", s_playermodel.modelskin ); - trap_Cvar_Set( "team_headmodel", s_playermodel.modelskin ); -} - -/* -================= -PlayerModel_MenuEvent -================= -*/ -static void PlayerModel_MenuEvent( void* ptr, int event ) -{ - if (event != QM_ACTIVATED) - return; - - switch (((menucommon_s*)ptr)->id) - { - case ID_PREVPAGE: - if (s_playermodel.modelpage > 0) - { - s_playermodel.modelpage--; - PlayerModel_UpdateGrid(); - } - break; - - case ID_NEXTPAGE: - if (s_playermodel.modelpage < s_playermodel.numpages-1) - { - s_playermodel.modelpage++; - PlayerModel_UpdateGrid(); - } - break; - - case ID_BACK: - PlayerModel_SaveChanges(); - UI_PopMenu(); - break; - } -} - -/* -================= -PlayerModel_MenuKey -================= -*/ -static sfxHandle_t PlayerModel_MenuKey( int key ) -{ - menucommon_s* m; - int picnum; - - switch (key) - { - case K_KP_LEFTARROW: - case K_LEFTARROW: - m = Menu_ItemAtCursor(&s_playermodel.menu); - picnum = m->id - ID_PLAYERPIC0; - if (picnum >= 0 && picnum <= 15) - { - if (picnum > 0) - { - Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-1); - return (menu_move_sound); - - } - else if (s_playermodel.modelpage > 0) - { - s_playermodel.modelpage--; - Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+15); - PlayerModel_UpdateGrid(); - return (menu_move_sound); - } - else - return (menu_buzz_sound); - } - break; - - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - m = Menu_ItemAtCursor(&s_playermodel.menu); - picnum = m->id - ID_PLAYERPIC0; - if (picnum >= 0 && picnum <= 15) - { - if ((picnum < 15) && (s_playermodel.modelpage*MAX_MODELSPERPAGE + picnum+1 < s_playermodel.nummodels)) - { - Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+1); - return (menu_move_sound); - } - else if ((picnum == 15) && (s_playermodel.modelpage < s_playermodel.numpages-1)) - { - s_playermodel.modelpage++; - Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-15); - PlayerModel_UpdateGrid(); - return (menu_move_sound); - } - else - return (menu_buzz_sound); - } - break; - - case K_MOUSE2: - case K_ESCAPE: - PlayerModel_SaveChanges(); - break; - } - - return ( Menu_DefaultKey( &s_playermodel.menu, key ) ); -} - -/* -================= -PlayerModel_PicEvent -================= -*/ -static void PlayerModel_PicEvent( void* ptr, int event ) -{ - int modelnum; - int maxlen; - char* buffptr; - char* pdest; - int i; - - if (event != QM_ACTIVATED) - return; - - for (i=0; iid - ID_PLAYERPIC0; - s_playermodel.pics[i].generic.flags |= QMF_HIGHLIGHT; - s_playermodel.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; - - // get model and strip icon_ - modelnum = s_playermodel.modelpage*MAX_MODELSPERPAGE + i; - buffptr = s_playermodel.modelnames[modelnum] + strlen("models/players/"); - pdest = strstr(buffptr,"icon_"); - if (pdest) - { - // track the whole model/skin name - Q_strncpyz(s_playermodel.modelskin,buffptr,pdest-buffptr+1); - strcat(s_playermodel.modelskin,pdest + 5); - - // seperate the model name - maxlen = pdest-buffptr; - if (maxlen > 16) - maxlen = 16; - Q_strncpyz( s_playermodel.modelname.string, buffptr, maxlen ); - Q_strupr( s_playermodel.modelname.string ); - - // seperate the skin name - maxlen = strlen(pdest+5)+1; - if (maxlen > 16) - maxlen = 16; - Q_strncpyz( s_playermodel.skinname.string, pdest+5, maxlen ); - Q_strupr( s_playermodel.skinname.string ); - - s_playermodel.selectedmodel = modelnum; - - if( trap_MemoryRemaining() > LOW_MEMORY ) { - PlayerModel_UpdateModel(); - } - } -} - -/* -================= -PlayerModel_DrawPlayer -================= -*/ -static void PlayerModel_DrawPlayer( void *self ) -{ - menubitmap_s* b; - - b = (menubitmap_s*) self; - - if( trap_MemoryRemaining() <= LOW_MEMORY ) { - UI_DrawProportionalString( b->generic.x, b->generic.y + b->height / 2, "LOW MEMORY", UI_LEFT, color_red ); - return; - } - - UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_playermodel.playerinfo, uis.realtime/2 ); -} - -/* -================= -PlayerModel_BuildList -================= -*/ -static void PlayerModel_BuildList( void ) -{ - int numdirs; - int numfiles; - char dirlist[2048]; - char filelist[2048]; - char skinname[64]; - char* dirptr; - char* fileptr; - int i; - int j; - int dirlen; - int filelen; - qboolean precache; - - precache = trap_Cvar_VariableValue("com_buildscript"); - - s_playermodel.modelpage = 0; - s_playermodel.nummodels = 0; - - // iterate directory of all player models - numdirs = trap_FS_GetFileList("models/players", "/", dirlist, 2048 ); - dirptr = dirlist; - for (i=0; i= MAX_PLAYERMODELS) - // return; - } - - if( precache ) { - trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", skinname), qfalse ); - } - } - } - - //APSFIXME - Degenerate no models case - - s_playermodel.numpages = s_playermodel.nummodels/MAX_MODELSPERPAGE; - if (s_playermodel.nummodels % MAX_MODELSPERPAGE) - s_playermodel.numpages++; -} - -/* -================= -PlayerModel_SetMenuItems -================= -*/ -static void PlayerModel_SetMenuItems( void ) -{ - int i; - int maxlen; - char modelskin[64]; - char* buffptr; - char* pdest; - - // name - trap_Cvar_VariableStringBuffer( "name", s_playermodel.playername.string, 16 ); - Q_CleanStr( s_playermodel.playername.string ); - - // model - trap_Cvar_VariableStringBuffer( "model", s_playermodel.modelskin, 64 ); - - // find model in our list - for (i=0; i 16) - maxlen = 16; - Q_strncpyz( s_playermodel.modelname.string, buffptr, maxlen ); - Q_strupr( s_playermodel.modelname.string ); - - // seperate the skin name - maxlen = strlen(pdest+5)+1; - if (maxlen > 16) - maxlen = 16; - Q_strncpyz( s_playermodel.skinname.string, pdest+5, maxlen ); - Q_strupr( s_playermodel.skinname.string ); - break; - } - } -} - -/* -================= -PlayerModel_MenuInit -================= -*/ -static void PlayerModel_MenuInit( void ) -{ - int i; - int j; - int k; - int x; - int y; - static char playername[32]; - static char modelname[32]; - static char skinname[32]; - - // zero set all our globals - memset( &s_playermodel, 0 ,sizeof(playermodel_t) ); - - PlayerModel_Cache(); - - s_playermodel.menu.key = PlayerModel_MenuKey; - s_playermodel.menu.wrapAround = qtrue; - s_playermodel.menu.fullscreen = qtrue; - - s_playermodel.banner.generic.type = MTYPE_BTEXT; - s_playermodel.banner.generic.x = 320; - s_playermodel.banner.generic.y = 16; - s_playermodel.banner.string = "PLAYER MODEL"; - s_playermodel.banner.color = color_white; - s_playermodel.banner.style = UI_CENTER; - - s_playermodel.framel.generic.type = MTYPE_BITMAP; - s_playermodel.framel.generic.name = MODEL_FRAMEL; - s_playermodel.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_playermodel.framel.generic.x = 0; - s_playermodel.framel.generic.y = 78; - s_playermodel.framel.width = 256; - s_playermodel.framel.height = 329; - - s_playermodel.framer.generic.type = MTYPE_BITMAP; - s_playermodel.framer.generic.name = MODEL_FRAMER; - s_playermodel.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_playermodel.framer.generic.x = 376; - s_playermodel.framer.generic.y = 76; - s_playermodel.framer.width = 256; - s_playermodel.framer.height = 334; - - s_playermodel.ports.generic.type = MTYPE_BITMAP; - s_playermodel.ports.generic.name = MODEL_PORTS; - s_playermodel.ports.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_playermodel.ports.generic.x = 50; - s_playermodel.ports.generic.y = 59; - s_playermodel.ports.width = 274; - s_playermodel.ports.height = 274; - - y = 59; - for (i=0,k=0; i 1) + { + if (s_playermodel.modelpage > 0) + s_playermodel.left.generic.flags &= ~QMF_INACTIVE; + else + s_playermodel.left.generic.flags |= QMF_INACTIVE; + + if (s_playermodel.modelpage < s_playermodel.numpages-1) + s_playermodel.right.generic.flags &= ~QMF_INACTIVE; + else + s_playermodel.right.generic.flags |= QMF_INACTIVE; + } + else + { + // hide left/right markers + s_playermodel.left.generic.flags |= QMF_INACTIVE; + s_playermodel.right.generic.flags |= QMF_INACTIVE; + } +} + +/* +================= +PlayerModel_UpdateModel +================= +*/ +static void PlayerModel_UpdateModel( void ) +{ + vec3_t viewangles; + vec3_t moveangles; + + memset( &s_playermodel.playerinfo, 0, sizeof(playerInfo_t) ); + + viewangles[YAW] = 180 - 30; + viewangles[PITCH] = 0; + viewangles[ROLL] = 0; + VectorClear( moveangles ); + + UI_PlayerInfo_SetModel( &s_playermodel.playerinfo, s_playermodel.modelskin ); + UI_PlayerInfo_SetInfo( &s_playermodel.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, moveangles, WP_MACHINEGUN, qfalse ); +} + +/* +================= +PlayerModel_SaveChanges +================= +*/ +static void PlayerModel_SaveChanges( void ) +{ + trap_Cvar_Set( "model", s_playermodel.modelskin ); + trap_Cvar_Set( "headmodel", s_playermodel.modelskin ); + trap_Cvar_Set( "team_model", s_playermodel.modelskin ); + trap_Cvar_Set( "team_headmodel", s_playermodel.modelskin ); +} + +/* +================= +PlayerModel_MenuEvent +================= +*/ +static void PlayerModel_MenuEvent( void* ptr, int event ) +{ + if (event != QM_ACTIVATED) + return; + + switch (((menucommon_s*)ptr)->id) + { + case ID_PREVPAGE: + if (s_playermodel.modelpage > 0) + { + s_playermodel.modelpage--; + PlayerModel_UpdateGrid(); + } + break; + + case ID_NEXTPAGE: + if (s_playermodel.modelpage < s_playermodel.numpages-1) + { + s_playermodel.modelpage++; + PlayerModel_UpdateGrid(); + } + break; + + case ID_BACK: + PlayerModel_SaveChanges(); + UI_PopMenu(); + break; + } +} + +/* +================= +PlayerModel_MenuKey +================= +*/ +static sfxHandle_t PlayerModel_MenuKey( int key ) +{ + menucommon_s* m; + int picnum; + + switch (key) + { + case K_KP_LEFTARROW: + case K_LEFTARROW: + m = Menu_ItemAtCursor(&s_playermodel.menu); + picnum = m->id - ID_PLAYERPIC0; + if (picnum >= 0 && picnum <= 15) + { + if (picnum > 0) + { + Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-1); + return (menu_move_sound); + + } + else if (s_playermodel.modelpage > 0) + { + s_playermodel.modelpage--; + Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+15); + PlayerModel_UpdateGrid(); + return (menu_move_sound); + } + else + return (menu_buzz_sound); + } + break; + + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + m = Menu_ItemAtCursor(&s_playermodel.menu); + picnum = m->id - ID_PLAYERPIC0; + if (picnum >= 0 && picnum <= 15) + { + if ((picnum < 15) && (s_playermodel.modelpage*MAX_MODELSPERPAGE + picnum+1 < s_playermodel.nummodels)) + { + Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+1); + return (menu_move_sound); + } + else if ((picnum == 15) && (s_playermodel.modelpage < s_playermodel.numpages-1)) + { + s_playermodel.modelpage++; + Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-15); + PlayerModel_UpdateGrid(); + return (menu_move_sound); + } + else + return (menu_buzz_sound); + } + break; + + case K_MOUSE2: + case K_ESCAPE: + PlayerModel_SaveChanges(); + break; + } + + return ( Menu_DefaultKey( &s_playermodel.menu, key ) ); +} + +/* +================= +PlayerModel_PicEvent +================= +*/ +static void PlayerModel_PicEvent( void* ptr, int event ) +{ + int modelnum; + int maxlen; + char* buffptr; + char* pdest; + int i; + + if (event != QM_ACTIVATED) + return; + + for (i=0; iid - ID_PLAYERPIC0; + s_playermodel.pics[i].generic.flags |= QMF_HIGHLIGHT; + s_playermodel.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; + + // get model and strip icon_ + modelnum = s_playermodel.modelpage*MAX_MODELSPERPAGE + i; + buffptr = s_playermodel.modelnames[modelnum] + strlen("models/players/"); + pdest = strstr(buffptr,"icon_"); + if (pdest) + { + // track the whole model/skin name + Q_strncpyz(s_playermodel.modelskin,buffptr,pdest-buffptr+1); + strcat(s_playermodel.modelskin,pdest + 5); + + // seperate the model name + maxlen = pdest-buffptr; + if (maxlen > 16) + maxlen = 16; + Q_strncpyz( s_playermodel.modelname.string, buffptr, maxlen ); + Q_strupr( s_playermodel.modelname.string ); + + // seperate the skin name + maxlen = strlen(pdest+5)+1; + if (maxlen > 16) + maxlen = 16; + Q_strncpyz( s_playermodel.skinname.string, pdest+5, maxlen ); + Q_strupr( s_playermodel.skinname.string ); + + s_playermodel.selectedmodel = modelnum; + + if( trap_MemoryRemaining() > LOW_MEMORY ) { + PlayerModel_UpdateModel(); + } + } +} + +/* +================= +PlayerModel_DrawPlayer +================= +*/ +static void PlayerModel_DrawPlayer( void *self ) +{ + menubitmap_s* b; + + b = (menubitmap_s*) self; + + if( trap_MemoryRemaining() <= LOW_MEMORY ) { + UI_DrawProportionalString( b->generic.x, b->generic.y + b->height / 2, "LOW MEMORY", UI_LEFT, color_red ); + return; + } + + UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_playermodel.playerinfo, uis.realtime/2 ); +} + +/* +================= +PlayerModel_BuildList +================= +*/ +static void PlayerModel_BuildList( void ) +{ + int numdirs; + int numfiles; + char dirlist[2048]; + char filelist[2048]; + char skinname[64]; + char* dirptr; + char* fileptr; + int i; + int j; + int dirlen; + int filelen; + qboolean precache; + + precache = trap_Cvar_VariableValue("com_buildscript"); + + s_playermodel.modelpage = 0; + s_playermodel.nummodels = 0; + + // iterate directory of all player models + numdirs = trap_FS_GetFileList("models/players", "/", dirlist, 2048 ); + dirptr = dirlist; + for (i=0; i= MAX_PLAYERMODELS) + // return; + } + + if( precache ) { + trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", skinname), qfalse ); + } + } + } + + //APSFIXME - Degenerate no models case + + s_playermodel.numpages = s_playermodel.nummodels/MAX_MODELSPERPAGE; + if (s_playermodel.nummodels % MAX_MODELSPERPAGE) + s_playermodel.numpages++; +} + +/* +================= +PlayerModel_SetMenuItems +================= +*/ +static void PlayerModel_SetMenuItems( void ) +{ + int i; + int maxlen; + char modelskin[64]; + char* buffptr; + char* pdest; + + // name + trap_Cvar_VariableStringBuffer( "name", s_playermodel.playername.string, 16 ); + Q_CleanStr( s_playermodel.playername.string ); + + // model + trap_Cvar_VariableStringBuffer( "model", s_playermodel.modelskin, 64 ); + + // find model in our list + for (i=0; i 16) + maxlen = 16; + Q_strncpyz( s_playermodel.modelname.string, buffptr, maxlen ); + Q_strupr( s_playermodel.modelname.string ); + + // seperate the skin name + maxlen = strlen(pdest+5)+1; + if (maxlen > 16) + maxlen = 16; + Q_strncpyz( s_playermodel.skinname.string, pdest+5, maxlen ); + Q_strupr( s_playermodel.skinname.string ); + break; + } + } +} + +/* +================= +PlayerModel_MenuInit +================= +*/ +static void PlayerModel_MenuInit( void ) +{ + int i; + int j; + int k; + int x; + int y; + static char playername[32]; + static char modelname[32]; + static char skinname[32]; + + // zero set all our globals + memset( &s_playermodel, 0 ,sizeof(playermodel_t) ); + + PlayerModel_Cache(); + + s_playermodel.menu.key = PlayerModel_MenuKey; + s_playermodel.menu.wrapAround = qtrue; + s_playermodel.menu.fullscreen = qtrue; + + s_playermodel.banner.generic.type = MTYPE_BTEXT; + s_playermodel.banner.generic.x = 320; + s_playermodel.banner.generic.y = 16; + s_playermodel.banner.string = "PLAYER MODEL"; + s_playermodel.banner.color = color_white; + s_playermodel.banner.style = UI_CENTER; + + s_playermodel.framel.generic.type = MTYPE_BITMAP; + s_playermodel.framel.generic.name = MODEL_FRAMEL; + s_playermodel.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_playermodel.framel.generic.x = 0; + s_playermodel.framel.generic.y = 78; + s_playermodel.framel.width = 256; + s_playermodel.framel.height = 329; + + s_playermodel.framer.generic.type = MTYPE_BITMAP; + s_playermodel.framer.generic.name = MODEL_FRAMER; + s_playermodel.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_playermodel.framer.generic.x = 376; + s_playermodel.framer.generic.y = 76; + s_playermodel.framer.width = 256; + s_playermodel.framer.height = 334; + + s_playermodel.ports.generic.type = MTYPE_BITMAP; + s_playermodel.ports.generic.name = MODEL_PORTS; + s_playermodel.ports.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_playermodel.ports.generic.x = 50; + s_playermodel.ports.generic.y = 59; + s_playermodel.ports.width = 274; + s_playermodel.ports.height = 274; + + y = 59; + for (i=0,k=0; icurrentWeapon = weaponNum; -tryagain: - pi->realWeapon = weaponNum; - pi->weaponModel = 0; - pi->barrelModel = 0; - pi->flashModel = 0; - - if ( weaponNum == WP_NONE ) { - return; - } - - for ( item = bg_itemlist + 1; item->classname ; item++ ) { - if ( item->giType != IT_WEAPON ) { - continue; - } - if ( item->giTag == weaponNum ) { - break; - } - } - - if ( item->classname ) { - pi->weaponModel = trap_R_RegisterModel( item->world_model[0] ); - } - - if( pi->weaponModel == 0 ) { - if( weaponNum == WP_MACHINEGUN ) { - weaponNum = WP_NONE; - goto tryagain; - } - weaponNum = WP_MACHINEGUN; - goto tryagain; - } - - if ( weaponNum == WP_MACHINEGUN || weaponNum == WP_GAUNTLET || weaponNum == WP_BFG ) { - strcpy( path, item->world_model[0] ); - COM_StripExtension( path, path ); - strcat( path, "_barrel.md3" ); - pi->barrelModel = trap_R_RegisterModel( path ); - } - - strcpy( path, item->world_model[0] ); - COM_StripExtension( path, path ); - strcat( path, "_flash.md3" ); - pi->flashModel = trap_R_RegisterModel( path ); - - switch( weaponNum ) { - case WP_GAUNTLET: - MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); - break; - - case WP_MACHINEGUN: - MAKERGB( pi->flashDlightColor, 1, 1, 0 ); - break; - - case WP_SHOTGUN: - MAKERGB( pi->flashDlightColor, 1, 1, 0 ); - break; - - case WP_GRENADE_LAUNCHER: - MAKERGB( pi->flashDlightColor, 1, 0.7f, 0.5f ); - break; - - case WP_ROCKET_LAUNCHER: - MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); - break; - - case WP_LIGHTNING: - MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); - break; - - case WP_RAILGUN: - MAKERGB( pi->flashDlightColor, 1, 0.5f, 0 ); - break; - - case WP_PLASMAGUN: - MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); - break; - - case WP_BFG: - MAKERGB( pi->flashDlightColor, 1, 0.7f, 1 ); - break; - - case WP_GRAPPLING_HOOK: - MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); - break; - - default: - MAKERGB( pi->flashDlightColor, 1, 1, 1 ); - break; - } -} - - -/* -=============== -UI_ForceLegsAnim -=============== -*/ -static void UI_ForceLegsAnim( playerInfo_t *pi, int anim ) { - pi->legsAnim = ( ( pi->legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; - - if ( anim == LEGS_JUMP ) { - pi->legsAnimationTimer = UI_TIMER_JUMP; - } -} - - -/* -=============== -UI_SetLegsAnim -=============== -*/ -static void UI_SetLegsAnim( playerInfo_t *pi, int anim ) { - if ( pi->pendingLegsAnim ) { - anim = pi->pendingLegsAnim; - pi->pendingLegsAnim = 0; - } - UI_ForceLegsAnim( pi, anim ); -} - - -/* -=============== -UI_ForceTorsoAnim -=============== -*/ -static void UI_ForceTorsoAnim( playerInfo_t *pi, int anim ) { - pi->torsoAnim = ( ( pi->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; - - if ( anim == TORSO_GESTURE ) { - pi->torsoAnimationTimer = UI_TIMER_GESTURE; - } - - if ( anim == TORSO_ATTACK || anim == TORSO_ATTACK2 ) { - pi->torsoAnimationTimer = UI_TIMER_ATTACK; - } -} - - -/* -=============== -UI_SetTorsoAnim -=============== -*/ -static void UI_SetTorsoAnim( playerInfo_t *pi, int anim ) { - if ( pi->pendingTorsoAnim ) { - anim = pi->pendingTorsoAnim; - pi->pendingTorsoAnim = 0; - } - - UI_ForceTorsoAnim( pi, anim ); -} - - -/* -=============== -UI_TorsoSequencing -=============== -*/ -static void UI_TorsoSequencing( playerInfo_t *pi ) { - int currentAnim; - - currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; - - if ( pi->weapon != pi->currentWeapon ) { - if ( currentAnim != TORSO_DROP ) { - pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; - UI_ForceTorsoAnim( pi, TORSO_DROP ); - } - } - - if ( pi->torsoAnimationTimer > 0 ) { - return; - } - - if( currentAnim == TORSO_GESTURE ) { - UI_SetTorsoAnim( pi, TORSO_STAND ); - return; - } - - if( currentAnim == TORSO_ATTACK || currentAnim == TORSO_ATTACK2 ) { - UI_SetTorsoAnim( pi, TORSO_STAND ); - return; - } - - if ( currentAnim == TORSO_DROP ) { - UI_PlayerInfo_SetWeapon( pi, pi->weapon ); - pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; - UI_ForceTorsoAnim( pi, TORSO_RAISE ); - return; - } - - if ( currentAnim == TORSO_RAISE ) { - UI_SetTorsoAnim( pi, TORSO_STAND ); - return; - } -} - - -/* -=============== -UI_LegsSequencing -=============== -*/ -static void UI_LegsSequencing( playerInfo_t *pi ) { - int currentAnim; - - currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT; - - if ( pi->legsAnimationTimer > 0 ) { - if ( currentAnim == LEGS_JUMP ) { - jumpHeight = JUMP_HEIGHT * sin( M_PI * ( UI_TIMER_JUMP - pi->legsAnimationTimer ) / UI_TIMER_JUMP ); - } - return; - } - - if ( currentAnim == LEGS_JUMP ) { - UI_ForceLegsAnim( pi, LEGS_LAND ); - pi->legsAnimationTimer = UI_TIMER_LAND; - jumpHeight = 0; - return; - } - - if ( currentAnim == LEGS_LAND ) { - UI_SetLegsAnim( pi, LEGS_IDLE ); - return; - } -} - - -/* -====================== -UI_PositionEntityOnTag -====================== -*/ -static void UI_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent, - clipHandle_t parentModel, char *tagName ) { - int i; - orientation_t lerped; - - // lerp the tag - trap_CM_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame, - 1.0 - parent->backlerp, tagName ); - - // FIXME: allow origin offsets along tag? - VectorCopy( parent->origin, entity->origin ); - for ( i = 0 ; i < 3 ; i++ ) { - VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin ); - } - - // cast away const because of compiler problems - MatrixMultiply( lerped.axis, ((refEntity_t*)parent)->axis, entity->axis ); - entity->backlerp = parent->backlerp; -} - - -/* -====================== -UI_PositionRotatedEntityOnTag -====================== -*/ -static void UI_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent, - clipHandle_t parentModel, char *tagName ) { - int i; - orientation_t lerped; - vec3_t tempAxis[3]; - - // lerp the tag - trap_CM_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame, - 1.0 - parent->backlerp, tagName ); - - // FIXME: allow origin offsets along tag? - VectorCopy( parent->origin, entity->origin ); - for ( i = 0 ; i < 3 ; i++ ) { - VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin ); - } - - // cast away const because of compiler problems - MatrixMultiply( entity->axis, ((refEntity_t *)parent)->axis, tempAxis ); - MatrixMultiply( lerped.axis, tempAxis, entity->axis ); -} - - -/* -=============== -UI_SetLerpFrameAnimation -=============== -*/ -static void UI_SetLerpFrameAnimation( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) { - animation_t *anim; - - lf->animationNumber = newAnimation; - newAnimation &= ~ANIM_TOGGLEBIT; - - if ( newAnimation < 0 || newAnimation >= MAX_ANIMATIONS ) { - trap_Error( va("Bad animation number: %i", newAnimation) ); - } - - anim = &ci->animations[ newAnimation ]; - - lf->animation = anim; - lf->animationTime = lf->frameTime + anim->initialLerp; -} - - -/* -=============== -UI_RunLerpFrame -=============== -*/ -static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) { - int f; - animation_t *anim; - - // see if the animation sequence is switching - if ( newAnimation != lf->animationNumber || !lf->animation ) { - UI_SetLerpFrameAnimation( ci, lf, newAnimation ); - } - - // if we have passed the current frame, move it to - // oldFrame and calculate a new frame - if ( dp_realtime >= lf->frameTime ) { - lf->oldFrame = lf->frame; - lf->oldFrameTime = lf->frameTime; - - // get the next frame based on the animation - anim = lf->animation; - if ( dp_realtime < lf->animationTime ) { - lf->frameTime = lf->animationTime; // initial lerp - } else { - lf->frameTime = lf->oldFrameTime + anim->frameLerp; - } - f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; - if ( f >= anim->numFrames ) { - f -= anim->numFrames; - if ( anim->loopFrames ) { - f %= anim->loopFrames; - f += anim->numFrames - anim->loopFrames; - } else { - f = anim->numFrames - 1; - // the animation is stuck at the end, so it - // can immediately transition to another sequence - lf->frameTime = dp_realtime; - } - } - lf->frame = anim->firstFrame + f; - if ( dp_realtime > lf->frameTime ) { - lf->frameTime = dp_realtime; - } - } - - if ( lf->frameTime > dp_realtime + 200 ) { - lf->frameTime = dp_realtime; - } - - if ( lf->oldFrameTime > dp_realtime ) { - lf->oldFrameTime = dp_realtime; - } - // calculate current lerp value - if ( lf->frameTime == lf->oldFrameTime ) { - lf->backlerp = 0; - } else { - lf->backlerp = 1.0 - (float)( dp_realtime - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime ); - } -} - - -/* -=============== -UI_PlayerAnimation -=============== -*/ -static void UI_PlayerAnimation( playerInfo_t *pi, int *legsOld, int *legs, float *legsBackLerp, - int *torsoOld, int *torso, float *torsoBackLerp ) { - - // legs animation - pi->legsAnimationTimer -= uis.frametime; - if ( pi->legsAnimationTimer < 0 ) { - pi->legsAnimationTimer = 0; - } - - UI_LegsSequencing( pi ); - - if ( pi->legs.yawing && ( pi->legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_IDLE ) { - UI_RunLerpFrame( pi, &pi->legs, LEGS_TURN ); - } else { - UI_RunLerpFrame( pi, &pi->legs, pi->legsAnim ); - } - *legsOld = pi->legs.oldFrame; - *legs = pi->legs.frame; - *legsBackLerp = pi->legs.backlerp; - - // torso animation - pi->torsoAnimationTimer -= uis.frametime; - if ( pi->torsoAnimationTimer < 0 ) { - pi->torsoAnimationTimer = 0; - } - - UI_TorsoSequencing( pi ); - - UI_RunLerpFrame( pi, &pi->torso, pi->torsoAnim ); - *torsoOld = pi->torso.oldFrame; - *torso = pi->torso.frame; - *torsoBackLerp = pi->torso.backlerp; -} - - -/* -================== -UI_SwingAngles -================== -*/ -static void UI_SwingAngles( float destination, float swingTolerance, float clampTolerance, - float speed, float *angle, qboolean *swinging ) { - float swing; - float move; - float scale; - - if ( !*swinging ) { - // see if a swing should be started - swing = AngleSubtract( *angle, destination ); - if ( swing > swingTolerance || swing < -swingTolerance ) { - *swinging = qtrue; - } - } - - if ( !*swinging ) { - return; - } - - // modify the speed depending on the delta - // so it doesn't seem so linear - swing = AngleSubtract( destination, *angle ); - scale = fabs( swing ); - if ( scale < swingTolerance * 0.5 ) { - scale = 0.5; - } else if ( scale < swingTolerance ) { - scale = 1.0; - } else { - scale = 2.0; - } - - // swing towards the destination angle - if ( swing >= 0 ) { - move = uis.frametime * scale * speed; - if ( move >= swing ) { - move = swing; - *swinging = qfalse; - } - *angle = AngleMod( *angle + move ); - } else if ( swing < 0 ) { - move = uis.frametime * scale * -speed; - if ( move <= swing ) { - move = swing; - *swinging = qfalse; - } - *angle = AngleMod( *angle + move ); - } - - // clamp to no more than tolerance - swing = AngleSubtract( destination, *angle ); - if ( swing > clampTolerance ) { - *angle = AngleMod( destination - (clampTolerance - 1) ); - } else if ( swing < -clampTolerance ) { - *angle = AngleMod( destination + (clampTolerance - 1) ); - } -} - - -/* -====================== -UI_MovedirAdjustment -====================== -*/ -static float UI_MovedirAdjustment( playerInfo_t *pi ) { - vec3_t relativeAngles; - vec3_t moveVector; - - VectorSubtract( pi->viewAngles, pi->moveAngles, relativeAngles ); - AngleVectors( relativeAngles, moveVector, NULL, NULL ); - if ( Q_fabs( moveVector[0] ) < 0.01 ) { - moveVector[0] = 0.0; - } - if ( Q_fabs( moveVector[1] ) < 0.01 ) { - moveVector[1] = 0.0; - } - - if ( moveVector[1] == 0 && moveVector[0] > 0 ) { - return 0; - } - if ( moveVector[1] < 0 && moveVector[0] > 0 ) { - return 22; - } - if ( moveVector[1] < 0 && moveVector[0] == 0 ) { - return 45; - } - if ( moveVector[1] < 0 && moveVector[0] < 0 ) { - return -22; - } - if ( moveVector[1] == 0 && moveVector[0] < 0 ) { - return 0; - } - if ( moveVector[1] > 0 && moveVector[0] < 0 ) { - return 22; - } - if ( moveVector[1] > 0 && moveVector[0] == 0 ) { - return -45; - } - - return -22; -} - - -/* -=============== -UI_PlayerAngles -=============== -*/ -static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[3], vec3_t torso[3], vec3_t head[3] ) { - vec3_t legsAngles, torsoAngles, headAngles; - float dest; - float adjust; - - VectorCopy( pi->viewAngles, headAngles ); - headAngles[YAW] = AngleMod( headAngles[YAW] ); - VectorClear( legsAngles ); - VectorClear( torsoAngles ); - - // --------- yaw ------------- - - // allow yaw to drift a bit - if ( ( pi->legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE - || ( pi->torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND ) { - // if not standing still, always point all in the same direction - pi->torso.yawing = qtrue; // always center - pi->torso.pitching = qtrue; // always center - pi->legs.yawing = qtrue; // always center - } - - // adjust legs for movement dir - adjust = UI_MovedirAdjustment( pi ); - legsAngles[YAW] = headAngles[YAW] + adjust; - torsoAngles[YAW] = headAngles[YAW] + 0.25 * adjust; - - - // torso - UI_SwingAngles( torsoAngles[YAW], 25, 90, SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing ); - UI_SwingAngles( legsAngles[YAW], 40, 90, SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing ); - - torsoAngles[YAW] = pi->torso.yawAngle; - legsAngles[YAW] = pi->legs.yawAngle; - - // --------- pitch ------------- - - // only show a fraction of the pitch angle in the torso - if ( headAngles[PITCH] > 180 ) { - dest = (-360 + headAngles[PITCH]) * 0.75; - } else { - dest = headAngles[PITCH] * 0.75; - } - UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching ); - torsoAngles[PITCH] = pi->torso.pitchAngle; - - // pull the angles back out of the hierarchial chain - AnglesSubtract( headAngles, torsoAngles, headAngles ); - AnglesSubtract( torsoAngles, legsAngles, torsoAngles ); - AnglesToAxis( legsAngles, legs ); - AnglesToAxis( torsoAngles, torso ); - AnglesToAxis( headAngles, head ); -} - - -/* -=============== -UI_PlayerFloatSprite -=============== -*/ -static void UI_PlayerFloatSprite( playerInfo_t *pi, vec3_t origin, qhandle_t shader ) { - refEntity_t ent; - - memset( &ent, 0, sizeof( ent ) ); - VectorCopy( origin, ent.origin ); - ent.origin[2] += 48; - ent.reType = RT_SPRITE; - ent.customShader = shader; - ent.radius = 10; - ent.renderfx = 0; - trap_R_AddRefEntityToScene( &ent ); -} - - -/* -====================== -UI_MachinegunSpinAngle -====================== -*/ -float UI_MachinegunSpinAngle( playerInfo_t *pi ) { - int delta; - float angle; - float speed; - int torsoAnim; - - delta = dp_realtime - pi->barrelTime; - if ( pi->barrelSpinning ) { - angle = pi->barrelAngle + delta * SPIN_SPEED; - } else { - if ( delta > COAST_TIME ) { - delta = COAST_TIME; - } - - speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME ); - angle = pi->barrelAngle + delta * speed; - } - - torsoAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; - if( torsoAnim == TORSO_ATTACK2 ) { - torsoAnim = TORSO_ATTACK; - } - if ( pi->barrelSpinning == !(torsoAnim == TORSO_ATTACK) ) { - pi->barrelTime = dp_realtime; - pi->barrelAngle = AngleMod( angle ); - pi->barrelSpinning = !!(torsoAnim == TORSO_ATTACK); - } - - return angle; -} - - -/* -=============== -UI_DrawPlayer -=============== -*/ -void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) { - refdef_t refdef; - refEntity_t legs; - refEntity_t torso; - refEntity_t head; - refEntity_t gun; - refEntity_t barrel; - refEntity_t flash; - vec3_t origin; - int renderfx; - vec3_t mins = {-16, -16, -24}; - vec3_t maxs = {16, 16, 32}; - float len; - float xx; - - if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) { - return; - } - - dp_realtime = time; - - if ( pi->pendingWeapon != -1 && dp_realtime > pi->weaponTimer ) { - pi->weapon = pi->pendingWeapon; - pi->lastWeapon = pi->pendingWeapon; - pi->pendingWeapon = -1; - pi->weaponTimer = 0; - if( pi->currentWeapon != pi->weapon ) { - trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); - } - } - - UI_AdjustFrom640( &x, &y, &w, &h ); - - y -= jumpHeight; - - memset( &refdef, 0, sizeof( refdef ) ); - memset( &legs, 0, sizeof(legs) ); - memset( &torso, 0, sizeof(torso) ); - memset( &head, 0, sizeof(head) ); - - refdef.rdflags = RDF_NOWORLDMODEL; - - AxisClear( refdef.viewaxis ); - - refdef.x = x; - refdef.y = y; - refdef.width = w; - refdef.height = h; - - refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f); - xx = refdef.width / tan( refdef.fov_x / 360 * M_PI ); - refdef.fov_y = atan2( refdef.height, xx ); - refdef.fov_y *= ( 360 / M_PI ); - - // calculate distance so the player nearly fills the box - len = 0.7 * ( maxs[2] - mins[2] ); - origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); - origin[1] = 0.5 * ( mins[1] + maxs[1] ); - origin[2] = -0.5 * ( mins[2] + maxs[2] ); - - refdef.time = dp_realtime; - - trap_R_ClearScene(); - - // get the rotation information - UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); - - // get the animation state (after rotation, to allow feet shuffle) - UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, - &torso.oldframe, &torso.frame, &torso.backlerp ); - - renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; - - // - // add the legs - // - legs.hModel = pi->legsModel; - legs.customSkin = pi->legsSkin; - - VectorCopy( origin, legs.origin ); - - VectorCopy( origin, legs.lightingOrigin ); - legs.renderfx = renderfx; - VectorCopy (legs.origin, legs.oldorigin); - - trap_R_AddRefEntityToScene( &legs ); - - if (!legs.hModel) { - return; - } - - // - // add the torso - // - torso.hModel = pi->torsoModel; - if (!torso.hModel) { - return; - } - - torso.customSkin = pi->torsoSkin; - - VectorCopy( origin, torso.lightingOrigin ); - - UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso"); - - torso.renderfx = renderfx; - - trap_R_AddRefEntityToScene( &torso ); - - // - // add the head - // - head.hModel = pi->headModel; - if (!head.hModel) { - return; - } - head.customSkin = pi->headSkin; - - VectorCopy( origin, head.lightingOrigin ); - - UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head"); - - head.renderfx = renderfx; - - trap_R_AddRefEntityToScene( &head ); - - // - // add the gun - // - if ( pi->currentWeapon != WP_NONE ) { - memset( &gun, 0, sizeof(gun) ); - gun.hModel = pi->weaponModel; - VectorCopy( origin, gun.lightingOrigin ); - UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); - gun.renderfx = renderfx; - trap_R_AddRefEntityToScene( &gun ); - } - - // - // add the spinning barrel - // - if ( pi->realWeapon == WP_MACHINEGUN || pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) { - vec3_t angles; - - memset( &barrel, 0, sizeof(barrel) ); - VectorCopy( origin, barrel.lightingOrigin ); - barrel.renderfx = renderfx; - - barrel.hModel = pi->barrelModel; - angles[YAW] = 0; - angles[PITCH] = 0; - angles[ROLL] = UI_MachinegunSpinAngle( pi ); - if( pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) { - angles[PITCH] = angles[ROLL]; - angles[ROLL] = 0; - } - AnglesToAxis( angles, barrel.axis ); - - UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel"); - - trap_R_AddRefEntityToScene( &barrel ); - } - - // - // add muzzle flash - // - if ( dp_realtime <= pi->muzzleFlashTime ) { - if ( pi->flashModel ) { - memset( &flash, 0, sizeof(flash) ); - flash.hModel = pi->flashModel; - VectorCopy( origin, flash.lightingOrigin ); - UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash"); - flash.renderfx = renderfx; - trap_R_AddRefEntityToScene( &flash ); - } - - // make a dlight for the flash - if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { - trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0], - pi->flashDlightColor[1], pi->flashDlightColor[2] ); - } - } - - // - // add the chat icon - // - if ( pi->chat ) { - UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); - } - - // - // add an accent light - // - origin[0] -= 100; // + = behind, - = in front - origin[1] += 100; // + = left, - = right - origin[2] += 100; // + = above, - = below - trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0 ); - - origin[0] -= 100; - origin[1] -= 100; - origin[2] -= 100; - trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0 ); - - trap_R_RenderScene( &refdef ); -} - - -/* -========================== -UI_RegisterClientSkin -========================== -*/ -static qboolean UI_RegisterClientSkin( playerInfo_t *pi, const char *modelName, const char *skinName ) { - char filename[MAX_QPATH]; - - Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower_%s.skin", modelName, skinName ); - pi->legsSkin = trap_R_RegisterSkin( filename ); - - Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper_%s.skin", modelName, skinName ); - pi->torsoSkin = trap_R_RegisterSkin( filename ); - - Com_sprintf( filename, sizeof( filename ), "models/players/%s/head_%s.skin", modelName, skinName ); - pi->headSkin = trap_R_RegisterSkin( filename ); - - if ( !pi->legsSkin || !pi->torsoSkin || !pi->headSkin ) { - return qfalse; - } - - return qtrue; -} - - -/* -====================== -UI_ParseAnimationFile -====================== -*/ -static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animations ) { - char *text_p, *prev; - int len; - int i; - char *token; - float fps; - int skip; - char text[20000]; - fileHandle_t f; - - memset( animations, 0, sizeof( animation_t ) * MAX_ANIMATIONS ); - - // load the file - len = trap_FS_FOpenFile( filename, &f, FS_READ ); - if ( len <= 0 ) { - return qfalse; - } - if ( len >= ( sizeof( text ) - 1 ) ) { - Com_Printf( "File %s too long\n", filename ); - return qfalse; - } - trap_FS_Read( text, len, f ); - text[len] = 0; - trap_FS_FCloseFile( f ); - - // parse the text - text_p = text; - skip = 0; // quite the compiler warning - - // read optional parameters - while ( 1 ) { - prev = text_p; // so we can unget - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - if ( !Q_stricmp( token, "footsteps" ) ) { - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - continue; - } else if ( !Q_stricmp( token, "headoffset" ) ) { - for ( i = 0 ; i < 3 ; i++ ) { - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - } - continue; - } else if ( !Q_stricmp( token, "sex" ) ) { - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - continue; - } - - // if it is a number, start parsing animations - if ( token[0] >= '0' && token[0] <= '9' ) { - text_p = prev; // unget the token - break; - } - - Com_Printf( "unknown token '%s' is %s\n", token, filename ); - } - - // read information for each frame - for ( i = 0 ; i < MAX_ANIMATIONS ; i++ ) { - - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - animations[i].firstFrame = atoi( token ); - // leg only frames are adjusted to not count the upper body only frames - if ( i == LEGS_WALKCR ) { - skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame; - } - if ( i >= LEGS_WALKCR ) { - animations[i].firstFrame -= skip; - } - - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - animations[i].numFrames = atoi( token ); - - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - animations[i].loopFrames = atoi( token ); - - token = COM_Parse( &text_p ); - if ( !token ) { - break; - } - fps = atof( token ); - if ( fps == 0 ) { - fps = 1; - } - animations[i].frameLerp = 1000 / fps; - animations[i].initialLerp = 1000 / fps; - } - - if ( i != MAX_ANIMATIONS ) { - Com_Printf( "Error parsing animation file: %s", filename ); - return qfalse; - } - - return qtrue; -} - - -/* -========================== -UI_RegisterClientModelname -========================== -*/ -qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName ) { - char modelName[MAX_QPATH]; - char skinName[MAX_QPATH]; - char filename[MAX_QPATH]; - char *slash; - - pi->torsoModel = 0; - pi->headModel = 0; - - if ( !modelSkinName[0] ) { - return qfalse; - } - - Q_strncpyz( modelName, modelSkinName, sizeof( modelName ) ); - - slash = strchr( modelName, '/' ); - if ( !slash ) { - // modelName did not include a skin name - Q_strncpyz( skinName, "default", sizeof( skinName ) ); - } else { - Q_strncpyz( skinName, slash + 1, sizeof( skinName ) ); - // truncate modelName - *slash = 0; - } - - // load cmodels before models so filecache works - - Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower.md3", modelName ); - pi->legsModel = trap_R_RegisterModel( filename ); - if ( !pi->legsModel ) { - Com_Printf( "Failed to load model file %s\n", filename ); - return qfalse; - } - - Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper.md3", modelName ); - pi->torsoModel = trap_R_RegisterModel( filename ); - if ( !pi->torsoModel ) { - Com_Printf( "Failed to load model file %s\n", filename ); - return qfalse; - } - - Com_sprintf( filename, sizeof( filename ), "models/players/%s/head.md3", modelName ); - pi->headModel = trap_R_RegisterModel( filename ); - if ( !pi->headModel ) { - Com_Printf( "Failed to load model file %s\n", filename ); - return qfalse; - } - - // if any skins failed to load, fall back to default - if ( !UI_RegisterClientSkin( pi, modelName, skinName ) ) { - if ( !UI_RegisterClientSkin( pi, modelName, "default" ) ) { - Com_Printf( "Failed to load skin file: %s : %s\n", modelName, skinName ); - return qfalse; - } - } - - // load the animations - Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName ); - if ( !UI_ParseAnimationFile( filename, pi->animations ) ) { - Com_Printf( "Failed to load animation file %s\n", filename ); - return qfalse; - } - - return qtrue; -} - - -/* -=============== -UI_PlayerInfo_SetModel -=============== -*/ -void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model ) { - memset( pi, 0, sizeof(*pi) ); - UI_RegisterClientModelname( pi, model ); - pi->weapon = WP_MACHINEGUN; - pi->currentWeapon = pi->weapon; - pi->lastWeapon = pi->weapon; - pi->pendingWeapon = -1; - pi->weaponTimer = 0; - pi->chat = qfalse; - pi->newModel = qtrue; - UI_PlayerInfo_SetWeapon( pi, pi->weapon ); -} - - -/* -=============== -UI_PlayerInfo_SetInfo -=============== -*/ -void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNumber, qboolean chat ) { - int currentAnim; - weapon_t weaponNum; - - pi->chat = chat; - - // view angles - VectorCopy( viewAngles, pi->viewAngles ); - - // move angles - VectorCopy( moveAngles, pi->moveAngles ); - - if ( pi->newModel ) { - pi->newModel = qfalse; - - jumpHeight = 0; - pi->pendingLegsAnim = 0; - UI_ForceLegsAnim( pi, legsAnim ); - pi->legs.yawAngle = viewAngles[YAW]; - pi->legs.yawing = qfalse; - - pi->pendingTorsoAnim = 0; - UI_ForceTorsoAnim( pi, torsoAnim ); - pi->torso.yawAngle = viewAngles[YAW]; - pi->torso.yawing = qfalse; - - if ( weaponNumber != -1 ) { - pi->weapon = weaponNumber; - pi->currentWeapon = weaponNumber; - pi->lastWeapon = weaponNumber; - pi->pendingWeapon = -1; - pi->weaponTimer = 0; - UI_PlayerInfo_SetWeapon( pi, pi->weapon ); - } - - return; - } - - // weapon - if ( weaponNumber == -1 ) { - pi->pendingWeapon = -1; - pi->weaponTimer = 0; - } - else if ( weaponNumber != WP_NONE ) { - pi->pendingWeapon = weaponNumber; - pi->weaponTimer = dp_realtime + UI_TIMER_WEAPON_DELAY; - } - weaponNum = pi->lastWeapon; - pi->weapon = weaponNum; - - if ( torsoAnim == BOTH_DEATH1 || legsAnim == BOTH_DEATH1 ) { - torsoAnim = legsAnim = BOTH_DEATH1; - pi->weapon = pi->currentWeapon = WP_NONE; - UI_PlayerInfo_SetWeapon( pi, pi->weapon ); - - jumpHeight = 0; - pi->pendingLegsAnim = 0; - UI_ForceLegsAnim( pi, legsAnim ); - - pi->pendingTorsoAnim = 0; - UI_ForceTorsoAnim( pi, torsoAnim ); - - return; - } - - // leg animation - currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT; - if ( legsAnim != LEGS_JUMP && ( currentAnim == LEGS_JUMP || currentAnim == LEGS_LAND ) ) { - pi->pendingLegsAnim = legsAnim; - } - else if ( legsAnim != currentAnim ) { - jumpHeight = 0; - pi->pendingLegsAnim = 0; - UI_ForceLegsAnim( pi, legsAnim ); - } - - // torso animation - if ( torsoAnim == TORSO_STAND || torsoAnim == TORSO_STAND2 ) { - if ( weaponNum == WP_NONE || weaponNum == WP_GAUNTLET ) { - torsoAnim = TORSO_STAND2; - } - else { - torsoAnim = TORSO_STAND; - } - } - - if ( torsoAnim == TORSO_ATTACK || torsoAnim == TORSO_ATTACK2 ) { - if ( weaponNum == WP_NONE || weaponNum == WP_GAUNTLET ) { - torsoAnim = TORSO_ATTACK2; - } - else { - torsoAnim = TORSO_ATTACK; - } - pi->muzzleFlashTime = dp_realtime + UI_TIMER_MUZZLE_FLASH; - //FIXME play firing sound here - } - - currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; - - if ( weaponNum != pi->currentWeapon || currentAnim == TORSO_RAISE || currentAnim == TORSO_DROP ) { - pi->pendingTorsoAnim = torsoAnim; - } - else if ( ( currentAnim == TORSO_GESTURE || currentAnim == TORSO_ATTACK ) && ( torsoAnim != currentAnim ) ) { - pi->pendingTorsoAnim = torsoAnim; - } - else if ( torsoAnim != currentAnim ) { - pi->pendingTorsoAnim = 0; - UI_ForceTorsoAnim( pi, torsoAnim ); - } -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +// ui_players.c + +#include "ui_local.h" + + +#define UI_TIMER_GESTURE 2300 +#define UI_TIMER_JUMP 1000 +#define UI_TIMER_LAND 130 +#define UI_TIMER_WEAPON_SWITCH 300 +#define UI_TIMER_ATTACK 500 +#define UI_TIMER_MUZZLE_FLASH 20 +#define UI_TIMER_WEAPON_DELAY 250 + +#define JUMP_HEIGHT 56 + +#define SWINGSPEED 0.3f + +#define SPIN_SPEED 0.9f +#define COAST_TIME 1000 + + +static int dp_realtime; +static float jumpHeight; + + +/* +=============== +UI_PlayerInfo_SetWeapon +=============== +*/ +static void UI_PlayerInfo_SetWeapon( playerInfo_t *pi, weapon_t weaponNum ) { + gitem_t * item; + char path[MAX_QPATH]; + + pi->currentWeapon = weaponNum; +tryagain: + pi->realWeapon = weaponNum; + pi->weaponModel = 0; + pi->barrelModel = 0; + pi->flashModel = 0; + + if ( weaponNum == WP_NONE ) { + return; + } + + for ( item = bg_itemlist + 1; item->classname ; item++ ) { + if ( item->giType != IT_WEAPON ) { + continue; + } + if ( item->giTag == weaponNum ) { + break; + } + } + + if ( item->classname ) { + pi->weaponModel = trap_R_RegisterModel( item->world_model[0] ); + } + + if( pi->weaponModel == 0 ) { + if( weaponNum == WP_MACHINEGUN ) { + weaponNum = WP_NONE; + goto tryagain; + } + weaponNum = WP_MACHINEGUN; + goto tryagain; + } + + if ( weaponNum == WP_MACHINEGUN || weaponNum == WP_GAUNTLET || weaponNum == WP_BFG ) { + strcpy( path, item->world_model[0] ); + COM_StripExtension( path, path ); + strcat( path, "_barrel.md3" ); + pi->barrelModel = trap_R_RegisterModel( path ); + } + + strcpy( path, item->world_model[0] ); + COM_StripExtension( path, path ); + strcat( path, "_flash.md3" ); + pi->flashModel = trap_R_RegisterModel( path ); + + switch( weaponNum ) { + case WP_GAUNTLET: + MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); + break; + + case WP_MACHINEGUN: + MAKERGB( pi->flashDlightColor, 1, 1, 0 ); + break; + + case WP_SHOTGUN: + MAKERGB( pi->flashDlightColor, 1, 1, 0 ); + break; + + case WP_GRENADE_LAUNCHER: + MAKERGB( pi->flashDlightColor, 1, 0.7f, 0.5f ); + break; + + case WP_ROCKET_LAUNCHER: + MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 ); + break; + + case WP_LIGHTNING: + MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); + break; + + case WP_RAILGUN: + MAKERGB( pi->flashDlightColor, 1, 0.5f, 0 ); + break; + + case WP_PLASMAGUN: + MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); + break; + + case WP_BFG: + MAKERGB( pi->flashDlightColor, 1, 0.7f, 1 ); + break; + + case WP_GRAPPLING_HOOK: + MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 ); + break; + + default: + MAKERGB( pi->flashDlightColor, 1, 1, 1 ); + break; + } +} + + +/* +=============== +UI_ForceLegsAnim +=============== +*/ +static void UI_ForceLegsAnim( playerInfo_t *pi, int anim ) { + pi->legsAnim = ( ( pi->legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; + + if ( anim == LEGS_JUMP ) { + pi->legsAnimationTimer = UI_TIMER_JUMP; + } +} + + +/* +=============== +UI_SetLegsAnim +=============== +*/ +static void UI_SetLegsAnim( playerInfo_t *pi, int anim ) { + if ( pi->pendingLegsAnim ) { + anim = pi->pendingLegsAnim; + pi->pendingLegsAnim = 0; + } + UI_ForceLegsAnim( pi, anim ); +} + + +/* +=============== +UI_ForceTorsoAnim +=============== +*/ +static void UI_ForceTorsoAnim( playerInfo_t *pi, int anim ) { + pi->torsoAnim = ( ( pi->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim; + + if ( anim == TORSO_GESTURE ) { + pi->torsoAnimationTimer = UI_TIMER_GESTURE; + } + + if ( anim == TORSO_ATTACK || anim == TORSO_ATTACK2 ) { + pi->torsoAnimationTimer = UI_TIMER_ATTACK; + } +} + + +/* +=============== +UI_SetTorsoAnim +=============== +*/ +static void UI_SetTorsoAnim( playerInfo_t *pi, int anim ) { + if ( pi->pendingTorsoAnim ) { + anim = pi->pendingTorsoAnim; + pi->pendingTorsoAnim = 0; + } + + UI_ForceTorsoAnim( pi, anim ); +} + + +/* +=============== +UI_TorsoSequencing +=============== +*/ +static void UI_TorsoSequencing( playerInfo_t *pi ) { + int currentAnim; + + currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; + + if ( pi->weapon != pi->currentWeapon ) { + if ( currentAnim != TORSO_DROP ) { + pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; + UI_ForceTorsoAnim( pi, TORSO_DROP ); + } + } + + if ( pi->torsoAnimationTimer > 0 ) { + return; + } + + if( currentAnim == TORSO_GESTURE ) { + UI_SetTorsoAnim( pi, TORSO_STAND ); + return; + } + + if( currentAnim == TORSO_ATTACK || currentAnim == TORSO_ATTACK2 ) { + UI_SetTorsoAnim( pi, TORSO_STAND ); + return; + } + + if ( currentAnim == TORSO_DROP ) { + UI_PlayerInfo_SetWeapon( pi, pi->weapon ); + pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH; + UI_ForceTorsoAnim( pi, TORSO_RAISE ); + return; + } + + if ( currentAnim == TORSO_RAISE ) { + UI_SetTorsoAnim( pi, TORSO_STAND ); + return; + } +} + + +/* +=============== +UI_LegsSequencing +=============== +*/ +static void UI_LegsSequencing( playerInfo_t *pi ) { + int currentAnim; + + currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT; + + if ( pi->legsAnimationTimer > 0 ) { + if ( currentAnim == LEGS_JUMP ) { + jumpHeight = JUMP_HEIGHT * sin( M_PI * ( UI_TIMER_JUMP - pi->legsAnimationTimer ) / UI_TIMER_JUMP ); + } + return; + } + + if ( currentAnim == LEGS_JUMP ) { + UI_ForceLegsAnim( pi, LEGS_LAND ); + pi->legsAnimationTimer = UI_TIMER_LAND; + jumpHeight = 0; + return; + } + + if ( currentAnim == LEGS_LAND ) { + UI_SetLegsAnim( pi, LEGS_IDLE ); + return; + } +} + + +/* +====================== +UI_PositionEntityOnTag +====================== +*/ +static void UI_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent, + clipHandle_t parentModel, char *tagName ) { + int i; + orientation_t lerped; + + // lerp the tag + trap_CM_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame, + 1.0 - parent->backlerp, tagName ); + + // FIXME: allow origin offsets along tag? + VectorCopy( parent->origin, entity->origin ); + for ( i = 0 ; i < 3 ; i++ ) { + VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin ); + } + + // cast away const because of compiler problems + MatrixMultiply( lerped.axis, ((refEntity_t*)parent)->axis, entity->axis ); + entity->backlerp = parent->backlerp; +} + + +/* +====================== +UI_PositionRotatedEntityOnTag +====================== +*/ +static void UI_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent, + clipHandle_t parentModel, char *tagName ) { + int i; + orientation_t lerped; + vec3_t tempAxis[3]; + + // lerp the tag + trap_CM_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame, + 1.0 - parent->backlerp, tagName ); + + // FIXME: allow origin offsets along tag? + VectorCopy( parent->origin, entity->origin ); + for ( i = 0 ; i < 3 ; i++ ) { + VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin ); + } + + // cast away const because of compiler problems + MatrixMultiply( entity->axis, ((refEntity_t *)parent)->axis, tempAxis ); + MatrixMultiply( lerped.axis, tempAxis, entity->axis ); +} + + +/* +=============== +UI_SetLerpFrameAnimation +=============== +*/ +static void UI_SetLerpFrameAnimation( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) { + animation_t *anim; + + lf->animationNumber = newAnimation; + newAnimation &= ~ANIM_TOGGLEBIT; + + if ( newAnimation < 0 || newAnimation >= MAX_ANIMATIONS ) { + trap_Error( va("Bad animation number: %i", newAnimation) ); + } + + anim = &ci->animations[ newAnimation ]; + + lf->animation = anim; + lf->animationTime = lf->frameTime + anim->initialLerp; +} + + +/* +=============== +UI_RunLerpFrame +=============== +*/ +static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) { + int f; + animation_t *anim; + + // see if the animation sequence is switching + if ( newAnimation != lf->animationNumber || !lf->animation ) { + UI_SetLerpFrameAnimation( ci, lf, newAnimation ); + } + + // if we have passed the current frame, move it to + // oldFrame and calculate a new frame + if ( dp_realtime >= lf->frameTime ) { + lf->oldFrame = lf->frame; + lf->oldFrameTime = lf->frameTime; + + // get the next frame based on the animation + anim = lf->animation; + if ( dp_realtime < lf->animationTime ) { + lf->frameTime = lf->animationTime; // initial lerp + } else { + lf->frameTime = lf->oldFrameTime + anim->frameLerp; + } + f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp; + if ( f >= anim->numFrames ) { + f -= anim->numFrames; + if ( anim->loopFrames ) { + f %= anim->loopFrames; + f += anim->numFrames - anim->loopFrames; + } else { + f = anim->numFrames - 1; + // the animation is stuck at the end, so it + // can immediately transition to another sequence + lf->frameTime = dp_realtime; + } + } + lf->frame = anim->firstFrame + f; + if ( dp_realtime > lf->frameTime ) { + lf->frameTime = dp_realtime; + } + } + + if ( lf->frameTime > dp_realtime + 200 ) { + lf->frameTime = dp_realtime; + } + + if ( lf->oldFrameTime > dp_realtime ) { + lf->oldFrameTime = dp_realtime; + } + // calculate current lerp value + if ( lf->frameTime == lf->oldFrameTime ) { + lf->backlerp = 0; + } else { + lf->backlerp = 1.0 - (float)( dp_realtime - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime ); + } +} + + +/* +=============== +UI_PlayerAnimation +=============== +*/ +static void UI_PlayerAnimation( playerInfo_t *pi, int *legsOld, int *legs, float *legsBackLerp, + int *torsoOld, int *torso, float *torsoBackLerp ) { + + // legs animation + pi->legsAnimationTimer -= uis.frametime; + if ( pi->legsAnimationTimer < 0 ) { + pi->legsAnimationTimer = 0; + } + + UI_LegsSequencing( pi ); + + if ( pi->legs.yawing && ( pi->legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_IDLE ) { + UI_RunLerpFrame( pi, &pi->legs, LEGS_TURN ); + } else { + UI_RunLerpFrame( pi, &pi->legs, pi->legsAnim ); + } + *legsOld = pi->legs.oldFrame; + *legs = pi->legs.frame; + *legsBackLerp = pi->legs.backlerp; + + // torso animation + pi->torsoAnimationTimer -= uis.frametime; + if ( pi->torsoAnimationTimer < 0 ) { + pi->torsoAnimationTimer = 0; + } + + UI_TorsoSequencing( pi ); + + UI_RunLerpFrame( pi, &pi->torso, pi->torsoAnim ); + *torsoOld = pi->torso.oldFrame; + *torso = pi->torso.frame; + *torsoBackLerp = pi->torso.backlerp; +} + + +/* +================== +UI_SwingAngles +================== +*/ +static void UI_SwingAngles( float destination, float swingTolerance, float clampTolerance, + float speed, float *angle, qboolean *swinging ) { + float swing; + float move; + float scale; + + if ( !*swinging ) { + // see if a swing should be started + swing = AngleSubtract( *angle, destination ); + if ( swing > swingTolerance || swing < -swingTolerance ) { + *swinging = qtrue; + } + } + + if ( !*swinging ) { + return; + } + + // modify the speed depending on the delta + // so it doesn't seem so linear + swing = AngleSubtract( destination, *angle ); + scale = fabs( swing ); + if ( scale < swingTolerance * 0.5 ) { + scale = 0.5; + } else if ( scale < swingTolerance ) { + scale = 1.0; + } else { + scale = 2.0; + } + + // swing towards the destination angle + if ( swing >= 0 ) { + move = uis.frametime * scale * speed; + if ( move >= swing ) { + move = swing; + *swinging = qfalse; + } + *angle = AngleMod( *angle + move ); + } else if ( swing < 0 ) { + move = uis.frametime * scale * -speed; + if ( move <= swing ) { + move = swing; + *swinging = qfalse; + } + *angle = AngleMod( *angle + move ); + } + + // clamp to no more than tolerance + swing = AngleSubtract( destination, *angle ); + if ( swing > clampTolerance ) { + *angle = AngleMod( destination - (clampTolerance - 1) ); + } else if ( swing < -clampTolerance ) { + *angle = AngleMod( destination + (clampTolerance - 1) ); + } +} + + +/* +====================== +UI_MovedirAdjustment +====================== +*/ +static float UI_MovedirAdjustment( playerInfo_t *pi ) { + vec3_t relativeAngles; + vec3_t moveVector; + + VectorSubtract( pi->viewAngles, pi->moveAngles, relativeAngles ); + AngleVectors( relativeAngles, moveVector, NULL, NULL ); + if ( Q_fabs( moveVector[0] ) < 0.01 ) { + moveVector[0] = 0.0; + } + if ( Q_fabs( moveVector[1] ) < 0.01 ) { + moveVector[1] = 0.0; + } + + if ( moveVector[1] == 0 && moveVector[0] > 0 ) { + return 0; + } + if ( moveVector[1] < 0 && moveVector[0] > 0 ) { + return 22; + } + if ( moveVector[1] < 0 && moveVector[0] == 0 ) { + return 45; + } + if ( moveVector[1] < 0 && moveVector[0] < 0 ) { + return -22; + } + if ( moveVector[1] == 0 && moveVector[0] < 0 ) { + return 0; + } + if ( moveVector[1] > 0 && moveVector[0] < 0 ) { + return 22; + } + if ( moveVector[1] > 0 && moveVector[0] == 0 ) { + return -45; + } + + return -22; +} + + +/* +=============== +UI_PlayerAngles +=============== +*/ +static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[3], vec3_t torso[3], vec3_t head[3] ) { + vec3_t legsAngles, torsoAngles, headAngles; + float dest; + float adjust; + + VectorCopy( pi->viewAngles, headAngles ); + headAngles[YAW] = AngleMod( headAngles[YAW] ); + VectorClear( legsAngles ); + VectorClear( torsoAngles ); + + // --------- yaw ------------- + + // allow yaw to drift a bit + if ( ( pi->legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE + || ( pi->torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND ) { + // if not standing still, always point all in the same direction + pi->torso.yawing = qtrue; // always center + pi->torso.pitching = qtrue; // always center + pi->legs.yawing = qtrue; // always center + } + + // adjust legs for movement dir + adjust = UI_MovedirAdjustment( pi ); + legsAngles[YAW] = headAngles[YAW] + adjust; + torsoAngles[YAW] = headAngles[YAW] + 0.25 * adjust; + + + // torso + UI_SwingAngles( torsoAngles[YAW], 25, 90, SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing ); + UI_SwingAngles( legsAngles[YAW], 40, 90, SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing ); + + torsoAngles[YAW] = pi->torso.yawAngle; + legsAngles[YAW] = pi->legs.yawAngle; + + // --------- pitch ------------- + + // only show a fraction of the pitch angle in the torso + if ( headAngles[PITCH] > 180 ) { + dest = (-360 + headAngles[PITCH]) * 0.75; + } else { + dest = headAngles[PITCH] * 0.75; + } + UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching ); + torsoAngles[PITCH] = pi->torso.pitchAngle; + + // pull the angles back out of the hierarchial chain + AnglesSubtract( headAngles, torsoAngles, headAngles ); + AnglesSubtract( torsoAngles, legsAngles, torsoAngles ); + AnglesToAxis( legsAngles, legs ); + AnglesToAxis( torsoAngles, torso ); + AnglesToAxis( headAngles, head ); +} + + +/* +=============== +UI_PlayerFloatSprite +=============== +*/ +static void UI_PlayerFloatSprite( playerInfo_t *pi, vec3_t origin, qhandle_t shader ) { + refEntity_t ent; + + memset( &ent, 0, sizeof( ent ) ); + VectorCopy( origin, ent.origin ); + ent.origin[2] += 48; + ent.reType = RT_SPRITE; + ent.customShader = shader; + ent.radius = 10; + ent.renderfx = 0; + trap_R_AddRefEntityToScene( &ent ); +} + + +/* +====================== +UI_MachinegunSpinAngle +====================== +*/ +float UI_MachinegunSpinAngle( playerInfo_t *pi ) { + int delta; + float angle; + float speed; + int torsoAnim; + + delta = dp_realtime - pi->barrelTime; + if ( pi->barrelSpinning ) { + angle = pi->barrelAngle + delta * SPIN_SPEED; + } else { + if ( delta > COAST_TIME ) { + delta = COAST_TIME; + } + + speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME ); + angle = pi->barrelAngle + delta * speed; + } + + torsoAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; + if( torsoAnim == TORSO_ATTACK2 ) { + torsoAnim = TORSO_ATTACK; + } + if ( pi->barrelSpinning == !(torsoAnim == TORSO_ATTACK) ) { + pi->barrelTime = dp_realtime; + pi->barrelAngle = AngleMod( angle ); + pi->barrelSpinning = !!(torsoAnim == TORSO_ATTACK); + } + + return angle; +} + + +/* +=============== +UI_DrawPlayer +=============== +*/ +void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) { + refdef_t refdef; + refEntity_t legs; + refEntity_t torso; + refEntity_t head; + refEntity_t gun; + refEntity_t barrel; + refEntity_t flash; + vec3_t origin; + int renderfx; + vec3_t mins = {-16, -16, -24}; + vec3_t maxs = {16, 16, 32}; + float len; + float xx; + + if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) { + return; + } + + dp_realtime = time; + + if ( pi->pendingWeapon != -1 && dp_realtime > pi->weaponTimer ) { + pi->weapon = pi->pendingWeapon; + pi->lastWeapon = pi->pendingWeapon; + pi->pendingWeapon = -1; + pi->weaponTimer = 0; + if( pi->currentWeapon != pi->weapon ) { + trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); + } + } + + UI_AdjustFrom640( &x, &y, &w, &h ); + + y -= jumpHeight; + + memset( &refdef, 0, sizeof( refdef ) ); + memset( &legs, 0, sizeof(legs) ); + memset( &torso, 0, sizeof(torso) ); + memset( &head, 0, sizeof(head) ); + + refdef.rdflags = RDF_NOWORLDMODEL; + + AxisClear( refdef.viewaxis ); + + refdef.x = x; + refdef.y = y; + refdef.width = w; + refdef.height = h; + + refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f); + xx = refdef.width / tan( refdef.fov_x / 360 * M_PI ); + refdef.fov_y = atan2( refdef.height, xx ); + refdef.fov_y *= ( 360 / M_PI ); + + // calculate distance so the player nearly fills the box + len = 0.7 * ( maxs[2] - mins[2] ); + origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); + origin[1] = 0.5 * ( mins[1] + maxs[1] ); + origin[2] = -0.5 * ( mins[2] + maxs[2] ); + + refdef.time = dp_realtime; + + trap_R_ClearScene(); + + // get the rotation information + UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); + + // get the animation state (after rotation, to allow feet shuffle) + UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, + &torso.oldframe, &torso.frame, &torso.backlerp ); + + renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; + + // + // add the legs + // + legs.hModel = pi->legsModel; + legs.customSkin = pi->legsSkin; + + VectorCopy( origin, legs.origin ); + + VectorCopy( origin, legs.lightingOrigin ); + legs.renderfx = renderfx; + VectorCopy (legs.origin, legs.oldorigin); + + trap_R_AddRefEntityToScene( &legs ); + + if (!legs.hModel) { + return; + } + + // + // add the torso + // + torso.hModel = pi->torsoModel; + if (!torso.hModel) { + return; + } + + torso.customSkin = pi->torsoSkin; + + VectorCopy( origin, torso.lightingOrigin ); + + UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso"); + + torso.renderfx = renderfx; + + trap_R_AddRefEntityToScene( &torso ); + + // + // add the head + // + head.hModel = pi->headModel; + if (!head.hModel) { + return; + } + head.customSkin = pi->headSkin; + + VectorCopy( origin, head.lightingOrigin ); + + UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head"); + + head.renderfx = renderfx; + + trap_R_AddRefEntityToScene( &head ); + + // + // add the gun + // + if ( pi->currentWeapon != WP_NONE ) { + memset( &gun, 0, sizeof(gun) ); + gun.hModel = pi->weaponModel; + VectorCopy( origin, gun.lightingOrigin ); + UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); + gun.renderfx = renderfx; + trap_R_AddRefEntityToScene( &gun ); + } + + // + // add the spinning barrel + // + if ( pi->realWeapon == WP_MACHINEGUN || pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) { + vec3_t angles; + + memset( &barrel, 0, sizeof(barrel) ); + VectorCopy( origin, barrel.lightingOrigin ); + barrel.renderfx = renderfx; + + barrel.hModel = pi->barrelModel; + angles[YAW] = 0; + angles[PITCH] = 0; + angles[ROLL] = UI_MachinegunSpinAngle( pi ); + if( pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) { + angles[PITCH] = angles[ROLL]; + angles[ROLL] = 0; + } + AnglesToAxis( angles, barrel.axis ); + + UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel"); + + trap_R_AddRefEntityToScene( &barrel ); + } + + // + // add muzzle flash + // + if ( dp_realtime <= pi->muzzleFlashTime ) { + if ( pi->flashModel ) { + memset( &flash, 0, sizeof(flash) ); + flash.hModel = pi->flashModel; + VectorCopy( origin, flash.lightingOrigin ); + UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash"); + flash.renderfx = renderfx; + trap_R_AddRefEntityToScene( &flash ); + } + + // make a dlight for the flash + if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { + trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0], + pi->flashDlightColor[1], pi->flashDlightColor[2] ); + } + } + + // + // add the chat icon + // + if ( pi->chat ) { + UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); + } + + // + // add an accent light + // + origin[0] -= 100; // + = behind, - = in front + origin[1] += 100; // + = left, - = right + origin[2] += 100; // + = above, - = below + trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0 ); + + origin[0] -= 100; + origin[1] -= 100; + origin[2] -= 100; + trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0 ); + + trap_R_RenderScene( &refdef ); +} + + +/* +========================== +UI_RegisterClientSkin +========================== +*/ +static qboolean UI_RegisterClientSkin( playerInfo_t *pi, const char *modelName, const char *skinName ) { + char filename[MAX_QPATH]; + + Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower_%s.skin", modelName, skinName ); + pi->legsSkin = trap_R_RegisterSkin( filename ); + + Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper_%s.skin", modelName, skinName ); + pi->torsoSkin = trap_R_RegisterSkin( filename ); + + Com_sprintf( filename, sizeof( filename ), "models/players/%s/head_%s.skin", modelName, skinName ); + pi->headSkin = trap_R_RegisterSkin( filename ); + + if ( !pi->legsSkin || !pi->torsoSkin || !pi->headSkin ) { + return qfalse; + } + + return qtrue; +} + + +/* +====================== +UI_ParseAnimationFile +====================== +*/ +static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animations ) { + char *text_p, *prev; + int len; + int i; + char *token; + float fps; + int skip; + char text[20000]; + fileHandle_t f; + + memset( animations, 0, sizeof( animation_t ) * MAX_ANIMATIONS ); + + // load the file + len = trap_FS_FOpenFile( filename, &f, FS_READ ); + if ( len <= 0 ) { + return qfalse; + } + if ( len >= ( sizeof( text ) - 1 ) ) { + Com_Printf( "File %s too long\n", filename ); + return qfalse; + } + trap_FS_Read( text, len, f ); + text[len] = 0; + trap_FS_FCloseFile( f ); + + // parse the text + text_p = text; + skip = 0; // quite the compiler warning + + // read optional parameters + while ( 1 ) { + prev = text_p; // so we can unget + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + if ( !Q_stricmp( token, "footsteps" ) ) { + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + continue; + } else if ( !Q_stricmp( token, "headoffset" ) ) { + for ( i = 0 ; i < 3 ; i++ ) { + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + } + continue; + } else if ( !Q_stricmp( token, "sex" ) ) { + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + continue; + } + + // if it is a number, start parsing animations + if ( token[0] >= '0' && token[0] <= '9' ) { + text_p = prev; // unget the token + break; + } + + Com_Printf( "unknown token '%s' is %s\n", token, filename ); + } + + // read information for each frame + for ( i = 0 ; i < MAX_ANIMATIONS ; i++ ) { + + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + animations[i].firstFrame = atoi( token ); + // leg only frames are adjusted to not count the upper body only frames + if ( i == LEGS_WALKCR ) { + skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame; + } + if ( i >= LEGS_WALKCR ) { + animations[i].firstFrame -= skip; + } + + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + animations[i].numFrames = atoi( token ); + + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + animations[i].loopFrames = atoi( token ); + + token = COM_Parse( &text_p ); + if ( !token ) { + break; + } + fps = atof( token ); + if ( fps == 0 ) { + fps = 1; + } + animations[i].frameLerp = 1000 / fps; + animations[i].initialLerp = 1000 / fps; + } + + if ( i != MAX_ANIMATIONS ) { + Com_Printf( "Error parsing animation file: %s", filename ); + return qfalse; + } + + return qtrue; +} + + +/* +========================== +UI_RegisterClientModelname +========================== +*/ +qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName ) { + char modelName[MAX_QPATH]; + char skinName[MAX_QPATH]; + char filename[MAX_QPATH]; + char *slash; + + pi->torsoModel = 0; + pi->headModel = 0; + + if ( !modelSkinName[0] ) { + return qfalse; + } + + Q_strncpyz( modelName, modelSkinName, sizeof( modelName ) ); + + slash = strchr( modelName, '/' ); + if ( !slash ) { + // modelName did not include a skin name + Q_strncpyz( skinName, "default", sizeof( skinName ) ); + } else { + Q_strncpyz( skinName, slash + 1, sizeof( skinName ) ); + // truncate modelName + *slash = 0; + } + + // load cmodels before models so filecache works + + Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower.md3", modelName ); + pi->legsModel = trap_R_RegisterModel( filename ); + if ( !pi->legsModel ) { + Com_Printf( "Failed to load model file %s\n", filename ); + return qfalse; + } + + Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper.md3", modelName ); + pi->torsoModel = trap_R_RegisterModel( filename ); + if ( !pi->torsoModel ) { + Com_Printf( "Failed to load model file %s\n", filename ); + return qfalse; + } + + Com_sprintf( filename, sizeof( filename ), "models/players/%s/head.md3", modelName ); + pi->headModel = trap_R_RegisterModel( filename ); + if ( !pi->headModel ) { + Com_Printf( "Failed to load model file %s\n", filename ); + return qfalse; + } + + // if any skins failed to load, fall back to default + if ( !UI_RegisterClientSkin( pi, modelName, skinName ) ) { + if ( !UI_RegisterClientSkin( pi, modelName, "default" ) ) { + Com_Printf( "Failed to load skin file: %s : %s\n", modelName, skinName ); + return qfalse; + } + } + + // load the animations + Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName ); + if ( !UI_ParseAnimationFile( filename, pi->animations ) ) { + Com_Printf( "Failed to load animation file %s\n", filename ); + return qfalse; + } + + return qtrue; +} + + +/* +=============== +UI_PlayerInfo_SetModel +=============== +*/ +void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model ) { + memset( pi, 0, sizeof(*pi) ); + UI_RegisterClientModelname( pi, model ); + pi->weapon = WP_MACHINEGUN; + pi->currentWeapon = pi->weapon; + pi->lastWeapon = pi->weapon; + pi->pendingWeapon = -1; + pi->weaponTimer = 0; + pi->chat = qfalse; + pi->newModel = qtrue; + UI_PlayerInfo_SetWeapon( pi, pi->weapon ); +} + + +/* +=============== +UI_PlayerInfo_SetInfo +=============== +*/ +void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNumber, qboolean chat ) { + int currentAnim; + weapon_t weaponNum; + + pi->chat = chat; + + // view angles + VectorCopy( viewAngles, pi->viewAngles ); + + // move angles + VectorCopy( moveAngles, pi->moveAngles ); + + if ( pi->newModel ) { + pi->newModel = qfalse; + + jumpHeight = 0; + pi->pendingLegsAnim = 0; + UI_ForceLegsAnim( pi, legsAnim ); + pi->legs.yawAngle = viewAngles[YAW]; + pi->legs.yawing = qfalse; + + pi->pendingTorsoAnim = 0; + UI_ForceTorsoAnim( pi, torsoAnim ); + pi->torso.yawAngle = viewAngles[YAW]; + pi->torso.yawing = qfalse; + + if ( weaponNumber != -1 ) { + pi->weapon = weaponNumber; + pi->currentWeapon = weaponNumber; + pi->lastWeapon = weaponNumber; + pi->pendingWeapon = -1; + pi->weaponTimer = 0; + UI_PlayerInfo_SetWeapon( pi, pi->weapon ); + } + + return; + } + + // weapon + if ( weaponNumber == -1 ) { + pi->pendingWeapon = -1; + pi->weaponTimer = 0; + } + else if ( weaponNumber != WP_NONE ) { + pi->pendingWeapon = weaponNumber; + pi->weaponTimer = dp_realtime + UI_TIMER_WEAPON_DELAY; + } + weaponNum = pi->lastWeapon; + pi->weapon = weaponNum; + + if ( torsoAnim == BOTH_DEATH1 || legsAnim == BOTH_DEATH1 ) { + torsoAnim = legsAnim = BOTH_DEATH1; + pi->weapon = pi->currentWeapon = WP_NONE; + UI_PlayerInfo_SetWeapon( pi, pi->weapon ); + + jumpHeight = 0; + pi->pendingLegsAnim = 0; + UI_ForceLegsAnim( pi, legsAnim ); + + pi->pendingTorsoAnim = 0; + UI_ForceTorsoAnim( pi, torsoAnim ); + + return; + } + + // leg animation + currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT; + if ( legsAnim != LEGS_JUMP && ( currentAnim == LEGS_JUMP || currentAnim == LEGS_LAND ) ) { + pi->pendingLegsAnim = legsAnim; + } + else if ( legsAnim != currentAnim ) { + jumpHeight = 0; + pi->pendingLegsAnim = 0; + UI_ForceLegsAnim( pi, legsAnim ); + } + + // torso animation + if ( torsoAnim == TORSO_STAND || torsoAnim == TORSO_STAND2 ) { + if ( weaponNum == WP_NONE || weaponNum == WP_GAUNTLET ) { + torsoAnim = TORSO_STAND2; + } + else { + torsoAnim = TORSO_STAND; + } + } + + if ( torsoAnim == TORSO_ATTACK || torsoAnim == TORSO_ATTACK2 ) { + if ( weaponNum == WP_NONE || weaponNum == WP_GAUNTLET ) { + torsoAnim = TORSO_ATTACK2; + } + else { + torsoAnim = TORSO_ATTACK; + } + pi->muzzleFlashTime = dp_realtime + UI_TIMER_MUZZLE_FLASH; + //FIXME play firing sound here + } + + currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT; + + if ( weaponNum != pi->currentWeapon || currentAnim == TORSO_RAISE || currentAnim == TORSO_DROP ) { + pi->pendingTorsoAnim = torsoAnim; + } + else if ( ( currentAnim == TORSO_GESTURE || currentAnim == TORSO_ATTACK ) && ( torsoAnim != currentAnim ) ) { + pi->pendingTorsoAnim = torsoAnim; + } + else if ( torsoAnim != currentAnim ) { + pi->pendingTorsoAnim = 0; + UI_ForceTorsoAnim( pi, torsoAnim ); + } +} diff --git a/code/q3_ui/ui_playersettings.c b/code/q3_ui/ui_playersettings.c index c299f75..99fafd0 100755 --- a/code/q3_ui/ui_playersettings.c +++ b/code/q3_ui/ui_playersettings.c @@ -1,513 +1,513 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_MODEL0 "menu/art/model_0" -#define ART_MODEL1 "menu/art/model_1" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FX_BASE "menu/art/fx_base" -#define ART_FX_BLUE "menu/art/fx_blue" -#define ART_FX_CYAN "menu/art/fx_cyan" -#define ART_FX_GREEN "menu/art/fx_grn" -#define ART_FX_RED "menu/art/fx_red" -#define ART_FX_TEAL "menu/art/fx_teal" -#define ART_FX_WHITE "menu/art/fx_white" -#define ART_FX_YELLOW "menu/art/fx_yel" - -#define ID_NAME 10 -#define ID_HANDICAP 11 -#define ID_EFFECTS 12 -#define ID_BACK 13 -#define ID_MODEL 14 - -#define MAX_NAMELENGTH 20 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - menubitmap_s player; - - menufield_s name; - menulist_s handicap; - menulist_s effects; - - menubitmap_s back; - menubitmap_s model; - menubitmap_s item_null; - - qhandle_t fxBasePic; - qhandle_t fxPic[7]; - playerInfo_t playerinfo; - int current_fx; - char playerModel[MAX_QPATH]; -} playersettings_t; - -static playersettings_t s_playersettings; - -static int gamecodetoui[] = {4,2,3,0,5,1,6}; -static int uitogamecode[] = {4,6,2,3,1,5,7}; - -static const char *handicap_items[] = { - "None", - "95", - "90", - "85", - "80", - "75", - "70", - "65", - "60", - "55", - "50", - "45", - "40", - "35", - "30", - "25", - "20", - "15", - "10", - "5", - 0 -}; - - -/* -================= -PlayerSettings_DrawName -================= -*/ -static void PlayerSettings_DrawName( void *self ) { - menufield_s *f; - qboolean focus; - int style; - char *txt; - char c; - float *color; - int n; - int basex, x, y; - char name[32]; - - f = (menufield_s*)self; - basex = f->generic.x; - y = f->generic.y; - focus = (f->generic.parent->cursor == f->generic.menuPosition); - - style = UI_LEFT|UI_SMALLFONT; - color = text_color_normal; - if( focus ) { - style |= UI_PULSE; - color = text_color_highlight; - } - - UI_DrawProportionalString( basex, y, "Name", style, color ); - - // draw the actual name - basex += 64; - y += PROP_HEIGHT; - txt = f->field.buffer; - color = g_color_table[ColorIndex(COLOR_WHITE)]; - x = basex; - while ( (c = *txt) != 0 ) { - if ( !focus && Q_IsColorString( txt ) ) { - n = ColorIndex( *(txt+1) ); - if( n == 0 ) { - n = 7; - } - color = g_color_table[n]; - txt += 2; - continue; - } - UI_DrawChar( x, y, c, style, color ); - txt++; - x += SMALLCHAR_WIDTH; - } - - // draw cursor if we have focus - if( focus ) { - if ( trap_Key_GetOverstrikeMode() ) { - c = 11; - } else { - c = 10; - } - - style &= ~UI_PULSE; - style |= UI_BLINK; - - UI_DrawChar( basex + f->field.cursor * SMALLCHAR_WIDTH, y, c, style, color_white ); - } - - // draw at bottom also using proportional font - Q_strncpyz( name, f->field.buffer, sizeof(name) ); - Q_CleanStr( name ); - UI_DrawProportionalString( 320, 440, name, UI_CENTER|UI_BIGFONT, text_color_normal ); -} - - -/* -================= -PlayerSettings_DrawHandicap -================= -*/ -static void PlayerSettings_DrawHandicap( void *self ) { - menulist_s *item; - qboolean focus; - int style; - float *color; - - item = (menulist_s *)self; - focus = (item->generic.parent->cursor == item->generic.menuPosition); - - style = UI_LEFT|UI_SMALLFONT; - color = text_color_normal; - if( focus ) { - style |= UI_PULSE; - color = text_color_highlight; - } - - UI_DrawProportionalString( item->generic.x, item->generic.y, "Handicap", style, color ); - UI_DrawProportionalString( item->generic.x + 64, item->generic.y + PROP_HEIGHT, handicap_items[item->curvalue], style, color ); -} - - -/* -================= -PlayerSettings_DrawEffects -================= -*/ -static void PlayerSettings_DrawEffects( void *self ) { - menulist_s *item; - qboolean focus; - int style; - float *color; - - item = (menulist_s *)self; - focus = (item->generic.parent->cursor == item->generic.menuPosition); - - style = UI_LEFT|UI_SMALLFONT; - color = text_color_normal; - if( focus ) { - style |= UI_PULSE; - color = text_color_highlight; - } - - UI_DrawProportionalString( item->generic.x, item->generic.y, "Effects", style, color ); - - UI_DrawHandlePic( item->generic.x + 64, item->generic.y + PROP_HEIGHT + 8, 128, 8, s_playersettings.fxBasePic ); - UI_DrawHandlePic( item->generic.x + 64 + item->curvalue * 16 + 8, item->generic.y + PROP_HEIGHT + 6, 16, 12, s_playersettings.fxPic[item->curvalue] ); -} - - -/* -================= -PlayerSettings_DrawPlayer -================= -*/ -static void PlayerSettings_DrawPlayer( void *self ) { - menubitmap_s *b; - vec3_t viewangles; - char buf[MAX_QPATH]; - - trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) ); - if ( strcmp( buf, s_playersettings.playerModel ) != 0 ) { - UI_PlayerInfo_SetModel( &s_playersettings.playerinfo, buf ); - strcpy( s_playersettings.playerModel, buf ); - - viewangles[YAW] = 180 - 30; - viewangles[PITCH] = 0; - viewangles[ROLL] = 0; - UI_PlayerInfo_SetInfo( &s_playersettings.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); - } - - b = (menubitmap_s*) self; - UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_playersettings.playerinfo, uis.realtime/2 ); -} - - -/* -================= -PlayerSettings_SaveChanges -================= -*/ -static void PlayerSettings_SaveChanges( void ) { - // name - trap_Cvar_Set( "name", s_playersettings.name.field.buffer ); - - // handicap - trap_Cvar_SetValue( "handicap", 100 - s_playersettings.handicap.curvalue * 5 ); - - // effects color - trap_Cvar_SetValue( "color1", uitogamecode[s_playersettings.effects.curvalue] ); -} - - -/* -================= -PlayerSettings_MenuKey -================= -*/ -static sfxHandle_t PlayerSettings_MenuKey( int key ) { - if( key == K_MOUSE2 || key == K_ESCAPE ) { - PlayerSettings_SaveChanges(); - } - return Menu_DefaultKey( &s_playersettings.menu, key ); -} - - -/* -================= -PlayerSettings_SetMenuItems -================= -*/ -static void PlayerSettings_SetMenuItems( void ) { - vec3_t viewangles; - int c; - int h; - - // name - Q_strncpyz( s_playersettings.name.field.buffer, UI_Cvar_VariableString("name"), sizeof(s_playersettings.name.field.buffer) ); - - // effects color - c = trap_Cvar_VariableValue( "color1" ) - 1; - if( c < 0 || c > 6 ) { - c = 6; - } - s_playersettings.effects.curvalue = gamecodetoui[c]; - - // model/skin - memset( &s_playersettings.playerinfo, 0, sizeof(playerInfo_t) ); - - viewangles[YAW] = 180 - 30; - viewangles[PITCH] = 0; - viewangles[ROLL] = 0; - - UI_PlayerInfo_SetModel( &s_playersettings.playerinfo, UI_Cvar_VariableString( "model" ) ); - UI_PlayerInfo_SetInfo( &s_playersettings.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); - - // handicap - h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); - s_playersettings.handicap.curvalue = 20 - h / 5; -} - - -/* -================= -PlayerSettings_MenuEvent -================= -*/ -static void PlayerSettings_MenuEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_HANDICAP: - trap_Cvar_Set( "handicap", va( "%i", 100 - 25 * s_playersettings.handicap.curvalue ) ); - break; - - case ID_MODEL: - PlayerSettings_SaveChanges(); - UI_PlayerModelMenu(); - break; - - case ID_BACK: - PlayerSettings_SaveChanges(); - UI_PopMenu(); - break; - } -} - - -/* -================= -PlayerSettings_MenuInit -================= -*/ -static void PlayerSettings_MenuInit( void ) { - int y; - - memset(&s_playersettings,0,sizeof(playersettings_t)); - - PlayerSettings_Cache(); - - s_playersettings.menu.key = PlayerSettings_MenuKey; - s_playersettings.menu.wrapAround = qtrue; - s_playersettings.menu.fullscreen = qtrue; - - s_playersettings.banner.generic.type = MTYPE_BTEXT; - s_playersettings.banner.generic.x = 320; - s_playersettings.banner.generic.y = 16; - s_playersettings.banner.string = "PLAYER SETTINGS"; - s_playersettings.banner.color = color_white; - s_playersettings.banner.style = UI_CENTER; - - s_playersettings.framel.generic.type = MTYPE_BITMAP; - s_playersettings.framel.generic.name = ART_FRAMEL; - s_playersettings.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_playersettings.framel.generic.x = 0; - s_playersettings.framel.generic.y = 78; - s_playersettings.framel.width = 256; - s_playersettings.framel.height = 329; - - s_playersettings.framer.generic.type = MTYPE_BITMAP; - s_playersettings.framer.generic.name = ART_FRAMER; - s_playersettings.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_playersettings.framer.generic.x = 376; - s_playersettings.framer.generic.y = 76; - s_playersettings.framer.width = 256; - s_playersettings.framer.height = 334; - - y = 144; - s_playersettings.name.generic.type = MTYPE_FIELD; - s_playersettings.name.generic.flags = QMF_NODEFAULTINIT; - s_playersettings.name.generic.ownerdraw = PlayerSettings_DrawName; - s_playersettings.name.field.widthInChars = MAX_NAMELENGTH; - s_playersettings.name.field.maxchars = MAX_NAMELENGTH; - s_playersettings.name.generic.x = 192; - s_playersettings.name.generic.y = y; - s_playersettings.name.generic.left = 192 - 8; - s_playersettings.name.generic.top = y - 8; - s_playersettings.name.generic.right = 192 + 200; - s_playersettings.name.generic.bottom = y + 2 * PROP_HEIGHT; - - y += 3 * PROP_HEIGHT; - s_playersettings.handicap.generic.type = MTYPE_SPINCONTROL; - s_playersettings.handicap.generic.flags = QMF_NODEFAULTINIT; - s_playersettings.handicap.generic.id = ID_HANDICAP; - s_playersettings.handicap.generic.ownerdraw = PlayerSettings_DrawHandicap; - s_playersettings.handicap.generic.x = 192; - s_playersettings.handicap.generic.y = y; - s_playersettings.handicap.generic.left = 192 - 8; - s_playersettings.handicap.generic.top = y - 8; - s_playersettings.handicap.generic.right = 192 + 200; - s_playersettings.handicap.generic.bottom = y + 2 * PROP_HEIGHT; - s_playersettings.handicap.numitems = 20; - - y += 3 * PROP_HEIGHT; - s_playersettings.effects.generic.type = MTYPE_SPINCONTROL; - s_playersettings.effects.generic.flags = QMF_NODEFAULTINIT; - s_playersettings.effects.generic.id = ID_EFFECTS; - s_playersettings.effects.generic.ownerdraw = PlayerSettings_DrawEffects; - s_playersettings.effects.generic.x = 192; - s_playersettings.effects.generic.y = y; - s_playersettings.effects.generic.left = 192 - 8; - s_playersettings.effects.generic.top = y - 8; - s_playersettings.effects.generic.right = 192 + 200; - s_playersettings.effects.generic.bottom = y + 2* PROP_HEIGHT; - s_playersettings.effects.numitems = 7; - - s_playersettings.model.generic.type = MTYPE_BITMAP; - s_playersettings.model.generic.name = ART_MODEL0; - s_playersettings.model.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_playersettings.model.generic.id = ID_MODEL; - s_playersettings.model.generic.callback = PlayerSettings_MenuEvent; - s_playersettings.model.generic.x = 640; - s_playersettings.model.generic.y = 480-64; - s_playersettings.model.width = 128; - s_playersettings.model.height = 64; - s_playersettings.model.focuspic = ART_MODEL1; - - s_playersettings.player.generic.type = MTYPE_BITMAP; - s_playersettings.player.generic.flags = QMF_INACTIVE; - s_playersettings.player.generic.ownerdraw = PlayerSettings_DrawPlayer; - s_playersettings.player.generic.x = 400; - s_playersettings.player.generic.y = -40; - s_playersettings.player.width = 32*10; - s_playersettings.player.height = 56*10; - - s_playersettings.back.generic.type = MTYPE_BITMAP; - s_playersettings.back.generic.name = ART_BACK0; - s_playersettings.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_playersettings.back.generic.id = ID_BACK; - s_playersettings.back.generic.callback = PlayerSettings_MenuEvent; - s_playersettings.back.generic.x = 0; - s_playersettings.back.generic.y = 480-64; - s_playersettings.back.width = 128; - s_playersettings.back.height = 64; - s_playersettings.back.focuspic = ART_BACK1; - - s_playersettings.item_null.generic.type = MTYPE_BITMAP; - s_playersettings.item_null.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY|QMF_SILENT; - s_playersettings.item_null.generic.x = 0; - s_playersettings.item_null.generic.y = 0; - s_playersettings.item_null.width = 640; - s_playersettings.item_null.height = 480; - - Menu_AddItem( &s_playersettings.menu, &s_playersettings.banner ); - Menu_AddItem( &s_playersettings.menu, &s_playersettings.framel ); - Menu_AddItem( &s_playersettings.menu, &s_playersettings.framer ); - - Menu_AddItem( &s_playersettings.menu, &s_playersettings.name ); - Menu_AddItem( &s_playersettings.menu, &s_playersettings.handicap ); - Menu_AddItem( &s_playersettings.menu, &s_playersettings.effects ); - Menu_AddItem( &s_playersettings.menu, &s_playersettings.model ); - Menu_AddItem( &s_playersettings.menu, &s_playersettings.back ); - - Menu_AddItem( &s_playersettings.menu, &s_playersettings.player ); - - Menu_AddItem( &s_playersettings.menu, &s_playersettings.item_null ); - - PlayerSettings_SetMenuItems(); -} - - -/* -================= -PlayerSettings_Cache -================= -*/ -void PlayerSettings_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_MODEL0 ); - trap_R_RegisterShaderNoMip( ART_MODEL1 ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - - s_playersettings.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE ); - s_playersettings.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED ); - s_playersettings.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW ); - s_playersettings.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_GREEN ); - s_playersettings.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_TEAL ); - s_playersettings.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE ); - s_playersettings.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_CYAN ); - s_playersettings.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE ); -} - - -/* -================= -UI_PlayerSettingsMenu -================= -*/ -void UI_PlayerSettingsMenu( void ) { - PlayerSettings_MenuInit(); - UI_PushMenu( &s_playersettings.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_MODEL0 "menu/art/model_0" +#define ART_MODEL1 "menu/art/model_1" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FX_BASE "menu/art/fx_base" +#define ART_FX_BLUE "menu/art/fx_blue" +#define ART_FX_CYAN "menu/art/fx_cyan" +#define ART_FX_GREEN "menu/art/fx_grn" +#define ART_FX_RED "menu/art/fx_red" +#define ART_FX_TEAL "menu/art/fx_teal" +#define ART_FX_WHITE "menu/art/fx_white" +#define ART_FX_YELLOW "menu/art/fx_yel" + +#define ID_NAME 10 +#define ID_HANDICAP 11 +#define ID_EFFECTS 12 +#define ID_BACK 13 +#define ID_MODEL 14 + +#define MAX_NAMELENGTH 20 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + menubitmap_s player; + + menufield_s name; + menulist_s handicap; + menulist_s effects; + + menubitmap_s back; + menubitmap_s model; + menubitmap_s item_null; + + qhandle_t fxBasePic; + qhandle_t fxPic[7]; + playerInfo_t playerinfo; + int current_fx; + char playerModel[MAX_QPATH]; +} playersettings_t; + +static playersettings_t s_playersettings; + +static int gamecodetoui[] = {4,2,3,0,5,1,6}; +static int uitogamecode[] = {4,6,2,3,1,5,7}; + +static const char *handicap_items[] = { + "None", + "95", + "90", + "85", + "80", + "75", + "70", + "65", + "60", + "55", + "50", + "45", + "40", + "35", + "30", + "25", + "20", + "15", + "10", + "5", + 0 +}; + + +/* +================= +PlayerSettings_DrawName +================= +*/ +static void PlayerSettings_DrawName( void *self ) { + menufield_s *f; + qboolean focus; + int style; + char *txt; + char c; + float *color; + int n; + int basex, x, y; + char name[32]; + + f = (menufield_s*)self; + basex = f->generic.x; + y = f->generic.y; + focus = (f->generic.parent->cursor == f->generic.menuPosition); + + style = UI_LEFT|UI_SMALLFONT; + color = text_color_normal; + if( focus ) { + style |= UI_PULSE; + color = text_color_highlight; + } + + UI_DrawProportionalString( basex, y, "Name", style, color ); + + // draw the actual name + basex += 64; + y += PROP_HEIGHT; + txt = f->field.buffer; + color = g_color_table[ColorIndex(COLOR_WHITE)]; + x = basex; + while ( (c = *txt) != 0 ) { + if ( !focus && Q_IsColorString( txt ) ) { + n = ColorIndex( *(txt+1) ); + if( n == 0 ) { + n = 7; + } + color = g_color_table[n]; + txt += 2; + continue; + } + UI_DrawChar( x, y, c, style, color ); + txt++; + x += SMALLCHAR_WIDTH; + } + + // draw cursor if we have focus + if( focus ) { + if ( trap_Key_GetOverstrikeMode() ) { + c = 11; + } else { + c = 10; + } + + style &= ~UI_PULSE; + style |= UI_BLINK; + + UI_DrawChar( basex + f->field.cursor * SMALLCHAR_WIDTH, y, c, style, color_white ); + } + + // draw at bottom also using proportional font + Q_strncpyz( name, f->field.buffer, sizeof(name) ); + Q_CleanStr( name ); + UI_DrawProportionalString( 320, 440, name, UI_CENTER|UI_BIGFONT, text_color_normal ); +} + + +/* +================= +PlayerSettings_DrawHandicap +================= +*/ +static void PlayerSettings_DrawHandicap( void *self ) { + menulist_s *item; + qboolean focus; + int style; + float *color; + + item = (menulist_s *)self; + focus = (item->generic.parent->cursor == item->generic.menuPosition); + + style = UI_LEFT|UI_SMALLFONT; + color = text_color_normal; + if( focus ) { + style |= UI_PULSE; + color = text_color_highlight; + } + + UI_DrawProportionalString( item->generic.x, item->generic.y, "Handicap", style, color ); + UI_DrawProportionalString( item->generic.x + 64, item->generic.y + PROP_HEIGHT, handicap_items[item->curvalue], style, color ); +} + + +/* +================= +PlayerSettings_DrawEffects +================= +*/ +static void PlayerSettings_DrawEffects( void *self ) { + menulist_s *item; + qboolean focus; + int style; + float *color; + + item = (menulist_s *)self; + focus = (item->generic.parent->cursor == item->generic.menuPosition); + + style = UI_LEFT|UI_SMALLFONT; + color = text_color_normal; + if( focus ) { + style |= UI_PULSE; + color = text_color_highlight; + } + + UI_DrawProportionalString( item->generic.x, item->generic.y, "Effects", style, color ); + + UI_DrawHandlePic( item->generic.x + 64, item->generic.y + PROP_HEIGHT + 8, 128, 8, s_playersettings.fxBasePic ); + UI_DrawHandlePic( item->generic.x + 64 + item->curvalue * 16 + 8, item->generic.y + PROP_HEIGHT + 6, 16, 12, s_playersettings.fxPic[item->curvalue] ); +} + + +/* +================= +PlayerSettings_DrawPlayer +================= +*/ +static void PlayerSettings_DrawPlayer( void *self ) { + menubitmap_s *b; + vec3_t viewangles; + char buf[MAX_QPATH]; + + trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) ); + if ( strcmp( buf, s_playersettings.playerModel ) != 0 ) { + UI_PlayerInfo_SetModel( &s_playersettings.playerinfo, buf ); + strcpy( s_playersettings.playerModel, buf ); + + viewangles[YAW] = 180 - 30; + viewangles[PITCH] = 0; + viewangles[ROLL] = 0; + UI_PlayerInfo_SetInfo( &s_playersettings.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); + } + + b = (menubitmap_s*) self; + UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_playersettings.playerinfo, uis.realtime/2 ); +} + + +/* +================= +PlayerSettings_SaveChanges +================= +*/ +static void PlayerSettings_SaveChanges( void ) { + // name + trap_Cvar_Set( "name", s_playersettings.name.field.buffer ); + + // handicap + trap_Cvar_SetValue( "handicap", 100 - s_playersettings.handicap.curvalue * 5 ); + + // effects color + trap_Cvar_SetValue( "color1", uitogamecode[s_playersettings.effects.curvalue] ); +} + + +/* +================= +PlayerSettings_MenuKey +================= +*/ +static sfxHandle_t PlayerSettings_MenuKey( int key ) { + if( key == K_MOUSE2 || key == K_ESCAPE ) { + PlayerSettings_SaveChanges(); + } + return Menu_DefaultKey( &s_playersettings.menu, key ); +} + + +/* +================= +PlayerSettings_SetMenuItems +================= +*/ +static void PlayerSettings_SetMenuItems( void ) { + vec3_t viewangles; + int c; + int h; + + // name + Q_strncpyz( s_playersettings.name.field.buffer, UI_Cvar_VariableString("name"), sizeof(s_playersettings.name.field.buffer) ); + + // effects color + c = trap_Cvar_VariableValue( "color1" ) - 1; + if( c < 0 || c > 6 ) { + c = 6; + } + s_playersettings.effects.curvalue = gamecodetoui[c]; + + // model/skin + memset( &s_playersettings.playerinfo, 0, sizeof(playerInfo_t) ); + + viewangles[YAW] = 180 - 30; + viewangles[PITCH] = 0; + viewangles[ROLL] = 0; + + UI_PlayerInfo_SetModel( &s_playersettings.playerinfo, UI_Cvar_VariableString( "model" ) ); + UI_PlayerInfo_SetInfo( &s_playersettings.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); + + // handicap + h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); + s_playersettings.handicap.curvalue = 20 - h / 5; +} + + +/* +================= +PlayerSettings_MenuEvent +================= +*/ +static void PlayerSettings_MenuEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_HANDICAP: + trap_Cvar_Set( "handicap", va( "%i", 100 - 25 * s_playersettings.handicap.curvalue ) ); + break; + + case ID_MODEL: + PlayerSettings_SaveChanges(); + UI_PlayerModelMenu(); + break; + + case ID_BACK: + PlayerSettings_SaveChanges(); + UI_PopMenu(); + break; + } +} + + +/* +================= +PlayerSettings_MenuInit +================= +*/ +static void PlayerSettings_MenuInit( void ) { + int y; + + memset(&s_playersettings,0,sizeof(playersettings_t)); + + PlayerSettings_Cache(); + + s_playersettings.menu.key = PlayerSettings_MenuKey; + s_playersettings.menu.wrapAround = qtrue; + s_playersettings.menu.fullscreen = qtrue; + + s_playersettings.banner.generic.type = MTYPE_BTEXT; + s_playersettings.banner.generic.x = 320; + s_playersettings.banner.generic.y = 16; + s_playersettings.banner.string = "PLAYER SETTINGS"; + s_playersettings.banner.color = color_white; + s_playersettings.banner.style = UI_CENTER; + + s_playersettings.framel.generic.type = MTYPE_BITMAP; + s_playersettings.framel.generic.name = ART_FRAMEL; + s_playersettings.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_playersettings.framel.generic.x = 0; + s_playersettings.framel.generic.y = 78; + s_playersettings.framel.width = 256; + s_playersettings.framel.height = 329; + + s_playersettings.framer.generic.type = MTYPE_BITMAP; + s_playersettings.framer.generic.name = ART_FRAMER; + s_playersettings.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_playersettings.framer.generic.x = 376; + s_playersettings.framer.generic.y = 76; + s_playersettings.framer.width = 256; + s_playersettings.framer.height = 334; + + y = 144; + s_playersettings.name.generic.type = MTYPE_FIELD; + s_playersettings.name.generic.flags = QMF_NODEFAULTINIT; + s_playersettings.name.generic.ownerdraw = PlayerSettings_DrawName; + s_playersettings.name.field.widthInChars = MAX_NAMELENGTH; + s_playersettings.name.field.maxchars = MAX_NAMELENGTH; + s_playersettings.name.generic.x = 192; + s_playersettings.name.generic.y = y; + s_playersettings.name.generic.left = 192 - 8; + s_playersettings.name.generic.top = y - 8; + s_playersettings.name.generic.right = 192 + 200; + s_playersettings.name.generic.bottom = y + 2 * PROP_HEIGHT; + + y += 3 * PROP_HEIGHT; + s_playersettings.handicap.generic.type = MTYPE_SPINCONTROL; + s_playersettings.handicap.generic.flags = QMF_NODEFAULTINIT; + s_playersettings.handicap.generic.id = ID_HANDICAP; + s_playersettings.handicap.generic.ownerdraw = PlayerSettings_DrawHandicap; + s_playersettings.handicap.generic.x = 192; + s_playersettings.handicap.generic.y = y; + s_playersettings.handicap.generic.left = 192 - 8; + s_playersettings.handicap.generic.top = y - 8; + s_playersettings.handicap.generic.right = 192 + 200; + s_playersettings.handicap.generic.bottom = y + 2 * PROP_HEIGHT; + s_playersettings.handicap.numitems = 20; + + y += 3 * PROP_HEIGHT; + s_playersettings.effects.generic.type = MTYPE_SPINCONTROL; + s_playersettings.effects.generic.flags = QMF_NODEFAULTINIT; + s_playersettings.effects.generic.id = ID_EFFECTS; + s_playersettings.effects.generic.ownerdraw = PlayerSettings_DrawEffects; + s_playersettings.effects.generic.x = 192; + s_playersettings.effects.generic.y = y; + s_playersettings.effects.generic.left = 192 - 8; + s_playersettings.effects.generic.top = y - 8; + s_playersettings.effects.generic.right = 192 + 200; + s_playersettings.effects.generic.bottom = y + 2* PROP_HEIGHT; + s_playersettings.effects.numitems = 7; + + s_playersettings.model.generic.type = MTYPE_BITMAP; + s_playersettings.model.generic.name = ART_MODEL0; + s_playersettings.model.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_playersettings.model.generic.id = ID_MODEL; + s_playersettings.model.generic.callback = PlayerSettings_MenuEvent; + s_playersettings.model.generic.x = 640; + s_playersettings.model.generic.y = 480-64; + s_playersettings.model.width = 128; + s_playersettings.model.height = 64; + s_playersettings.model.focuspic = ART_MODEL1; + + s_playersettings.player.generic.type = MTYPE_BITMAP; + s_playersettings.player.generic.flags = QMF_INACTIVE; + s_playersettings.player.generic.ownerdraw = PlayerSettings_DrawPlayer; + s_playersettings.player.generic.x = 400; + s_playersettings.player.generic.y = -40; + s_playersettings.player.width = 32*10; + s_playersettings.player.height = 56*10; + + s_playersettings.back.generic.type = MTYPE_BITMAP; + s_playersettings.back.generic.name = ART_BACK0; + s_playersettings.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_playersettings.back.generic.id = ID_BACK; + s_playersettings.back.generic.callback = PlayerSettings_MenuEvent; + s_playersettings.back.generic.x = 0; + s_playersettings.back.generic.y = 480-64; + s_playersettings.back.width = 128; + s_playersettings.back.height = 64; + s_playersettings.back.focuspic = ART_BACK1; + + s_playersettings.item_null.generic.type = MTYPE_BITMAP; + s_playersettings.item_null.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY|QMF_SILENT; + s_playersettings.item_null.generic.x = 0; + s_playersettings.item_null.generic.y = 0; + s_playersettings.item_null.width = 640; + s_playersettings.item_null.height = 480; + + Menu_AddItem( &s_playersettings.menu, &s_playersettings.banner ); + Menu_AddItem( &s_playersettings.menu, &s_playersettings.framel ); + Menu_AddItem( &s_playersettings.menu, &s_playersettings.framer ); + + Menu_AddItem( &s_playersettings.menu, &s_playersettings.name ); + Menu_AddItem( &s_playersettings.menu, &s_playersettings.handicap ); + Menu_AddItem( &s_playersettings.menu, &s_playersettings.effects ); + Menu_AddItem( &s_playersettings.menu, &s_playersettings.model ); + Menu_AddItem( &s_playersettings.menu, &s_playersettings.back ); + + Menu_AddItem( &s_playersettings.menu, &s_playersettings.player ); + + Menu_AddItem( &s_playersettings.menu, &s_playersettings.item_null ); + + PlayerSettings_SetMenuItems(); +} + + +/* +================= +PlayerSettings_Cache +================= +*/ +void PlayerSettings_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_MODEL0 ); + trap_R_RegisterShaderNoMip( ART_MODEL1 ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + + s_playersettings.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE ); + s_playersettings.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED ); + s_playersettings.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW ); + s_playersettings.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_GREEN ); + s_playersettings.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_TEAL ); + s_playersettings.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE ); + s_playersettings.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_CYAN ); + s_playersettings.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE ); +} + + +/* +================= +UI_PlayerSettingsMenu +================= +*/ +void UI_PlayerSettingsMenu( void ) { + PlayerSettings_MenuInit(); + UI_PushMenu( &s_playersettings.menu ); +} diff --git a/code/q3_ui/ui_preferences.c b/code/q3_ui/ui_preferences.c index c83ba6a..4b62f5c 100755 --- a/code/q3_ui/ui_preferences.c +++ b/code/q3_ui/ui_preferences.c @@ -1,419 +1,419 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -GAME OPTIONS MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" - -#define PREFERENCES_X_POS 360 - -#define ID_CROSSHAIR 127 -#define ID_SIMPLEITEMS 128 -#define ID_HIGHQUALITYSKY 129 -#define ID_EJECTINGBRASS 130 -#define ID_WALLMARKS 131 -#define ID_DYNAMICLIGHTS 132 -#define ID_IDENTIFYTARGET 133 -#define ID_SYNCEVERYFRAME 134 -#define ID_FORCEMODEL 135 -#define ID_DRAWTEAMOVERLAY 136 -#define ID_ALLOWDOWNLOAD 137 -#define ID_BACK 138 - -#define NUM_CROSSHAIRS 10 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menulist_s crosshair; - menuradiobutton_s simpleitems; - menuradiobutton_s brass; - menuradiobutton_s wallmarks; - menuradiobutton_s dynamiclights; - menuradiobutton_s identifytarget; - menuradiobutton_s highqualitysky; - menuradiobutton_s synceveryframe; - menuradiobutton_s forcemodel; - menulist_s drawteamoverlay; - menuradiobutton_s allowdownload; - menubitmap_s back; - - qhandle_t crosshairShader[NUM_CROSSHAIRS]; -} preferences_t; - -static preferences_t s_preferences; - -static const char *teamoverlay_names[] = -{ - "off", - "upper right", - "lower right", - "lower left", - 0 -}; - -static void Preferences_SetMenuItems( void ) { - s_preferences.crosshair.curvalue = (int)trap_Cvar_VariableValue( "cg_drawCrosshair" ) % NUM_CROSSHAIRS; - s_preferences.simpleitems.curvalue = trap_Cvar_VariableValue( "cg_simpleItems" ) != 0; - s_preferences.brass.curvalue = trap_Cvar_VariableValue( "cg_brassTime" ) != 0; - s_preferences.wallmarks.curvalue = trap_Cvar_VariableValue( "cg_marks" ) != 0; - s_preferences.identifytarget.curvalue = trap_Cvar_VariableValue( "cg_drawCrosshairNames" ) != 0; - s_preferences.dynamiclights.curvalue = trap_Cvar_VariableValue( "r_dynamiclight" ) != 0; - s_preferences.highqualitysky.curvalue = trap_Cvar_VariableValue ( "r_fastsky" ) == 0; - s_preferences.synceveryframe.curvalue = trap_Cvar_VariableValue( "r_finish" ) != 0; - s_preferences.forcemodel.curvalue = trap_Cvar_VariableValue( "cg_forcemodel" ) != 0; - s_preferences.drawteamoverlay.curvalue = Com_Clamp( 0, 3, trap_Cvar_VariableValue( "cg_drawTeamOverlay" ) ); - s_preferences.allowdownload.curvalue = trap_Cvar_VariableValue( "cl_allowDownload" ) != 0; -} - - -static void Preferences_Event( void* ptr, int notification ) { - if( notification != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_CROSSHAIR: - s_preferences.crosshair.curvalue++; - if( s_preferences.crosshair.curvalue == NUM_CROSSHAIRS ) { - s_preferences.crosshair.curvalue = 0; - } - trap_Cvar_SetValue( "cg_drawCrosshair", s_preferences.crosshair.curvalue ); - break; - - case ID_SIMPLEITEMS: - trap_Cvar_SetValue( "cg_simpleItems", s_preferences.simpleitems.curvalue ); - break; - - case ID_HIGHQUALITYSKY: - trap_Cvar_SetValue( "r_fastsky", !s_preferences.highqualitysky.curvalue ); - break; - - case ID_EJECTINGBRASS: - if ( s_preferences.brass.curvalue ) - trap_Cvar_Reset( "cg_brassTime" ); - else - trap_Cvar_SetValue( "cg_brassTime", 0 ); - break; - - case ID_WALLMARKS: - trap_Cvar_SetValue( "cg_marks", s_preferences.wallmarks.curvalue ); - break; - - case ID_DYNAMICLIGHTS: - trap_Cvar_SetValue( "r_dynamiclight", s_preferences.dynamiclights.curvalue ); - break; - - case ID_IDENTIFYTARGET: - trap_Cvar_SetValue( "cg_drawCrosshairNames", s_preferences.identifytarget.curvalue ); - break; - - case ID_SYNCEVERYFRAME: - trap_Cvar_SetValue( "r_finish", s_preferences.synceveryframe.curvalue ); - break; - - case ID_FORCEMODEL: - trap_Cvar_SetValue( "cg_forcemodel", s_preferences.forcemodel.curvalue ); - break; - - case ID_DRAWTEAMOVERLAY: - trap_Cvar_SetValue( "cg_drawTeamOverlay", s_preferences.drawteamoverlay.curvalue ); - break; - - case ID_ALLOWDOWNLOAD: - trap_Cvar_SetValue( "cl_allowDownload", s_preferences.allowdownload.curvalue ); - trap_Cvar_SetValue( "sv_allowDownload", s_preferences.allowdownload.curvalue ); - break; - - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -================= -Crosshair_Draw -================= -*/ -static void Crosshair_Draw( void *self ) { - menulist_s *s; - float *color; - int x, y; - int style; - qboolean focus; - - s = (menulist_s *)self; - x = s->generic.x; - y = s->generic.y; - - style = UI_SMALLFONT; - focus = (s->generic.parent->cursor == s->generic.menuPosition); - - if ( s->generic.flags & QMF_GRAYED ) - color = text_color_disabled; - else if ( focus ) - { - color = text_color_highlight; - style |= UI_PULSE; - } - else if ( s->generic.flags & QMF_BLINK ) - { - color = text_color_highlight; - style |= UI_BLINK; - } - else - color = text_color_normal; - - if ( focus ) - { - // draw cursor - UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); - } - - UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); - if( !s->curvalue ) { - return; - } - UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y - 4, 24, 24, s_preferences.crosshairShader[s->curvalue] ); -} - - -static void Preferences_MenuInit( void ) { - int y; - - memset( &s_preferences, 0 ,sizeof(preferences_t) ); - - Preferences_Cache(); - - s_preferences.menu.wrapAround = qtrue; - s_preferences.menu.fullscreen = qtrue; - - s_preferences.banner.generic.type = MTYPE_BTEXT; - s_preferences.banner.generic.x = 320; - s_preferences.banner.generic.y = 16; - s_preferences.banner.string = "GAME OPTIONS"; - s_preferences.banner.color = color_white; - s_preferences.banner.style = UI_CENTER; - - s_preferences.framel.generic.type = MTYPE_BITMAP; - s_preferences.framel.generic.name = ART_FRAMEL; - s_preferences.framel.generic.flags = QMF_INACTIVE; - s_preferences.framel.generic.x = 0; - s_preferences.framel.generic.y = 78; - s_preferences.framel.width = 256; - s_preferences.framel.height = 329; - - s_preferences.framer.generic.type = MTYPE_BITMAP; - s_preferences.framer.generic.name = ART_FRAMER; - s_preferences.framer.generic.flags = QMF_INACTIVE; - s_preferences.framer.generic.x = 376; - s_preferences.framer.generic.y = 76; - s_preferences.framer.width = 256; - s_preferences.framer.height = 334; - - y = 144; - s_preferences.crosshair.generic.type = MTYPE_TEXT; - s_preferences.crosshair.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT|QMF_NODEFAULTINIT|QMF_OWNERDRAW; - s_preferences.crosshair.generic.x = PREFERENCES_X_POS; - s_preferences.crosshair.generic.y = y; - s_preferences.crosshair.generic.name = "Crosshair:"; - s_preferences.crosshair.generic.callback = Preferences_Event; - s_preferences.crosshair.generic.ownerdraw = Crosshair_Draw; - s_preferences.crosshair.generic.id = ID_CROSSHAIR; - s_preferences.crosshair.generic.top = y - 4; - s_preferences.crosshair.generic.bottom = y + 20; - s_preferences.crosshair.generic.left = PREFERENCES_X_POS - ( ( strlen(s_preferences.crosshair.generic.name) + 1 ) * SMALLCHAR_WIDTH ); - s_preferences.crosshair.generic.right = PREFERENCES_X_POS + 48; - - y += BIGCHAR_HEIGHT+2+4; - s_preferences.simpleitems.generic.type = MTYPE_RADIOBUTTON; - s_preferences.simpleitems.generic.name = "Simple Items:"; - s_preferences.simpleitems.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.simpleitems.generic.callback = Preferences_Event; - s_preferences.simpleitems.generic.id = ID_SIMPLEITEMS; - s_preferences.simpleitems.generic.x = PREFERENCES_X_POS; - s_preferences.simpleitems.generic.y = y; - - y += BIGCHAR_HEIGHT; - s_preferences.wallmarks.generic.type = MTYPE_RADIOBUTTON; - s_preferences.wallmarks.generic.name = "Marks on Walls:"; - s_preferences.wallmarks.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.wallmarks.generic.callback = Preferences_Event; - s_preferences.wallmarks.generic.id = ID_WALLMARKS; - s_preferences.wallmarks.generic.x = PREFERENCES_X_POS; - s_preferences.wallmarks.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.brass.generic.type = MTYPE_RADIOBUTTON; - s_preferences.brass.generic.name = "Ejecting Brass:"; - s_preferences.brass.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.brass.generic.callback = Preferences_Event; - s_preferences.brass.generic.id = ID_EJECTINGBRASS; - s_preferences.brass.generic.x = PREFERENCES_X_POS; - s_preferences.brass.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.dynamiclights.generic.type = MTYPE_RADIOBUTTON; - s_preferences.dynamiclights.generic.name = "Dynamic Lights:"; - s_preferences.dynamiclights.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.dynamiclights.generic.callback = Preferences_Event; - s_preferences.dynamiclights.generic.id = ID_DYNAMICLIGHTS; - s_preferences.dynamiclights.generic.x = PREFERENCES_X_POS; - s_preferences.dynamiclights.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.identifytarget.generic.type = MTYPE_RADIOBUTTON; - s_preferences.identifytarget.generic.name = "Identify Target:"; - s_preferences.identifytarget.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.identifytarget.generic.callback = Preferences_Event; - s_preferences.identifytarget.generic.id = ID_IDENTIFYTARGET; - s_preferences.identifytarget.generic.x = PREFERENCES_X_POS; - s_preferences.identifytarget.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.highqualitysky.generic.type = MTYPE_RADIOBUTTON; - s_preferences.highqualitysky.generic.name = "High Quality Sky:"; - s_preferences.highqualitysky.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.highqualitysky.generic.callback = Preferences_Event; - s_preferences.highqualitysky.generic.id = ID_HIGHQUALITYSKY; - s_preferences.highqualitysky.generic.x = PREFERENCES_X_POS; - s_preferences.highqualitysky.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.synceveryframe.generic.type = MTYPE_RADIOBUTTON; - s_preferences.synceveryframe.generic.name = "Sync Every Frame:"; - s_preferences.synceveryframe.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.synceveryframe.generic.callback = Preferences_Event; - s_preferences.synceveryframe.generic.id = ID_SYNCEVERYFRAME; - s_preferences.synceveryframe.generic.x = PREFERENCES_X_POS; - s_preferences.synceveryframe.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.forcemodel.generic.type = MTYPE_RADIOBUTTON; - s_preferences.forcemodel.generic.name = "Force Player Models:"; - s_preferences.forcemodel.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.forcemodel.generic.callback = Preferences_Event; - s_preferences.forcemodel.generic.id = ID_FORCEMODEL; - s_preferences.forcemodel.generic.x = PREFERENCES_X_POS; - s_preferences.forcemodel.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.drawteamoverlay.generic.type = MTYPE_SPINCONTROL; - s_preferences.drawteamoverlay.generic.name = "Draw Team Overlay:"; - s_preferences.drawteamoverlay.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.drawteamoverlay.generic.callback = Preferences_Event; - s_preferences.drawteamoverlay.generic.id = ID_DRAWTEAMOVERLAY; - s_preferences.drawteamoverlay.generic.x = PREFERENCES_X_POS; - s_preferences.drawteamoverlay.generic.y = y; - s_preferences.drawteamoverlay.itemnames = teamoverlay_names; - - y += BIGCHAR_HEIGHT+2; - s_preferences.allowdownload.generic.type = MTYPE_RADIOBUTTON; - s_preferences.allowdownload.generic.name = "Automatic Downloading:"; - s_preferences.allowdownload.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_preferences.allowdownload.generic.callback = Preferences_Event; - s_preferences.allowdownload.generic.id = ID_ALLOWDOWNLOAD; - s_preferences.allowdownload.generic.x = PREFERENCES_X_POS; - s_preferences.allowdownload.generic.y = y; - - y += BIGCHAR_HEIGHT+2; - s_preferences.back.generic.type = MTYPE_BITMAP; - s_preferences.back.generic.name = ART_BACK0; - s_preferences.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_preferences.back.generic.callback = Preferences_Event; - s_preferences.back.generic.id = ID_BACK; - s_preferences.back.generic.x = 0; - s_preferences.back.generic.y = 480-64; - s_preferences.back.width = 128; - s_preferences.back.height = 64; - s_preferences.back.focuspic = ART_BACK1; - - Menu_AddItem( &s_preferences.menu, &s_preferences.banner ); - Menu_AddItem( &s_preferences.menu, &s_preferences.framel ); - Menu_AddItem( &s_preferences.menu, &s_preferences.framer ); - - Menu_AddItem( &s_preferences.menu, &s_preferences.crosshair ); - Menu_AddItem( &s_preferences.menu, &s_preferences.simpleitems ); - Menu_AddItem( &s_preferences.menu, &s_preferences.wallmarks ); - Menu_AddItem( &s_preferences.menu, &s_preferences.brass ); - Menu_AddItem( &s_preferences.menu, &s_preferences.dynamiclights ); - Menu_AddItem( &s_preferences.menu, &s_preferences.identifytarget ); - Menu_AddItem( &s_preferences.menu, &s_preferences.highqualitysky ); - Menu_AddItem( &s_preferences.menu, &s_preferences.synceveryframe ); - Menu_AddItem( &s_preferences.menu, &s_preferences.forcemodel ); - Menu_AddItem( &s_preferences.menu, &s_preferences.drawteamoverlay ); - Menu_AddItem( &s_preferences.menu, &s_preferences.allowdownload ); - - Menu_AddItem( &s_preferences.menu, &s_preferences.back ); - - Preferences_SetMenuItems(); -} - - -/* -=============== -Preferences_Cache -=============== -*/ -void Preferences_Cache( void ) { - int n; - - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - for( n = 0; n < NUM_CROSSHAIRS; n++ ) { - s_preferences.crosshairShader[n] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) ); - } -} - - -/* -=============== -UI_PreferencesMenu -=============== -*/ -void UI_PreferencesMenu( void ) { - Preferences_MenuInit(); - UI_PushMenu( &s_preferences.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +GAME OPTIONS MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" + +#define PREFERENCES_X_POS 360 + +#define ID_CROSSHAIR 127 +#define ID_SIMPLEITEMS 128 +#define ID_HIGHQUALITYSKY 129 +#define ID_EJECTINGBRASS 130 +#define ID_WALLMARKS 131 +#define ID_DYNAMICLIGHTS 132 +#define ID_IDENTIFYTARGET 133 +#define ID_SYNCEVERYFRAME 134 +#define ID_FORCEMODEL 135 +#define ID_DRAWTEAMOVERLAY 136 +#define ID_ALLOWDOWNLOAD 137 +#define ID_BACK 138 + +#define NUM_CROSSHAIRS 10 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menulist_s crosshair; + menuradiobutton_s simpleitems; + menuradiobutton_s brass; + menuradiobutton_s wallmarks; + menuradiobutton_s dynamiclights; + menuradiobutton_s identifytarget; + menuradiobutton_s highqualitysky; + menuradiobutton_s synceveryframe; + menuradiobutton_s forcemodel; + menulist_s drawteamoverlay; + menuradiobutton_s allowdownload; + menubitmap_s back; + + qhandle_t crosshairShader[NUM_CROSSHAIRS]; +} preferences_t; + +static preferences_t s_preferences; + +static const char *teamoverlay_names[] = +{ + "off", + "upper right", + "lower right", + "lower left", + 0 +}; + +static void Preferences_SetMenuItems( void ) { + s_preferences.crosshair.curvalue = (int)trap_Cvar_VariableValue( "cg_drawCrosshair" ) % NUM_CROSSHAIRS; + s_preferences.simpleitems.curvalue = trap_Cvar_VariableValue( "cg_simpleItems" ) != 0; + s_preferences.brass.curvalue = trap_Cvar_VariableValue( "cg_brassTime" ) != 0; + s_preferences.wallmarks.curvalue = trap_Cvar_VariableValue( "cg_marks" ) != 0; + s_preferences.identifytarget.curvalue = trap_Cvar_VariableValue( "cg_drawCrosshairNames" ) != 0; + s_preferences.dynamiclights.curvalue = trap_Cvar_VariableValue( "r_dynamiclight" ) != 0; + s_preferences.highqualitysky.curvalue = trap_Cvar_VariableValue ( "r_fastsky" ) == 0; + s_preferences.synceveryframe.curvalue = trap_Cvar_VariableValue( "r_finish" ) != 0; + s_preferences.forcemodel.curvalue = trap_Cvar_VariableValue( "cg_forcemodel" ) != 0; + s_preferences.drawteamoverlay.curvalue = Com_Clamp( 0, 3, trap_Cvar_VariableValue( "cg_drawTeamOverlay" ) ); + s_preferences.allowdownload.curvalue = trap_Cvar_VariableValue( "cl_allowDownload" ) != 0; +} + + +static void Preferences_Event( void* ptr, int notification ) { + if( notification != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_CROSSHAIR: + s_preferences.crosshair.curvalue++; + if( s_preferences.crosshair.curvalue == NUM_CROSSHAIRS ) { + s_preferences.crosshair.curvalue = 0; + } + trap_Cvar_SetValue( "cg_drawCrosshair", s_preferences.crosshair.curvalue ); + break; + + case ID_SIMPLEITEMS: + trap_Cvar_SetValue( "cg_simpleItems", s_preferences.simpleitems.curvalue ); + break; + + case ID_HIGHQUALITYSKY: + trap_Cvar_SetValue( "r_fastsky", !s_preferences.highqualitysky.curvalue ); + break; + + case ID_EJECTINGBRASS: + if ( s_preferences.brass.curvalue ) + trap_Cvar_Reset( "cg_brassTime" ); + else + trap_Cvar_SetValue( "cg_brassTime", 0 ); + break; + + case ID_WALLMARKS: + trap_Cvar_SetValue( "cg_marks", s_preferences.wallmarks.curvalue ); + break; + + case ID_DYNAMICLIGHTS: + trap_Cvar_SetValue( "r_dynamiclight", s_preferences.dynamiclights.curvalue ); + break; + + case ID_IDENTIFYTARGET: + trap_Cvar_SetValue( "cg_drawCrosshairNames", s_preferences.identifytarget.curvalue ); + break; + + case ID_SYNCEVERYFRAME: + trap_Cvar_SetValue( "r_finish", s_preferences.synceveryframe.curvalue ); + break; + + case ID_FORCEMODEL: + trap_Cvar_SetValue( "cg_forcemodel", s_preferences.forcemodel.curvalue ); + break; + + case ID_DRAWTEAMOVERLAY: + trap_Cvar_SetValue( "cg_drawTeamOverlay", s_preferences.drawteamoverlay.curvalue ); + break; + + case ID_ALLOWDOWNLOAD: + trap_Cvar_SetValue( "cl_allowDownload", s_preferences.allowdownload.curvalue ); + trap_Cvar_SetValue( "sv_allowDownload", s_preferences.allowdownload.curvalue ); + break; + + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +================= +Crosshair_Draw +================= +*/ +static void Crosshair_Draw( void *self ) { + menulist_s *s; + float *color; + int x, y; + int style; + qboolean focus; + + s = (menulist_s *)self; + x = s->generic.x; + y = s->generic.y; + + style = UI_SMALLFONT; + focus = (s->generic.parent->cursor == s->generic.menuPosition); + + if ( s->generic.flags & QMF_GRAYED ) + color = text_color_disabled; + else if ( focus ) + { + color = text_color_highlight; + style |= UI_PULSE; + } + else if ( s->generic.flags & QMF_BLINK ) + { + color = text_color_highlight; + style |= UI_BLINK; + } + else + color = text_color_normal; + + if ( focus ) + { + // draw cursor + UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); + } + + UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); + if( !s->curvalue ) { + return; + } + UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y - 4, 24, 24, s_preferences.crosshairShader[s->curvalue] ); +} + + +static void Preferences_MenuInit( void ) { + int y; + + memset( &s_preferences, 0 ,sizeof(preferences_t) ); + + Preferences_Cache(); + + s_preferences.menu.wrapAround = qtrue; + s_preferences.menu.fullscreen = qtrue; + + s_preferences.banner.generic.type = MTYPE_BTEXT; + s_preferences.banner.generic.x = 320; + s_preferences.banner.generic.y = 16; + s_preferences.banner.string = "GAME OPTIONS"; + s_preferences.banner.color = color_white; + s_preferences.banner.style = UI_CENTER; + + s_preferences.framel.generic.type = MTYPE_BITMAP; + s_preferences.framel.generic.name = ART_FRAMEL; + s_preferences.framel.generic.flags = QMF_INACTIVE; + s_preferences.framel.generic.x = 0; + s_preferences.framel.generic.y = 78; + s_preferences.framel.width = 256; + s_preferences.framel.height = 329; + + s_preferences.framer.generic.type = MTYPE_BITMAP; + s_preferences.framer.generic.name = ART_FRAMER; + s_preferences.framer.generic.flags = QMF_INACTIVE; + s_preferences.framer.generic.x = 376; + s_preferences.framer.generic.y = 76; + s_preferences.framer.width = 256; + s_preferences.framer.height = 334; + + y = 144; + s_preferences.crosshair.generic.type = MTYPE_TEXT; + s_preferences.crosshair.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT|QMF_NODEFAULTINIT|QMF_OWNERDRAW; + s_preferences.crosshair.generic.x = PREFERENCES_X_POS; + s_preferences.crosshair.generic.y = y; + s_preferences.crosshair.generic.name = "Crosshair:"; + s_preferences.crosshair.generic.callback = Preferences_Event; + s_preferences.crosshair.generic.ownerdraw = Crosshair_Draw; + s_preferences.crosshair.generic.id = ID_CROSSHAIR; + s_preferences.crosshair.generic.top = y - 4; + s_preferences.crosshair.generic.bottom = y + 20; + s_preferences.crosshair.generic.left = PREFERENCES_X_POS - ( ( strlen(s_preferences.crosshair.generic.name) + 1 ) * SMALLCHAR_WIDTH ); + s_preferences.crosshair.generic.right = PREFERENCES_X_POS + 48; + + y += BIGCHAR_HEIGHT+2+4; + s_preferences.simpleitems.generic.type = MTYPE_RADIOBUTTON; + s_preferences.simpleitems.generic.name = "Simple Items:"; + s_preferences.simpleitems.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.simpleitems.generic.callback = Preferences_Event; + s_preferences.simpleitems.generic.id = ID_SIMPLEITEMS; + s_preferences.simpleitems.generic.x = PREFERENCES_X_POS; + s_preferences.simpleitems.generic.y = y; + + y += BIGCHAR_HEIGHT; + s_preferences.wallmarks.generic.type = MTYPE_RADIOBUTTON; + s_preferences.wallmarks.generic.name = "Marks on Walls:"; + s_preferences.wallmarks.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.wallmarks.generic.callback = Preferences_Event; + s_preferences.wallmarks.generic.id = ID_WALLMARKS; + s_preferences.wallmarks.generic.x = PREFERENCES_X_POS; + s_preferences.wallmarks.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.brass.generic.type = MTYPE_RADIOBUTTON; + s_preferences.brass.generic.name = "Ejecting Brass:"; + s_preferences.brass.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.brass.generic.callback = Preferences_Event; + s_preferences.brass.generic.id = ID_EJECTINGBRASS; + s_preferences.brass.generic.x = PREFERENCES_X_POS; + s_preferences.brass.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.dynamiclights.generic.type = MTYPE_RADIOBUTTON; + s_preferences.dynamiclights.generic.name = "Dynamic Lights:"; + s_preferences.dynamiclights.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.dynamiclights.generic.callback = Preferences_Event; + s_preferences.dynamiclights.generic.id = ID_DYNAMICLIGHTS; + s_preferences.dynamiclights.generic.x = PREFERENCES_X_POS; + s_preferences.dynamiclights.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.identifytarget.generic.type = MTYPE_RADIOBUTTON; + s_preferences.identifytarget.generic.name = "Identify Target:"; + s_preferences.identifytarget.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.identifytarget.generic.callback = Preferences_Event; + s_preferences.identifytarget.generic.id = ID_IDENTIFYTARGET; + s_preferences.identifytarget.generic.x = PREFERENCES_X_POS; + s_preferences.identifytarget.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.highqualitysky.generic.type = MTYPE_RADIOBUTTON; + s_preferences.highqualitysky.generic.name = "High Quality Sky:"; + s_preferences.highqualitysky.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.highqualitysky.generic.callback = Preferences_Event; + s_preferences.highqualitysky.generic.id = ID_HIGHQUALITYSKY; + s_preferences.highqualitysky.generic.x = PREFERENCES_X_POS; + s_preferences.highqualitysky.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.synceveryframe.generic.type = MTYPE_RADIOBUTTON; + s_preferences.synceveryframe.generic.name = "Sync Every Frame:"; + s_preferences.synceveryframe.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.synceveryframe.generic.callback = Preferences_Event; + s_preferences.synceveryframe.generic.id = ID_SYNCEVERYFRAME; + s_preferences.synceveryframe.generic.x = PREFERENCES_X_POS; + s_preferences.synceveryframe.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.forcemodel.generic.type = MTYPE_RADIOBUTTON; + s_preferences.forcemodel.generic.name = "Force Player Models:"; + s_preferences.forcemodel.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.forcemodel.generic.callback = Preferences_Event; + s_preferences.forcemodel.generic.id = ID_FORCEMODEL; + s_preferences.forcemodel.generic.x = PREFERENCES_X_POS; + s_preferences.forcemodel.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.drawteamoverlay.generic.type = MTYPE_SPINCONTROL; + s_preferences.drawteamoverlay.generic.name = "Draw Team Overlay:"; + s_preferences.drawteamoverlay.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.drawteamoverlay.generic.callback = Preferences_Event; + s_preferences.drawteamoverlay.generic.id = ID_DRAWTEAMOVERLAY; + s_preferences.drawteamoverlay.generic.x = PREFERENCES_X_POS; + s_preferences.drawteamoverlay.generic.y = y; + s_preferences.drawteamoverlay.itemnames = teamoverlay_names; + + y += BIGCHAR_HEIGHT+2; + s_preferences.allowdownload.generic.type = MTYPE_RADIOBUTTON; + s_preferences.allowdownload.generic.name = "Automatic Downloading:"; + s_preferences.allowdownload.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_preferences.allowdownload.generic.callback = Preferences_Event; + s_preferences.allowdownload.generic.id = ID_ALLOWDOWNLOAD; + s_preferences.allowdownload.generic.x = PREFERENCES_X_POS; + s_preferences.allowdownload.generic.y = y; + + y += BIGCHAR_HEIGHT+2; + s_preferences.back.generic.type = MTYPE_BITMAP; + s_preferences.back.generic.name = ART_BACK0; + s_preferences.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_preferences.back.generic.callback = Preferences_Event; + s_preferences.back.generic.id = ID_BACK; + s_preferences.back.generic.x = 0; + s_preferences.back.generic.y = 480-64; + s_preferences.back.width = 128; + s_preferences.back.height = 64; + s_preferences.back.focuspic = ART_BACK1; + + Menu_AddItem( &s_preferences.menu, &s_preferences.banner ); + Menu_AddItem( &s_preferences.menu, &s_preferences.framel ); + Menu_AddItem( &s_preferences.menu, &s_preferences.framer ); + + Menu_AddItem( &s_preferences.menu, &s_preferences.crosshair ); + Menu_AddItem( &s_preferences.menu, &s_preferences.simpleitems ); + Menu_AddItem( &s_preferences.menu, &s_preferences.wallmarks ); + Menu_AddItem( &s_preferences.menu, &s_preferences.brass ); + Menu_AddItem( &s_preferences.menu, &s_preferences.dynamiclights ); + Menu_AddItem( &s_preferences.menu, &s_preferences.identifytarget ); + Menu_AddItem( &s_preferences.menu, &s_preferences.highqualitysky ); + Menu_AddItem( &s_preferences.menu, &s_preferences.synceveryframe ); + Menu_AddItem( &s_preferences.menu, &s_preferences.forcemodel ); + Menu_AddItem( &s_preferences.menu, &s_preferences.drawteamoverlay ); + Menu_AddItem( &s_preferences.menu, &s_preferences.allowdownload ); + + Menu_AddItem( &s_preferences.menu, &s_preferences.back ); + + Preferences_SetMenuItems(); +} + + +/* +=============== +Preferences_Cache +=============== +*/ +void Preferences_Cache( void ) { + int n; + + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + for( n = 0; n < NUM_CROSSHAIRS; n++ ) { + s_preferences.crosshairShader[n] = trap_R_RegisterShaderNoMip( va("gfx/2d/crosshair%c", 'a' + n ) ); + } +} + + +/* +=============== +UI_PreferencesMenu +=============== +*/ +void UI_PreferencesMenu( void ) { + Preferences_MenuInit(); + UI_PushMenu( &s_preferences.menu ); +} diff --git a/code/q3_ui/ui_qmenu.c b/code/q3_ui/ui_qmenu.c index 400448a..a6ec29e 100755 --- a/code/q3_ui/ui_qmenu.c +++ b/code/q3_ui/ui_qmenu.c @@ -1,1746 +1,1746 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/********************************************************************** - UI_QMENU.C - - Quake's menu framework system. -**********************************************************************/ -#include "ui_local.h" - -sfxHandle_t menu_in_sound; -sfxHandle_t menu_move_sound; -sfxHandle_t menu_out_sound; -sfxHandle_t menu_buzz_sound; -sfxHandle_t menu_null_sound; -sfxHandle_t weaponChangeSound; - -static qhandle_t sliderBar; -static qhandle_t sliderButton_0; -static qhandle_t sliderButton_1; - -vec4_t menu_text_color = {1.0f, 1.0f, 1.0f, 1.0f}; -vec4_t menu_dim_color = {0.0f, 0.0f, 0.0f, 0.75f}; -vec4_t color_black = {0.00f, 0.00f, 0.00f, 1.00f}; -vec4_t color_white = {1.00f, 1.00f, 1.00f, 1.00f}; -vec4_t color_yellow = {1.00f, 1.00f, 0.00f, 1.00f}; -vec4_t color_blue = {0.00f, 0.00f, 1.00f, 1.00f}; -vec4_t color_lightOrange = {1.00f, 0.68f, 0.00f, 1.00f }; -vec4_t color_orange = {1.00f, 0.43f, 0.00f, 1.00f}; -vec4_t color_red = {1.00f, 0.00f, 0.00f, 1.00f}; -vec4_t color_dim = {0.00f, 0.00f, 0.00f, 0.25f}; - -// current color scheme -vec4_t pulse_color = {1.00f, 1.00f, 1.00f, 1.00f}; -vec4_t text_color_disabled = {0.50f, 0.50f, 0.50f, 1.00f}; // light gray -vec4_t text_color_normal = {1.00f, 0.43f, 0.00f, 1.00f}; // light orange -vec4_t text_color_highlight = {1.00f, 1.00f, 0.00f, 1.00f}; // bright yellow -vec4_t listbar_color = {1.00f, 0.43f, 0.00f, 0.30f}; // transluscent orange -vec4_t text_color_status = {1.00f, 1.00f, 1.00f, 1.00f}; // bright white - -// action widget -static void Action_Init( menuaction_s *a ); -static void Action_Draw( menuaction_s *a ); - -// radio button widget -static void RadioButton_Init( menuradiobutton_s *rb ); -static void RadioButton_Draw( menuradiobutton_s *rb ); -static sfxHandle_t RadioButton_Key( menuradiobutton_s *rb, int key ); - -// slider widget -static void Slider_Init( menuslider_s *s ); -static sfxHandle_t Slider_Key( menuslider_s *s, int key ); -static void Slider_Draw( menuslider_s *s ); - -// spin control widget -static void SpinControl_Init( menulist_s *s ); -static void SpinControl_Draw( menulist_s *s ); -static sfxHandle_t SpinControl_Key( menulist_s *l, int key ); - -// text widget -static void Text_Init( menutext_s *b ); -static void Text_Draw( menutext_s *b ); - -// scrolllist widget -static void ScrollList_Init( menulist_s *l ); -sfxHandle_t ScrollList_Key( menulist_s *l, int key ); - -// proportional text widget -static void PText_Init( menutext_s *b ); -static void PText_Draw( menutext_s *b ); - -// proportional banner text widget -static void BText_Init( menutext_s *b ); -static void BText_Draw( menutext_s *b ); - -/* -================= -Text_Init -================= -*/ -static void Text_Init( menutext_s *t ) -{ - t->generic.flags |= QMF_INACTIVE; -} - -/* -================= -Text_Draw -================= -*/ -static void Text_Draw( menutext_s *t ) -{ - int x; - int y; - char buff[512]; - float* color; - - x = t->generic.x; - y = t->generic.y; - - buff[0] = '\0'; - - // possible label - if (t->generic.name) - strcpy(buff,t->generic.name); - - // possible value - if (t->string) - strcat(buff,t->string); - - if (t->generic.flags & QMF_GRAYED) - color = text_color_disabled; - else - color = t->color; - - UI_DrawString( x, y, buff, t->style, color ); -} - -/* -================= -BText_Init -================= -*/ -static void BText_Init( menutext_s *t ) -{ - t->generic.flags |= QMF_INACTIVE; -} - -/* -================= -BText_Draw -================= -*/ -static void BText_Draw( menutext_s *t ) -{ - int x; - int y; - float* color; - - x = t->generic.x; - y = t->generic.y; - - if (t->generic.flags & QMF_GRAYED) - color = text_color_disabled; - else - color = t->color; - - UI_DrawBannerString( x, y, t->string, t->style, color ); -} - -/* -================= -PText_Init -================= -*/ -static void PText_Init( menutext_s *t ) -{ - int x; - int y; - int w; - int h; - float sizeScale; - - sizeScale = UI_ProportionalSizeScale( t->style ); - - x = t->generic.x; - y = t->generic.y; - w = UI_ProportionalStringWidth( t->string ) * sizeScale; - h = PROP_HEIGHT * sizeScale; - - if( t->generic.flags & QMF_RIGHT_JUSTIFY ) { - x -= w; - } - else if( t->generic.flags & QMF_CENTER_JUSTIFY ) { - x -= w / 2; - } - - t->generic.left = x - PROP_GAP_WIDTH * sizeScale; - t->generic.right = x + w + PROP_GAP_WIDTH * sizeScale; - t->generic.top = y; - t->generic.bottom = y + h; -} - -/* -================= -PText_Draw -================= -*/ -static void PText_Draw( menutext_s *t ) -{ - int x; - int y; - float * color; - int style; - - x = t->generic.x; - y = t->generic.y; - - if (t->generic.flags & QMF_GRAYED) - color = text_color_disabled; - else - color = t->color; - - style = t->style; - if( t->generic.flags & QMF_PULSEIFFOCUS ) { - if( Menu_ItemAtCursor( t->generic.parent ) == t ) { - style |= UI_PULSE; - } - else { - style |= UI_INVERSE; - } - } - - UI_DrawProportionalString( x, y, t->string, style, color ); -} - -/* -================= -Bitmap_Init -================= -*/ -void Bitmap_Init( menubitmap_s *b ) -{ - int x; - int y; - int w; - int h; - - x = b->generic.x; - y = b->generic.y; - w = b->width; - h = b->height; - if( w < 0 ) { - w = -w; - } - if( h < 0 ) { - h = -h; - } - - if (b->generic.flags & QMF_RIGHT_JUSTIFY) - { - x = x - w; - } - else if (b->generic.flags & QMF_CENTER_JUSTIFY) - { - x = x - w/2; - } - - b->generic.left = x; - b->generic.right = x + w; - b->generic.top = y; - b->generic.bottom = y + h; - - b->shader = 0; - b->focusshader = 0; -} - -/* -================= -Bitmap_Draw -================= -*/ -void Bitmap_Draw( menubitmap_s *b ) -{ - float x; - float y; - float w; - float h; - vec4_t tempcolor; - float* color; - - x = b->generic.x; - y = b->generic.y; - w = b->width; - h = b->height; - - if (b->generic.flags & QMF_RIGHT_JUSTIFY) - { - x = x - w; - } - else if (b->generic.flags & QMF_CENTER_JUSTIFY) - { - x = x - w/2; - } - - // used to refresh shader - if (b->generic.name && !b->shader) - { - b->shader = trap_R_RegisterShaderNoMip( b->generic.name ); - if (!b->shader && b->errorpic) - b->shader = trap_R_RegisterShaderNoMip( b->errorpic ); - } - - if (b->focuspic && !b->focusshader) - b->focusshader = trap_R_RegisterShaderNoMip( b->focuspic ); - - if (b->generic.flags & QMF_GRAYED) - { - if (b->shader) - { - trap_R_SetColor( colorMdGrey ); - UI_DrawHandlePic( x, y, w, h, b->shader ); - trap_R_SetColor( NULL ); - } - } - else - { - if (b->shader) - UI_DrawHandlePic( x, y, w, h, b->shader ); - - // bk001204 - parentheses - if ( ( (b->generic.flags & QMF_PULSE) - || (b->generic.flags & QMF_PULSEIFFOCUS) ) - && (Menu_ItemAtCursor( b->generic.parent ) == b)) - { - if (b->focuscolor) - { - tempcolor[0] = b->focuscolor[0]; - tempcolor[1] = b->focuscolor[1]; - tempcolor[2] = b->focuscolor[2]; - color = tempcolor; - } - else - color = pulse_color; - color[3] = 0.5+0.5*sin(uis.realtime/PULSE_DIVISOR); - - trap_R_SetColor( color ); - UI_DrawHandlePic( x, y, w, h, b->focusshader ); - trap_R_SetColor( NULL ); - } - else if ((b->generic.flags & QMF_HIGHLIGHT) || ((b->generic.flags & QMF_HIGHLIGHT_IF_FOCUS) && (Menu_ItemAtCursor( b->generic.parent ) == b))) - { - if (b->focuscolor) - { - trap_R_SetColor( b->focuscolor ); - UI_DrawHandlePic( x, y, w, h, b->focusshader ); - trap_R_SetColor( NULL ); - } - else - UI_DrawHandlePic( x, y, w, h, b->focusshader ); - } - } -} - -/* -================= -Action_Init -================= -*/ -static void Action_Init( menuaction_s *a ) -{ - int len; - - // calculate bounds - if (a->generic.name) - len = strlen(a->generic.name); - else - len = 0; - - // left justify text - a->generic.left = a->generic.x; - a->generic.right = a->generic.x + len*BIGCHAR_WIDTH; - a->generic.top = a->generic.y; - a->generic.bottom = a->generic.y + BIGCHAR_HEIGHT; -} - -/* -================= -Action_Draw -================= -*/ -static void Action_Draw( menuaction_s *a ) -{ - int x, y; - int style; - float* color; - - style = 0; - color = menu_text_color; - if ( a->generic.flags & QMF_GRAYED ) - { - color = text_color_disabled; - } - else if (( a->generic.flags & QMF_PULSEIFFOCUS ) && ( a->generic.parent->cursor == a->generic.menuPosition )) - { - color = text_color_highlight; - style = UI_PULSE; - } - else if (( a->generic.flags & QMF_HIGHLIGHT_IF_FOCUS ) && ( a->generic.parent->cursor == a->generic.menuPosition )) - { - color = text_color_highlight; - } - else if ( a->generic.flags & QMF_BLINK ) - { - style = UI_BLINK; - color = text_color_highlight; - } - - x = a->generic.x; - y = a->generic.y; - - UI_DrawString( x, y, a->generic.name, UI_LEFT|style, color ); - - if ( a->generic.parent->cursor == a->generic.menuPosition ) - { - // draw cursor - UI_DrawChar( x - BIGCHAR_WIDTH, y, 13, UI_LEFT|UI_BLINK, color); - } -} - -/* -================= -RadioButton_Init -================= -*/ -static void RadioButton_Init( menuradiobutton_s *rb ) -{ - int len; - - // calculate bounds - if (rb->generic.name) - len = strlen(rb->generic.name); - else - len = 0; - - rb->generic.left = rb->generic.x - (len+1)*SMALLCHAR_WIDTH; - rb->generic.right = rb->generic.x + 6*SMALLCHAR_WIDTH; - rb->generic.top = rb->generic.y; - rb->generic.bottom = rb->generic.y + SMALLCHAR_HEIGHT; -} - -/* -================= -RadioButton_Key -================= -*/ -static sfxHandle_t RadioButton_Key( menuradiobutton_s *rb, int key ) -{ - switch (key) - { - case K_MOUSE1: - if (!(rb->generic.flags & QMF_HASMOUSEFOCUS)) - break; - - case K_JOY1: - case K_JOY2: - case K_JOY3: - case K_JOY4: - case K_ENTER: - case K_KP_ENTER: - case K_KP_LEFTARROW: - case K_LEFTARROW: - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - rb->curvalue = !rb->curvalue; - if ( rb->generic.callback ) - rb->generic.callback( rb, QM_ACTIVATED ); - - return (menu_move_sound); - } - - // key not handled - return 0; -} - -/* -================= -RadioButton_Draw -================= -*/ -static void RadioButton_Draw( menuradiobutton_s *rb ) -{ - int x; - int y; - float *color; - int style; - qboolean focus; - - x = rb->generic.x; - y = rb->generic.y; - - focus = (rb->generic.parent->cursor == rb->generic.menuPosition); - - if ( rb->generic.flags & QMF_GRAYED ) - { - color = text_color_disabled; - style = UI_LEFT|UI_SMALLFONT; - } - else if ( focus ) - { - color = text_color_highlight; - style = UI_LEFT|UI_PULSE|UI_SMALLFONT; - } - else - { - color = text_color_normal; - style = UI_LEFT|UI_SMALLFONT; - } - - if ( focus ) - { - // draw cursor - UI_FillRect( rb->generic.left, rb->generic.top, rb->generic.right-rb->generic.left+1, rb->generic.bottom-rb->generic.top+1, listbar_color ); - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); - } - - if ( rb->generic.name ) - UI_DrawString( x - SMALLCHAR_WIDTH, y, rb->generic.name, UI_RIGHT|UI_SMALLFONT, color ); - - if ( !rb->curvalue ) - { - UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y + 2, 16, 16, uis.rb_off); - UI_DrawString( x + SMALLCHAR_WIDTH + 16, y, "off", style, color ); - } - else - { - UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y + 2, 16, 16, uis.rb_on ); - UI_DrawString( x + SMALLCHAR_WIDTH + 16, y, "on", style, color ); - } -} - -/* -================= -Slider_Init -================= -*/ -static void Slider_Init( menuslider_s *s ) -{ - int len; - - // calculate bounds - if (s->generic.name) - len = strlen(s->generic.name); - else - len = 0; - - s->generic.left = s->generic.x - (len+1)*SMALLCHAR_WIDTH; - s->generic.right = s->generic.x + (SLIDER_RANGE+2+1)*SMALLCHAR_WIDTH; - s->generic.top = s->generic.y; - s->generic.bottom = s->generic.y + SMALLCHAR_HEIGHT; -} - -/* -================= -Slider_Key -================= -*/ -static sfxHandle_t Slider_Key( menuslider_s *s, int key ) -{ - sfxHandle_t sound; - int x; - int oldvalue; - - switch (key) - { - case K_MOUSE1: - x = uis.cursorx - s->generic.x - 2*SMALLCHAR_WIDTH; - oldvalue = s->curvalue; - s->curvalue = (x/(float)(SLIDER_RANGE*SMALLCHAR_WIDTH)) * (s->maxvalue-s->minvalue) + s->minvalue; - - if (s->curvalue < s->minvalue) - s->curvalue = s->minvalue; - else if (s->curvalue > s->maxvalue) - s->curvalue = s->maxvalue; - if (s->curvalue != oldvalue) - sound = menu_move_sound; - else - sound = 0; - break; - - case K_KP_LEFTARROW: - case K_LEFTARROW: - if (s->curvalue > s->minvalue) - { - s->curvalue--; - sound = menu_move_sound; - } - else - sound = menu_buzz_sound; - break; - - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - if (s->curvalue < s->maxvalue) - { - s->curvalue++; - sound = menu_move_sound; - } - else - sound = menu_buzz_sound; - break; - - default: - // key not handled - sound = 0; - break; - } - - if ( sound && s->generic.callback ) - s->generic.callback( s, QM_ACTIVATED ); - - return (sound); -} - -#if 1 -/* -================= -Slider_Draw -================= -*/ -static void Slider_Draw( menuslider_s *s ) { - int x; - int y; - int style; - float *color; - int button; - qboolean focus; - - x = s->generic.x; - y = s->generic.y; - focus = (s->generic.parent->cursor == s->generic.menuPosition); - - if( s->generic.flags & QMF_GRAYED ) { - color = text_color_disabled; - style = UI_SMALLFONT; - } - else if( focus ) { - color = text_color_highlight; - style = UI_SMALLFONT | UI_PULSE; - } - else { - color = text_color_normal; - style = UI_SMALLFONT; - } - - // draw label - UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, UI_RIGHT|style, color ); - - // draw slider - UI_SetColor( color ); - UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y, 96, 16, sliderBar ); - UI_SetColor( NULL ); - - // clamp thumb - if( s->maxvalue > s->minvalue ) { - s->range = ( s->curvalue - s->minvalue ) / ( float ) ( s->maxvalue - s->minvalue ); - if( s->range < 0 ) { - s->range = 0; - } - else if( s->range > 1) { - s->range = 1; - } - } - else { - s->range = 0; - } - - // draw thumb - if( style & UI_PULSE) { - button = sliderButton_1; - } - else { - button = sliderButton_0; - } - - UI_DrawHandlePic( (int)( x + 2*SMALLCHAR_WIDTH + (SLIDER_RANGE-1)*SMALLCHAR_WIDTH* s->range ) - 2, y - 2, 12, 20, button ); -} -#else -/* -================= -Slider_Draw -================= -*/ -static void Slider_Draw( menuslider_s *s ) -{ - float *color; - int style; - int i; - int x; - int y; - qboolean focus; - - x = s->generic.x; - y = s->generic.y; - focus = (s->generic.parent->cursor == s->generic.menuPosition); - - style = UI_SMALLFONT; - if ( s->generic.flags & QMF_GRAYED ) - { - color = text_color_disabled; - } - else if (focus) - { - color = text_color_highlight; - style |= UI_PULSE; - } - else - { - color = text_color_normal; - } - - if ( focus ) - { - // draw cursor - UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); - } - - // draw label - UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, UI_RIGHT|style, color ); - - // draw slider - UI_DrawChar( x + SMALLCHAR_WIDTH, y, 128, UI_LEFT|style, color); - for ( i = 0; i < SLIDER_RANGE; i++ ) - UI_DrawChar( x + (i+2)*SMALLCHAR_WIDTH, y, 129, UI_LEFT|style, color); - UI_DrawChar( x + (i+2)*SMALLCHAR_WIDTH, y, 130, UI_LEFT|style, color); - - // clamp thumb - if (s->maxvalue > s->minvalue) - { - s->range = ( s->curvalue - s->minvalue ) / ( float ) ( s->maxvalue - s->minvalue ); - if ( s->range < 0) - s->range = 0; - else if ( s->range > 1) - s->range = 1; - } - else - s->range = 0; - - // draw thumb - if (style & UI_PULSE) { - style &= ~UI_PULSE; - style |= UI_BLINK; - } - UI_DrawChar( (int)( x + 2*SMALLCHAR_WIDTH + (SLIDER_RANGE-1)*SMALLCHAR_WIDTH* s->range ), y, 131, UI_LEFT|style, color); -} -#endif - -/* -================= -SpinControl_Init -================= -*/ -static void SpinControl_Init( menulist_s *s ) { - int len; - int l; - const char* str; - - if (s->generic.name) - len = strlen(s->generic.name) * SMALLCHAR_WIDTH; - else - len = 0; - - s->generic.left = s->generic.x - SMALLCHAR_WIDTH - len; - - len = s->numitems = 0; - while ( (str = s->itemnames[s->numitems]) != 0 ) - { - l = strlen(str); - if (l > len) - len = l; - - s->numitems++; - } - - s->generic.top = s->generic.y; - s->generic.right = s->generic.x + (len+1)*SMALLCHAR_WIDTH; - s->generic.bottom = s->generic.y + SMALLCHAR_HEIGHT; -} - -/* -================= -SpinControl_Key -================= -*/ -static sfxHandle_t SpinControl_Key( menulist_s *s, int key ) -{ - sfxHandle_t sound; - - sound = 0; - switch (key) - { - case K_MOUSE1: - s->curvalue++; - if (s->curvalue >= s->numitems) - s->curvalue = 0; - sound = menu_move_sound; - break; - - case K_KP_LEFTARROW: - case K_LEFTARROW: - if (s->curvalue > 0) - { - s->curvalue--; - sound = menu_move_sound; - } - else - sound = menu_buzz_sound; - break; - - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - if (s->curvalue < s->numitems-1) - { - s->curvalue++; - sound = menu_move_sound; - } - else - sound = menu_buzz_sound; - break; - } - - if ( sound && s->generic.callback ) - s->generic.callback( s, QM_ACTIVATED ); - - return (sound); -} - -/* -================= -SpinControl_Draw -================= -*/ -static void SpinControl_Draw( menulist_s *s ) -{ - float *color; - int x,y; - int style; - qboolean focus; - - x = s->generic.x; - y = s->generic.y; - - style = UI_SMALLFONT; - focus = (s->generic.parent->cursor == s->generic.menuPosition); - - if ( s->generic.flags & QMF_GRAYED ) - color = text_color_disabled; - else if ( focus ) - { - color = text_color_highlight; - style |= UI_PULSE; - } - else if ( s->generic.flags & QMF_BLINK ) - { - color = text_color_highlight; - style |= UI_BLINK; - } - else - color = text_color_normal; - - if ( focus ) - { - // draw cursor - UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); - } - - UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); - UI_DrawString( x + SMALLCHAR_WIDTH, y, s->itemnames[s->curvalue], style|UI_LEFT, color ); -} - -/* -================= -ScrollList_Init -================= -*/ -static void ScrollList_Init( menulist_s *l ) -{ - int w; - - l->oldvalue = 0; - l->curvalue = 0; - l->top = 0; - - if( !l->columns ) { - l->columns = 1; - l->seperation = 0; - } - else if( !l->seperation ) { - l->seperation = 3; - } - - w = ( (l->width + l->seperation) * l->columns - l->seperation) * SMALLCHAR_WIDTH; - - l->generic.left = l->generic.x; - l->generic.top = l->generic.y; - l->generic.right = l->generic.x + w; - l->generic.bottom = l->generic.y + l->height * SMALLCHAR_HEIGHT; - - if( l->generic.flags & QMF_CENTER_JUSTIFY ) { - l->generic.left -= w / 2; - l->generic.right -= w / 2; - } -} - -/* -================= -ScrollList_Key -================= -*/ -sfxHandle_t ScrollList_Key( menulist_s *l, int key ) -{ - int x; - int y; - int w; - int i; - int j; - int c; - int cursorx; - int cursory; - int column; - int index; - - switch (key) - { - case K_MOUSE1: - if (l->generic.flags & QMF_HASMOUSEFOCUS) - { - // check scroll region - x = l->generic.x; - y = l->generic.y; - w = ( (l->width + l->seperation) * l->columns - l->seperation) * SMALLCHAR_WIDTH; - if( l->generic.flags & QMF_CENTER_JUSTIFY ) { - x -= w / 2; - } - if (UI_CursorInRect( x, y, w, l->height*SMALLCHAR_HEIGHT )) - { - cursorx = (uis.cursorx - x)/SMALLCHAR_WIDTH; - column = cursorx / (l->width + l->seperation); - cursory = (uis.cursory - y)/SMALLCHAR_HEIGHT; - index = column * l->height + cursory; - if (l->top + index < l->numitems) - { - l->oldvalue = l->curvalue; - l->curvalue = l->top + index; - - if (l->oldvalue != l->curvalue && l->generic.callback) - { - l->generic.callback( l, QM_GOTFOCUS ); - return (menu_move_sound); - } - } - } - - // absorbed, silent sound effect - return (menu_null_sound); - } - break; - - case K_KP_HOME: - case K_HOME: - l->oldvalue = l->curvalue; - l->curvalue = 0; - l->top = 0; - - if (l->oldvalue != l->curvalue && l->generic.callback) - { - l->generic.callback( l, QM_GOTFOCUS ); - return (menu_move_sound); - } - return (menu_buzz_sound); - - case K_KP_END: - case K_END: - l->oldvalue = l->curvalue; - l->curvalue = l->numitems-1; - if( l->columns > 1 ) { - c = (l->curvalue / l->height + 1) * l->height; - l->top = c - (l->columns * l->height); - } - else { - l->top = l->curvalue - (l->height - 1); - } - if (l->top < 0) - l->top = 0; - - if (l->oldvalue != l->curvalue && l->generic.callback) - { - l->generic.callback( l, QM_GOTFOCUS ); - return (menu_move_sound); - } - return (menu_buzz_sound); - - case K_PGUP: - case K_KP_PGUP: - if( l->columns > 1 ) { - return menu_null_sound; - } - - if (l->curvalue > 0) - { - l->oldvalue = l->curvalue; - l->curvalue -= l->height-1; - if (l->curvalue < 0) - l->curvalue = 0; - l->top = l->curvalue; - if (l->top < 0) - l->top = 0; - - if (l->generic.callback) - l->generic.callback( l, QM_GOTFOCUS ); - - return (menu_move_sound); - } - return (menu_buzz_sound); - - case K_PGDN: - case K_KP_PGDN: - if( l->columns > 1 ) { - return menu_null_sound; - } - - if (l->curvalue < l->numitems-1) - { - l->oldvalue = l->curvalue; - l->curvalue += l->height-1; - if (l->curvalue > l->numitems-1) - l->curvalue = l->numitems-1; - l->top = l->curvalue - (l->height-1); - if (l->top < 0) - l->top = 0; - - if (l->generic.callback) - l->generic.callback( l, QM_GOTFOCUS ); - - return (menu_move_sound); - } - return (menu_buzz_sound); - - case K_KP_UPARROW: - case K_UPARROW: - if( l->curvalue == 0 ) { - return menu_buzz_sound; - } - - l->oldvalue = l->curvalue; - l->curvalue--; - - if( l->curvalue < l->top ) { - if( l->columns == 1 ) { - l->top--; - } - else { - l->top -= l->height; - } - } - - if( l->generic.callback ) { - l->generic.callback( l, QM_GOTFOCUS ); - } - - return (menu_move_sound); - - case K_KP_DOWNARROW: - case K_DOWNARROW: - if( l->curvalue == l->numitems - 1 ) { - return menu_buzz_sound; - } - - l->oldvalue = l->curvalue; - l->curvalue++; - - if( l->curvalue >= l->top + l->columns * l->height ) { - if( l->columns == 1 ) { - l->top++; - } - else { - l->top += l->height; - } - } - - if( l->generic.callback ) { - l->generic.callback( l, QM_GOTFOCUS ); - } - - return menu_move_sound; - - case K_KP_LEFTARROW: - case K_LEFTARROW: - if( l->columns == 1 ) { - return menu_null_sound; - } - - if( l->curvalue < l->height ) { - return menu_buzz_sound; - } - - l->oldvalue = l->curvalue; - l->curvalue -= l->height; - - if( l->curvalue < l->top ) { - l->top -= l->height; - } - - if( l->generic.callback ) { - l->generic.callback( l, QM_GOTFOCUS ); - } - - return menu_move_sound; - - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - if( l->columns == 1 ) { - return menu_null_sound; - } - - c = l->curvalue + l->height; - - if( c >= l->numitems ) { - return menu_buzz_sound; - } - - l->oldvalue = l->curvalue; - l->curvalue = c; - - if( l->curvalue > l->top + l->columns * l->height - 1 ) { - l->top += l->height; - } - - if( l->generic.callback ) { - l->generic.callback( l, QM_GOTFOCUS ); - } - - return menu_move_sound; - } - - // cycle look for ascii key inside list items - if ( !Q_isprint( key ) ) - return (0); - - // force to lower for case insensitive compare - if ( Q_isupper( key ) ) - { - key -= 'A' - 'a'; - } - - // iterate list items - for (i=1; i<=l->numitems; i++) - { - j = (l->curvalue + i) % l->numitems; - c = l->itemnames[j][0]; - if ( Q_isupper( c ) ) - { - c -= 'A' - 'a'; - } - - if (c == key) - { - // set current item, mimic windows listbox scroll behavior - if (j < l->top) - { - // behind top most item, set this as new top - l->top = j; - } - else if (j > l->top+l->height-1) - { - // past end of list box, do page down - l->top = (j+1) - l->height; - } - - if (l->curvalue != j) - { - l->oldvalue = l->curvalue; - l->curvalue = j; - if (l->generic.callback) - l->generic.callback( l, QM_GOTFOCUS ); - return ( menu_move_sound ); - } - - return (menu_buzz_sound); - } - } - - return (menu_buzz_sound); -} - -/* -================= -ScrollList_Draw -================= -*/ -void ScrollList_Draw( menulist_s *l ) -{ - int x; - int u; - int y; - int i; - int base; - int column; - float* color; - qboolean hasfocus; - int style; - - hasfocus = (l->generic.parent->cursor == l->generic.menuPosition); - - x = l->generic.x; - for( column = 0; column < l->columns; column++ ) { - y = l->generic.y; - base = l->top + column * l->height; - for( i = base; i < base + l->height; i++) { - if (i >= l->numitems) - break; - - if (i == l->curvalue) - { - u = x - 2; - if( l->generic.flags & QMF_CENTER_JUSTIFY ) { - u -= (l->width * SMALLCHAR_WIDTH) / 2 + 1; - } - - UI_FillRect(u,y,l->width*SMALLCHAR_WIDTH,SMALLCHAR_HEIGHT+2,listbar_color); - color = text_color_highlight; - - if (hasfocus) - style = UI_PULSE|UI_LEFT|UI_SMALLFONT; - else - style = UI_LEFT|UI_SMALLFONT; - } - else - { - color = text_color_normal; - style = UI_LEFT|UI_SMALLFONT; - } - if( l->generic.flags & QMF_CENTER_JUSTIFY ) { - style |= UI_CENTER; - } - - UI_DrawString( - x, - y, - l->itemnames[i], - style, - color); - - y += SMALLCHAR_HEIGHT; - } - x += (l->width + l->seperation) * SMALLCHAR_WIDTH; - } -} - -/* -================= -Menu_AddItem -================= -*/ -void Menu_AddItem( menuframework_s *menu, void *item ) -{ - menucommon_s *itemptr; - - if (menu->nitems >= MAX_MENUITEMS) - trap_Error ("Menu_AddItem: excessive items"); - - menu->items[menu->nitems] = item; - ((menucommon_s*)menu->items[menu->nitems])->parent = menu; - ((menucommon_s*)menu->items[menu->nitems])->menuPosition = menu->nitems; - ((menucommon_s*)menu->items[menu->nitems])->flags &= ~QMF_HASMOUSEFOCUS; - - // perform any item specific initializations - itemptr = (menucommon_s*)item; - if (!(itemptr->flags & QMF_NODEFAULTINIT)) - { - switch (itemptr->type) - { - case MTYPE_ACTION: - Action_Init((menuaction_s*)item); - break; - - case MTYPE_FIELD: - MenuField_Init((menufield_s*)item); - break; - - case MTYPE_SPINCONTROL: - SpinControl_Init((menulist_s*)item); - break; - - case MTYPE_RADIOBUTTON: - RadioButton_Init((menuradiobutton_s*)item); - break; - - case MTYPE_SLIDER: - Slider_Init((menuslider_s*)item); - break; - - case MTYPE_BITMAP: - Bitmap_Init((menubitmap_s*)item); - break; - - case MTYPE_TEXT: - Text_Init((menutext_s*)item); - break; - - case MTYPE_SCROLLLIST: - ScrollList_Init((menulist_s*)item); - break; - - case MTYPE_PTEXT: - PText_Init((menutext_s*)item); - break; - - case MTYPE_BTEXT: - BText_Init((menutext_s*)item); - break; - - default: - trap_Error( va("Menu_Init: unknown type %d", itemptr->type) ); - } - } - - menu->nitems++; -} - -/* -================= -Menu_CursorMoved -================= -*/ -void Menu_CursorMoved( menuframework_s *m ) -{ - void (*callback)( void *self, int notification ); - - if (m->cursor_prev == m->cursor) - return; - - if (m->cursor_prev >= 0 && m->cursor_prev < m->nitems) - { - callback = ((menucommon_s*)(m->items[m->cursor_prev]))->callback; - if (callback) - callback(m->items[m->cursor_prev],QM_LOSTFOCUS); - } - - if (m->cursor >= 0 && m->cursor < m->nitems) - { - callback = ((menucommon_s*)(m->items[m->cursor]))->callback; - if (callback) - callback(m->items[m->cursor],QM_GOTFOCUS); - } -} - -/* -================= -Menu_SetCursor -================= -*/ -void Menu_SetCursor( menuframework_s *m, int cursor ) -{ - if (((menucommon_s*)(m->items[cursor]))->flags & (QMF_GRAYED|QMF_INACTIVE)) - { - // cursor can't go there - return; - } - - m->cursor_prev = m->cursor; - m->cursor = cursor; - - Menu_CursorMoved( m ); -} - -/* -================= -Menu_SetCursorToItem -================= -*/ -void Menu_SetCursorToItem( menuframework_s *m, void* ptr ) -{ - int i; - - for (i=0; initems; i++) - { - if (m->items[i] == ptr) - { - Menu_SetCursor( m, i ); - return; - } - } -} - -/* -** Menu_AdjustCursor -** -** This function takes the given menu, the direction, and attempts -** to adjust the menu's cursor so that it's at the next available -** slot. -*/ -void Menu_AdjustCursor( menuframework_s *m, int dir ) { - menucommon_s *item = NULL; - qboolean wrapped = qfalse; - -wrap: - while ( m->cursor >= 0 && m->cursor < m->nitems ) { - item = ( menucommon_s * ) m->items[m->cursor]; - if (( item->flags & (QMF_GRAYED|QMF_MOUSEONLY|QMF_INACTIVE) ) ) { - m->cursor += dir; - } - else { - break; - } - } - - if ( dir == 1 ) { - if ( m->cursor >= m->nitems ) { - if ( m->wrapAround ) { - if ( wrapped ) { - m->cursor = m->cursor_prev; - return; - } - m->cursor = 0; - wrapped = qtrue; - goto wrap; - } - m->cursor = m->cursor_prev; - } - } - else { - if ( m->cursor < 0 ) { - if ( m->wrapAround ) { - if ( wrapped ) { - m->cursor = m->cursor_prev; - return; - } - m->cursor = m->nitems - 1; - wrapped = qtrue; - goto wrap; - } - m->cursor = m->cursor_prev; - } - } -} - -/* -================= -Menu_Draw -================= -*/ -void Menu_Draw( menuframework_s *menu ) -{ - int i; - menucommon_s *itemptr; - - // draw menu - for (i=0; initems; i++) - { - itemptr = (menucommon_s*)menu->items[i]; - - if (itemptr->flags & QMF_HIDDEN) - continue; - - if (itemptr->ownerdraw) - { - // total subclassing, owner draws everything - itemptr->ownerdraw( itemptr ); - } - else - { - switch (itemptr->type) - { - case MTYPE_RADIOBUTTON: - RadioButton_Draw( (menuradiobutton_s*)itemptr ); - break; - - case MTYPE_FIELD: - MenuField_Draw( (menufield_s*)itemptr ); - break; - - case MTYPE_SLIDER: - Slider_Draw( (menuslider_s*)itemptr ); - break; - - case MTYPE_SPINCONTROL: - SpinControl_Draw( (menulist_s*)itemptr ); - break; - - case MTYPE_ACTION: - Action_Draw( (menuaction_s*)itemptr ); - break; - - case MTYPE_BITMAP: - Bitmap_Draw( (menubitmap_s*)itemptr ); - break; - - case MTYPE_TEXT: - Text_Draw( (menutext_s*)itemptr ); - break; - - case MTYPE_SCROLLLIST: - ScrollList_Draw( (menulist_s*)itemptr ); - break; - - case MTYPE_PTEXT: - PText_Draw( (menutext_s*)itemptr ); - break; - - case MTYPE_BTEXT: - BText_Draw( (menutext_s*)itemptr ); - break; - - default: - trap_Error( va("Menu_Draw: unknown type %d", itemptr->type) ); - } - } -#ifndef NDEBUG - if( uis.debug ) { - int x; - int y; - int w; - int h; - - if( !( itemptr->flags & QMF_INACTIVE ) ) { - x = itemptr->left; - y = itemptr->top; - w = itemptr->right - itemptr->left + 1; - h = itemptr->bottom - itemptr->top + 1; - - if (itemptr->flags & QMF_HASMOUSEFOCUS) { - UI_DrawRect(x, y, w, h, colorYellow ); - } - else { - UI_DrawRect(x, y, w, h, colorWhite ); - } - } - } -#endif - } - - itemptr = Menu_ItemAtCursor( menu ); - if ( itemptr && itemptr->statusbar) - itemptr->statusbar( ( void * ) itemptr ); -} - -/* -================= -Menu_ItemAtCursor -================= -*/ -void *Menu_ItemAtCursor( menuframework_s *m ) -{ - if ( m->cursor < 0 || m->cursor >= m->nitems ) - return 0; - - return m->items[m->cursor]; -} - -/* -================= -Menu_ActivateItem -================= -*/ -sfxHandle_t Menu_ActivateItem( menuframework_s *s, menucommon_s* item ) { - if ( item->callback ) { - item->callback( item, QM_ACTIVATED ); - if( !( item->flags & QMF_SILENT ) ) { - return menu_move_sound; - } - } - - return 0; -} - -/* -================= -Menu_DefaultKey -================= -*/ -sfxHandle_t Menu_DefaultKey( menuframework_s *m, int key ) -{ - sfxHandle_t sound = 0; - menucommon_s *item; - int cursor_prev; - - // menu system keys - switch ( key ) - { - case K_MOUSE2: - case K_ESCAPE: - UI_PopMenu(); - return menu_out_sound; - } - - if (!m || !m->nitems) - return 0; - - // route key stimulus to widget - item = Menu_ItemAtCursor( m ); - if (item && !(item->flags & (QMF_GRAYED|QMF_INACTIVE))) - { - switch (item->type) - { - case MTYPE_SPINCONTROL: - sound = SpinControl_Key( (menulist_s*)item, key ); - break; - - case MTYPE_RADIOBUTTON: - sound = RadioButton_Key( (menuradiobutton_s*)item, key ); - break; - - case MTYPE_SLIDER: - sound = Slider_Key( (menuslider_s*)item, key ); - break; - - case MTYPE_SCROLLLIST: - sound = ScrollList_Key( (menulist_s*)item, key ); - break; - - case MTYPE_FIELD: - sound = MenuField_Key( (menufield_s*)item, &key ); - break; - } - - if (sound) { - // key was handled - return sound; - } - } - - // default handling - switch ( key ) - { -#ifndef NDEBUG - case K_F11: - uis.debug ^= 1; - break; - - case K_F12: - trap_Cmd_ExecuteText(EXEC_APPEND, "screenshot\n"); - break; -#endif - case K_KP_UPARROW: - case K_UPARROW: - cursor_prev = m->cursor; - m->cursor_prev = m->cursor; - m->cursor--; - Menu_AdjustCursor( m, -1 ); - if ( cursor_prev != m->cursor ) { - Menu_CursorMoved( m ); - sound = menu_move_sound; - } - break; - - case K_TAB: - case K_KP_DOWNARROW: - case K_DOWNARROW: - cursor_prev = m->cursor; - m->cursor_prev = m->cursor; - m->cursor++; - Menu_AdjustCursor( m, 1 ); - if ( cursor_prev != m->cursor ) { - Menu_CursorMoved( m ); - sound = menu_move_sound; - } - break; - - case K_MOUSE1: - case K_MOUSE3: - if (item) - if ((item->flags & QMF_HASMOUSEFOCUS) && !(item->flags & (QMF_GRAYED|QMF_INACTIVE))) - return (Menu_ActivateItem( m, item )); - break; - - case K_JOY1: - case K_JOY2: - case K_JOY3: - case K_JOY4: - case K_AUX1: - case K_AUX2: - case K_AUX3: - case K_AUX4: - case K_AUX5: - case K_AUX6: - case K_AUX7: - case K_AUX8: - case K_AUX9: - case K_AUX10: - case K_AUX11: - case K_AUX12: - case K_AUX13: - case K_AUX14: - case K_AUX15: - case K_AUX16: - case K_KP_ENTER: - case K_ENTER: - if (item) - if (!(item->flags & (QMF_MOUSEONLY|QMF_GRAYED|QMF_INACTIVE))) - return (Menu_ActivateItem( m, item )); - break; - } - - return sound; -} - -/* -================= -Menu_Cache -================= -*/ -void Menu_Cache( void ) -{ - uis.charset = trap_R_RegisterShaderNoMip( "gfx/2d/bigchars" ); - uis.charsetProp = trap_R_RegisterShaderNoMip( "menu/art/font1_prop.tga" ); - uis.charsetPropGlow = trap_R_RegisterShaderNoMip( "menu/art/font1_prop_glo.tga" ); - uis.charsetPropB = trap_R_RegisterShaderNoMip( "menu/art/font2_prop.tga" ); - uis.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" ); - uis.rb_on = trap_R_RegisterShaderNoMip( "menu/art/switch_on" ); - uis.rb_off = trap_R_RegisterShaderNoMip( "menu/art/switch_off" ); - - uis.whiteShader = trap_R_RegisterShaderNoMip( "white" ); - if ( uis.glconfig.hardwareType == GLHW_RAGEPRO ) { - // the blend effect turns to shit with the normal - uis.menuBackShader = trap_R_RegisterShaderNoMip( "menubackRagePro" ); - } else { - uis.menuBackShader = trap_R_RegisterShaderNoMip( "menuback" ); - } - uis.menuBackNoLogoShader = trap_R_RegisterShaderNoMip( "menubacknologo" ); - - menu_in_sound = trap_S_RegisterSound( "sound/misc/menu1.wav", qfalse ); - menu_move_sound = trap_S_RegisterSound( "sound/misc/menu2.wav", qfalse ); - menu_out_sound = trap_S_RegisterSound( "sound/misc/menu3.wav", qfalse ); - menu_buzz_sound = trap_S_RegisterSound( "sound/misc/menu4.wav", qfalse ); - weaponChangeSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse ); - - // need a nonzero sound, make an empty sound for this - menu_null_sound = -1; - - sliderBar = trap_R_RegisterShaderNoMip( "menu/art/slider2" ); - sliderButton_0 = trap_R_RegisterShaderNoMip( "menu/art/sliderbutt_0" ); - sliderButton_1 = trap_R_RegisterShaderNoMip( "menu/art/sliderbutt_1" ); -} - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/********************************************************************** + UI_QMENU.C + + Quake's menu framework system. +**********************************************************************/ +#include "ui_local.h" + +sfxHandle_t menu_in_sound; +sfxHandle_t menu_move_sound; +sfxHandle_t menu_out_sound; +sfxHandle_t menu_buzz_sound; +sfxHandle_t menu_null_sound; +sfxHandle_t weaponChangeSound; + +static qhandle_t sliderBar; +static qhandle_t sliderButton_0; +static qhandle_t sliderButton_1; + +vec4_t menu_text_color = {1.0f, 1.0f, 1.0f, 1.0f}; +vec4_t menu_dim_color = {0.0f, 0.0f, 0.0f, 0.75f}; +vec4_t color_black = {0.00f, 0.00f, 0.00f, 1.00f}; +vec4_t color_white = {1.00f, 1.00f, 1.00f, 1.00f}; +vec4_t color_yellow = {1.00f, 1.00f, 0.00f, 1.00f}; +vec4_t color_blue = {0.00f, 0.00f, 1.00f, 1.00f}; +vec4_t color_lightOrange = {1.00f, 0.68f, 0.00f, 1.00f }; +vec4_t color_orange = {1.00f, 0.43f, 0.00f, 1.00f}; +vec4_t color_red = {1.00f, 0.00f, 0.00f, 1.00f}; +vec4_t color_dim = {0.00f, 0.00f, 0.00f, 0.25f}; + +// current color scheme +vec4_t pulse_color = {1.00f, 1.00f, 1.00f, 1.00f}; +vec4_t text_color_disabled = {0.50f, 0.50f, 0.50f, 1.00f}; // light gray +vec4_t text_color_normal = {1.00f, 0.43f, 0.00f, 1.00f}; // light orange +vec4_t text_color_highlight = {1.00f, 1.00f, 0.00f, 1.00f}; // bright yellow +vec4_t listbar_color = {1.00f, 0.43f, 0.00f, 0.30f}; // transluscent orange +vec4_t text_color_status = {1.00f, 1.00f, 1.00f, 1.00f}; // bright white + +// action widget +static void Action_Init( menuaction_s *a ); +static void Action_Draw( menuaction_s *a ); + +// radio button widget +static void RadioButton_Init( menuradiobutton_s *rb ); +static void RadioButton_Draw( menuradiobutton_s *rb ); +static sfxHandle_t RadioButton_Key( menuradiobutton_s *rb, int key ); + +// slider widget +static void Slider_Init( menuslider_s *s ); +static sfxHandle_t Slider_Key( menuslider_s *s, int key ); +static void Slider_Draw( menuslider_s *s ); + +// spin control widget +static void SpinControl_Init( menulist_s *s ); +static void SpinControl_Draw( menulist_s *s ); +static sfxHandle_t SpinControl_Key( menulist_s *l, int key ); + +// text widget +static void Text_Init( menutext_s *b ); +static void Text_Draw( menutext_s *b ); + +// scrolllist widget +static void ScrollList_Init( menulist_s *l ); +sfxHandle_t ScrollList_Key( menulist_s *l, int key ); + +// proportional text widget +static void PText_Init( menutext_s *b ); +static void PText_Draw( menutext_s *b ); + +// proportional banner text widget +static void BText_Init( menutext_s *b ); +static void BText_Draw( menutext_s *b ); + +/* +================= +Text_Init +================= +*/ +static void Text_Init( menutext_s *t ) +{ + t->generic.flags |= QMF_INACTIVE; +} + +/* +================= +Text_Draw +================= +*/ +static void Text_Draw( menutext_s *t ) +{ + int x; + int y; + char buff[512]; + float* color; + + x = t->generic.x; + y = t->generic.y; + + buff[0] = '\0'; + + // possible label + if (t->generic.name) + strcpy(buff,t->generic.name); + + // possible value + if (t->string) + strcat(buff,t->string); + + if (t->generic.flags & QMF_GRAYED) + color = text_color_disabled; + else + color = t->color; + + UI_DrawString( x, y, buff, t->style, color ); +} + +/* +================= +BText_Init +================= +*/ +static void BText_Init( menutext_s *t ) +{ + t->generic.flags |= QMF_INACTIVE; +} + +/* +================= +BText_Draw +================= +*/ +static void BText_Draw( menutext_s *t ) +{ + int x; + int y; + float* color; + + x = t->generic.x; + y = t->generic.y; + + if (t->generic.flags & QMF_GRAYED) + color = text_color_disabled; + else + color = t->color; + + UI_DrawBannerString( x, y, t->string, t->style, color ); +} + +/* +================= +PText_Init +================= +*/ +static void PText_Init( menutext_s *t ) +{ + int x; + int y; + int w; + int h; + float sizeScale; + + sizeScale = UI_ProportionalSizeScale( t->style ); + + x = t->generic.x; + y = t->generic.y; + w = UI_ProportionalStringWidth( t->string ) * sizeScale; + h = PROP_HEIGHT * sizeScale; + + if( t->generic.flags & QMF_RIGHT_JUSTIFY ) { + x -= w; + } + else if( t->generic.flags & QMF_CENTER_JUSTIFY ) { + x -= w / 2; + } + + t->generic.left = x - PROP_GAP_WIDTH * sizeScale; + t->generic.right = x + w + PROP_GAP_WIDTH * sizeScale; + t->generic.top = y; + t->generic.bottom = y + h; +} + +/* +================= +PText_Draw +================= +*/ +static void PText_Draw( menutext_s *t ) +{ + int x; + int y; + float * color; + int style; + + x = t->generic.x; + y = t->generic.y; + + if (t->generic.flags & QMF_GRAYED) + color = text_color_disabled; + else + color = t->color; + + style = t->style; + if( t->generic.flags & QMF_PULSEIFFOCUS ) { + if( Menu_ItemAtCursor( t->generic.parent ) == t ) { + style |= UI_PULSE; + } + else { + style |= UI_INVERSE; + } + } + + UI_DrawProportionalString( x, y, t->string, style, color ); +} + +/* +================= +Bitmap_Init +================= +*/ +void Bitmap_Init( menubitmap_s *b ) +{ + int x; + int y; + int w; + int h; + + x = b->generic.x; + y = b->generic.y; + w = b->width; + h = b->height; + if( w < 0 ) { + w = -w; + } + if( h < 0 ) { + h = -h; + } + + if (b->generic.flags & QMF_RIGHT_JUSTIFY) + { + x = x - w; + } + else if (b->generic.flags & QMF_CENTER_JUSTIFY) + { + x = x - w/2; + } + + b->generic.left = x; + b->generic.right = x + w; + b->generic.top = y; + b->generic.bottom = y + h; + + b->shader = 0; + b->focusshader = 0; +} + +/* +================= +Bitmap_Draw +================= +*/ +void Bitmap_Draw( menubitmap_s *b ) +{ + float x; + float y; + float w; + float h; + vec4_t tempcolor; + float* color; + + x = b->generic.x; + y = b->generic.y; + w = b->width; + h = b->height; + + if (b->generic.flags & QMF_RIGHT_JUSTIFY) + { + x = x - w; + } + else if (b->generic.flags & QMF_CENTER_JUSTIFY) + { + x = x - w/2; + } + + // used to refresh shader + if (b->generic.name && !b->shader) + { + b->shader = trap_R_RegisterShaderNoMip( b->generic.name ); + if (!b->shader && b->errorpic) + b->shader = trap_R_RegisterShaderNoMip( b->errorpic ); + } + + if (b->focuspic && !b->focusshader) + b->focusshader = trap_R_RegisterShaderNoMip( b->focuspic ); + + if (b->generic.flags & QMF_GRAYED) + { + if (b->shader) + { + trap_R_SetColor( colorMdGrey ); + UI_DrawHandlePic( x, y, w, h, b->shader ); + trap_R_SetColor( NULL ); + } + } + else + { + if (b->shader) + UI_DrawHandlePic( x, y, w, h, b->shader ); + + // bk001204 - parentheses + if ( ( (b->generic.flags & QMF_PULSE) + || (b->generic.flags & QMF_PULSEIFFOCUS) ) + && (Menu_ItemAtCursor( b->generic.parent ) == b)) + { + if (b->focuscolor) + { + tempcolor[0] = b->focuscolor[0]; + tempcolor[1] = b->focuscolor[1]; + tempcolor[2] = b->focuscolor[2]; + color = tempcolor; + } + else + color = pulse_color; + color[3] = 0.5+0.5*sin(uis.realtime/PULSE_DIVISOR); + + trap_R_SetColor( color ); + UI_DrawHandlePic( x, y, w, h, b->focusshader ); + trap_R_SetColor( NULL ); + } + else if ((b->generic.flags & QMF_HIGHLIGHT) || ((b->generic.flags & QMF_HIGHLIGHT_IF_FOCUS) && (Menu_ItemAtCursor( b->generic.parent ) == b))) + { + if (b->focuscolor) + { + trap_R_SetColor( b->focuscolor ); + UI_DrawHandlePic( x, y, w, h, b->focusshader ); + trap_R_SetColor( NULL ); + } + else + UI_DrawHandlePic( x, y, w, h, b->focusshader ); + } + } +} + +/* +================= +Action_Init +================= +*/ +static void Action_Init( menuaction_s *a ) +{ + int len; + + // calculate bounds + if (a->generic.name) + len = strlen(a->generic.name); + else + len = 0; + + // left justify text + a->generic.left = a->generic.x; + a->generic.right = a->generic.x + len*BIGCHAR_WIDTH; + a->generic.top = a->generic.y; + a->generic.bottom = a->generic.y + BIGCHAR_HEIGHT; +} + +/* +================= +Action_Draw +================= +*/ +static void Action_Draw( menuaction_s *a ) +{ + int x, y; + int style; + float* color; + + style = 0; + color = menu_text_color; + if ( a->generic.flags & QMF_GRAYED ) + { + color = text_color_disabled; + } + else if (( a->generic.flags & QMF_PULSEIFFOCUS ) && ( a->generic.parent->cursor == a->generic.menuPosition )) + { + color = text_color_highlight; + style = UI_PULSE; + } + else if (( a->generic.flags & QMF_HIGHLIGHT_IF_FOCUS ) && ( a->generic.parent->cursor == a->generic.menuPosition )) + { + color = text_color_highlight; + } + else if ( a->generic.flags & QMF_BLINK ) + { + style = UI_BLINK; + color = text_color_highlight; + } + + x = a->generic.x; + y = a->generic.y; + + UI_DrawString( x, y, a->generic.name, UI_LEFT|style, color ); + + if ( a->generic.parent->cursor == a->generic.menuPosition ) + { + // draw cursor + UI_DrawChar( x - BIGCHAR_WIDTH, y, 13, UI_LEFT|UI_BLINK, color); + } +} + +/* +================= +RadioButton_Init +================= +*/ +static void RadioButton_Init( menuradiobutton_s *rb ) +{ + int len; + + // calculate bounds + if (rb->generic.name) + len = strlen(rb->generic.name); + else + len = 0; + + rb->generic.left = rb->generic.x - (len+1)*SMALLCHAR_WIDTH; + rb->generic.right = rb->generic.x + 6*SMALLCHAR_WIDTH; + rb->generic.top = rb->generic.y; + rb->generic.bottom = rb->generic.y + SMALLCHAR_HEIGHT; +} + +/* +================= +RadioButton_Key +================= +*/ +static sfxHandle_t RadioButton_Key( menuradiobutton_s *rb, int key ) +{ + switch (key) + { + case K_MOUSE1: + if (!(rb->generic.flags & QMF_HASMOUSEFOCUS)) + break; + + case K_JOY1: + case K_JOY2: + case K_JOY3: + case K_JOY4: + case K_ENTER: + case K_KP_ENTER: + case K_KP_LEFTARROW: + case K_LEFTARROW: + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + rb->curvalue = !rb->curvalue; + if ( rb->generic.callback ) + rb->generic.callback( rb, QM_ACTIVATED ); + + return (menu_move_sound); + } + + // key not handled + return 0; +} + +/* +================= +RadioButton_Draw +================= +*/ +static void RadioButton_Draw( menuradiobutton_s *rb ) +{ + int x; + int y; + float *color; + int style; + qboolean focus; + + x = rb->generic.x; + y = rb->generic.y; + + focus = (rb->generic.parent->cursor == rb->generic.menuPosition); + + if ( rb->generic.flags & QMF_GRAYED ) + { + color = text_color_disabled; + style = UI_LEFT|UI_SMALLFONT; + } + else if ( focus ) + { + color = text_color_highlight; + style = UI_LEFT|UI_PULSE|UI_SMALLFONT; + } + else + { + color = text_color_normal; + style = UI_LEFT|UI_SMALLFONT; + } + + if ( focus ) + { + // draw cursor + UI_FillRect( rb->generic.left, rb->generic.top, rb->generic.right-rb->generic.left+1, rb->generic.bottom-rb->generic.top+1, listbar_color ); + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); + } + + if ( rb->generic.name ) + UI_DrawString( x - SMALLCHAR_WIDTH, y, rb->generic.name, UI_RIGHT|UI_SMALLFONT, color ); + + if ( !rb->curvalue ) + { + UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y + 2, 16, 16, uis.rb_off); + UI_DrawString( x + SMALLCHAR_WIDTH + 16, y, "off", style, color ); + } + else + { + UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y + 2, 16, 16, uis.rb_on ); + UI_DrawString( x + SMALLCHAR_WIDTH + 16, y, "on", style, color ); + } +} + +/* +================= +Slider_Init +================= +*/ +static void Slider_Init( menuslider_s *s ) +{ + int len; + + // calculate bounds + if (s->generic.name) + len = strlen(s->generic.name); + else + len = 0; + + s->generic.left = s->generic.x - (len+1)*SMALLCHAR_WIDTH; + s->generic.right = s->generic.x + (SLIDER_RANGE+2+1)*SMALLCHAR_WIDTH; + s->generic.top = s->generic.y; + s->generic.bottom = s->generic.y + SMALLCHAR_HEIGHT; +} + +/* +================= +Slider_Key +================= +*/ +static sfxHandle_t Slider_Key( menuslider_s *s, int key ) +{ + sfxHandle_t sound; + int x; + int oldvalue; + + switch (key) + { + case K_MOUSE1: + x = uis.cursorx - s->generic.x - 2*SMALLCHAR_WIDTH; + oldvalue = s->curvalue; + s->curvalue = (x/(float)(SLIDER_RANGE*SMALLCHAR_WIDTH)) * (s->maxvalue-s->minvalue) + s->minvalue; + + if (s->curvalue < s->minvalue) + s->curvalue = s->minvalue; + else if (s->curvalue > s->maxvalue) + s->curvalue = s->maxvalue; + if (s->curvalue != oldvalue) + sound = menu_move_sound; + else + sound = 0; + break; + + case K_KP_LEFTARROW: + case K_LEFTARROW: + if (s->curvalue > s->minvalue) + { + s->curvalue--; + sound = menu_move_sound; + } + else + sound = menu_buzz_sound; + break; + + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + if (s->curvalue < s->maxvalue) + { + s->curvalue++; + sound = menu_move_sound; + } + else + sound = menu_buzz_sound; + break; + + default: + // key not handled + sound = 0; + break; + } + + if ( sound && s->generic.callback ) + s->generic.callback( s, QM_ACTIVATED ); + + return (sound); +} + +#if 1 +/* +================= +Slider_Draw +================= +*/ +static void Slider_Draw( menuslider_s *s ) { + int x; + int y; + int style; + float *color; + int button; + qboolean focus; + + x = s->generic.x; + y = s->generic.y; + focus = (s->generic.parent->cursor == s->generic.menuPosition); + + if( s->generic.flags & QMF_GRAYED ) { + color = text_color_disabled; + style = UI_SMALLFONT; + } + else if( focus ) { + color = text_color_highlight; + style = UI_SMALLFONT | UI_PULSE; + } + else { + color = text_color_normal; + style = UI_SMALLFONT; + } + + // draw label + UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, UI_RIGHT|style, color ); + + // draw slider + UI_SetColor( color ); + UI_DrawHandlePic( x + SMALLCHAR_WIDTH, y, 96, 16, sliderBar ); + UI_SetColor( NULL ); + + // clamp thumb + if( s->maxvalue > s->minvalue ) { + s->range = ( s->curvalue - s->minvalue ) / ( float ) ( s->maxvalue - s->minvalue ); + if( s->range < 0 ) { + s->range = 0; + } + else if( s->range > 1) { + s->range = 1; + } + } + else { + s->range = 0; + } + + // draw thumb + if( style & UI_PULSE) { + button = sliderButton_1; + } + else { + button = sliderButton_0; + } + + UI_DrawHandlePic( (int)( x + 2*SMALLCHAR_WIDTH + (SLIDER_RANGE-1)*SMALLCHAR_WIDTH* s->range ) - 2, y - 2, 12, 20, button ); +} +#else +/* +================= +Slider_Draw +================= +*/ +static void Slider_Draw( menuslider_s *s ) +{ + float *color; + int style; + int i; + int x; + int y; + qboolean focus; + + x = s->generic.x; + y = s->generic.y; + focus = (s->generic.parent->cursor == s->generic.menuPosition); + + style = UI_SMALLFONT; + if ( s->generic.flags & QMF_GRAYED ) + { + color = text_color_disabled; + } + else if (focus) + { + color = text_color_highlight; + style |= UI_PULSE; + } + else + { + color = text_color_normal; + } + + if ( focus ) + { + // draw cursor + UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); + } + + // draw label + UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, UI_RIGHT|style, color ); + + // draw slider + UI_DrawChar( x + SMALLCHAR_WIDTH, y, 128, UI_LEFT|style, color); + for ( i = 0; i < SLIDER_RANGE; i++ ) + UI_DrawChar( x + (i+2)*SMALLCHAR_WIDTH, y, 129, UI_LEFT|style, color); + UI_DrawChar( x + (i+2)*SMALLCHAR_WIDTH, y, 130, UI_LEFT|style, color); + + // clamp thumb + if (s->maxvalue > s->minvalue) + { + s->range = ( s->curvalue - s->minvalue ) / ( float ) ( s->maxvalue - s->minvalue ); + if ( s->range < 0) + s->range = 0; + else if ( s->range > 1) + s->range = 1; + } + else + s->range = 0; + + // draw thumb + if (style & UI_PULSE) { + style &= ~UI_PULSE; + style |= UI_BLINK; + } + UI_DrawChar( (int)( x + 2*SMALLCHAR_WIDTH + (SLIDER_RANGE-1)*SMALLCHAR_WIDTH* s->range ), y, 131, UI_LEFT|style, color); +} +#endif + +/* +================= +SpinControl_Init +================= +*/ +static void SpinControl_Init( menulist_s *s ) { + int len; + int l; + const char* str; + + if (s->generic.name) + len = strlen(s->generic.name) * SMALLCHAR_WIDTH; + else + len = 0; + + s->generic.left = s->generic.x - SMALLCHAR_WIDTH - len; + + len = s->numitems = 0; + while ( (str = s->itemnames[s->numitems]) != 0 ) + { + l = strlen(str); + if (l > len) + len = l; + + s->numitems++; + } + + s->generic.top = s->generic.y; + s->generic.right = s->generic.x + (len+1)*SMALLCHAR_WIDTH; + s->generic.bottom = s->generic.y + SMALLCHAR_HEIGHT; +} + +/* +================= +SpinControl_Key +================= +*/ +static sfxHandle_t SpinControl_Key( menulist_s *s, int key ) +{ + sfxHandle_t sound; + + sound = 0; + switch (key) + { + case K_MOUSE1: + s->curvalue++; + if (s->curvalue >= s->numitems) + s->curvalue = 0; + sound = menu_move_sound; + break; + + case K_KP_LEFTARROW: + case K_LEFTARROW: + if (s->curvalue > 0) + { + s->curvalue--; + sound = menu_move_sound; + } + else + sound = menu_buzz_sound; + break; + + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + if (s->curvalue < s->numitems-1) + { + s->curvalue++; + sound = menu_move_sound; + } + else + sound = menu_buzz_sound; + break; + } + + if ( sound && s->generic.callback ) + s->generic.callback( s, QM_ACTIVATED ); + + return (sound); +} + +/* +================= +SpinControl_Draw +================= +*/ +static void SpinControl_Draw( menulist_s *s ) +{ + float *color; + int x,y; + int style; + qboolean focus; + + x = s->generic.x; + y = s->generic.y; + + style = UI_SMALLFONT; + focus = (s->generic.parent->cursor == s->generic.menuPosition); + + if ( s->generic.flags & QMF_GRAYED ) + color = text_color_disabled; + else if ( focus ) + { + color = text_color_highlight; + style |= UI_PULSE; + } + else if ( s->generic.flags & QMF_BLINK ) + { + color = text_color_highlight; + style |= UI_BLINK; + } + else + color = text_color_normal; + + if ( focus ) + { + // draw cursor + UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); + } + + UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); + UI_DrawString( x + SMALLCHAR_WIDTH, y, s->itemnames[s->curvalue], style|UI_LEFT, color ); +} + +/* +================= +ScrollList_Init +================= +*/ +static void ScrollList_Init( menulist_s *l ) +{ + int w; + + l->oldvalue = 0; + l->curvalue = 0; + l->top = 0; + + if( !l->columns ) { + l->columns = 1; + l->seperation = 0; + } + else if( !l->seperation ) { + l->seperation = 3; + } + + w = ( (l->width + l->seperation) * l->columns - l->seperation) * SMALLCHAR_WIDTH; + + l->generic.left = l->generic.x; + l->generic.top = l->generic.y; + l->generic.right = l->generic.x + w; + l->generic.bottom = l->generic.y + l->height * SMALLCHAR_HEIGHT; + + if( l->generic.flags & QMF_CENTER_JUSTIFY ) { + l->generic.left -= w / 2; + l->generic.right -= w / 2; + } +} + +/* +================= +ScrollList_Key +================= +*/ +sfxHandle_t ScrollList_Key( menulist_s *l, int key ) +{ + int x; + int y; + int w; + int i; + int j; + int c; + int cursorx; + int cursory; + int column; + int index; + + switch (key) + { + case K_MOUSE1: + if (l->generic.flags & QMF_HASMOUSEFOCUS) + { + // check scroll region + x = l->generic.x; + y = l->generic.y; + w = ( (l->width + l->seperation) * l->columns - l->seperation) * SMALLCHAR_WIDTH; + if( l->generic.flags & QMF_CENTER_JUSTIFY ) { + x -= w / 2; + } + if (UI_CursorInRect( x, y, w, l->height*SMALLCHAR_HEIGHT )) + { + cursorx = (uis.cursorx - x)/SMALLCHAR_WIDTH; + column = cursorx / (l->width + l->seperation); + cursory = (uis.cursory - y)/SMALLCHAR_HEIGHT; + index = column * l->height + cursory; + if (l->top + index < l->numitems) + { + l->oldvalue = l->curvalue; + l->curvalue = l->top + index; + + if (l->oldvalue != l->curvalue && l->generic.callback) + { + l->generic.callback( l, QM_GOTFOCUS ); + return (menu_move_sound); + } + } + } + + // absorbed, silent sound effect + return (menu_null_sound); + } + break; + + case K_KP_HOME: + case K_HOME: + l->oldvalue = l->curvalue; + l->curvalue = 0; + l->top = 0; + + if (l->oldvalue != l->curvalue && l->generic.callback) + { + l->generic.callback( l, QM_GOTFOCUS ); + return (menu_move_sound); + } + return (menu_buzz_sound); + + case K_KP_END: + case K_END: + l->oldvalue = l->curvalue; + l->curvalue = l->numitems-1; + if( l->columns > 1 ) { + c = (l->curvalue / l->height + 1) * l->height; + l->top = c - (l->columns * l->height); + } + else { + l->top = l->curvalue - (l->height - 1); + } + if (l->top < 0) + l->top = 0; + + if (l->oldvalue != l->curvalue && l->generic.callback) + { + l->generic.callback( l, QM_GOTFOCUS ); + return (menu_move_sound); + } + return (menu_buzz_sound); + + case K_PGUP: + case K_KP_PGUP: + if( l->columns > 1 ) { + return menu_null_sound; + } + + if (l->curvalue > 0) + { + l->oldvalue = l->curvalue; + l->curvalue -= l->height-1; + if (l->curvalue < 0) + l->curvalue = 0; + l->top = l->curvalue; + if (l->top < 0) + l->top = 0; + + if (l->generic.callback) + l->generic.callback( l, QM_GOTFOCUS ); + + return (menu_move_sound); + } + return (menu_buzz_sound); + + case K_PGDN: + case K_KP_PGDN: + if( l->columns > 1 ) { + return menu_null_sound; + } + + if (l->curvalue < l->numitems-1) + { + l->oldvalue = l->curvalue; + l->curvalue += l->height-1; + if (l->curvalue > l->numitems-1) + l->curvalue = l->numitems-1; + l->top = l->curvalue - (l->height-1); + if (l->top < 0) + l->top = 0; + + if (l->generic.callback) + l->generic.callback( l, QM_GOTFOCUS ); + + return (menu_move_sound); + } + return (menu_buzz_sound); + + case K_KP_UPARROW: + case K_UPARROW: + if( l->curvalue == 0 ) { + return menu_buzz_sound; + } + + l->oldvalue = l->curvalue; + l->curvalue--; + + if( l->curvalue < l->top ) { + if( l->columns == 1 ) { + l->top--; + } + else { + l->top -= l->height; + } + } + + if( l->generic.callback ) { + l->generic.callback( l, QM_GOTFOCUS ); + } + + return (menu_move_sound); + + case K_KP_DOWNARROW: + case K_DOWNARROW: + if( l->curvalue == l->numitems - 1 ) { + return menu_buzz_sound; + } + + l->oldvalue = l->curvalue; + l->curvalue++; + + if( l->curvalue >= l->top + l->columns * l->height ) { + if( l->columns == 1 ) { + l->top++; + } + else { + l->top += l->height; + } + } + + if( l->generic.callback ) { + l->generic.callback( l, QM_GOTFOCUS ); + } + + return menu_move_sound; + + case K_KP_LEFTARROW: + case K_LEFTARROW: + if( l->columns == 1 ) { + return menu_null_sound; + } + + if( l->curvalue < l->height ) { + return menu_buzz_sound; + } + + l->oldvalue = l->curvalue; + l->curvalue -= l->height; + + if( l->curvalue < l->top ) { + l->top -= l->height; + } + + if( l->generic.callback ) { + l->generic.callback( l, QM_GOTFOCUS ); + } + + return menu_move_sound; + + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + if( l->columns == 1 ) { + return menu_null_sound; + } + + c = l->curvalue + l->height; + + if( c >= l->numitems ) { + return menu_buzz_sound; + } + + l->oldvalue = l->curvalue; + l->curvalue = c; + + if( l->curvalue > l->top + l->columns * l->height - 1 ) { + l->top += l->height; + } + + if( l->generic.callback ) { + l->generic.callback( l, QM_GOTFOCUS ); + } + + return menu_move_sound; + } + + // cycle look for ascii key inside list items + if ( !Q_isprint( key ) ) + return (0); + + // force to lower for case insensitive compare + if ( Q_isupper( key ) ) + { + key -= 'A' - 'a'; + } + + // iterate list items + for (i=1; i<=l->numitems; i++) + { + j = (l->curvalue + i) % l->numitems; + c = l->itemnames[j][0]; + if ( Q_isupper( c ) ) + { + c -= 'A' - 'a'; + } + + if (c == key) + { + // set current item, mimic windows listbox scroll behavior + if (j < l->top) + { + // behind top most item, set this as new top + l->top = j; + } + else if (j > l->top+l->height-1) + { + // past end of list box, do page down + l->top = (j+1) - l->height; + } + + if (l->curvalue != j) + { + l->oldvalue = l->curvalue; + l->curvalue = j; + if (l->generic.callback) + l->generic.callback( l, QM_GOTFOCUS ); + return ( menu_move_sound ); + } + + return (menu_buzz_sound); + } + } + + return (menu_buzz_sound); +} + +/* +================= +ScrollList_Draw +================= +*/ +void ScrollList_Draw( menulist_s *l ) +{ + int x; + int u; + int y; + int i; + int base; + int column; + float* color; + qboolean hasfocus; + int style; + + hasfocus = (l->generic.parent->cursor == l->generic.menuPosition); + + x = l->generic.x; + for( column = 0; column < l->columns; column++ ) { + y = l->generic.y; + base = l->top + column * l->height; + for( i = base; i < base + l->height; i++) { + if (i >= l->numitems) + break; + + if (i == l->curvalue) + { + u = x - 2; + if( l->generic.flags & QMF_CENTER_JUSTIFY ) { + u -= (l->width * SMALLCHAR_WIDTH) / 2 + 1; + } + + UI_FillRect(u,y,l->width*SMALLCHAR_WIDTH,SMALLCHAR_HEIGHT+2,listbar_color); + color = text_color_highlight; + + if (hasfocus) + style = UI_PULSE|UI_LEFT|UI_SMALLFONT; + else + style = UI_LEFT|UI_SMALLFONT; + } + else + { + color = text_color_normal; + style = UI_LEFT|UI_SMALLFONT; + } + if( l->generic.flags & QMF_CENTER_JUSTIFY ) { + style |= UI_CENTER; + } + + UI_DrawString( + x, + y, + l->itemnames[i], + style, + color); + + y += SMALLCHAR_HEIGHT; + } + x += (l->width + l->seperation) * SMALLCHAR_WIDTH; + } +} + +/* +================= +Menu_AddItem +================= +*/ +void Menu_AddItem( menuframework_s *menu, void *item ) +{ + menucommon_s *itemptr; + + if (menu->nitems >= MAX_MENUITEMS) + trap_Error ("Menu_AddItem: excessive items"); + + menu->items[menu->nitems] = item; + ((menucommon_s*)menu->items[menu->nitems])->parent = menu; + ((menucommon_s*)menu->items[menu->nitems])->menuPosition = menu->nitems; + ((menucommon_s*)menu->items[menu->nitems])->flags &= ~QMF_HASMOUSEFOCUS; + + // perform any item specific initializations + itemptr = (menucommon_s*)item; + if (!(itemptr->flags & QMF_NODEFAULTINIT)) + { + switch (itemptr->type) + { + case MTYPE_ACTION: + Action_Init((menuaction_s*)item); + break; + + case MTYPE_FIELD: + MenuField_Init((menufield_s*)item); + break; + + case MTYPE_SPINCONTROL: + SpinControl_Init((menulist_s*)item); + break; + + case MTYPE_RADIOBUTTON: + RadioButton_Init((menuradiobutton_s*)item); + break; + + case MTYPE_SLIDER: + Slider_Init((menuslider_s*)item); + break; + + case MTYPE_BITMAP: + Bitmap_Init((menubitmap_s*)item); + break; + + case MTYPE_TEXT: + Text_Init((menutext_s*)item); + break; + + case MTYPE_SCROLLLIST: + ScrollList_Init((menulist_s*)item); + break; + + case MTYPE_PTEXT: + PText_Init((menutext_s*)item); + break; + + case MTYPE_BTEXT: + BText_Init((menutext_s*)item); + break; + + default: + trap_Error( va("Menu_Init: unknown type %d", itemptr->type) ); + } + } + + menu->nitems++; +} + +/* +================= +Menu_CursorMoved +================= +*/ +void Menu_CursorMoved( menuframework_s *m ) +{ + void (*callback)( void *self, int notification ); + + if (m->cursor_prev == m->cursor) + return; + + if (m->cursor_prev >= 0 && m->cursor_prev < m->nitems) + { + callback = ((menucommon_s*)(m->items[m->cursor_prev]))->callback; + if (callback) + callback(m->items[m->cursor_prev],QM_LOSTFOCUS); + } + + if (m->cursor >= 0 && m->cursor < m->nitems) + { + callback = ((menucommon_s*)(m->items[m->cursor]))->callback; + if (callback) + callback(m->items[m->cursor],QM_GOTFOCUS); + } +} + +/* +================= +Menu_SetCursor +================= +*/ +void Menu_SetCursor( menuframework_s *m, int cursor ) +{ + if (((menucommon_s*)(m->items[cursor]))->flags & (QMF_GRAYED|QMF_INACTIVE)) + { + // cursor can't go there + return; + } + + m->cursor_prev = m->cursor; + m->cursor = cursor; + + Menu_CursorMoved( m ); +} + +/* +================= +Menu_SetCursorToItem +================= +*/ +void Menu_SetCursorToItem( menuframework_s *m, void* ptr ) +{ + int i; + + for (i=0; initems; i++) + { + if (m->items[i] == ptr) + { + Menu_SetCursor( m, i ); + return; + } + } +} + +/* +** Menu_AdjustCursor +** +** This function takes the given menu, the direction, and attempts +** to adjust the menu's cursor so that it's at the next available +** slot. +*/ +void Menu_AdjustCursor( menuframework_s *m, int dir ) { + menucommon_s *item = NULL; + qboolean wrapped = qfalse; + +wrap: + while ( m->cursor >= 0 && m->cursor < m->nitems ) { + item = ( menucommon_s * ) m->items[m->cursor]; + if (( item->flags & (QMF_GRAYED|QMF_MOUSEONLY|QMF_INACTIVE) ) ) { + m->cursor += dir; + } + else { + break; + } + } + + if ( dir == 1 ) { + if ( m->cursor >= m->nitems ) { + if ( m->wrapAround ) { + if ( wrapped ) { + m->cursor = m->cursor_prev; + return; + } + m->cursor = 0; + wrapped = qtrue; + goto wrap; + } + m->cursor = m->cursor_prev; + } + } + else { + if ( m->cursor < 0 ) { + if ( m->wrapAround ) { + if ( wrapped ) { + m->cursor = m->cursor_prev; + return; + } + m->cursor = m->nitems - 1; + wrapped = qtrue; + goto wrap; + } + m->cursor = m->cursor_prev; + } + } +} + +/* +================= +Menu_Draw +================= +*/ +void Menu_Draw( menuframework_s *menu ) +{ + int i; + menucommon_s *itemptr; + + // draw menu + for (i=0; initems; i++) + { + itemptr = (menucommon_s*)menu->items[i]; + + if (itemptr->flags & QMF_HIDDEN) + continue; + + if (itemptr->ownerdraw) + { + // total subclassing, owner draws everything + itemptr->ownerdraw( itemptr ); + } + else + { + switch (itemptr->type) + { + case MTYPE_RADIOBUTTON: + RadioButton_Draw( (menuradiobutton_s*)itemptr ); + break; + + case MTYPE_FIELD: + MenuField_Draw( (menufield_s*)itemptr ); + break; + + case MTYPE_SLIDER: + Slider_Draw( (menuslider_s*)itemptr ); + break; + + case MTYPE_SPINCONTROL: + SpinControl_Draw( (menulist_s*)itemptr ); + break; + + case MTYPE_ACTION: + Action_Draw( (menuaction_s*)itemptr ); + break; + + case MTYPE_BITMAP: + Bitmap_Draw( (menubitmap_s*)itemptr ); + break; + + case MTYPE_TEXT: + Text_Draw( (menutext_s*)itemptr ); + break; + + case MTYPE_SCROLLLIST: + ScrollList_Draw( (menulist_s*)itemptr ); + break; + + case MTYPE_PTEXT: + PText_Draw( (menutext_s*)itemptr ); + break; + + case MTYPE_BTEXT: + BText_Draw( (menutext_s*)itemptr ); + break; + + default: + trap_Error( va("Menu_Draw: unknown type %d", itemptr->type) ); + } + } +#ifndef NDEBUG + if( uis.debug ) { + int x; + int y; + int w; + int h; + + if( !( itemptr->flags & QMF_INACTIVE ) ) { + x = itemptr->left; + y = itemptr->top; + w = itemptr->right - itemptr->left + 1; + h = itemptr->bottom - itemptr->top + 1; + + if (itemptr->flags & QMF_HASMOUSEFOCUS) { + UI_DrawRect(x, y, w, h, colorYellow ); + } + else { + UI_DrawRect(x, y, w, h, colorWhite ); + } + } + } +#endif + } + + itemptr = Menu_ItemAtCursor( menu ); + if ( itemptr && itemptr->statusbar) + itemptr->statusbar( ( void * ) itemptr ); +} + +/* +================= +Menu_ItemAtCursor +================= +*/ +void *Menu_ItemAtCursor( menuframework_s *m ) +{ + if ( m->cursor < 0 || m->cursor >= m->nitems ) + return 0; + + return m->items[m->cursor]; +} + +/* +================= +Menu_ActivateItem +================= +*/ +sfxHandle_t Menu_ActivateItem( menuframework_s *s, menucommon_s* item ) { + if ( item->callback ) { + item->callback( item, QM_ACTIVATED ); + if( !( item->flags & QMF_SILENT ) ) { + return menu_move_sound; + } + } + + return 0; +} + +/* +================= +Menu_DefaultKey +================= +*/ +sfxHandle_t Menu_DefaultKey( menuframework_s *m, int key ) +{ + sfxHandle_t sound = 0; + menucommon_s *item; + int cursor_prev; + + // menu system keys + switch ( key ) + { + case K_MOUSE2: + case K_ESCAPE: + UI_PopMenu(); + return menu_out_sound; + } + + if (!m || !m->nitems) + return 0; + + // route key stimulus to widget + item = Menu_ItemAtCursor( m ); + if (item && !(item->flags & (QMF_GRAYED|QMF_INACTIVE))) + { + switch (item->type) + { + case MTYPE_SPINCONTROL: + sound = SpinControl_Key( (menulist_s*)item, key ); + break; + + case MTYPE_RADIOBUTTON: + sound = RadioButton_Key( (menuradiobutton_s*)item, key ); + break; + + case MTYPE_SLIDER: + sound = Slider_Key( (menuslider_s*)item, key ); + break; + + case MTYPE_SCROLLLIST: + sound = ScrollList_Key( (menulist_s*)item, key ); + break; + + case MTYPE_FIELD: + sound = MenuField_Key( (menufield_s*)item, &key ); + break; + } + + if (sound) { + // key was handled + return sound; + } + } + + // default handling + switch ( key ) + { +#ifndef NDEBUG + case K_F11: + uis.debug ^= 1; + break; + + case K_F12: + trap_Cmd_ExecuteText(EXEC_APPEND, "screenshot\n"); + break; +#endif + case K_KP_UPARROW: + case K_UPARROW: + cursor_prev = m->cursor; + m->cursor_prev = m->cursor; + m->cursor--; + Menu_AdjustCursor( m, -1 ); + if ( cursor_prev != m->cursor ) { + Menu_CursorMoved( m ); + sound = menu_move_sound; + } + break; + + case K_TAB: + case K_KP_DOWNARROW: + case K_DOWNARROW: + cursor_prev = m->cursor; + m->cursor_prev = m->cursor; + m->cursor++; + Menu_AdjustCursor( m, 1 ); + if ( cursor_prev != m->cursor ) { + Menu_CursorMoved( m ); + sound = menu_move_sound; + } + break; + + case K_MOUSE1: + case K_MOUSE3: + if (item) + if ((item->flags & QMF_HASMOUSEFOCUS) && !(item->flags & (QMF_GRAYED|QMF_INACTIVE))) + return (Menu_ActivateItem( m, item )); + break; + + case K_JOY1: + case K_JOY2: + case K_JOY3: + case K_JOY4: + case K_AUX1: + case K_AUX2: + case K_AUX3: + case K_AUX4: + case K_AUX5: + case K_AUX6: + case K_AUX7: + case K_AUX8: + case K_AUX9: + case K_AUX10: + case K_AUX11: + case K_AUX12: + case K_AUX13: + case K_AUX14: + case K_AUX15: + case K_AUX16: + case K_KP_ENTER: + case K_ENTER: + if (item) + if (!(item->flags & (QMF_MOUSEONLY|QMF_GRAYED|QMF_INACTIVE))) + return (Menu_ActivateItem( m, item )); + break; + } + + return sound; +} + +/* +================= +Menu_Cache +================= +*/ +void Menu_Cache( void ) +{ + uis.charset = trap_R_RegisterShaderNoMip( "gfx/2d/bigchars" ); + uis.charsetProp = trap_R_RegisterShaderNoMip( "menu/art/font1_prop.tga" ); + uis.charsetPropGlow = trap_R_RegisterShaderNoMip( "menu/art/font1_prop_glo.tga" ); + uis.charsetPropB = trap_R_RegisterShaderNoMip( "menu/art/font2_prop.tga" ); + uis.cursor = trap_R_RegisterShaderNoMip( "menu/art/3_cursor2" ); + uis.rb_on = trap_R_RegisterShaderNoMip( "menu/art/switch_on" ); + uis.rb_off = trap_R_RegisterShaderNoMip( "menu/art/switch_off" ); + + uis.whiteShader = trap_R_RegisterShaderNoMip( "white" ); + if ( uis.glconfig.hardwareType == GLHW_RAGEPRO ) { + // the blend effect turns to shit with the normal + uis.menuBackShader = trap_R_RegisterShaderNoMip( "menubackRagePro" ); + } else { + uis.menuBackShader = trap_R_RegisterShaderNoMip( "menuback" ); + } + uis.menuBackNoLogoShader = trap_R_RegisterShaderNoMip( "menubacknologo" ); + + menu_in_sound = trap_S_RegisterSound( "sound/misc/menu1.wav", qfalse ); + menu_move_sound = trap_S_RegisterSound( "sound/misc/menu2.wav", qfalse ); + menu_out_sound = trap_S_RegisterSound( "sound/misc/menu3.wav", qfalse ); + menu_buzz_sound = trap_S_RegisterSound( "sound/misc/menu4.wav", qfalse ); + weaponChangeSound = trap_S_RegisterSound( "sound/weapons/change.wav", qfalse ); + + // need a nonzero sound, make an empty sound for this + menu_null_sound = -1; + + sliderBar = trap_R_RegisterShaderNoMip( "menu/art/slider2" ); + sliderButton_0 = trap_R_RegisterShaderNoMip( "menu/art/sliderbutt_0" ); + sliderButton_1 = trap_R_RegisterShaderNoMip( "menu/art/sliderbutt_1" ); +} + diff --git a/code/q3_ui/ui_rankings.c b/code/q3_ui/ui_rankings.c index 762e964..69e20c1 100755 --- a/code/q3_ui/ui_rankings.c +++ b/code/q3_ui/ui_rankings.c @@ -1,420 +1,420 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -// -// ui_rankings.c -// - -#include "ui_local.h" - - -#define RANKINGS_FRAME "menu/art/cut_frame" - -#define ID_LOGIN 100 -#define ID_LOGOUT 101 -#define ID_CREATE 102 -#define ID_SPECTATE 103 -#define ID_SETUP 104 -#define ID_LEAVE 105 - - -typedef struct -{ - menuframework_s menu; - menubitmap_s frame; - menutext_s login; - menutext_s logout; - menutext_s create; - menutext_s spectate; - menutext_s setup; - menutext_s leave; -} rankings_t; - -static rankings_t s_rankings; - -static menuframework_s s_rankings_menu; -static menuaction_s s_rankings_login; -static menuaction_s s_rankings_logout; -static menuaction_s s_rankings_create; -static menuaction_s s_rankings_spectate; -static menuaction_s s_rankings_setup; -static menuaction_s s_rankings_leave; - - -/* -=============== -Rankings_DrawText -=============== -*/ -void Rankings_DrawText( void* self ) -{ - menufield_s *f; - qboolean focus; - int style; - char *txt; - char c; - float *color; - int basex, x, y; - - f = (menufield_s*)self; - basex = f->generic.x; - y = f->generic.y + 4; - focus = (f->generic.parent->cursor == f->generic.menuPosition); - - style = UI_LEFT|UI_SMALLFONT; - color = text_color_normal; - if( focus ) { - style |= UI_PULSE; - color = text_color_highlight; - } - - // draw the actual text - txt = f->field.buffer; - color = g_color_table[ColorIndex(COLOR_WHITE)]; - x = basex; - while ( (c = *txt) != 0 ) { - UI_DrawChar( x, y, c, style, color ); - txt++; - x += SMALLCHAR_WIDTH; - } - - // draw cursor if we have focus - if( focus ) { - if ( trap_Key_GetOverstrikeMode() ) { - c = 11; - } else { - c = 10; - } - - style &= ~UI_PULSE; - style |= UI_BLINK; - - UI_DrawChar( basex + f->field.cursor * SMALLCHAR_WIDTH, y, c, style, color_white ); - } -} - -/* -=============== -Rankings_DrawName -=============== -*/ -void Rankings_DrawName( void* self ) -{ - menufield_s *f; - int length; - char* p; - - f = (menufield_s*)self; - - // GRANK_FIXME - enforce valid characters - for( p = f->field.buffer; *p != '\0'; p++ ) - { - //if( ispunct(*p) || isspace(*p) ) - if( !( ( (*p) >= '0' && (*p) <= '9') || Q_isalpha(*p)) ) - { - *p = '\0'; - } - } - - // strip color codes - Q_CleanStr( f->field.buffer ); - length = strlen( f->field.buffer ); - if( f->field.cursor > length ) - { - f->field.cursor = length; - } - - Rankings_DrawText( f ); -} - -#if 0 // old version -/* -=============== -Rankings_DrawName -=============== -*/ -void Rankings_DrawName( void* self ) -{ - menufield_s* f; - int length; - - f = (menufield_s*)self; - - // strip color codes - Q_CleanStr( f->field.buffer ); - length = strlen( f->field.buffer ); - if( f->field.cursor > length ) - { - f->field.cursor = length; - } - - // show beginning of long names - /* - if( Menu_ItemAtCursor( f->generic.parent ) != f ) - { - if( f->field.scroll > 0 ) - { - f->field.cursor = 0; - f->field.scroll = 0; - } - } - */ - - MenuField_Draw( f ); -} -#endif - -/* -=============== -Rankings_DrawPassword -=============== -*/ -void Rankings_DrawPassword( void* self ) -{ - menufield_s* f; - char password[MAX_EDIT_LINE]; - int length; - int i; - char* p; - - f = (menufield_s*)self; - - // GRANK_FIXME - enforce valid characters - for( p = f->field.buffer; *p != '\0'; p++ ) - { - //if( ispunct(*p) || isspace(*p) ) - if( !( ( (*p) >= '0' && (*p) <= '9') || Q_isalpha(*p)) ) - { - *p = '\0'; - } - } - - length = strlen( f->field.buffer ); - if( f->field.cursor > length ) - { - f->field.cursor = length; - } - - // save password - Q_strncpyz( password, f->field.buffer, sizeof(password) ); - - // mask password with * - for( i = 0; i < length; i++ ) - { - f->field.buffer[i] = '*'; - } - - // draw masked password - Rankings_DrawText( f ); - //MenuField_Draw( f ); - - // restore password - Q_strncpyz( f->field.buffer, password, sizeof(f->field.buffer) ); -} - -/* -=============== -Rankings_MenuEvent -=============== -*/ -static void Rankings_MenuEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_LOGIN: - UI_LoginMenu(); - break; - - case ID_LOGOUT: - // server side masqueraded player logout first - trap_CL_UI_RankUserRequestLogout(); - UI_ForceMenuOff(); - break; - - case ID_CREATE: - UI_SignupMenu(); - break; - - case ID_SPECTATE: - trap_Cmd_ExecuteText( EXEC_APPEND, "cmd rank_spectate\n" ); - UI_ForceMenuOff(); - break; - - case ID_SETUP: - UI_SetupMenu(); - break; - - case ID_LEAVE: - trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); - UI_ForceMenuOff(); - break; - - } -} - - -/* -=============== -Rankings_MenuInit -=============== -*/ -void Rankings_MenuInit( void ) { - grank_status_t status; - int y; - - memset( &s_rankings, 0, sizeof(s_rankings) ); - - Rankings_Cache(); - - s_rankings.menu.wrapAround = qtrue; - s_rankings.menu.fullscreen = qfalse; - - s_rankings.frame.generic.type = MTYPE_BITMAP; - s_rankings.frame.generic.flags = QMF_INACTIVE; - s_rankings.frame.generic.name = RANKINGS_FRAME; - s_rankings.frame.generic.x = 142; - s_rankings.frame.generic.y = 118; - s_rankings.frame.width = 359; - s_rankings.frame.height = 256; - - y = 194; - - s_rankings.login.generic.type = MTYPE_PTEXT; - s_rankings.login.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_rankings.login.generic.id = ID_LOGIN; - s_rankings.login.generic.callback = Rankings_MenuEvent; - s_rankings.login.generic.x = 320; - s_rankings.login.generic.y = y; - s_rankings.login.string = "LOGIN"; - s_rankings.login.style = UI_CENTER|UI_SMALLFONT; - s_rankings.login.color = colorRed; - y += 20; - - s_rankings.logout.generic.type = MTYPE_PTEXT; - s_rankings.logout.generic.flags = QMF_HIDDEN|QMF_INACTIVE|QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_rankings.logout.generic.id = ID_LOGOUT; - s_rankings.logout.generic.callback = Rankings_MenuEvent; - s_rankings.logout.generic.x = 320; - s_rankings.logout.generic.y = y; - s_rankings.logout.string = "LOGOUT"; - s_rankings.logout.style = UI_CENTER|UI_SMALLFONT; - s_rankings.logout.color = colorRed; - - s_rankings.create.generic.type = MTYPE_PTEXT; - s_rankings.create.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_rankings.create.generic.id = ID_CREATE; - s_rankings.create.generic.callback = Rankings_MenuEvent; - s_rankings.create.generic.x = 320; - s_rankings.create.generic.y = y; - s_rankings.create.string = "SIGN UP"; - s_rankings.create.style = UI_CENTER|UI_SMALLFONT; - s_rankings.create.color = colorRed; - y += 20; - - s_rankings.spectate.generic.type = MTYPE_PTEXT; - s_rankings.spectate.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_rankings.spectate.generic.id = ID_SPECTATE; - s_rankings.spectate.generic.callback = Rankings_MenuEvent; - s_rankings.spectate.generic.x = 320; - s_rankings.spectate.generic.y = y; - s_rankings.spectate.string = "SPECTATE"; - s_rankings.spectate.style = UI_CENTER|UI_SMALLFONT; - s_rankings.spectate.color = colorRed; - y += 20; - - s_rankings.setup.generic.type = MTYPE_PTEXT; - s_rankings.setup.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_rankings.setup.generic.id = ID_SETUP; - s_rankings.setup.generic.callback = Rankings_MenuEvent; - s_rankings.setup.generic.x = 320; - s_rankings.setup.generic.y = y; - s_rankings.setup.string = "SETUP"; - s_rankings.setup.style = UI_CENTER|UI_SMALLFONT; - s_rankings.setup.color = colorRed; - y += 20; - - s_rankings.leave.generic.type = MTYPE_PTEXT; - s_rankings.leave.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_rankings.leave.generic.id = ID_LEAVE; - s_rankings.leave.generic.callback = Rankings_MenuEvent; - s_rankings.leave.generic.x = 320; - s_rankings.leave.generic.y = y; - s_rankings.leave.string = "LEAVE ARENA"; - s_rankings.leave.style = UI_CENTER|UI_SMALLFONT; - s_rankings.leave.color = colorRed; - y += 20; - - status = (grank_status_t)trap_Cvar_VariableValue("client_status"); - if( (status != QGR_STATUS_NEW) && (status != QGR_STATUS_SPECTATOR) ) - { - s_rankings.login.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; - s_rankings.create.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; - s_rankings.spectate.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; - - s_rankings.logout.generic.flags &= ~(QMF_HIDDEN | QMF_INACTIVE); - } - - if ( (status == QGR_STATUS_VALIDATING) || - (status == QGR_STATUS_PENDING) || - (status == QGR_STATUS_LEAVING) ) - { - s_rankings.login.generic.flags |= QMF_GRAYED; - s_rankings.create.generic.flags |= QMF_GRAYED; - s_rankings.logout.generic.flags |= QMF_GRAYED; - } - - //GRank FIXME -- don't need setup option any more - s_rankings.setup.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; - - Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.frame ); - Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.login ); - Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.logout ); - Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.create ); - Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.spectate ); - Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.setup ); - Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.leave ); -} - - -/* -=============== -Rankings_Cache -=============== -*/ -void Rankings_Cache( void ) { - trap_R_RegisterShaderNoMip( RANKINGS_FRAME ); -} - - -/* -=============== -UI_RankingsMenu -=============== -*/ -void UI_RankingsMenu( void ) { - Rankings_MenuInit(); - UI_PushMenu ( &s_rankings.menu ); -} - - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +// +// ui_rankings.c +// + +#include "ui_local.h" + + +#define RANKINGS_FRAME "menu/art/cut_frame" + +#define ID_LOGIN 100 +#define ID_LOGOUT 101 +#define ID_CREATE 102 +#define ID_SPECTATE 103 +#define ID_SETUP 104 +#define ID_LEAVE 105 + + +typedef struct +{ + menuframework_s menu; + menubitmap_s frame; + menutext_s login; + menutext_s logout; + menutext_s create; + menutext_s spectate; + menutext_s setup; + menutext_s leave; +} rankings_t; + +static rankings_t s_rankings; + +static menuframework_s s_rankings_menu; +static menuaction_s s_rankings_login; +static menuaction_s s_rankings_logout; +static menuaction_s s_rankings_create; +static menuaction_s s_rankings_spectate; +static menuaction_s s_rankings_setup; +static menuaction_s s_rankings_leave; + + +/* +=============== +Rankings_DrawText +=============== +*/ +void Rankings_DrawText( void* self ) +{ + menufield_s *f; + qboolean focus; + int style; + char *txt; + char c; + float *color; + int basex, x, y; + + f = (menufield_s*)self; + basex = f->generic.x; + y = f->generic.y + 4; + focus = (f->generic.parent->cursor == f->generic.menuPosition); + + style = UI_LEFT|UI_SMALLFONT; + color = text_color_normal; + if( focus ) { + style |= UI_PULSE; + color = text_color_highlight; + } + + // draw the actual text + txt = f->field.buffer; + color = g_color_table[ColorIndex(COLOR_WHITE)]; + x = basex; + while ( (c = *txt) != 0 ) { + UI_DrawChar( x, y, c, style, color ); + txt++; + x += SMALLCHAR_WIDTH; + } + + // draw cursor if we have focus + if( focus ) { + if ( trap_Key_GetOverstrikeMode() ) { + c = 11; + } else { + c = 10; + } + + style &= ~UI_PULSE; + style |= UI_BLINK; + + UI_DrawChar( basex + f->field.cursor * SMALLCHAR_WIDTH, y, c, style, color_white ); + } +} + +/* +=============== +Rankings_DrawName +=============== +*/ +void Rankings_DrawName( void* self ) +{ + menufield_s *f; + int length; + char* p; + + f = (menufield_s*)self; + + // GRANK_FIXME - enforce valid characters + for( p = f->field.buffer; *p != '\0'; p++ ) + { + //if( ispunct(*p) || isspace(*p) ) + if( !( ( (*p) >= '0' && (*p) <= '9') || Q_isalpha(*p)) ) + { + *p = '\0'; + } + } + + // strip color codes + Q_CleanStr( f->field.buffer ); + length = strlen( f->field.buffer ); + if( f->field.cursor > length ) + { + f->field.cursor = length; + } + + Rankings_DrawText( f ); +} + +#if 0 // old version +/* +=============== +Rankings_DrawName +=============== +*/ +void Rankings_DrawName( void* self ) +{ + menufield_s* f; + int length; + + f = (menufield_s*)self; + + // strip color codes + Q_CleanStr( f->field.buffer ); + length = strlen( f->field.buffer ); + if( f->field.cursor > length ) + { + f->field.cursor = length; + } + + // show beginning of long names + /* + if( Menu_ItemAtCursor( f->generic.parent ) != f ) + { + if( f->field.scroll > 0 ) + { + f->field.cursor = 0; + f->field.scroll = 0; + } + } + */ + + MenuField_Draw( f ); +} +#endif + +/* +=============== +Rankings_DrawPassword +=============== +*/ +void Rankings_DrawPassword( void* self ) +{ + menufield_s* f; + char password[MAX_EDIT_LINE]; + int length; + int i; + char* p; + + f = (menufield_s*)self; + + // GRANK_FIXME - enforce valid characters + for( p = f->field.buffer; *p != '\0'; p++ ) + { + //if( ispunct(*p) || isspace(*p) ) + if( !( ( (*p) >= '0' && (*p) <= '9') || Q_isalpha(*p)) ) + { + *p = '\0'; + } + } + + length = strlen( f->field.buffer ); + if( f->field.cursor > length ) + { + f->field.cursor = length; + } + + // save password + Q_strncpyz( password, f->field.buffer, sizeof(password) ); + + // mask password with * + for( i = 0; i < length; i++ ) + { + f->field.buffer[i] = '*'; + } + + // draw masked password + Rankings_DrawText( f ); + //MenuField_Draw( f ); + + // restore password + Q_strncpyz( f->field.buffer, password, sizeof(f->field.buffer) ); +} + +/* +=============== +Rankings_MenuEvent +=============== +*/ +static void Rankings_MenuEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_LOGIN: + UI_LoginMenu(); + break; + + case ID_LOGOUT: + // server side masqueraded player logout first + trap_CL_UI_RankUserRequestLogout(); + UI_ForceMenuOff(); + break; + + case ID_CREATE: + UI_SignupMenu(); + break; + + case ID_SPECTATE: + trap_Cmd_ExecuteText( EXEC_APPEND, "cmd rank_spectate\n" ); + UI_ForceMenuOff(); + break; + + case ID_SETUP: + UI_SetupMenu(); + break; + + case ID_LEAVE: + trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); + UI_ForceMenuOff(); + break; + + } +} + + +/* +=============== +Rankings_MenuInit +=============== +*/ +void Rankings_MenuInit( void ) { + grank_status_t status; + int y; + + memset( &s_rankings, 0, sizeof(s_rankings) ); + + Rankings_Cache(); + + s_rankings.menu.wrapAround = qtrue; + s_rankings.menu.fullscreen = qfalse; + + s_rankings.frame.generic.type = MTYPE_BITMAP; + s_rankings.frame.generic.flags = QMF_INACTIVE; + s_rankings.frame.generic.name = RANKINGS_FRAME; + s_rankings.frame.generic.x = 142; + s_rankings.frame.generic.y = 118; + s_rankings.frame.width = 359; + s_rankings.frame.height = 256; + + y = 194; + + s_rankings.login.generic.type = MTYPE_PTEXT; + s_rankings.login.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_rankings.login.generic.id = ID_LOGIN; + s_rankings.login.generic.callback = Rankings_MenuEvent; + s_rankings.login.generic.x = 320; + s_rankings.login.generic.y = y; + s_rankings.login.string = "LOGIN"; + s_rankings.login.style = UI_CENTER|UI_SMALLFONT; + s_rankings.login.color = colorRed; + y += 20; + + s_rankings.logout.generic.type = MTYPE_PTEXT; + s_rankings.logout.generic.flags = QMF_HIDDEN|QMF_INACTIVE|QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_rankings.logout.generic.id = ID_LOGOUT; + s_rankings.logout.generic.callback = Rankings_MenuEvent; + s_rankings.logout.generic.x = 320; + s_rankings.logout.generic.y = y; + s_rankings.logout.string = "LOGOUT"; + s_rankings.logout.style = UI_CENTER|UI_SMALLFONT; + s_rankings.logout.color = colorRed; + + s_rankings.create.generic.type = MTYPE_PTEXT; + s_rankings.create.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_rankings.create.generic.id = ID_CREATE; + s_rankings.create.generic.callback = Rankings_MenuEvent; + s_rankings.create.generic.x = 320; + s_rankings.create.generic.y = y; + s_rankings.create.string = "SIGN UP"; + s_rankings.create.style = UI_CENTER|UI_SMALLFONT; + s_rankings.create.color = colorRed; + y += 20; + + s_rankings.spectate.generic.type = MTYPE_PTEXT; + s_rankings.spectate.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_rankings.spectate.generic.id = ID_SPECTATE; + s_rankings.spectate.generic.callback = Rankings_MenuEvent; + s_rankings.spectate.generic.x = 320; + s_rankings.spectate.generic.y = y; + s_rankings.spectate.string = "SPECTATE"; + s_rankings.spectate.style = UI_CENTER|UI_SMALLFONT; + s_rankings.spectate.color = colorRed; + y += 20; + + s_rankings.setup.generic.type = MTYPE_PTEXT; + s_rankings.setup.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_rankings.setup.generic.id = ID_SETUP; + s_rankings.setup.generic.callback = Rankings_MenuEvent; + s_rankings.setup.generic.x = 320; + s_rankings.setup.generic.y = y; + s_rankings.setup.string = "SETUP"; + s_rankings.setup.style = UI_CENTER|UI_SMALLFONT; + s_rankings.setup.color = colorRed; + y += 20; + + s_rankings.leave.generic.type = MTYPE_PTEXT; + s_rankings.leave.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_rankings.leave.generic.id = ID_LEAVE; + s_rankings.leave.generic.callback = Rankings_MenuEvent; + s_rankings.leave.generic.x = 320; + s_rankings.leave.generic.y = y; + s_rankings.leave.string = "LEAVE ARENA"; + s_rankings.leave.style = UI_CENTER|UI_SMALLFONT; + s_rankings.leave.color = colorRed; + y += 20; + + status = (grank_status_t)trap_Cvar_VariableValue("client_status"); + if( (status != QGR_STATUS_NEW) && (status != QGR_STATUS_SPECTATOR) ) + { + s_rankings.login.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; + s_rankings.create.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; + s_rankings.spectate.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; + + s_rankings.logout.generic.flags &= ~(QMF_HIDDEN | QMF_INACTIVE); + } + + if ( (status == QGR_STATUS_VALIDATING) || + (status == QGR_STATUS_PENDING) || + (status == QGR_STATUS_LEAVING) ) + { + s_rankings.login.generic.flags |= QMF_GRAYED; + s_rankings.create.generic.flags |= QMF_GRAYED; + s_rankings.logout.generic.flags |= QMF_GRAYED; + } + + //GRank FIXME -- don't need setup option any more + s_rankings.setup.generic.flags |= QMF_HIDDEN | QMF_INACTIVE; + + Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.frame ); + Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.login ); + Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.logout ); + Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.create ); + Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.spectate ); + Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.setup ); + Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.leave ); +} + + +/* +=============== +Rankings_Cache +=============== +*/ +void Rankings_Cache( void ) { + trap_R_RegisterShaderNoMip( RANKINGS_FRAME ); +} + + +/* +=============== +UI_RankingsMenu +=============== +*/ +void UI_RankingsMenu( void ) { + Rankings_MenuInit(); + UI_PushMenu ( &s_rankings.menu ); +} + + diff --git a/code/q3_ui/ui_rankstatus.c b/code/q3_ui/ui_rankstatus.c index 3563364..fc080f5 100755 --- a/code/q3_ui/ui_rankstatus.c +++ b/code/q3_ui/ui_rankstatus.c @@ -1,209 +1,209 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -// -// ui_rankstatus.c -// - -#include "ui_local.h" - - -#define RANKSTATUS_FRAME "menu/art/cut_frame" - -#define ID_MESSAGE 100 -#define ID_OK 101 - - -typedef struct -{ - menuframework_s menu; - menubitmap_s frame; - menutext_s message; - menutext_s ok; -} rankstatus_t; - -static rankstatus_t s_rankstatus; - -static menuframework_s s_rankstatus_menu; -static menuaction_s s_rankstatus_ok; - -static grank_status_t s_status = 0; -static char* s_rankstatus_message = NULL; - -static vec4_t s_rankingstatus_color_prompt = {1.00, 0.43, 0.00, 1.00}; - -/* -=============== -RankStatus_MenuEvent -=============== -*/ -static void RankStatus_MenuEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_OK: - UI_PopMenu(); - - switch( s_status ) - { - case QGR_STATUS_NO_USER: - UI_RankingsMenu(); - break; - case QGR_STATUS_BAD_PASSWORD: - UI_RankingsMenu(); - UI_LoginMenu(); - break; - case QGR_STATUS_USER_EXISTS: - UI_RankingsMenu(); - UI_SignupMenu(); - break; - case QGR_STATUS_NO_MEMBERSHIP: - UI_RankingsMenu(); - break; - case QGR_STATUS_TIMEOUT: - UI_RankingsMenu(); - break; - case QGR_STATUS_INVALIDUSER: - UI_RankingsMenu(); - break; - case QGR_STATUS_ERROR: - UI_RankingsMenu(); - break; - default: - break; - } - - break; - } -} - - -/* -=============== -RankStatus_MenuInit -=============== -*/ -void RankStatus_MenuInit( void ) { - int y; - - memset( &s_rankstatus, 0, sizeof(s_rankstatus) ); - - RankStatus_Cache(); - - s_rankstatus.menu.wrapAround = qtrue; - s_rankstatus.menu.fullscreen = qfalse; - - s_rankstatus.frame.generic.type = MTYPE_BITMAP; - s_rankstatus.frame.generic.flags = QMF_INACTIVE; - s_rankstatus.frame.generic.name = RANKSTATUS_FRAME; - s_rankstatus.frame.generic.x = 142; //320-233; - s_rankstatus.frame.generic.y = 118; //240-166; - s_rankstatus.frame.width = 359; //466; - s_rankstatus.frame.height = 256; //332; - - y = 214; - - s_rankstatus.message.generic.type = MTYPE_PTEXT; - s_rankstatus.message.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE; - s_rankstatus.message.generic.id = ID_MESSAGE; - s_rankstatus.message.generic.x = 320; - s_rankstatus.message.generic.y = y; - s_rankstatus.message.string = s_rankstatus_message; - s_rankstatus.message.style = UI_CENTER|UI_SMALLFONT; - s_rankstatus.message.color = s_rankingstatus_color_prompt; - y += 40; - - s_rankstatus.ok.generic.type = MTYPE_PTEXT; - s_rankstatus.ok.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_rankstatus.ok.generic.id = ID_OK; - s_rankstatus.ok.generic.callback = RankStatus_MenuEvent; - s_rankstatus.ok.generic.x = 320; - s_rankstatus.ok.generic.y = y; - s_rankstatus.ok.string = "OK"; - s_rankstatus.ok.style = UI_CENTER|UI_SMALLFONT; - s_rankstatus.ok.color = colorRed; - - Menu_AddItem( &s_rankstatus.menu, (void*) &s_rankstatus.frame ); - Menu_AddItem( &s_rankstatus.menu, (void*) &s_rankstatus.message ); - Menu_AddItem( &s_rankstatus.menu, (void*) &s_rankstatus.ok ); -} - - -/* -=============== -RankStatus_Cache -=============== -*/ -void RankStatus_Cache( void ) { - trap_R_RegisterShaderNoMip( RANKSTATUS_FRAME ); -} - - -/* -=============== -UI_RankStatusMenu -=============== -*/ -void UI_RankStatusMenu( void ) { - - s_status = (grank_status_t)trap_Cvar_VariableValue("client_status"); - - switch( s_status ) - { - case QGR_STATUS_NEW: - return; - case QGR_STATUS_PENDING: - // GRANK_FIXME - return; - case QGR_STATUS_NO_USER: - // GRANK_FIXME - get this when user exists - s_rankstatus_message = "Username unavailable"; - break; - case QGR_STATUS_BAD_PASSWORD: - s_rankstatus_message = "Invalid password"; - break; - case QGR_STATUS_TIMEOUT: - s_rankstatus_message = "Timed out"; - break; - case QGR_STATUS_NO_MEMBERSHIP: - s_rankstatus_message = "No membership"; - break; - case QGR_STATUS_INVALIDUSER: - s_rankstatus_message = "Validation failed"; - break; - case QGR_STATUS_ERROR: - s_rankstatus_message = "Error"; - break; - case QGR_STATUS_SPECTATOR: - case QGR_STATUS_ACTIVE: - UI_ForceMenuOff(); - return; - default: - return; - } - RankStatus_MenuInit(); - trap_CL_UI_RankUserReset(); - UI_PushMenu ( &s_rankstatus.menu ); -} - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +// +// ui_rankstatus.c +// + +#include "ui_local.h" + + +#define RANKSTATUS_FRAME "menu/art/cut_frame" + +#define ID_MESSAGE 100 +#define ID_OK 101 + + +typedef struct +{ + menuframework_s menu; + menubitmap_s frame; + menutext_s message; + menutext_s ok; +} rankstatus_t; + +static rankstatus_t s_rankstatus; + +static menuframework_s s_rankstatus_menu; +static menuaction_s s_rankstatus_ok; + +static grank_status_t s_status = 0; +static char* s_rankstatus_message = NULL; + +static vec4_t s_rankingstatus_color_prompt = {1.00, 0.43, 0.00, 1.00}; + +/* +=============== +RankStatus_MenuEvent +=============== +*/ +static void RankStatus_MenuEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_OK: + UI_PopMenu(); + + switch( s_status ) + { + case QGR_STATUS_NO_USER: + UI_RankingsMenu(); + break; + case QGR_STATUS_BAD_PASSWORD: + UI_RankingsMenu(); + UI_LoginMenu(); + break; + case QGR_STATUS_USER_EXISTS: + UI_RankingsMenu(); + UI_SignupMenu(); + break; + case QGR_STATUS_NO_MEMBERSHIP: + UI_RankingsMenu(); + break; + case QGR_STATUS_TIMEOUT: + UI_RankingsMenu(); + break; + case QGR_STATUS_INVALIDUSER: + UI_RankingsMenu(); + break; + case QGR_STATUS_ERROR: + UI_RankingsMenu(); + break; + default: + break; + } + + break; + } +} + + +/* +=============== +RankStatus_MenuInit +=============== +*/ +void RankStatus_MenuInit( void ) { + int y; + + memset( &s_rankstatus, 0, sizeof(s_rankstatus) ); + + RankStatus_Cache(); + + s_rankstatus.menu.wrapAround = qtrue; + s_rankstatus.menu.fullscreen = qfalse; + + s_rankstatus.frame.generic.type = MTYPE_BITMAP; + s_rankstatus.frame.generic.flags = QMF_INACTIVE; + s_rankstatus.frame.generic.name = RANKSTATUS_FRAME; + s_rankstatus.frame.generic.x = 142; //320-233; + s_rankstatus.frame.generic.y = 118; //240-166; + s_rankstatus.frame.width = 359; //466; + s_rankstatus.frame.height = 256; //332; + + y = 214; + + s_rankstatus.message.generic.type = MTYPE_PTEXT; + s_rankstatus.message.generic.flags = QMF_CENTER_JUSTIFY|QMF_INACTIVE; + s_rankstatus.message.generic.id = ID_MESSAGE; + s_rankstatus.message.generic.x = 320; + s_rankstatus.message.generic.y = y; + s_rankstatus.message.string = s_rankstatus_message; + s_rankstatus.message.style = UI_CENTER|UI_SMALLFONT; + s_rankstatus.message.color = s_rankingstatus_color_prompt; + y += 40; + + s_rankstatus.ok.generic.type = MTYPE_PTEXT; + s_rankstatus.ok.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_rankstatus.ok.generic.id = ID_OK; + s_rankstatus.ok.generic.callback = RankStatus_MenuEvent; + s_rankstatus.ok.generic.x = 320; + s_rankstatus.ok.generic.y = y; + s_rankstatus.ok.string = "OK"; + s_rankstatus.ok.style = UI_CENTER|UI_SMALLFONT; + s_rankstatus.ok.color = colorRed; + + Menu_AddItem( &s_rankstatus.menu, (void*) &s_rankstatus.frame ); + Menu_AddItem( &s_rankstatus.menu, (void*) &s_rankstatus.message ); + Menu_AddItem( &s_rankstatus.menu, (void*) &s_rankstatus.ok ); +} + + +/* +=============== +RankStatus_Cache +=============== +*/ +void RankStatus_Cache( void ) { + trap_R_RegisterShaderNoMip( RANKSTATUS_FRAME ); +} + + +/* +=============== +UI_RankStatusMenu +=============== +*/ +void UI_RankStatusMenu( void ) { + + s_status = (grank_status_t)trap_Cvar_VariableValue("client_status"); + + switch( s_status ) + { + case QGR_STATUS_NEW: + return; + case QGR_STATUS_PENDING: + // GRANK_FIXME + return; + case QGR_STATUS_NO_USER: + // GRANK_FIXME - get this when user exists + s_rankstatus_message = "Username unavailable"; + break; + case QGR_STATUS_BAD_PASSWORD: + s_rankstatus_message = "Invalid password"; + break; + case QGR_STATUS_TIMEOUT: + s_rankstatus_message = "Timed out"; + break; + case QGR_STATUS_NO_MEMBERSHIP: + s_rankstatus_message = "No membership"; + break; + case QGR_STATUS_INVALIDUSER: + s_rankstatus_message = "Validation failed"; + break; + case QGR_STATUS_ERROR: + s_rankstatus_message = "Error"; + break; + case QGR_STATUS_SPECTATOR: + case QGR_STATUS_ACTIVE: + UI_ForceMenuOff(); + return; + default: + return; + } + RankStatus_MenuInit(); + trap_CL_UI_RankUserReset(); + UI_PushMenu ( &s_rankstatus.menu ); +} + diff --git a/code/q3_ui/ui_removebots.c b/code/q3_ui/ui_removebots.c index 8d13fdc..0b159fc 100755 --- a/code/q3_ui/ui_removebots.c +++ b/code/q3_ui/ui_removebots.c @@ -1,342 +1,342 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -REMOVE BOTS MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ART_BACKGROUND "menu/art/addbotframe" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_DELETE0 "menu/art/delete_0" -#define ART_DELETE1 "menu/art/delete_1" -#define ART_ARROWS "menu/art/arrows_vert_0" -#define ART_ARROWUP "menu/art/arrows_vert_top" -#define ART_ARROWDOWN "menu/art/arrows_vert_bot" - -#define ID_UP 10 -#define ID_DOWN 11 -#define ID_DELETE 12 -#define ID_BACK 13 -#define ID_BOTNAME0 20 -#define ID_BOTNAME1 21 -#define ID_BOTNAME2 22 -#define ID_BOTNAME3 23 -#define ID_BOTNAME4 24 -#define ID_BOTNAME5 25 -#define ID_BOTNAME6 26 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s background; - - menubitmap_s arrows; - menubitmap_s up; - menubitmap_s down; - - menutext_s bots[7]; - - menubitmap_s delete; - menubitmap_s back; - - int numBots; - int baseBotNum; - int selectedBotNum; - char botnames[7][32]; - int botClientNums[MAX_BOTS]; -} removeBotsMenuInfo_t; - -static removeBotsMenuInfo_t removeBotsMenuInfo; - - -/* -================= -UI_RemoveBotsMenu_SetBotNames -================= -*/ -static void UI_RemoveBotsMenu_SetBotNames( void ) { - int n; - char info[MAX_INFO_STRING]; - - for ( n = 0; (n < 7) && (removeBotsMenuInfo.baseBotNum + n < removeBotsMenuInfo.numBots); n++ ) { - trap_GetConfigString( CS_PLAYERS + removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.baseBotNum + n], info, MAX_INFO_STRING ); - Q_strncpyz( removeBotsMenuInfo.botnames[n], Info_ValueForKey( info, "n" ), sizeof(removeBotsMenuInfo.botnames[n]) ); - Q_CleanStr( removeBotsMenuInfo.botnames[n] ); - } - -} - - -/* -================= -UI_RemoveBotsMenu_DeleteEvent -================= -*/ -static void UI_RemoveBotsMenu_DeleteEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - - trap_Cmd_ExecuteText( EXEC_APPEND, va("clientkick %i\n", removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.baseBotNum + removeBotsMenuInfo.selectedBotNum]) ); -} - - -/* -================= -UI_RemoveBotsMenu_BotEvent -================= -*/ -static void UI_RemoveBotsMenu_BotEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - - removeBotsMenuInfo.bots[removeBotsMenuInfo.selectedBotNum].color = color_orange; - removeBotsMenuInfo.selectedBotNum = ((menucommon_s*)ptr)->id - ID_BOTNAME0; - removeBotsMenuInfo.bots[removeBotsMenuInfo.selectedBotNum].color = color_white; -} - - -/* -================= -UI_RemoveAddBotsMenu_BackEvent -================= -*/ -static void UI_RemoveBotsMenu_BackEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - UI_PopMenu(); -} - - -/* -================= -UI_RemoveBotsMenu_UpEvent -================= -*/ -static void UI_RemoveBotsMenu_UpEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - - if( removeBotsMenuInfo.baseBotNum > 0 ) { - removeBotsMenuInfo.baseBotNum--; - UI_RemoveBotsMenu_SetBotNames(); - } -} - - -/* -================= -UI_RemoveBotsMenu_DownEvent -================= -*/ -static void UI_RemoveBotsMenu_DownEvent( void* ptr, int event ) { - if (event != QM_ACTIVATED) { - return; - } - - if( removeBotsMenuInfo.baseBotNum + 7 < removeBotsMenuInfo.numBots ) { - removeBotsMenuInfo.baseBotNum++; - UI_RemoveBotsMenu_SetBotNames(); - } -} - - -/* -================= -UI_RemoveBotsMenu_GetBots -================= -*/ -static void UI_RemoveBotsMenu_GetBots( void ) { - int numPlayers; - int isBot; - int n; - char info[MAX_INFO_STRING]; - - trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); - numPlayers = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); - removeBotsMenuInfo.numBots = 0; - - for( n = 0; n < numPlayers; n++ ) { - trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); - - isBot = atoi( Info_ValueForKey( info, "skill" ) ); - if( !isBot ) { - continue; - } - - removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.numBots] = n; - removeBotsMenuInfo.numBots++; - } -} - - -/* -================= -UI_RemoveBots_Cache -================= -*/ -void UI_RemoveBots_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACKGROUND ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_DELETE0 ); - trap_R_RegisterShaderNoMip( ART_DELETE1 ); -} - - -/* -================= -UI_RemoveBotsMenu_Init -================= -*/ -static void UI_RemoveBotsMenu_Init( void ) { - int n; - int count; - int y; - - memset( &removeBotsMenuInfo, 0 ,sizeof(removeBotsMenuInfo) ); - removeBotsMenuInfo.menu.fullscreen = qfalse; - removeBotsMenuInfo.menu.wrapAround = qtrue; - - UI_RemoveBots_Cache(); - - UI_RemoveBotsMenu_GetBots(); - UI_RemoveBotsMenu_SetBotNames(); - count = removeBotsMenuInfo.numBots < 7 ? removeBotsMenuInfo.numBots : 7; - - removeBotsMenuInfo.banner.generic.type = MTYPE_BTEXT; - removeBotsMenuInfo.banner.generic.x = 320; - removeBotsMenuInfo.banner.generic.y = 16; - removeBotsMenuInfo.banner.string = "REMOVE BOTS"; - removeBotsMenuInfo.banner.color = color_white; - removeBotsMenuInfo.banner.style = UI_CENTER; - - removeBotsMenuInfo.background.generic.type = MTYPE_BITMAP; - removeBotsMenuInfo.background.generic.name = ART_BACKGROUND; - removeBotsMenuInfo.background.generic.flags = QMF_INACTIVE; - removeBotsMenuInfo.background.generic.x = 320-233; - removeBotsMenuInfo.background.generic.y = 240-166; - removeBotsMenuInfo.background.width = 466; - removeBotsMenuInfo.background.height = 332; - - removeBotsMenuInfo.arrows.generic.type = MTYPE_BITMAP; - removeBotsMenuInfo.arrows.generic.name = ART_ARROWS; - removeBotsMenuInfo.arrows.generic.flags = QMF_INACTIVE; - removeBotsMenuInfo.arrows.generic.x = 200; - removeBotsMenuInfo.arrows.generic.y = 128; - removeBotsMenuInfo.arrows.width = 64; - removeBotsMenuInfo.arrows.height = 128; - - removeBotsMenuInfo.up.generic.type = MTYPE_BITMAP; - removeBotsMenuInfo.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - removeBotsMenuInfo.up.generic.x = 200; - removeBotsMenuInfo.up.generic.y = 128; - removeBotsMenuInfo.up.generic.id = ID_UP; - removeBotsMenuInfo.up.generic.callback = UI_RemoveBotsMenu_UpEvent; - removeBotsMenuInfo.up.width = 64; - removeBotsMenuInfo.up.height = 64; - removeBotsMenuInfo.up.focuspic = ART_ARROWUP; - - removeBotsMenuInfo.down.generic.type = MTYPE_BITMAP; - removeBotsMenuInfo.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - removeBotsMenuInfo.down.generic.x = 200; - removeBotsMenuInfo.down.generic.y = 128+64; - removeBotsMenuInfo.down.generic.id = ID_DOWN; - removeBotsMenuInfo.down.generic.callback = UI_RemoveBotsMenu_DownEvent; - removeBotsMenuInfo.down.width = 64; - removeBotsMenuInfo.down.height = 64; - removeBotsMenuInfo.down.focuspic = ART_ARROWDOWN; - - for( n = 0, y = 120; n < count; n++, y += 20 ) { - removeBotsMenuInfo.bots[n].generic.type = MTYPE_PTEXT; - removeBotsMenuInfo.bots[n].generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - removeBotsMenuInfo.bots[n].generic.id = ID_BOTNAME0 + n; - removeBotsMenuInfo.bots[n].generic.x = 320 - 56; - removeBotsMenuInfo.bots[n].generic.y = y; - removeBotsMenuInfo.bots[n].generic.callback = UI_RemoveBotsMenu_BotEvent; - removeBotsMenuInfo.bots[n].string = removeBotsMenuInfo.botnames[n]; - removeBotsMenuInfo.bots[n].color = color_orange; - removeBotsMenuInfo.bots[n].style = UI_LEFT|UI_SMALLFONT; - } - - removeBotsMenuInfo.delete.generic.type = MTYPE_BITMAP; - removeBotsMenuInfo.delete.generic.name = ART_DELETE0; - removeBotsMenuInfo.delete.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - removeBotsMenuInfo.delete.generic.id = ID_DELETE; - removeBotsMenuInfo.delete.generic.callback = UI_RemoveBotsMenu_DeleteEvent; - removeBotsMenuInfo.delete.generic.x = 320+128-128; - removeBotsMenuInfo.delete.generic.y = 256+128-64; - removeBotsMenuInfo.delete.width = 128; - removeBotsMenuInfo.delete.height = 64; - removeBotsMenuInfo.delete.focuspic = ART_DELETE1; - - removeBotsMenuInfo.back.generic.type = MTYPE_BITMAP; - removeBotsMenuInfo.back.generic.name = ART_BACK0; - removeBotsMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - removeBotsMenuInfo.back.generic.id = ID_BACK; - removeBotsMenuInfo.back.generic.callback = UI_RemoveBotsMenu_BackEvent; - removeBotsMenuInfo.back.generic.x = 320-128; - removeBotsMenuInfo.back.generic.y = 256+128-64; - removeBotsMenuInfo.back.width = 128; - removeBotsMenuInfo.back.height = 64; - removeBotsMenuInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.background ); - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.banner ); - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.arrows ); - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.up ); - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.down ); - for( n = 0; n < count; n++ ) { - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.bots[n] ); - } - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.delete ); - Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.back ); - - removeBotsMenuInfo.baseBotNum = 0; - removeBotsMenuInfo.selectedBotNum = 0; - removeBotsMenuInfo.bots[0].color = color_white; -} - - -/* -================= -UI_RemoveBotsMenu -================= -*/ -void UI_RemoveBotsMenu( void ) { - UI_RemoveBotsMenu_Init(); - UI_PushMenu( &removeBotsMenuInfo.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +REMOVE BOTS MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ART_BACKGROUND "menu/art/addbotframe" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_DELETE0 "menu/art/delete_0" +#define ART_DELETE1 "menu/art/delete_1" +#define ART_ARROWS "menu/art/arrows_vert_0" +#define ART_ARROWUP "menu/art/arrows_vert_top" +#define ART_ARROWDOWN "menu/art/arrows_vert_bot" + +#define ID_UP 10 +#define ID_DOWN 11 +#define ID_DELETE 12 +#define ID_BACK 13 +#define ID_BOTNAME0 20 +#define ID_BOTNAME1 21 +#define ID_BOTNAME2 22 +#define ID_BOTNAME3 23 +#define ID_BOTNAME4 24 +#define ID_BOTNAME5 25 +#define ID_BOTNAME6 26 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s background; + + menubitmap_s arrows; + menubitmap_s up; + menubitmap_s down; + + menutext_s bots[7]; + + menubitmap_s delete; + menubitmap_s back; + + int numBots; + int baseBotNum; + int selectedBotNum; + char botnames[7][32]; + int botClientNums[MAX_BOTS]; +} removeBotsMenuInfo_t; + +static removeBotsMenuInfo_t removeBotsMenuInfo; + + +/* +================= +UI_RemoveBotsMenu_SetBotNames +================= +*/ +static void UI_RemoveBotsMenu_SetBotNames( void ) { + int n; + char info[MAX_INFO_STRING]; + + for ( n = 0; (n < 7) && (removeBotsMenuInfo.baseBotNum + n < removeBotsMenuInfo.numBots); n++ ) { + trap_GetConfigString( CS_PLAYERS + removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.baseBotNum + n], info, MAX_INFO_STRING ); + Q_strncpyz( removeBotsMenuInfo.botnames[n], Info_ValueForKey( info, "n" ), sizeof(removeBotsMenuInfo.botnames[n]) ); + Q_CleanStr( removeBotsMenuInfo.botnames[n] ); + } + +} + + +/* +================= +UI_RemoveBotsMenu_DeleteEvent +================= +*/ +static void UI_RemoveBotsMenu_DeleteEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + + trap_Cmd_ExecuteText( EXEC_APPEND, va("clientkick %i\n", removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.baseBotNum + removeBotsMenuInfo.selectedBotNum]) ); +} + + +/* +================= +UI_RemoveBotsMenu_BotEvent +================= +*/ +static void UI_RemoveBotsMenu_BotEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + + removeBotsMenuInfo.bots[removeBotsMenuInfo.selectedBotNum].color = color_orange; + removeBotsMenuInfo.selectedBotNum = ((menucommon_s*)ptr)->id - ID_BOTNAME0; + removeBotsMenuInfo.bots[removeBotsMenuInfo.selectedBotNum].color = color_white; +} + + +/* +================= +UI_RemoveAddBotsMenu_BackEvent +================= +*/ +static void UI_RemoveBotsMenu_BackEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + UI_PopMenu(); +} + + +/* +================= +UI_RemoveBotsMenu_UpEvent +================= +*/ +static void UI_RemoveBotsMenu_UpEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + + if( removeBotsMenuInfo.baseBotNum > 0 ) { + removeBotsMenuInfo.baseBotNum--; + UI_RemoveBotsMenu_SetBotNames(); + } +} + + +/* +================= +UI_RemoveBotsMenu_DownEvent +================= +*/ +static void UI_RemoveBotsMenu_DownEvent( void* ptr, int event ) { + if (event != QM_ACTIVATED) { + return; + } + + if( removeBotsMenuInfo.baseBotNum + 7 < removeBotsMenuInfo.numBots ) { + removeBotsMenuInfo.baseBotNum++; + UI_RemoveBotsMenu_SetBotNames(); + } +} + + +/* +================= +UI_RemoveBotsMenu_GetBots +================= +*/ +static void UI_RemoveBotsMenu_GetBots( void ) { + int numPlayers; + int isBot; + int n; + char info[MAX_INFO_STRING]; + + trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); + numPlayers = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); + removeBotsMenuInfo.numBots = 0; + + for( n = 0; n < numPlayers; n++ ) { + trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); + + isBot = atoi( Info_ValueForKey( info, "skill" ) ); + if( !isBot ) { + continue; + } + + removeBotsMenuInfo.botClientNums[removeBotsMenuInfo.numBots] = n; + removeBotsMenuInfo.numBots++; + } +} + + +/* +================= +UI_RemoveBots_Cache +================= +*/ +void UI_RemoveBots_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACKGROUND ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_DELETE0 ); + trap_R_RegisterShaderNoMip( ART_DELETE1 ); +} + + +/* +================= +UI_RemoveBotsMenu_Init +================= +*/ +static void UI_RemoveBotsMenu_Init( void ) { + int n; + int count; + int y; + + memset( &removeBotsMenuInfo, 0 ,sizeof(removeBotsMenuInfo) ); + removeBotsMenuInfo.menu.fullscreen = qfalse; + removeBotsMenuInfo.menu.wrapAround = qtrue; + + UI_RemoveBots_Cache(); + + UI_RemoveBotsMenu_GetBots(); + UI_RemoveBotsMenu_SetBotNames(); + count = removeBotsMenuInfo.numBots < 7 ? removeBotsMenuInfo.numBots : 7; + + removeBotsMenuInfo.banner.generic.type = MTYPE_BTEXT; + removeBotsMenuInfo.banner.generic.x = 320; + removeBotsMenuInfo.banner.generic.y = 16; + removeBotsMenuInfo.banner.string = "REMOVE BOTS"; + removeBotsMenuInfo.banner.color = color_white; + removeBotsMenuInfo.banner.style = UI_CENTER; + + removeBotsMenuInfo.background.generic.type = MTYPE_BITMAP; + removeBotsMenuInfo.background.generic.name = ART_BACKGROUND; + removeBotsMenuInfo.background.generic.flags = QMF_INACTIVE; + removeBotsMenuInfo.background.generic.x = 320-233; + removeBotsMenuInfo.background.generic.y = 240-166; + removeBotsMenuInfo.background.width = 466; + removeBotsMenuInfo.background.height = 332; + + removeBotsMenuInfo.arrows.generic.type = MTYPE_BITMAP; + removeBotsMenuInfo.arrows.generic.name = ART_ARROWS; + removeBotsMenuInfo.arrows.generic.flags = QMF_INACTIVE; + removeBotsMenuInfo.arrows.generic.x = 200; + removeBotsMenuInfo.arrows.generic.y = 128; + removeBotsMenuInfo.arrows.width = 64; + removeBotsMenuInfo.arrows.height = 128; + + removeBotsMenuInfo.up.generic.type = MTYPE_BITMAP; + removeBotsMenuInfo.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + removeBotsMenuInfo.up.generic.x = 200; + removeBotsMenuInfo.up.generic.y = 128; + removeBotsMenuInfo.up.generic.id = ID_UP; + removeBotsMenuInfo.up.generic.callback = UI_RemoveBotsMenu_UpEvent; + removeBotsMenuInfo.up.width = 64; + removeBotsMenuInfo.up.height = 64; + removeBotsMenuInfo.up.focuspic = ART_ARROWUP; + + removeBotsMenuInfo.down.generic.type = MTYPE_BITMAP; + removeBotsMenuInfo.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + removeBotsMenuInfo.down.generic.x = 200; + removeBotsMenuInfo.down.generic.y = 128+64; + removeBotsMenuInfo.down.generic.id = ID_DOWN; + removeBotsMenuInfo.down.generic.callback = UI_RemoveBotsMenu_DownEvent; + removeBotsMenuInfo.down.width = 64; + removeBotsMenuInfo.down.height = 64; + removeBotsMenuInfo.down.focuspic = ART_ARROWDOWN; + + for( n = 0, y = 120; n < count; n++, y += 20 ) { + removeBotsMenuInfo.bots[n].generic.type = MTYPE_PTEXT; + removeBotsMenuInfo.bots[n].generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + removeBotsMenuInfo.bots[n].generic.id = ID_BOTNAME0 + n; + removeBotsMenuInfo.bots[n].generic.x = 320 - 56; + removeBotsMenuInfo.bots[n].generic.y = y; + removeBotsMenuInfo.bots[n].generic.callback = UI_RemoveBotsMenu_BotEvent; + removeBotsMenuInfo.bots[n].string = removeBotsMenuInfo.botnames[n]; + removeBotsMenuInfo.bots[n].color = color_orange; + removeBotsMenuInfo.bots[n].style = UI_LEFT|UI_SMALLFONT; + } + + removeBotsMenuInfo.delete.generic.type = MTYPE_BITMAP; + removeBotsMenuInfo.delete.generic.name = ART_DELETE0; + removeBotsMenuInfo.delete.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + removeBotsMenuInfo.delete.generic.id = ID_DELETE; + removeBotsMenuInfo.delete.generic.callback = UI_RemoveBotsMenu_DeleteEvent; + removeBotsMenuInfo.delete.generic.x = 320+128-128; + removeBotsMenuInfo.delete.generic.y = 256+128-64; + removeBotsMenuInfo.delete.width = 128; + removeBotsMenuInfo.delete.height = 64; + removeBotsMenuInfo.delete.focuspic = ART_DELETE1; + + removeBotsMenuInfo.back.generic.type = MTYPE_BITMAP; + removeBotsMenuInfo.back.generic.name = ART_BACK0; + removeBotsMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + removeBotsMenuInfo.back.generic.id = ID_BACK; + removeBotsMenuInfo.back.generic.callback = UI_RemoveBotsMenu_BackEvent; + removeBotsMenuInfo.back.generic.x = 320-128; + removeBotsMenuInfo.back.generic.y = 256+128-64; + removeBotsMenuInfo.back.width = 128; + removeBotsMenuInfo.back.height = 64; + removeBotsMenuInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.background ); + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.banner ); + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.arrows ); + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.up ); + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.down ); + for( n = 0; n < count; n++ ) { + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.bots[n] ); + } + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.delete ); + Menu_AddItem( &removeBotsMenuInfo.menu, &removeBotsMenuInfo.back ); + + removeBotsMenuInfo.baseBotNum = 0; + removeBotsMenuInfo.selectedBotNum = 0; + removeBotsMenuInfo.bots[0].color = color_white; +} + + +/* +================= +UI_RemoveBotsMenu +================= +*/ +void UI_RemoveBotsMenu( void ) { + UI_RemoveBotsMenu_Init(); + UI_PushMenu( &removeBotsMenuInfo.menu ); +} diff --git a/code/q3_ui/ui_saveconfig.c b/code/q3_ui/ui_saveconfig.c index d13b676..4ac7d46 100755 --- a/code/q3_ui/ui_saveconfig.c +++ b/code/q3_ui/ui_saveconfig.c @@ -1,212 +1,212 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -============================================================================= - -SAVE CONFIG MENU - -============================================================================= -*/ - -#include "ui_local.h" - - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_SAVE0 "menu/art/save_0" -#define ART_SAVE1 "menu/art/save_1" -#define ART_BACKGROUND "menu/art/cut_frame" - -#define ID_NAME 10 -#define ID_BACK 11 -#define ID_SAVE 12 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s background; - menufield_s savename; - menubitmap_s back; - menubitmap_s save; -} saveConfig_t; - -static saveConfig_t saveConfig; - - -/* -=============== -UI_SaveConfigMenu_BackEvent -=============== -*/ -static void UI_SaveConfigMenu_BackEvent( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - UI_PopMenu(); -} - - -/* -=============== -UI_SaveConfigMenu_SaveEvent -=============== -*/ -static void UI_SaveConfigMenu_SaveEvent( void *ptr, int event ) { - char configname[MAX_QPATH]; - - if( event != QM_ACTIVATED ) { - return; - } - - if( !saveConfig.savename.field.buffer[0] ) { - return; - } - - COM_StripExtension(saveConfig.savename.field.buffer, configname ); - trap_Cmd_ExecuteText( EXEC_APPEND, va( "writeconfig %s.cfg\n", configname ) ); - UI_PopMenu(); -} - - -/* -=============== -UI_SaveConfigMenu_SavenameDraw -=============== -*/ -static void UI_SaveConfigMenu_SavenameDraw( void *self ) { - menufield_s *f; - int style; - float *color; - - f = (menufield_s *)self; - - if( f == Menu_ItemAtCursor( &saveConfig.menu ) ) { - style = UI_LEFT|UI_PULSE|UI_SMALLFONT; - color = text_color_highlight; - } - else { - style = UI_LEFT|UI_SMALLFONT; - color = colorRed; - } - - UI_DrawProportionalString( 320, 192, "Enter filename:", UI_CENTER|UI_SMALLFONT, color_orange ); - UI_FillRect( f->generic.x, f->generic.y, f->field.widthInChars*SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, colorBlack ); - MField_Draw( &f->field, f->generic.x, f->generic.y, style, color ); -} - - -/* -================= -UI_SaveConfigMenu_Init -================= -*/ -static void UI_SaveConfigMenu_Init( void ) { - memset( &saveConfig, 0, sizeof(saveConfig) ); - - UI_SaveConfigMenu_Cache(); - saveConfig.menu.wrapAround = qtrue; - saveConfig.menu.fullscreen = qtrue; - - saveConfig.banner.generic.type = MTYPE_BTEXT; - saveConfig.banner.generic.x = 320; - saveConfig.banner.generic.y = 16; - saveConfig.banner.string = "SAVE CONFIG"; - saveConfig.banner.color = color_white; - saveConfig.banner.style = UI_CENTER; - - saveConfig.background.generic.type = MTYPE_BITMAP; - saveConfig.background.generic.name = ART_BACKGROUND; - saveConfig.background.generic.flags = QMF_INACTIVE; - saveConfig.background.generic.x = 142; - saveConfig.background.generic.y = 118; - saveConfig.background.width = 359; - saveConfig.background.height = 256; - - saveConfig.savename.generic.type = MTYPE_FIELD; - saveConfig.savename.generic.flags = QMF_NODEFAULTINIT|QMF_UPPERCASE; - saveConfig.savename.generic.ownerdraw = UI_SaveConfigMenu_SavenameDraw; - saveConfig.savename.field.widthInChars = 20; - saveConfig.savename.field.maxchars = 20; - saveConfig.savename.generic.x = 240; - saveConfig.savename.generic.y = 155+72; - saveConfig.savename.generic.left = 240; - saveConfig.savename.generic.top = 155+72; - saveConfig.savename.generic.right = 233 + 20*SMALLCHAR_WIDTH; - saveConfig.savename.generic.bottom = 155+72 + SMALLCHAR_HEIGHT+2; - - saveConfig.back.generic.type = MTYPE_BITMAP; - saveConfig.back.generic.name = ART_BACK0; - saveConfig.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - saveConfig.back.generic.id = ID_BACK; - saveConfig.back.generic.callback = UI_SaveConfigMenu_BackEvent; - saveConfig.back.generic.x = 0; - saveConfig.back.generic.y = 480-64; - saveConfig.back.width = 128; - saveConfig.back.height = 64; - saveConfig.back.focuspic = ART_BACK1; - - saveConfig.save.generic.type = MTYPE_BITMAP; - saveConfig.save.generic.name = ART_SAVE0; - saveConfig.save.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - saveConfig.save.generic.id = ID_SAVE; - saveConfig.save.generic.callback = UI_SaveConfigMenu_SaveEvent; - saveConfig.save.generic.x = 640; - saveConfig.save.generic.y = 480-64; - saveConfig.save.width = 128; - saveConfig.save.height = 64; - saveConfig.save.focuspic = ART_SAVE1; - - Menu_AddItem( &saveConfig.menu, &saveConfig.banner ); - Menu_AddItem( &saveConfig.menu, &saveConfig.background ); - Menu_AddItem( &saveConfig.menu, &saveConfig.savename ); - Menu_AddItem( &saveConfig.menu, &saveConfig.back ); - Menu_AddItem( &saveConfig.menu, &saveConfig.save ); -} - - -/* -================= -UI_SaveConfigMenu_Cache -================= -*/ -void UI_SaveConfigMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_SAVE0 ); - trap_R_RegisterShaderNoMip( ART_SAVE1 ); - trap_R_RegisterShaderNoMip( ART_BACKGROUND ); -} - - -/* -=============== -UI_SaveConfigMenu -=============== -*/ -void UI_SaveConfigMenu( void ) { - UI_SaveConfigMenu_Init(); - UI_PushMenu( &saveConfig.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +============================================================================= + +SAVE CONFIG MENU + +============================================================================= +*/ + +#include "ui_local.h" + + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_SAVE0 "menu/art/save_0" +#define ART_SAVE1 "menu/art/save_1" +#define ART_BACKGROUND "menu/art/cut_frame" + +#define ID_NAME 10 +#define ID_BACK 11 +#define ID_SAVE 12 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s background; + menufield_s savename; + menubitmap_s back; + menubitmap_s save; +} saveConfig_t; + +static saveConfig_t saveConfig; + + +/* +=============== +UI_SaveConfigMenu_BackEvent +=============== +*/ +static void UI_SaveConfigMenu_BackEvent( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + UI_PopMenu(); +} + + +/* +=============== +UI_SaveConfigMenu_SaveEvent +=============== +*/ +static void UI_SaveConfigMenu_SaveEvent( void *ptr, int event ) { + char configname[MAX_QPATH]; + + if( event != QM_ACTIVATED ) { + return; + } + + if( !saveConfig.savename.field.buffer[0] ) { + return; + } + + COM_StripExtension(saveConfig.savename.field.buffer, configname ); + trap_Cmd_ExecuteText( EXEC_APPEND, va( "writeconfig %s.cfg\n", configname ) ); + UI_PopMenu(); +} + + +/* +=============== +UI_SaveConfigMenu_SavenameDraw +=============== +*/ +static void UI_SaveConfigMenu_SavenameDraw( void *self ) { + menufield_s *f; + int style; + float *color; + + f = (menufield_s *)self; + + if( f == Menu_ItemAtCursor( &saveConfig.menu ) ) { + style = UI_LEFT|UI_PULSE|UI_SMALLFONT; + color = text_color_highlight; + } + else { + style = UI_LEFT|UI_SMALLFONT; + color = colorRed; + } + + UI_DrawProportionalString( 320, 192, "Enter filename:", UI_CENTER|UI_SMALLFONT, color_orange ); + UI_FillRect( f->generic.x, f->generic.y, f->field.widthInChars*SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT, colorBlack ); + MField_Draw( &f->field, f->generic.x, f->generic.y, style, color ); +} + + +/* +================= +UI_SaveConfigMenu_Init +================= +*/ +static void UI_SaveConfigMenu_Init( void ) { + memset( &saveConfig, 0, sizeof(saveConfig) ); + + UI_SaveConfigMenu_Cache(); + saveConfig.menu.wrapAround = qtrue; + saveConfig.menu.fullscreen = qtrue; + + saveConfig.banner.generic.type = MTYPE_BTEXT; + saveConfig.banner.generic.x = 320; + saveConfig.banner.generic.y = 16; + saveConfig.banner.string = "SAVE CONFIG"; + saveConfig.banner.color = color_white; + saveConfig.banner.style = UI_CENTER; + + saveConfig.background.generic.type = MTYPE_BITMAP; + saveConfig.background.generic.name = ART_BACKGROUND; + saveConfig.background.generic.flags = QMF_INACTIVE; + saveConfig.background.generic.x = 142; + saveConfig.background.generic.y = 118; + saveConfig.background.width = 359; + saveConfig.background.height = 256; + + saveConfig.savename.generic.type = MTYPE_FIELD; + saveConfig.savename.generic.flags = QMF_NODEFAULTINIT|QMF_UPPERCASE; + saveConfig.savename.generic.ownerdraw = UI_SaveConfigMenu_SavenameDraw; + saveConfig.savename.field.widthInChars = 20; + saveConfig.savename.field.maxchars = 20; + saveConfig.savename.generic.x = 240; + saveConfig.savename.generic.y = 155+72; + saveConfig.savename.generic.left = 240; + saveConfig.savename.generic.top = 155+72; + saveConfig.savename.generic.right = 233 + 20*SMALLCHAR_WIDTH; + saveConfig.savename.generic.bottom = 155+72 + SMALLCHAR_HEIGHT+2; + + saveConfig.back.generic.type = MTYPE_BITMAP; + saveConfig.back.generic.name = ART_BACK0; + saveConfig.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + saveConfig.back.generic.id = ID_BACK; + saveConfig.back.generic.callback = UI_SaveConfigMenu_BackEvent; + saveConfig.back.generic.x = 0; + saveConfig.back.generic.y = 480-64; + saveConfig.back.width = 128; + saveConfig.back.height = 64; + saveConfig.back.focuspic = ART_BACK1; + + saveConfig.save.generic.type = MTYPE_BITMAP; + saveConfig.save.generic.name = ART_SAVE0; + saveConfig.save.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + saveConfig.save.generic.id = ID_SAVE; + saveConfig.save.generic.callback = UI_SaveConfigMenu_SaveEvent; + saveConfig.save.generic.x = 640; + saveConfig.save.generic.y = 480-64; + saveConfig.save.width = 128; + saveConfig.save.height = 64; + saveConfig.save.focuspic = ART_SAVE1; + + Menu_AddItem( &saveConfig.menu, &saveConfig.banner ); + Menu_AddItem( &saveConfig.menu, &saveConfig.background ); + Menu_AddItem( &saveConfig.menu, &saveConfig.savename ); + Menu_AddItem( &saveConfig.menu, &saveConfig.back ); + Menu_AddItem( &saveConfig.menu, &saveConfig.save ); +} + + +/* +================= +UI_SaveConfigMenu_Cache +================= +*/ +void UI_SaveConfigMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_SAVE0 ); + trap_R_RegisterShaderNoMip( ART_SAVE1 ); + trap_R_RegisterShaderNoMip( ART_BACKGROUND ); +} + + +/* +=============== +UI_SaveConfigMenu +=============== +*/ +void UI_SaveConfigMenu( void ) { + UI_SaveConfigMenu_Init(); + UI_PushMenu( &saveConfig.menu ); +} diff --git a/code/q3_ui/ui_serverinfo.c b/code/q3_ui/ui_serverinfo.c index 61f4ad8..7f36ae6 100755 --- a/code/q3_ui/ui_serverinfo.c +++ b/code/q3_ui/ui_serverinfo.c @@ -1,272 +1,272 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -#define SERVERINFO_FRAMEL "menu/art/frame2_l" -#define SERVERINFO_FRAMER "menu/art/frame1_r" -#define SERVERINFO_BACK0 "menu/art/back_0" -#define SERVERINFO_BACK1 "menu/art/back_1" - -static char* serverinfo_artlist[] = -{ - SERVERINFO_FRAMEL, - SERVERINFO_FRAMER, - SERVERINFO_BACK0, - SERVERINFO_BACK1, - NULL -}; - -#define ID_ADD 100 -#define ID_BACK 101 - -typedef struct -{ - menuframework_s menu; - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - menubitmap_s back; - menutext_s add; - char info[MAX_INFO_STRING]; - int numlines; -} serverinfo_t; - -static serverinfo_t s_serverinfo; - - -/* -================= -Favorites_Add - -Add current server to favorites -================= -*/ -void Favorites_Add( void ) -{ - char adrstr[128]; - char serverbuff[128]; - int i; - int best; - - trap_Cvar_VariableStringBuffer( "cl_currentServerAddress", serverbuff, sizeof(serverbuff) ); - if (!serverbuff[0]) - return; - - best = 0; - for (i=0; i '9' ) && !best) - best = i+1; - } - - if (best) - trap_Cvar_Set( va("server%d",best), serverbuff); -} - - -/* -================= -ServerInfo_Event -================= -*/ -static void ServerInfo_Event( void* ptr, int event ) -{ - switch (((menucommon_s*)ptr)->id) - { - case ID_ADD: - if (event != QM_ACTIVATED) - break; - - Favorites_Add(); - UI_PopMenu(); - break; - - case ID_BACK: - if (event != QM_ACTIVATED) - break; - - UI_PopMenu(); - break; - } -} - -/* -================= -ServerInfo_MenuDraw -================= -*/ -static void ServerInfo_MenuDraw( void ) -{ - const char *s; - char key[MAX_INFO_KEY]; - char value[MAX_INFO_VALUE]; - int y; - - y = SCREEN_HEIGHT/2 - s_serverinfo.numlines*(SMALLCHAR_HEIGHT)/2 - 20; - s = s_serverinfo.info; - while ( s ) { - Info_NextPair( &s, key, value ); - if ( !key[0] ) { - break; - } - - Q_strcat( key, MAX_INFO_KEY, ":" ); - - UI_DrawString(SCREEN_WIDTH*0.50 - 8,y,key,UI_RIGHT|UI_SMALLFONT,color_red); - UI_DrawString(SCREEN_WIDTH*0.50 + 8,y,value,UI_LEFT|UI_SMALLFONT,text_color_normal); - - y += SMALLCHAR_HEIGHT; - } - - Menu_Draw( &s_serverinfo.menu ); -} - -/* -================= -ServerInfo_MenuKey -================= -*/ -static sfxHandle_t ServerInfo_MenuKey( int key ) -{ - return ( Menu_DefaultKey( &s_serverinfo.menu, key ) ); -} - -/* -================= -ServerInfo_Cache -================= -*/ -void ServerInfo_Cache( void ) -{ - int i; - - // touch all our pics - for (i=0; ;i++) - { - if (!serverinfo_artlist[i]) - break; - trap_R_RegisterShaderNoMip(serverinfo_artlist[i]); - } -} - -/* -================= -UI_ServerInfoMenu -================= -*/ -void UI_ServerInfoMenu( void ) -{ - const char *s; - char key[MAX_INFO_KEY]; - char value[MAX_INFO_VALUE]; - - // zero set all our globals - memset( &s_serverinfo, 0 ,sizeof(serverinfo_t) ); - - ServerInfo_Cache(); - - s_serverinfo.menu.draw = ServerInfo_MenuDraw; - s_serverinfo.menu.key = ServerInfo_MenuKey; - s_serverinfo.menu.wrapAround = qtrue; - s_serverinfo.menu.fullscreen = qtrue; - - s_serverinfo.banner.generic.type = MTYPE_BTEXT; - s_serverinfo.banner.generic.x = 320; - s_serverinfo.banner.generic.y = 16; - s_serverinfo.banner.string = "SERVER INFO"; - s_serverinfo.banner.color = color_white; - s_serverinfo.banner.style = UI_CENTER; - - s_serverinfo.framel.generic.type = MTYPE_BITMAP; - s_serverinfo.framel.generic.name = SERVERINFO_FRAMEL; - s_serverinfo.framel.generic.flags = QMF_INACTIVE; - s_serverinfo.framel.generic.x = 0; - s_serverinfo.framel.generic.y = 78; - s_serverinfo.framel.width = 256; - s_serverinfo.framel.height = 329; - - s_serverinfo.framer.generic.type = MTYPE_BITMAP; - s_serverinfo.framer.generic.name = SERVERINFO_FRAMER; - s_serverinfo.framer.generic.flags = QMF_INACTIVE; - s_serverinfo.framer.generic.x = 376; - s_serverinfo.framer.generic.y = 76; - s_serverinfo.framer.width = 256; - s_serverinfo.framer.height = 334; - - s_serverinfo.add.generic.type = MTYPE_PTEXT; - s_serverinfo.add.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_serverinfo.add.generic.callback = ServerInfo_Event; - s_serverinfo.add.generic.id = ID_ADD; - s_serverinfo.add.generic.x = 320; - s_serverinfo.add.generic.y = 371; - s_serverinfo.add.string = "ADD TO FAVORITES"; - s_serverinfo.add.style = UI_CENTER|UI_SMALLFONT; - s_serverinfo.add.color = color_red; - if( trap_Cvar_VariableValue( "sv_running" ) ) { - s_serverinfo.add.generic.flags |= QMF_GRAYED; - } - - s_serverinfo.back.generic.type = MTYPE_BITMAP; - s_serverinfo.back.generic.name = SERVERINFO_BACK0; - s_serverinfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_serverinfo.back.generic.callback = ServerInfo_Event; - s_serverinfo.back.generic.id = ID_BACK; - s_serverinfo.back.generic.x = 0; - s_serverinfo.back.generic.y = 480-64; - s_serverinfo.back.width = 128; - s_serverinfo.back.height = 64; - s_serverinfo.back.focuspic = SERVERINFO_BACK1; - - trap_GetConfigString( CS_SERVERINFO, s_serverinfo.info, MAX_INFO_STRING ); - - s_serverinfo.numlines = 0; - s = s_serverinfo.info; - while ( s ) { - Info_NextPair( &s, key, value ); - if ( !key[0] ) { - break; - } - s_serverinfo.numlines++; - } - - if (s_serverinfo.numlines > 16) - s_serverinfo.numlines = 16; - - Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.banner ); - Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.framel ); - Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.framer ); - Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.add ); - Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.back ); - - UI_PushMenu( &s_serverinfo.menu ); -} - - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +#define SERVERINFO_FRAMEL "menu/art/frame2_l" +#define SERVERINFO_FRAMER "menu/art/frame1_r" +#define SERVERINFO_BACK0 "menu/art/back_0" +#define SERVERINFO_BACK1 "menu/art/back_1" + +static char* serverinfo_artlist[] = +{ + SERVERINFO_FRAMEL, + SERVERINFO_FRAMER, + SERVERINFO_BACK0, + SERVERINFO_BACK1, + NULL +}; + +#define ID_ADD 100 +#define ID_BACK 101 + +typedef struct +{ + menuframework_s menu; + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + menubitmap_s back; + menutext_s add; + char info[MAX_INFO_STRING]; + int numlines; +} serverinfo_t; + +static serverinfo_t s_serverinfo; + + +/* +================= +Favorites_Add + +Add current server to favorites +================= +*/ +void Favorites_Add( void ) +{ + char adrstr[128]; + char serverbuff[128]; + int i; + int best; + + trap_Cvar_VariableStringBuffer( "cl_currentServerAddress", serverbuff, sizeof(serverbuff) ); + if (!serverbuff[0]) + return; + + best = 0; + for (i=0; i '9' ) && !best) + best = i+1; + } + + if (best) + trap_Cvar_Set( va("server%d",best), serverbuff); +} + + +/* +================= +ServerInfo_Event +================= +*/ +static void ServerInfo_Event( void* ptr, int event ) +{ + switch (((menucommon_s*)ptr)->id) + { + case ID_ADD: + if (event != QM_ACTIVATED) + break; + + Favorites_Add(); + UI_PopMenu(); + break; + + case ID_BACK: + if (event != QM_ACTIVATED) + break; + + UI_PopMenu(); + break; + } +} + +/* +================= +ServerInfo_MenuDraw +================= +*/ +static void ServerInfo_MenuDraw( void ) +{ + const char *s; + char key[MAX_INFO_KEY]; + char value[MAX_INFO_VALUE]; + int y; + + y = SCREEN_HEIGHT/2 - s_serverinfo.numlines*(SMALLCHAR_HEIGHT)/2 - 20; + s = s_serverinfo.info; + while ( s ) { + Info_NextPair( &s, key, value ); + if ( !key[0] ) { + break; + } + + Q_strcat( key, MAX_INFO_KEY, ":" ); + + UI_DrawString(SCREEN_WIDTH*0.50 - 8,y,key,UI_RIGHT|UI_SMALLFONT,color_red); + UI_DrawString(SCREEN_WIDTH*0.50 + 8,y,value,UI_LEFT|UI_SMALLFONT,text_color_normal); + + y += SMALLCHAR_HEIGHT; + } + + Menu_Draw( &s_serverinfo.menu ); +} + +/* +================= +ServerInfo_MenuKey +================= +*/ +static sfxHandle_t ServerInfo_MenuKey( int key ) +{ + return ( Menu_DefaultKey( &s_serverinfo.menu, key ) ); +} + +/* +================= +ServerInfo_Cache +================= +*/ +void ServerInfo_Cache( void ) +{ + int i; + + // touch all our pics + for (i=0; ;i++) + { + if (!serverinfo_artlist[i]) + break; + trap_R_RegisterShaderNoMip(serverinfo_artlist[i]); + } +} + +/* +================= +UI_ServerInfoMenu +================= +*/ +void UI_ServerInfoMenu( void ) +{ + const char *s; + char key[MAX_INFO_KEY]; + char value[MAX_INFO_VALUE]; + + // zero set all our globals + memset( &s_serverinfo, 0 ,sizeof(serverinfo_t) ); + + ServerInfo_Cache(); + + s_serverinfo.menu.draw = ServerInfo_MenuDraw; + s_serverinfo.menu.key = ServerInfo_MenuKey; + s_serverinfo.menu.wrapAround = qtrue; + s_serverinfo.menu.fullscreen = qtrue; + + s_serverinfo.banner.generic.type = MTYPE_BTEXT; + s_serverinfo.banner.generic.x = 320; + s_serverinfo.banner.generic.y = 16; + s_serverinfo.banner.string = "SERVER INFO"; + s_serverinfo.banner.color = color_white; + s_serverinfo.banner.style = UI_CENTER; + + s_serverinfo.framel.generic.type = MTYPE_BITMAP; + s_serverinfo.framel.generic.name = SERVERINFO_FRAMEL; + s_serverinfo.framel.generic.flags = QMF_INACTIVE; + s_serverinfo.framel.generic.x = 0; + s_serverinfo.framel.generic.y = 78; + s_serverinfo.framel.width = 256; + s_serverinfo.framel.height = 329; + + s_serverinfo.framer.generic.type = MTYPE_BITMAP; + s_serverinfo.framer.generic.name = SERVERINFO_FRAMER; + s_serverinfo.framer.generic.flags = QMF_INACTIVE; + s_serverinfo.framer.generic.x = 376; + s_serverinfo.framer.generic.y = 76; + s_serverinfo.framer.width = 256; + s_serverinfo.framer.height = 334; + + s_serverinfo.add.generic.type = MTYPE_PTEXT; + s_serverinfo.add.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_serverinfo.add.generic.callback = ServerInfo_Event; + s_serverinfo.add.generic.id = ID_ADD; + s_serverinfo.add.generic.x = 320; + s_serverinfo.add.generic.y = 371; + s_serverinfo.add.string = "ADD TO FAVORITES"; + s_serverinfo.add.style = UI_CENTER|UI_SMALLFONT; + s_serverinfo.add.color = color_red; + if( trap_Cvar_VariableValue( "sv_running" ) ) { + s_serverinfo.add.generic.flags |= QMF_GRAYED; + } + + s_serverinfo.back.generic.type = MTYPE_BITMAP; + s_serverinfo.back.generic.name = SERVERINFO_BACK0; + s_serverinfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_serverinfo.back.generic.callback = ServerInfo_Event; + s_serverinfo.back.generic.id = ID_BACK; + s_serverinfo.back.generic.x = 0; + s_serverinfo.back.generic.y = 480-64; + s_serverinfo.back.width = 128; + s_serverinfo.back.height = 64; + s_serverinfo.back.focuspic = SERVERINFO_BACK1; + + trap_GetConfigString( CS_SERVERINFO, s_serverinfo.info, MAX_INFO_STRING ); + + s_serverinfo.numlines = 0; + s = s_serverinfo.info; + while ( s ) { + Info_NextPair( &s, key, value ); + if ( !key[0] ) { + break; + } + s_serverinfo.numlines++; + } + + if (s_serverinfo.numlines > 16) + s_serverinfo.numlines = 16; + + Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.banner ); + Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.framel ); + Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.framer ); + Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.add ); + Menu_AddItem( &s_serverinfo.menu, (void*) &s_serverinfo.back ); + + UI_PushMenu( &s_serverinfo.menu ); +} + + diff --git a/code/q3_ui/ui_servers2.c b/code/q3_ui/ui_servers2.c index d20fb6f..0804b5a 100755 --- a/code/q3_ui/ui_servers2.c +++ b/code/q3_ui/ui_servers2.c @@ -1,1640 +1,1640 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -MULTIPLAYER MENU (SERVER BROWSER) - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define MAX_GLOBALSERVERS 128 -#define MAX_PINGREQUESTS 32 -#define MAX_ADDRESSLENGTH 64 -#define MAX_HOSTNAMELENGTH 22 -#define MAX_MAPNAMELENGTH 16 -#define MAX_LISTBOXITEMS 128 -#define MAX_LOCALSERVERS 128 -#define MAX_STATUSLENGTH 64 -#define MAX_LEAGUELENGTH 28 -#define MAX_LISTBOXWIDTH 68 - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_CREATE0 "menu/art/create_0" -#define ART_CREATE1 "menu/art/create_1" -#define ART_SPECIFY0 "menu/art/specify_0" -#define ART_SPECIFY1 "menu/art/specify_1" -#define ART_REFRESH0 "menu/art/refresh_0" -#define ART_REFRESH1 "menu/art/refresh_1" -#define ART_CONNECT0 "menu/art/fight_0" -#define ART_CONNECT1 "menu/art/fight_1" -#define ART_ARROWS0 "menu/art/arrows_vert_0" -#define ART_ARROWS_UP "menu/art/arrows_vert_top" -#define ART_ARROWS_DOWN "menu/art/arrows_vert_bot" -#define ART_UNKNOWNMAP "menu/art/unknownmap" -#define ART_REMOVE0 "menu/art/delete_0" -#define ART_REMOVE1 "menu/art/delete_1" -#define ART_PUNKBUSTER "menu/art/pblogo" - -#define ID_MASTER 10 -#define ID_GAMETYPE 11 -#define ID_SORTKEY 12 -#define ID_SHOW_FULL 13 -#define ID_SHOW_EMPTY 14 -#define ID_LIST 15 -#define ID_SCROLL_UP 16 -#define ID_SCROLL_DOWN 17 -#define ID_BACK 18 -#define ID_REFRESH 19 -#define ID_SPECIFY 20 -#define ID_CREATE 21 -#define ID_CONNECT 22 -#define ID_REMOVE 23 -#define ID_PUNKBUSTER 24 - -#define GR_LOGO 30 -#define GR_LETTERS 31 - -#define AS_LOCAL 0 -#define AS_MPLAYER 1 -#define AS_GLOBAL 2 -#define AS_FAVORITES 3 - -#define SORT_HOST 0 -#define SORT_MAP 1 -#define SORT_CLIENTS 2 -#define SORT_GAME 3 -#define SORT_PING 4 - -#define GAMES_ALL 0 -#define GAMES_FFA 1 -#define GAMES_TEAMPLAY 2 -#define GAMES_TOURNEY 3 -#define GAMES_CTF 4 - -static const char *master_items[] = { - "Local", - "Internet", - "Favorites", - 0 -}; - -static const char *servertype_items[] = { - "All", - "Free For All", - "Team Deathmatch", - "Tournament", - "Capture the Flag", - 0 -}; - -static const char *sortkey_items[] = { - "Server Name", - "Map Name", - "Open Player Spots", - "Game Type", - "Ping Time", - 0 -}; - -static char* gamenames[] = { - "DM ", // deathmatch - "1v1", // tournament - "SP ", // single player - "Team DM", // team deathmatch - "CTF", // capture the flag - "One Flag CTF", // one flag ctf - "OverLoad", // Overload - "Harvester", // Harvester - "Rocket Arena 3", // Rocket Arena 3 - "Q3F", // Q3F - "Urban Terror", // Urban Terror - "OSP", // Orange Smoothie Productions - "???", // unknown - 0 -}; - -static char* netnames[] = { - "???", - "UDP", - "IPX", - NULL -}; - -static char quake3worldMessage[] = "Visit www.quake3world.com - News, Community, Events, Files"; - -const char* punkbuster_items[] = { - "Disabled", - "Enabled", - NULL -}; - -const char* punkbuster_msg[] = { - "PunkBuster will be", - "disabled the next time", - "Quake III Arena", - "is started.", - NULL -}; - -typedef struct { - char adrstr[MAX_ADDRESSLENGTH]; - int start; -} pinglist_t; - -typedef struct servernode_s { - char adrstr[MAX_ADDRESSLENGTH]; - char hostname[MAX_HOSTNAMELENGTH+3]; - char mapname[MAX_MAPNAMELENGTH]; - int numclients; - int maxclients; - int pingtime; - int gametype; - char gamename[12]; - int nettype; - int minPing; - int maxPing; - qboolean bPB; - -} servernode_t; - -typedef struct { - char buff[MAX_LISTBOXWIDTH]; - servernode_t* servernode; -} table_t; - -typedef struct { - menuframework_s menu; - - menutext_s banner; - - menulist_s master; - menulist_s gametype; - menulist_s sortkey; - menuradiobutton_s showfull; - menuradiobutton_s showempty; - - menulist_s list; - menubitmap_s mappic; - menubitmap_s arrows; - menubitmap_s up; - menubitmap_s down; - menutext_s status; - menutext_s statusbar; - - menubitmap_s remove; - menubitmap_s back; - menubitmap_s refresh; - menubitmap_s specify; - menubitmap_s create; - menubitmap_s go; - - pinglist_t pinglist[MAX_PINGREQUESTS]; - table_t table[MAX_LISTBOXITEMS]; - char* items[MAX_LISTBOXITEMS]; - int numqueriedservers; - int *numservers; - servernode_t *serverlist; - int currentping; - qboolean refreshservers; - int nextpingtime; - int maxservers; - int refreshtime; - char favoriteaddresses[MAX_FAVORITESERVERS][MAX_ADDRESSLENGTH]; - int numfavoriteaddresses; - - menulist_s punkbuster; - menubitmap_s pblogo; -} arenaservers_t; - -static arenaservers_t g_arenaservers; - - -static servernode_t g_globalserverlist[MAX_GLOBALSERVERS]; -static int g_numglobalservers; -static servernode_t g_localserverlist[MAX_LOCALSERVERS]; -static int g_numlocalservers; -static servernode_t g_favoriteserverlist[MAX_FAVORITESERVERS]; -static int g_numfavoriteservers; -static servernode_t g_mplayerserverlist[MAX_GLOBALSERVERS]; -static int g_nummplayerservers; -static int g_servertype; -static int g_gametype; -static int g_sortkey; -static int g_emptyservers; -static int g_fullservers; - - -/* -================= -ArenaServers_MaxPing -================= -*/ -static int ArenaServers_MaxPing( void ) { - int maxPing; - - maxPing = (int)trap_Cvar_VariableValue( "cl_maxPing" ); - if( maxPing < 100 ) { - maxPing = 100; - } - return maxPing; -} - - -/* -================= -ArenaServers_Compare -================= -*/ -static int QDECL ArenaServers_Compare( const void *arg1, const void *arg2 ) { - float f1; - float f2; - servernode_t* t1; - servernode_t* t2; - - t1 = (servernode_t *)arg1; - t2 = (servernode_t *)arg2; - - switch( g_sortkey ) { - case SORT_HOST: - return Q_stricmp( t1->hostname, t2->hostname ); - - case SORT_MAP: - return Q_stricmp( t1->mapname, t2->mapname ); - - case SORT_CLIENTS: - f1 = t1->maxclients - t1->numclients; - if( f1 < 0 ) { - f1 = 0; - } - - f2 = t2->maxclients - t2->numclients; - if( f2 < 0 ) { - f2 = 0; - } - - if( f1 < f2 ) { - return 1; - } - if( f1 == f2 ) { - return 0; - } - return -1; - - case SORT_GAME: - if( t1->gametype < t2->gametype ) { - return -1; - } - if( t1->gametype == t2->gametype ) { - return 0; - } - return 1; - - case SORT_PING: - if( t1->pingtime < t2->pingtime ) { - return -1; - } - if( t1->pingtime > t2->pingtime ) { - return 1; - } - return Q_stricmp( t1->hostname, t2->hostname ); - } - - return 0; -} - - -/* -================= -ArenaServers_Go -================= -*/ -static void ArenaServers_Go( void ) { - servernode_t* servernode; - - servernode = g_arenaservers.table[g_arenaservers.list.curvalue].servernode; - if( servernode ) { - trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", servernode->adrstr ) ); - } -} - - -/* -================= -ArenaServers_UpdatePicture -================= -*/ -static void ArenaServers_UpdatePicture( void ) { - static char picname[64]; - servernode_t* servernodeptr; - - if( !g_arenaservers.list.numitems ) { - g_arenaservers.mappic.generic.name = NULL; - } - else { - servernodeptr = g_arenaservers.table[g_arenaservers.list.curvalue].servernode; - Com_sprintf( picname, sizeof(picname), "levelshots/%s.tga", servernodeptr->mapname ); - g_arenaservers.mappic.generic.name = picname; - - } - - // force shader update during draw - g_arenaservers.mappic.shader = 0; -} - - -/* -================= -ArenaServers_UpdateMenu -================= -*/ -static void ArenaServers_UpdateMenu( void ) { - int i; - int j; - int count; - char* buff; - servernode_t* servernodeptr; - table_t* tableptr; - char *pingColor; - - if( g_arenaservers.numqueriedservers > 0 ) { - // servers found - if( g_arenaservers.refreshservers && ( g_arenaservers.currentping <= g_arenaservers.numqueriedservers ) ) { - // show progress - Com_sprintf( g_arenaservers.status.string, MAX_STATUSLENGTH, "%d of %d Arena Servers.", g_arenaservers.currentping, g_arenaservers.numqueriedservers); - g_arenaservers.statusbar.string = "Press SPACE to stop"; - qsort( g_arenaservers.serverlist, *g_arenaservers.numservers, sizeof( servernode_t ), ArenaServers_Compare); - } - else { - // all servers pinged - enable controls - g_arenaservers.master.generic.flags &= ~QMF_GRAYED; - g_arenaservers.gametype.generic.flags &= ~QMF_GRAYED; - g_arenaservers.sortkey.generic.flags &= ~QMF_GRAYED; - g_arenaservers.showempty.generic.flags &= ~QMF_GRAYED; - g_arenaservers.showfull.generic.flags &= ~QMF_GRAYED; - g_arenaservers.list.generic.flags &= ~QMF_GRAYED; - g_arenaservers.refresh.generic.flags &= ~QMF_GRAYED; - g_arenaservers.go.generic.flags &= ~QMF_GRAYED; - g_arenaservers.punkbuster.generic.flags &= ~QMF_GRAYED; - - // update status bar - if( g_servertype == AS_GLOBAL || g_servertype == AS_MPLAYER ) { - g_arenaservers.statusbar.string = quake3worldMessage; - } - else { - g_arenaservers.statusbar.string = ""; - } - - } - } - else { - // no servers found - if( g_arenaservers.refreshservers ) { - strcpy( g_arenaservers.status.string,"Scanning For Servers." ); - g_arenaservers.statusbar.string = "Press SPACE to stop"; - - // disable controls during refresh - g_arenaservers.master.generic.flags |= QMF_GRAYED; - g_arenaservers.gametype.generic.flags |= QMF_GRAYED; - g_arenaservers.sortkey.generic.flags |= QMF_GRAYED; - g_arenaservers.showempty.generic.flags |= QMF_GRAYED; - g_arenaservers.showfull.generic.flags |= QMF_GRAYED; - g_arenaservers.list.generic.flags |= QMF_GRAYED; - g_arenaservers.refresh.generic.flags |= QMF_GRAYED; - g_arenaservers.go.generic.flags |= QMF_GRAYED; - g_arenaservers.punkbuster.generic.flags |= QMF_GRAYED; - } - else { - if( g_arenaservers.numqueriedservers < 0 ) { - strcpy(g_arenaservers.status.string,"No Response From Master Server." ); - } - else { - strcpy(g_arenaservers.status.string,"No Servers Found." ); - } - - // update status bar - if( g_servertype == AS_GLOBAL || g_servertype == AS_MPLAYER ) { - g_arenaservers.statusbar.string = quake3worldMessage; - } - else { - g_arenaservers.statusbar.string = ""; - } - - // end of refresh - set control state - g_arenaservers.master.generic.flags &= ~QMF_GRAYED; - g_arenaservers.gametype.generic.flags &= ~QMF_GRAYED; - g_arenaservers.sortkey.generic.flags &= ~QMF_GRAYED; - g_arenaservers.showempty.generic.flags &= ~QMF_GRAYED; - g_arenaservers.showfull.generic.flags &= ~QMF_GRAYED; - g_arenaservers.list.generic.flags |= QMF_GRAYED; - g_arenaservers.refresh.generic.flags &= ~QMF_GRAYED; - g_arenaservers.go.generic.flags |= QMF_GRAYED; - g_arenaservers.punkbuster.generic.flags &= ~QMF_GRAYED; - } - - // zero out list box - g_arenaservers.list.numitems = 0; - g_arenaservers.list.curvalue = 0; - g_arenaservers.list.top = 0; - - // update picture - ArenaServers_UpdatePicture(); - return; - } - - // build list box strings - apply culling filters - servernodeptr = g_arenaservers.serverlist; - count = *g_arenaservers.numservers; - for( i = 0, j = 0; i < count; i++, servernodeptr++ ) { - tableptr = &g_arenaservers.table[j]; - tableptr->servernode = servernodeptr; - buff = tableptr->buff; - - // can only cull valid results - if( !g_emptyservers && !servernodeptr->numclients ) { - continue; - } - - if( !g_fullservers && ( servernodeptr->numclients == servernodeptr->maxclients ) ) { - continue; - } - - switch( g_gametype ) { - case GAMES_ALL: - break; - - case GAMES_FFA: - if( servernodeptr->gametype != GT_FFA ) { - continue; - } - break; - - case GAMES_TEAMPLAY: - if( servernodeptr->gametype != GT_TEAM ) { - continue; - } - break; - - case GAMES_TOURNEY: - if( servernodeptr->gametype != GT_TOURNAMENT ) { - continue; - } - break; - - case GAMES_CTF: - if( servernodeptr->gametype != GT_CTF ) { - continue; - } - break; - } - - if( servernodeptr->pingtime < servernodeptr->minPing ) { - pingColor = S_COLOR_BLUE; - } - else if( servernodeptr->maxPing && servernodeptr->pingtime > servernodeptr->maxPing ) { - pingColor = S_COLOR_BLUE; - } - else if( servernodeptr->pingtime < 200 ) { - pingColor = S_COLOR_GREEN; - } - else if( servernodeptr->pingtime < 400 ) { - pingColor = S_COLOR_YELLOW; - } - else { - pingColor = S_COLOR_RED; - } - - Com_sprintf( buff, MAX_LISTBOXWIDTH, "%-20.20s %-12.12s %2d/%2d %-8.8s %3s %s%3d " S_COLOR_YELLOW "%s", - servernodeptr->hostname, servernodeptr->mapname, servernodeptr->numclients, - servernodeptr->maxclients, servernodeptr->gamename, - netnames[servernodeptr->nettype], pingColor, servernodeptr->pingtime, servernodeptr->bPB ? "Yes" : "No" ); - j++; - } - - g_arenaservers.list.numitems = j; - g_arenaservers.list.curvalue = 0; - g_arenaservers.list.top = 0; - - // update picture - ArenaServers_UpdatePicture(); -} - - -/* -================= -ArenaServers_Remove -================= -*/ -static void ArenaServers_Remove( void ) -{ - int i; - servernode_t* servernodeptr; - table_t* tableptr; - - if (!g_arenaservers.list.numitems) - return; - - // remove selected item from display list - // items are in scattered order due to sort and cull - // perform delete on list box contents, resync all lists - - tableptr = &g_arenaservers.table[g_arenaservers.list.curvalue]; - servernodeptr = tableptr->servernode; - - // find address in master list - for (i=0; iadrstr)) - break; - - // delete address from master list - if (i <= g_arenaservers.numfavoriteaddresses-1) - { - if (i < g_arenaservers.numfavoriteaddresses-1) - { - // shift items up - memcpy( &g_arenaservers.favoriteaddresses[i], &g_arenaservers.favoriteaddresses[i+1], (g_arenaservers.numfavoriteaddresses - i - 1)*sizeof(MAX_ADDRESSLENGTH)); - } - g_arenaservers.numfavoriteaddresses--; - } - - // find address in server list - for (i=0; i= ArenaServers_MaxPing()) && (g_servertype != AS_FAVORITES)) - { - // slow global or local servers do not get entered - return; - } - - if (*g_arenaservers.numservers >= g_arenaservers.maxservers) { - // list full; - servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers)-1; - } else { - // next slot - servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers); - (*g_arenaservers.numservers)++; - } - - Q_strncpyz( servernodeptr->adrstr, adrstr, MAX_ADDRESSLENGTH ); - - Q_strncpyz( servernodeptr->hostname, Info_ValueForKey( info, "hostname"), MAX_HOSTNAMELENGTH ); - Q_CleanStr( servernodeptr->hostname ); - Q_strupr( servernodeptr->hostname ); - - Q_strncpyz( servernodeptr->mapname, Info_ValueForKey( info, "mapname"), MAX_MAPNAMELENGTH ); - Q_CleanStr( servernodeptr->mapname ); - Q_strupr( servernodeptr->mapname ); - - servernodeptr->numclients = atoi( Info_ValueForKey( info, "clients") ); - servernodeptr->maxclients = atoi( Info_ValueForKey( info, "sv_maxclients") ); - servernodeptr->pingtime = pingtime; - servernodeptr->minPing = atoi( Info_ValueForKey( info, "minPing") ); - servernodeptr->maxPing = atoi( Info_ValueForKey( info, "maxPing") ); - servernodeptr->bPB = atoi( Info_ValueForKey( info, "punkbuster") ); - - /* - s = Info_ValueForKey( info, "nettype" ); - for (i=0; ;i++) - { - if (!netnames[i]) - { - servernodeptr->nettype = 0; - break; - } - else if (!Q_stricmp( netnames[i], s )) - { - servernodeptr->nettype = i; - break; - } - } - */ - servernodeptr->nettype = atoi(Info_ValueForKey(info, "nettype")); - - s = Info_ValueForKey( info, "game"); - i = atoi( Info_ValueForKey( info, "gametype") ); - if( i < 0 ) { - i = 0; - } - else if( i > 11 ) { - i = 12; - } - if( *s ) { - servernodeptr->gametype = i;//-1; - Q_strncpyz( servernodeptr->gamename, s, sizeof(servernodeptr->gamename) ); - } - else { - servernodeptr->gametype = i; - Q_strncpyz( servernodeptr->gamename, gamenames[i], sizeof(servernodeptr->gamename) ); - } -} - - -/* -================= -ArenaServers_InsertFavorites - -Insert nonresponsive address book entries into display lists. -================= -*/ -void ArenaServers_InsertFavorites( void ) -{ - int i; - int j; - char info[MAX_INFO_STRING]; - - // resync existing results with new or deleted cvars - info[0] = '\0'; - Info_SetValueForKey( info, "hostname", "No Response" ); - for (i=0; i= g_numfavoriteservers) - { - // not in list, add it - ArenaServers_Insert( g_arenaservers.favoriteaddresses[i], info, ArenaServers_MaxPing() ); - } - } -} - - -/* -================= -ArenaServers_LoadFavorites - -Load cvar address book entries into local lists. -================= -*/ -void ArenaServers_LoadFavorites( void ) -{ - int i; - int j; - int numtempitems; - char emptyinfo[MAX_INFO_STRING]; - char adrstr[MAX_ADDRESSLENGTH]; - servernode_t templist[MAX_FAVORITESERVERS]; - qboolean found; - - found = qfalse; - emptyinfo[0] = '\0'; - - // copy the old - memcpy( templist, g_favoriteserverlist, sizeof(servernode_t)*MAX_FAVORITESERVERS ); - numtempitems = g_numfavoriteservers; - - // clear the current for sync - memset( g_favoriteserverlist, 0, sizeof(servernode_t)*MAX_FAVORITESERVERS ); - g_numfavoriteservers = 0; - - // resync existing results with new or deleted cvars - for (i=0; i '9') - continue; - - // favorite server addresses must be maintained outside refresh list - // this mimics local and global netadr's stored in client - // these can be fetched to fill ping list - strcpy( g_arenaservers.favoriteaddresses[g_numfavoriteservers], adrstr ); - - // find this server in the old list - for (j=0; j= 0) - { - g_arenaservers.currentping = *g_arenaservers.numservers; - g_arenaservers.numqueriedservers = *g_arenaservers.numservers; - } - - // sort - qsort( g_arenaservers.serverlist, *g_arenaservers.numservers, sizeof( servernode_t ), ArenaServers_Compare); - - ArenaServers_UpdateMenu(); -} - - -/* -================= -ArenaServers_DoRefresh -================= -*/ -static void ArenaServers_DoRefresh( void ) -{ - int i; - int j; - int time; - int maxPing; - char adrstr[MAX_ADDRESSLENGTH]; - char info[MAX_INFO_STRING]; - - if (uis.realtime < g_arenaservers.refreshtime) - { - if (g_servertype != AS_FAVORITES) { - if (g_servertype == AS_LOCAL) { - if (!trap_LAN_GetServerCount(g_servertype)) { - return; - } - } - if (trap_LAN_GetServerCount(g_servertype) < 0) { - // still waiting for response - return; - } - } - } - - if (uis.realtime < g_arenaservers.nextpingtime) - { - // wait for time trigger - return; - } - - // trigger at 10Hz intervals - g_arenaservers.nextpingtime = uis.realtime + 10; - - // process ping results - maxPing = ArenaServers_MaxPing(); - for (i=0; i maxPing) - { - // stale it out - info[0] = '\0'; - time = maxPing; - } - else - { - trap_LAN_GetPingInfo( i, info, MAX_INFO_STRING ); - } - - // insert ping results - ArenaServers_Insert( adrstr, info, time ); - - // clear this query from internal list - g_arenaservers.pinglist[j].adrstr[0] = '\0'; - } - - // clear this query from external list - trap_LAN_ClearPing( i ); - } - - // get results of servers query - // counts can increase as servers respond - if (g_servertype == AS_FAVORITES) { - g_arenaservers.numqueriedservers = g_arenaservers.numfavoriteaddresses; - } else { - g_arenaservers.numqueriedservers = trap_LAN_GetServerCount(g_servertype); - } - -// if (g_arenaservers.numqueriedservers > g_arenaservers.maxservers) -// g_arenaservers.numqueriedservers = g_arenaservers.maxservers; - - // send ping requests in reasonable bursts - // iterate ping through all found servers - for (i=0; i= MAX_PINGREQUESTS) - { - // ping queue is full - break; - } - - // find empty slot - for (j=0; j= MAX_PINGREQUESTS) - // no empty slots available yet - wait for timeout - break; - - // get an address to ping - - if (g_servertype == AS_FAVORITES) { - strcpy( adrstr, g_arenaservers.favoriteaddresses[g_arenaservers.currentping] ); - } else { - trap_LAN_GetServerAddressString(g_servertype, g_arenaservers.currentping, adrstr, MAX_ADDRESSLENGTH ); - } - - strcpy( g_arenaservers.pinglist[j].adrstr, adrstr ); - g_arenaservers.pinglist[j].start = uis.realtime; - - trap_Cmd_ExecuteText( EXEC_NOW, va( "ping %s\n", adrstr ) ); - - // advance to next server - g_arenaservers.currentping++; - } - - if (!trap_LAN_GetPingQueueCount()) - { - // all pings completed - ArenaServers_StopRefresh(); - return; - } - - // update the user interface with ping status - ArenaServers_UpdateMenu(); -} - - -/* -================= -ArenaServers_StartRefresh -================= -*/ -static void ArenaServers_StartRefresh( void ) -{ - int i; - char myargs[32], protocol[32]; - - memset( g_arenaservers.serverlist, 0, g_arenaservers.maxservers*sizeof(table_t) ); - - for (i=0; iid; - - if( event != QM_ACTIVATED && id != ID_LIST ) { - return; - } - - switch( id ) { - case ID_MASTER: - value = g_arenaservers.master.curvalue; - if (value >= 1) - { - value++; - } - trap_Cvar_SetValue( "ui_browserMaster", value ); - ArenaServers_SetType( value ); - break; - - case ID_GAMETYPE: - trap_Cvar_SetValue( "ui_browserGameType", g_arenaservers.gametype.curvalue ); - g_gametype = g_arenaservers.gametype.curvalue; - ArenaServers_UpdateMenu(); - break; - - case ID_SORTKEY: - trap_Cvar_SetValue( "ui_browserSortKey", g_arenaservers.sortkey.curvalue ); - ArenaServers_Sort( g_arenaservers.sortkey.curvalue ); - ArenaServers_UpdateMenu(); - break; - - case ID_SHOW_FULL: - trap_Cvar_SetValue( "ui_browserShowFull", g_arenaservers.showfull.curvalue ); - g_fullservers = g_arenaservers.showfull.curvalue; - ArenaServers_UpdateMenu(); - break; - - case ID_SHOW_EMPTY: - trap_Cvar_SetValue( "ui_browserShowEmpty", g_arenaservers.showempty.curvalue ); - g_emptyservers = g_arenaservers.showempty.curvalue; - ArenaServers_UpdateMenu(); - break; - - case ID_LIST: - if( event == QM_GOTFOCUS ) { - ArenaServers_UpdatePicture(); - } - break; - - case ID_SCROLL_UP: - ScrollList_Key( &g_arenaservers.list, K_UPARROW ); - break; - - case ID_SCROLL_DOWN: - ScrollList_Key( &g_arenaservers.list, K_DOWNARROW ); - break; - - case ID_BACK: - ArenaServers_StopRefresh(); - ArenaServers_SaveChanges(); - UI_PopMenu(); - break; - - case ID_REFRESH: - ArenaServers_StartRefresh(); - break; - - case ID_SPECIFY: - UI_SpecifyServerMenu(); - break; - - case ID_CREATE: - UI_StartServerMenu( qtrue ); - break; - - case ID_CONNECT: - ArenaServers_Go(); - break; - - case ID_REMOVE: - ArenaServers_Remove(); - ArenaServers_UpdateMenu(); - break; - - case ID_PUNKBUSTER: - if (g_arenaservers.punkbuster.curvalue) - { - UI_ConfirmMenu_Style( "Enable Punkbuster?", UI_CENTER|UI_INVERSE|UI_SMALLFONT, (voidfunc_f)NULL, Punkbuster_ConfirmEnable ); - } - else - { - UI_ConfirmMenu_Style( "Disable Punkbuster?", UI_CENTER|UI_INVERSE|UI_SMALLFONT, (voidfunc_f)NULL, Punkbuster_ConfirmDisable ); - } - break; - } -} - - -/* -================= -ArenaServers_MenuDraw -================= -*/ -static void ArenaServers_MenuDraw( void ) -{ - if (g_arenaservers.refreshservers) - ArenaServers_DoRefresh(); - - Menu_Draw( &g_arenaservers.menu ); -} - - -/* -================= -ArenaServers_MenuKey -================= -*/ -static sfxHandle_t ArenaServers_MenuKey( int key ) { - if( key == K_SPACE && g_arenaservers.refreshservers ) { - ArenaServers_StopRefresh(); - return menu_move_sound; - } - - if( ( key == K_DEL || key == K_KP_DEL ) && ( g_servertype == AS_FAVORITES ) && - ( Menu_ItemAtCursor( &g_arenaservers.menu) == &g_arenaservers.list ) ) { - ArenaServers_Remove(); - ArenaServers_UpdateMenu(); - return menu_move_sound; - } - - if( key == K_MOUSE2 || key == K_ESCAPE ) { - ArenaServers_StopRefresh(); - ArenaServers_SaveChanges(); - } - - - return Menu_DefaultKey( &g_arenaservers.menu, key ); -} - - -/* -================= -ArenaServers_MenuInit -================= -*/ -static void ArenaServers_MenuInit( void ) { - int i; - int type; - int y; - int value; - static char statusbuffer[MAX_STATUSLENGTH]; - - // zero set all our globals - memset( &g_arenaservers, 0 ,sizeof(arenaservers_t) ); - - ArenaServers_Cache(); - - g_arenaservers.menu.fullscreen = qtrue; - g_arenaservers.menu.wrapAround = qtrue; - g_arenaservers.menu.draw = ArenaServers_MenuDraw; - g_arenaservers.menu.key = ArenaServers_MenuKey; - - g_arenaservers.banner.generic.type = MTYPE_BTEXT; - g_arenaservers.banner.generic.flags = QMF_CENTER_JUSTIFY; - g_arenaservers.banner.generic.x = 320; - g_arenaservers.banner.generic.y = 16; - g_arenaservers.banner.string = "ARENA SERVERS"; - g_arenaservers.banner.style = UI_CENTER; - g_arenaservers.banner.color = color_white; - - y = 80; - g_arenaservers.master.generic.type = MTYPE_SPINCONTROL; - g_arenaservers.master.generic.name = "Servers:"; - g_arenaservers.master.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - g_arenaservers.master.generic.callback = ArenaServers_Event; - g_arenaservers.master.generic.id = ID_MASTER; - g_arenaservers.master.generic.x = 320; - g_arenaservers.master.generic.y = y; - g_arenaservers.master.itemnames = master_items; - - y += SMALLCHAR_HEIGHT; - g_arenaservers.gametype.generic.type = MTYPE_SPINCONTROL; - g_arenaservers.gametype.generic.name = "Game Type:"; - g_arenaservers.gametype.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - g_arenaservers.gametype.generic.callback = ArenaServers_Event; - g_arenaservers.gametype.generic.id = ID_GAMETYPE; - g_arenaservers.gametype.generic.x = 320; - g_arenaservers.gametype.generic.y = y; - g_arenaservers.gametype.itemnames = servertype_items; - - y += SMALLCHAR_HEIGHT; - g_arenaservers.sortkey.generic.type = MTYPE_SPINCONTROL; - g_arenaservers.sortkey.generic.name = "Sort By:"; - g_arenaservers.sortkey.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - g_arenaservers.sortkey.generic.callback = ArenaServers_Event; - g_arenaservers.sortkey.generic.id = ID_SORTKEY; - g_arenaservers.sortkey.generic.x = 320; - g_arenaservers.sortkey.generic.y = y; - g_arenaservers.sortkey.itemnames = sortkey_items; - - y += SMALLCHAR_HEIGHT; - g_arenaservers.showfull.generic.type = MTYPE_RADIOBUTTON; - g_arenaservers.showfull.generic.name = "Show Full:"; - g_arenaservers.showfull.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - g_arenaservers.showfull.generic.callback = ArenaServers_Event; - g_arenaservers.showfull.generic.id = ID_SHOW_FULL; - g_arenaservers.showfull.generic.x = 320; - g_arenaservers.showfull.generic.y = y; - - y += SMALLCHAR_HEIGHT; - g_arenaservers.showempty.generic.type = MTYPE_RADIOBUTTON; - g_arenaservers.showempty.generic.name = "Show Empty:"; - g_arenaservers.showempty.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - g_arenaservers.showempty.generic.callback = ArenaServers_Event; - g_arenaservers.showempty.generic.id = ID_SHOW_EMPTY; - g_arenaservers.showempty.generic.x = 320; - g_arenaservers.showempty.generic.y = y; - - y += 3 * SMALLCHAR_HEIGHT; - g_arenaservers.list.generic.type = MTYPE_SCROLLLIST; - g_arenaservers.list.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; - g_arenaservers.list.generic.id = ID_LIST; - g_arenaservers.list.generic.callback = ArenaServers_Event; - g_arenaservers.list.generic.x = 72; - g_arenaservers.list.generic.y = y; - g_arenaservers.list.width = MAX_LISTBOXWIDTH; - g_arenaservers.list.height = 11; - g_arenaservers.list.itemnames = (const char **)g_arenaservers.items; - for( i = 0; i < MAX_LISTBOXITEMS; i++ ) { - g_arenaservers.items[i] = g_arenaservers.table[i].buff; - } - - g_arenaservers.mappic.generic.type = MTYPE_BITMAP; - g_arenaservers.mappic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - g_arenaservers.mappic.generic.x = 72; - g_arenaservers.mappic.generic.y = 80; - g_arenaservers.mappic.width = 128; - g_arenaservers.mappic.height = 96; - g_arenaservers.mappic.errorpic = ART_UNKNOWNMAP; - - g_arenaservers.arrows.generic.type = MTYPE_BITMAP; - g_arenaservers.arrows.generic.name = ART_ARROWS0; - g_arenaservers.arrows.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - g_arenaservers.arrows.generic.callback = ArenaServers_Event; - g_arenaservers.arrows.generic.x = 512+48; - g_arenaservers.arrows.generic.y = 240-64+16; - g_arenaservers.arrows.width = 64; - g_arenaservers.arrows.height = 128; - - g_arenaservers.up.generic.type = MTYPE_BITMAP; - g_arenaservers.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - g_arenaservers.up.generic.callback = ArenaServers_Event; - g_arenaservers.up.generic.id = ID_SCROLL_UP; - g_arenaservers.up.generic.x = 512+48; - g_arenaservers.up.generic.y = 240-64+16; - g_arenaservers.up.width = 64; - g_arenaservers.up.height = 64; - g_arenaservers.up.focuspic = ART_ARROWS_UP; - - g_arenaservers.down.generic.type = MTYPE_BITMAP; - g_arenaservers.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - g_arenaservers.down.generic.callback = ArenaServers_Event; - g_arenaservers.down.generic.id = ID_SCROLL_DOWN; - g_arenaservers.down.generic.x = 512+48; - g_arenaservers.down.generic.y = 240+16; - g_arenaservers.down.width = 64; - g_arenaservers.down.height = 64; - g_arenaservers.down.focuspic = ART_ARROWS_DOWN; - - y = 376; - g_arenaservers.status.generic.type = MTYPE_TEXT; - g_arenaservers.status.generic.x = 320; - g_arenaservers.status.generic.y = y; - g_arenaservers.status.string = statusbuffer; - g_arenaservers.status.style = UI_CENTER|UI_SMALLFONT; - g_arenaservers.status.color = menu_text_color; - - y += SMALLCHAR_HEIGHT; - g_arenaservers.statusbar.generic.type = MTYPE_TEXT; - g_arenaservers.statusbar.generic.x = 320; - g_arenaservers.statusbar.generic.y = y; - g_arenaservers.statusbar.string = ""; - g_arenaservers.statusbar.style = UI_CENTER|UI_SMALLFONT; - g_arenaservers.statusbar.color = text_color_normal; - - g_arenaservers.remove.generic.type = MTYPE_BITMAP; - g_arenaservers.remove.generic.name = ART_REMOVE0; - g_arenaservers.remove.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - g_arenaservers.remove.generic.callback = ArenaServers_Event; - g_arenaservers.remove.generic.id = ID_REMOVE; - g_arenaservers.remove.generic.x = 450; - g_arenaservers.remove.generic.y = 86; - g_arenaservers.remove.width = 96; - g_arenaservers.remove.height = 48; - g_arenaservers.remove.focuspic = ART_REMOVE1; - - g_arenaservers.back.generic.type = MTYPE_BITMAP; - g_arenaservers.back.generic.name = ART_BACK0; - g_arenaservers.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - g_arenaservers.back.generic.callback = ArenaServers_Event; - g_arenaservers.back.generic.id = ID_BACK; - g_arenaservers.back.generic.x = 0; - g_arenaservers.back.generic.y = 480-64; - g_arenaservers.back.width = 128; - g_arenaservers.back.height = 64; - g_arenaservers.back.focuspic = ART_BACK1; - - g_arenaservers.specify.generic.type = MTYPE_BITMAP; - g_arenaservers.specify.generic.name = ART_SPECIFY0; - g_arenaservers.specify.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - g_arenaservers.specify.generic.callback = ArenaServers_Event; - g_arenaservers.specify.generic.id = ID_SPECIFY; - g_arenaservers.specify.generic.x = 128; - g_arenaservers.specify.generic.y = 480-64; - g_arenaservers.specify.width = 128; - g_arenaservers.specify.height = 64; - g_arenaservers.specify.focuspic = ART_SPECIFY1; - - g_arenaservers.refresh.generic.type = MTYPE_BITMAP; - g_arenaservers.refresh.generic.name = ART_REFRESH0; - g_arenaservers.refresh.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - g_arenaservers.refresh.generic.callback = ArenaServers_Event; - g_arenaservers.refresh.generic.id = ID_REFRESH; - g_arenaservers.refresh.generic.x = 256; - g_arenaservers.refresh.generic.y = 480-64; - g_arenaservers.refresh.width = 128; - g_arenaservers.refresh.height = 64; - g_arenaservers.refresh.focuspic = ART_REFRESH1; - - g_arenaservers.create.generic.type = MTYPE_BITMAP; - g_arenaservers.create.generic.name = ART_CREATE0; - g_arenaservers.create.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - g_arenaservers.create.generic.callback = ArenaServers_Event; - g_arenaservers.create.generic.id = ID_CREATE; - g_arenaservers.create.generic.x = 384; - g_arenaservers.create.generic.y = 480-64; - g_arenaservers.create.width = 128; - g_arenaservers.create.height = 64; - g_arenaservers.create.focuspic = ART_CREATE1; - - g_arenaservers.go.generic.type = MTYPE_BITMAP; - g_arenaservers.go.generic.name = ART_CONNECT0; - g_arenaservers.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - g_arenaservers.go.generic.callback = ArenaServers_Event; - g_arenaservers.go.generic.id = ID_CONNECT; - g_arenaservers.go.generic.x = 640; - g_arenaservers.go.generic.y = 480-64; - g_arenaservers.go.width = 128; - g_arenaservers.go.height = 64; - g_arenaservers.go.focuspic = ART_CONNECT1; - - g_arenaservers.punkbuster.generic.type = MTYPE_SPINCONTROL; - g_arenaservers.punkbuster.generic.name = "Punkbuster:"; - g_arenaservers.punkbuster.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - g_arenaservers.punkbuster.generic.callback = ArenaServers_Event; - g_arenaservers.punkbuster.generic.id = ID_PUNKBUSTER; - g_arenaservers.punkbuster.generic.x = 480+32; - g_arenaservers.punkbuster.generic.y = 144; - g_arenaservers.punkbuster.itemnames = punkbuster_items; - - g_arenaservers.pblogo.generic.type = MTYPE_BITMAP; - g_arenaservers.pblogo.generic.name = ART_PUNKBUSTER; - g_arenaservers.pblogo.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - g_arenaservers.pblogo.generic.x = 526; - g_arenaservers.pblogo.generic.y = 176; - g_arenaservers.pblogo.width = 32; - g_arenaservers.pblogo.height = 16; - g_arenaservers.pblogo.errorpic = ART_UNKNOWNMAP; - - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.banner ); - - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.master ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.gametype ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.sortkey ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.showfull); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.showempty ); - - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.mappic ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.list ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.status ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.statusbar ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.arrows ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.up ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.down ); - - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.remove ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.back ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.specify ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.refresh ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.create ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.go ); - - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.punkbuster ); - Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.pblogo ); - - ArenaServers_LoadFavorites(); - - g_servertype = Com_Clamp( 0, 3, ui_browserMaster.integer ); - // hack to get rid of MPlayer stuff - value = g_servertype; - if (value >= 1) - value--; - g_arenaservers.master.curvalue = value; - - g_gametype = Com_Clamp( 0, 4, ui_browserGameType.integer ); - g_arenaservers.gametype.curvalue = g_gametype; - - g_sortkey = Com_Clamp( 0, 4, ui_browserSortKey.integer ); - g_arenaservers.sortkey.curvalue = g_sortkey; - - g_fullservers = Com_Clamp( 0, 1, ui_browserShowFull.integer ); - g_arenaservers.showfull.curvalue = g_fullservers; - - g_emptyservers = Com_Clamp( 0, 1, ui_browserShowEmpty.integer ); - g_arenaservers.showempty.curvalue = g_emptyservers; - - g_arenaservers.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "cl_punkbuster" ) ); - - // force to initial state and refresh - type = g_servertype; - g_servertype = -1; - ArenaServers_SetType( type ); - - trap_Cvar_Register(NULL, "debug_protocol", "", 0 ); -} - - -/* -================= -ArenaServers_Cache -================= -*/ -void ArenaServers_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_CREATE0 ); - trap_R_RegisterShaderNoMip( ART_CREATE1 ); - trap_R_RegisterShaderNoMip( ART_SPECIFY0 ); - trap_R_RegisterShaderNoMip( ART_SPECIFY1 ); - trap_R_RegisterShaderNoMip( ART_REFRESH0 ); - trap_R_RegisterShaderNoMip( ART_REFRESH1 ); - trap_R_RegisterShaderNoMip( ART_CONNECT0 ); - trap_R_RegisterShaderNoMip( ART_CONNECT1 ); - trap_R_RegisterShaderNoMip( ART_ARROWS0 ); - trap_R_RegisterShaderNoMip( ART_ARROWS_UP ); - trap_R_RegisterShaderNoMip( ART_ARROWS_DOWN ); - trap_R_RegisterShaderNoMip( ART_UNKNOWNMAP ); - trap_R_RegisterShaderNoMip( ART_PUNKBUSTER ); -} - - -/* -================= -UI_ArenaServersMenu -================= -*/ -void UI_ArenaServersMenu( void ) { - ArenaServers_MenuInit(); - UI_PushMenu( &g_arenaservers.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +MULTIPLAYER MENU (SERVER BROWSER) + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define MAX_GLOBALSERVERS 128 +#define MAX_PINGREQUESTS 32 +#define MAX_ADDRESSLENGTH 64 +#define MAX_HOSTNAMELENGTH 22 +#define MAX_MAPNAMELENGTH 16 +#define MAX_LISTBOXITEMS 128 +#define MAX_LOCALSERVERS 128 +#define MAX_STATUSLENGTH 64 +#define MAX_LEAGUELENGTH 28 +#define MAX_LISTBOXWIDTH 68 + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_CREATE0 "menu/art/create_0" +#define ART_CREATE1 "menu/art/create_1" +#define ART_SPECIFY0 "menu/art/specify_0" +#define ART_SPECIFY1 "menu/art/specify_1" +#define ART_REFRESH0 "menu/art/refresh_0" +#define ART_REFRESH1 "menu/art/refresh_1" +#define ART_CONNECT0 "menu/art/fight_0" +#define ART_CONNECT1 "menu/art/fight_1" +#define ART_ARROWS0 "menu/art/arrows_vert_0" +#define ART_ARROWS_UP "menu/art/arrows_vert_top" +#define ART_ARROWS_DOWN "menu/art/arrows_vert_bot" +#define ART_UNKNOWNMAP "menu/art/unknownmap" +#define ART_REMOVE0 "menu/art/delete_0" +#define ART_REMOVE1 "menu/art/delete_1" +#define ART_PUNKBUSTER "menu/art/pblogo" + +#define ID_MASTER 10 +#define ID_GAMETYPE 11 +#define ID_SORTKEY 12 +#define ID_SHOW_FULL 13 +#define ID_SHOW_EMPTY 14 +#define ID_LIST 15 +#define ID_SCROLL_UP 16 +#define ID_SCROLL_DOWN 17 +#define ID_BACK 18 +#define ID_REFRESH 19 +#define ID_SPECIFY 20 +#define ID_CREATE 21 +#define ID_CONNECT 22 +#define ID_REMOVE 23 +#define ID_PUNKBUSTER 24 + +#define GR_LOGO 30 +#define GR_LETTERS 31 + +#define AS_LOCAL 0 +#define AS_MPLAYER 1 +#define AS_GLOBAL 2 +#define AS_FAVORITES 3 + +#define SORT_HOST 0 +#define SORT_MAP 1 +#define SORT_CLIENTS 2 +#define SORT_GAME 3 +#define SORT_PING 4 + +#define GAMES_ALL 0 +#define GAMES_FFA 1 +#define GAMES_TEAMPLAY 2 +#define GAMES_TOURNEY 3 +#define GAMES_CTF 4 + +static const char *master_items[] = { + "Local", + "Internet", + "Favorites", + 0 +}; + +static const char *servertype_items[] = { + "All", + "Free For All", + "Team Deathmatch", + "Tournament", + "Capture the Flag", + 0 +}; + +static const char *sortkey_items[] = { + "Server Name", + "Map Name", + "Open Player Spots", + "Game Type", + "Ping Time", + 0 +}; + +static char* gamenames[] = { + "DM ", // deathmatch + "1v1", // tournament + "SP ", // single player + "Team DM", // team deathmatch + "CTF", // capture the flag + "One Flag CTF", // one flag ctf + "OverLoad", // Overload + "Harvester", // Harvester + "Rocket Arena 3", // Rocket Arena 3 + "Q3F", // Q3F + "Urban Terror", // Urban Terror + "OSP", // Orange Smoothie Productions + "???", // unknown + 0 +}; + +static char* netnames[] = { + "???", + "UDP", + "IPX", + NULL +}; + +static char quake3worldMessage[] = "Visit www.quake3world.com - News, Community, Events, Files"; + +const char* punkbuster_items[] = { + "Disabled", + "Enabled", + NULL +}; + +const char* punkbuster_msg[] = { + "PunkBuster will be", + "disabled the next time", + "Quake III Arena", + "is started.", + NULL +}; + +typedef struct { + char adrstr[MAX_ADDRESSLENGTH]; + int start; +} pinglist_t; + +typedef struct servernode_s { + char adrstr[MAX_ADDRESSLENGTH]; + char hostname[MAX_HOSTNAMELENGTH+3]; + char mapname[MAX_MAPNAMELENGTH]; + int numclients; + int maxclients; + int pingtime; + int gametype; + char gamename[12]; + int nettype; + int minPing; + int maxPing; + qboolean bPB; + +} servernode_t; + +typedef struct { + char buff[MAX_LISTBOXWIDTH]; + servernode_t* servernode; +} table_t; + +typedef struct { + menuframework_s menu; + + menutext_s banner; + + menulist_s master; + menulist_s gametype; + menulist_s sortkey; + menuradiobutton_s showfull; + menuradiobutton_s showempty; + + menulist_s list; + menubitmap_s mappic; + menubitmap_s arrows; + menubitmap_s up; + menubitmap_s down; + menutext_s status; + menutext_s statusbar; + + menubitmap_s remove; + menubitmap_s back; + menubitmap_s refresh; + menubitmap_s specify; + menubitmap_s create; + menubitmap_s go; + + pinglist_t pinglist[MAX_PINGREQUESTS]; + table_t table[MAX_LISTBOXITEMS]; + char* items[MAX_LISTBOXITEMS]; + int numqueriedservers; + int *numservers; + servernode_t *serverlist; + int currentping; + qboolean refreshservers; + int nextpingtime; + int maxservers; + int refreshtime; + char favoriteaddresses[MAX_FAVORITESERVERS][MAX_ADDRESSLENGTH]; + int numfavoriteaddresses; + + menulist_s punkbuster; + menubitmap_s pblogo; +} arenaservers_t; + +static arenaservers_t g_arenaservers; + + +static servernode_t g_globalserverlist[MAX_GLOBALSERVERS]; +static int g_numglobalservers; +static servernode_t g_localserverlist[MAX_LOCALSERVERS]; +static int g_numlocalservers; +static servernode_t g_favoriteserverlist[MAX_FAVORITESERVERS]; +static int g_numfavoriteservers; +static servernode_t g_mplayerserverlist[MAX_GLOBALSERVERS]; +static int g_nummplayerservers; +static int g_servertype; +static int g_gametype; +static int g_sortkey; +static int g_emptyservers; +static int g_fullservers; + + +/* +================= +ArenaServers_MaxPing +================= +*/ +static int ArenaServers_MaxPing( void ) { + int maxPing; + + maxPing = (int)trap_Cvar_VariableValue( "cl_maxPing" ); + if( maxPing < 100 ) { + maxPing = 100; + } + return maxPing; +} + + +/* +================= +ArenaServers_Compare +================= +*/ +static int QDECL ArenaServers_Compare( const void *arg1, const void *arg2 ) { + float f1; + float f2; + servernode_t* t1; + servernode_t* t2; + + t1 = (servernode_t *)arg1; + t2 = (servernode_t *)arg2; + + switch( g_sortkey ) { + case SORT_HOST: + return Q_stricmp( t1->hostname, t2->hostname ); + + case SORT_MAP: + return Q_stricmp( t1->mapname, t2->mapname ); + + case SORT_CLIENTS: + f1 = t1->maxclients - t1->numclients; + if( f1 < 0 ) { + f1 = 0; + } + + f2 = t2->maxclients - t2->numclients; + if( f2 < 0 ) { + f2 = 0; + } + + if( f1 < f2 ) { + return 1; + } + if( f1 == f2 ) { + return 0; + } + return -1; + + case SORT_GAME: + if( t1->gametype < t2->gametype ) { + return -1; + } + if( t1->gametype == t2->gametype ) { + return 0; + } + return 1; + + case SORT_PING: + if( t1->pingtime < t2->pingtime ) { + return -1; + } + if( t1->pingtime > t2->pingtime ) { + return 1; + } + return Q_stricmp( t1->hostname, t2->hostname ); + } + + return 0; +} + + +/* +================= +ArenaServers_Go +================= +*/ +static void ArenaServers_Go( void ) { + servernode_t* servernode; + + servernode = g_arenaservers.table[g_arenaservers.list.curvalue].servernode; + if( servernode ) { + trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", servernode->adrstr ) ); + } +} + + +/* +================= +ArenaServers_UpdatePicture +================= +*/ +static void ArenaServers_UpdatePicture( void ) { + static char picname[64]; + servernode_t* servernodeptr; + + if( !g_arenaservers.list.numitems ) { + g_arenaservers.mappic.generic.name = NULL; + } + else { + servernodeptr = g_arenaservers.table[g_arenaservers.list.curvalue].servernode; + Com_sprintf( picname, sizeof(picname), "levelshots/%s.tga", servernodeptr->mapname ); + g_arenaservers.mappic.generic.name = picname; + + } + + // force shader update during draw + g_arenaservers.mappic.shader = 0; +} + + +/* +================= +ArenaServers_UpdateMenu +================= +*/ +static void ArenaServers_UpdateMenu( void ) { + int i; + int j; + int count; + char* buff; + servernode_t* servernodeptr; + table_t* tableptr; + char *pingColor; + + if( g_arenaservers.numqueriedservers > 0 ) { + // servers found + if( g_arenaservers.refreshservers && ( g_arenaservers.currentping <= g_arenaservers.numqueriedservers ) ) { + // show progress + Com_sprintf( g_arenaservers.status.string, MAX_STATUSLENGTH, "%d of %d Arena Servers.", g_arenaservers.currentping, g_arenaservers.numqueriedservers); + g_arenaservers.statusbar.string = "Press SPACE to stop"; + qsort( g_arenaservers.serverlist, *g_arenaservers.numservers, sizeof( servernode_t ), ArenaServers_Compare); + } + else { + // all servers pinged - enable controls + g_arenaservers.master.generic.flags &= ~QMF_GRAYED; + g_arenaservers.gametype.generic.flags &= ~QMF_GRAYED; + g_arenaservers.sortkey.generic.flags &= ~QMF_GRAYED; + g_arenaservers.showempty.generic.flags &= ~QMF_GRAYED; + g_arenaservers.showfull.generic.flags &= ~QMF_GRAYED; + g_arenaservers.list.generic.flags &= ~QMF_GRAYED; + g_arenaservers.refresh.generic.flags &= ~QMF_GRAYED; + g_arenaservers.go.generic.flags &= ~QMF_GRAYED; + g_arenaservers.punkbuster.generic.flags &= ~QMF_GRAYED; + + // update status bar + if( g_servertype == AS_GLOBAL || g_servertype == AS_MPLAYER ) { + g_arenaservers.statusbar.string = quake3worldMessage; + } + else { + g_arenaservers.statusbar.string = ""; + } + + } + } + else { + // no servers found + if( g_arenaservers.refreshservers ) { + strcpy( g_arenaservers.status.string,"Scanning For Servers." ); + g_arenaservers.statusbar.string = "Press SPACE to stop"; + + // disable controls during refresh + g_arenaservers.master.generic.flags |= QMF_GRAYED; + g_arenaservers.gametype.generic.flags |= QMF_GRAYED; + g_arenaservers.sortkey.generic.flags |= QMF_GRAYED; + g_arenaservers.showempty.generic.flags |= QMF_GRAYED; + g_arenaservers.showfull.generic.flags |= QMF_GRAYED; + g_arenaservers.list.generic.flags |= QMF_GRAYED; + g_arenaservers.refresh.generic.flags |= QMF_GRAYED; + g_arenaservers.go.generic.flags |= QMF_GRAYED; + g_arenaservers.punkbuster.generic.flags |= QMF_GRAYED; + } + else { + if( g_arenaservers.numqueriedservers < 0 ) { + strcpy(g_arenaservers.status.string,"No Response From Master Server." ); + } + else { + strcpy(g_arenaservers.status.string,"No Servers Found." ); + } + + // update status bar + if( g_servertype == AS_GLOBAL || g_servertype == AS_MPLAYER ) { + g_arenaservers.statusbar.string = quake3worldMessage; + } + else { + g_arenaservers.statusbar.string = ""; + } + + // end of refresh - set control state + g_arenaservers.master.generic.flags &= ~QMF_GRAYED; + g_arenaservers.gametype.generic.flags &= ~QMF_GRAYED; + g_arenaservers.sortkey.generic.flags &= ~QMF_GRAYED; + g_arenaservers.showempty.generic.flags &= ~QMF_GRAYED; + g_arenaservers.showfull.generic.flags &= ~QMF_GRAYED; + g_arenaservers.list.generic.flags |= QMF_GRAYED; + g_arenaservers.refresh.generic.flags &= ~QMF_GRAYED; + g_arenaservers.go.generic.flags |= QMF_GRAYED; + g_arenaservers.punkbuster.generic.flags &= ~QMF_GRAYED; + } + + // zero out list box + g_arenaservers.list.numitems = 0; + g_arenaservers.list.curvalue = 0; + g_arenaservers.list.top = 0; + + // update picture + ArenaServers_UpdatePicture(); + return; + } + + // build list box strings - apply culling filters + servernodeptr = g_arenaservers.serverlist; + count = *g_arenaservers.numservers; + for( i = 0, j = 0; i < count; i++, servernodeptr++ ) { + tableptr = &g_arenaservers.table[j]; + tableptr->servernode = servernodeptr; + buff = tableptr->buff; + + // can only cull valid results + if( !g_emptyservers && !servernodeptr->numclients ) { + continue; + } + + if( !g_fullservers && ( servernodeptr->numclients == servernodeptr->maxclients ) ) { + continue; + } + + switch( g_gametype ) { + case GAMES_ALL: + break; + + case GAMES_FFA: + if( servernodeptr->gametype != GT_FFA ) { + continue; + } + break; + + case GAMES_TEAMPLAY: + if( servernodeptr->gametype != GT_TEAM ) { + continue; + } + break; + + case GAMES_TOURNEY: + if( servernodeptr->gametype != GT_TOURNAMENT ) { + continue; + } + break; + + case GAMES_CTF: + if( servernodeptr->gametype != GT_CTF ) { + continue; + } + break; + } + + if( servernodeptr->pingtime < servernodeptr->minPing ) { + pingColor = S_COLOR_BLUE; + } + else if( servernodeptr->maxPing && servernodeptr->pingtime > servernodeptr->maxPing ) { + pingColor = S_COLOR_BLUE; + } + else if( servernodeptr->pingtime < 200 ) { + pingColor = S_COLOR_GREEN; + } + else if( servernodeptr->pingtime < 400 ) { + pingColor = S_COLOR_YELLOW; + } + else { + pingColor = S_COLOR_RED; + } + + Com_sprintf( buff, MAX_LISTBOXWIDTH, "%-20.20s %-12.12s %2d/%2d %-8.8s %3s %s%3d " S_COLOR_YELLOW "%s", + servernodeptr->hostname, servernodeptr->mapname, servernodeptr->numclients, + servernodeptr->maxclients, servernodeptr->gamename, + netnames[servernodeptr->nettype], pingColor, servernodeptr->pingtime, servernodeptr->bPB ? "Yes" : "No" ); + j++; + } + + g_arenaservers.list.numitems = j; + g_arenaservers.list.curvalue = 0; + g_arenaservers.list.top = 0; + + // update picture + ArenaServers_UpdatePicture(); +} + + +/* +================= +ArenaServers_Remove +================= +*/ +static void ArenaServers_Remove( void ) +{ + int i; + servernode_t* servernodeptr; + table_t* tableptr; + + if (!g_arenaservers.list.numitems) + return; + + // remove selected item from display list + // items are in scattered order due to sort and cull + // perform delete on list box contents, resync all lists + + tableptr = &g_arenaservers.table[g_arenaservers.list.curvalue]; + servernodeptr = tableptr->servernode; + + // find address in master list + for (i=0; iadrstr)) + break; + + // delete address from master list + if (i <= g_arenaservers.numfavoriteaddresses-1) + { + if (i < g_arenaservers.numfavoriteaddresses-1) + { + // shift items up + memcpy( &g_arenaservers.favoriteaddresses[i], &g_arenaservers.favoriteaddresses[i+1], (g_arenaservers.numfavoriteaddresses - i - 1)*sizeof(MAX_ADDRESSLENGTH)); + } + g_arenaservers.numfavoriteaddresses--; + } + + // find address in server list + for (i=0; i= ArenaServers_MaxPing()) && (g_servertype != AS_FAVORITES)) + { + // slow global or local servers do not get entered + return; + } + + if (*g_arenaservers.numservers >= g_arenaservers.maxservers) { + // list full; + servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers)-1; + } else { + // next slot + servernodeptr = g_arenaservers.serverlist+(*g_arenaservers.numservers); + (*g_arenaservers.numservers)++; + } + + Q_strncpyz( servernodeptr->adrstr, adrstr, MAX_ADDRESSLENGTH ); + + Q_strncpyz( servernodeptr->hostname, Info_ValueForKey( info, "hostname"), MAX_HOSTNAMELENGTH ); + Q_CleanStr( servernodeptr->hostname ); + Q_strupr( servernodeptr->hostname ); + + Q_strncpyz( servernodeptr->mapname, Info_ValueForKey( info, "mapname"), MAX_MAPNAMELENGTH ); + Q_CleanStr( servernodeptr->mapname ); + Q_strupr( servernodeptr->mapname ); + + servernodeptr->numclients = atoi( Info_ValueForKey( info, "clients") ); + servernodeptr->maxclients = atoi( Info_ValueForKey( info, "sv_maxclients") ); + servernodeptr->pingtime = pingtime; + servernodeptr->minPing = atoi( Info_ValueForKey( info, "minPing") ); + servernodeptr->maxPing = atoi( Info_ValueForKey( info, "maxPing") ); + servernodeptr->bPB = atoi( Info_ValueForKey( info, "punkbuster") ); + + /* + s = Info_ValueForKey( info, "nettype" ); + for (i=0; ;i++) + { + if (!netnames[i]) + { + servernodeptr->nettype = 0; + break; + } + else if (!Q_stricmp( netnames[i], s )) + { + servernodeptr->nettype = i; + break; + } + } + */ + servernodeptr->nettype = atoi(Info_ValueForKey(info, "nettype")); + + s = Info_ValueForKey( info, "game"); + i = atoi( Info_ValueForKey( info, "gametype") ); + if( i < 0 ) { + i = 0; + } + else if( i > 11 ) { + i = 12; + } + if( *s ) { + servernodeptr->gametype = i;//-1; + Q_strncpyz( servernodeptr->gamename, s, sizeof(servernodeptr->gamename) ); + } + else { + servernodeptr->gametype = i; + Q_strncpyz( servernodeptr->gamename, gamenames[i], sizeof(servernodeptr->gamename) ); + } +} + + +/* +================= +ArenaServers_InsertFavorites + +Insert nonresponsive address book entries into display lists. +================= +*/ +void ArenaServers_InsertFavorites( void ) +{ + int i; + int j; + char info[MAX_INFO_STRING]; + + // resync existing results with new or deleted cvars + info[0] = '\0'; + Info_SetValueForKey( info, "hostname", "No Response" ); + for (i=0; i= g_numfavoriteservers) + { + // not in list, add it + ArenaServers_Insert( g_arenaservers.favoriteaddresses[i], info, ArenaServers_MaxPing() ); + } + } +} + + +/* +================= +ArenaServers_LoadFavorites + +Load cvar address book entries into local lists. +================= +*/ +void ArenaServers_LoadFavorites( void ) +{ + int i; + int j; + int numtempitems; + char emptyinfo[MAX_INFO_STRING]; + char adrstr[MAX_ADDRESSLENGTH]; + servernode_t templist[MAX_FAVORITESERVERS]; + qboolean found; + + found = qfalse; + emptyinfo[0] = '\0'; + + // copy the old + memcpy( templist, g_favoriteserverlist, sizeof(servernode_t)*MAX_FAVORITESERVERS ); + numtempitems = g_numfavoriteservers; + + // clear the current for sync + memset( g_favoriteserverlist, 0, sizeof(servernode_t)*MAX_FAVORITESERVERS ); + g_numfavoriteservers = 0; + + // resync existing results with new or deleted cvars + for (i=0; i '9') + continue; + + // favorite server addresses must be maintained outside refresh list + // this mimics local and global netadr's stored in client + // these can be fetched to fill ping list + strcpy( g_arenaservers.favoriteaddresses[g_numfavoriteservers], adrstr ); + + // find this server in the old list + for (j=0; j= 0) + { + g_arenaservers.currentping = *g_arenaservers.numservers; + g_arenaservers.numqueriedservers = *g_arenaservers.numservers; + } + + // sort + qsort( g_arenaservers.serverlist, *g_arenaservers.numservers, sizeof( servernode_t ), ArenaServers_Compare); + + ArenaServers_UpdateMenu(); +} + + +/* +================= +ArenaServers_DoRefresh +================= +*/ +static void ArenaServers_DoRefresh( void ) +{ + int i; + int j; + int time; + int maxPing; + char adrstr[MAX_ADDRESSLENGTH]; + char info[MAX_INFO_STRING]; + + if (uis.realtime < g_arenaservers.refreshtime) + { + if (g_servertype != AS_FAVORITES) { + if (g_servertype == AS_LOCAL) { + if (!trap_LAN_GetServerCount(g_servertype)) { + return; + } + } + if (trap_LAN_GetServerCount(g_servertype) < 0) { + // still waiting for response + return; + } + } + } + + if (uis.realtime < g_arenaservers.nextpingtime) + { + // wait for time trigger + return; + } + + // trigger at 10Hz intervals + g_arenaservers.nextpingtime = uis.realtime + 10; + + // process ping results + maxPing = ArenaServers_MaxPing(); + for (i=0; i maxPing) + { + // stale it out + info[0] = '\0'; + time = maxPing; + } + else + { + trap_LAN_GetPingInfo( i, info, MAX_INFO_STRING ); + } + + // insert ping results + ArenaServers_Insert( adrstr, info, time ); + + // clear this query from internal list + g_arenaservers.pinglist[j].adrstr[0] = '\0'; + } + + // clear this query from external list + trap_LAN_ClearPing( i ); + } + + // get results of servers query + // counts can increase as servers respond + if (g_servertype == AS_FAVORITES) { + g_arenaservers.numqueriedservers = g_arenaservers.numfavoriteaddresses; + } else { + g_arenaservers.numqueriedservers = trap_LAN_GetServerCount(g_servertype); + } + +// if (g_arenaservers.numqueriedservers > g_arenaservers.maxservers) +// g_arenaservers.numqueriedservers = g_arenaservers.maxservers; + + // send ping requests in reasonable bursts + // iterate ping through all found servers + for (i=0; i= MAX_PINGREQUESTS) + { + // ping queue is full + break; + } + + // find empty slot + for (j=0; j= MAX_PINGREQUESTS) + // no empty slots available yet - wait for timeout + break; + + // get an address to ping + + if (g_servertype == AS_FAVORITES) { + strcpy( adrstr, g_arenaservers.favoriteaddresses[g_arenaservers.currentping] ); + } else { + trap_LAN_GetServerAddressString(g_servertype, g_arenaservers.currentping, adrstr, MAX_ADDRESSLENGTH ); + } + + strcpy( g_arenaservers.pinglist[j].adrstr, adrstr ); + g_arenaservers.pinglist[j].start = uis.realtime; + + trap_Cmd_ExecuteText( EXEC_NOW, va( "ping %s\n", adrstr ) ); + + // advance to next server + g_arenaservers.currentping++; + } + + if (!trap_LAN_GetPingQueueCount()) + { + // all pings completed + ArenaServers_StopRefresh(); + return; + } + + // update the user interface with ping status + ArenaServers_UpdateMenu(); +} + + +/* +================= +ArenaServers_StartRefresh +================= +*/ +static void ArenaServers_StartRefresh( void ) +{ + int i; + char myargs[32], protocol[32]; + + memset( g_arenaservers.serverlist, 0, g_arenaservers.maxservers*sizeof(table_t) ); + + for (i=0; iid; + + if( event != QM_ACTIVATED && id != ID_LIST ) { + return; + } + + switch( id ) { + case ID_MASTER: + value = g_arenaservers.master.curvalue; + if (value >= 1) + { + value++; + } + trap_Cvar_SetValue( "ui_browserMaster", value ); + ArenaServers_SetType( value ); + break; + + case ID_GAMETYPE: + trap_Cvar_SetValue( "ui_browserGameType", g_arenaservers.gametype.curvalue ); + g_gametype = g_arenaservers.gametype.curvalue; + ArenaServers_UpdateMenu(); + break; + + case ID_SORTKEY: + trap_Cvar_SetValue( "ui_browserSortKey", g_arenaservers.sortkey.curvalue ); + ArenaServers_Sort( g_arenaservers.sortkey.curvalue ); + ArenaServers_UpdateMenu(); + break; + + case ID_SHOW_FULL: + trap_Cvar_SetValue( "ui_browserShowFull", g_arenaservers.showfull.curvalue ); + g_fullservers = g_arenaservers.showfull.curvalue; + ArenaServers_UpdateMenu(); + break; + + case ID_SHOW_EMPTY: + trap_Cvar_SetValue( "ui_browserShowEmpty", g_arenaservers.showempty.curvalue ); + g_emptyservers = g_arenaservers.showempty.curvalue; + ArenaServers_UpdateMenu(); + break; + + case ID_LIST: + if( event == QM_GOTFOCUS ) { + ArenaServers_UpdatePicture(); + } + break; + + case ID_SCROLL_UP: + ScrollList_Key( &g_arenaservers.list, K_UPARROW ); + break; + + case ID_SCROLL_DOWN: + ScrollList_Key( &g_arenaservers.list, K_DOWNARROW ); + break; + + case ID_BACK: + ArenaServers_StopRefresh(); + ArenaServers_SaveChanges(); + UI_PopMenu(); + break; + + case ID_REFRESH: + ArenaServers_StartRefresh(); + break; + + case ID_SPECIFY: + UI_SpecifyServerMenu(); + break; + + case ID_CREATE: + UI_StartServerMenu( qtrue ); + break; + + case ID_CONNECT: + ArenaServers_Go(); + break; + + case ID_REMOVE: + ArenaServers_Remove(); + ArenaServers_UpdateMenu(); + break; + + case ID_PUNKBUSTER: + if (g_arenaservers.punkbuster.curvalue) + { + UI_ConfirmMenu_Style( "Enable Punkbuster?", UI_CENTER|UI_INVERSE|UI_SMALLFONT, (voidfunc_f)NULL, Punkbuster_ConfirmEnable ); + } + else + { + UI_ConfirmMenu_Style( "Disable Punkbuster?", UI_CENTER|UI_INVERSE|UI_SMALLFONT, (voidfunc_f)NULL, Punkbuster_ConfirmDisable ); + } + break; + } +} + + +/* +================= +ArenaServers_MenuDraw +================= +*/ +static void ArenaServers_MenuDraw( void ) +{ + if (g_arenaservers.refreshservers) + ArenaServers_DoRefresh(); + + Menu_Draw( &g_arenaservers.menu ); +} + + +/* +================= +ArenaServers_MenuKey +================= +*/ +static sfxHandle_t ArenaServers_MenuKey( int key ) { + if( key == K_SPACE && g_arenaservers.refreshservers ) { + ArenaServers_StopRefresh(); + return menu_move_sound; + } + + if( ( key == K_DEL || key == K_KP_DEL ) && ( g_servertype == AS_FAVORITES ) && + ( Menu_ItemAtCursor( &g_arenaservers.menu) == &g_arenaservers.list ) ) { + ArenaServers_Remove(); + ArenaServers_UpdateMenu(); + return menu_move_sound; + } + + if( key == K_MOUSE2 || key == K_ESCAPE ) { + ArenaServers_StopRefresh(); + ArenaServers_SaveChanges(); + } + + + return Menu_DefaultKey( &g_arenaservers.menu, key ); +} + + +/* +================= +ArenaServers_MenuInit +================= +*/ +static void ArenaServers_MenuInit( void ) { + int i; + int type; + int y; + int value; + static char statusbuffer[MAX_STATUSLENGTH]; + + // zero set all our globals + memset( &g_arenaservers, 0 ,sizeof(arenaservers_t) ); + + ArenaServers_Cache(); + + g_arenaservers.menu.fullscreen = qtrue; + g_arenaservers.menu.wrapAround = qtrue; + g_arenaservers.menu.draw = ArenaServers_MenuDraw; + g_arenaservers.menu.key = ArenaServers_MenuKey; + + g_arenaservers.banner.generic.type = MTYPE_BTEXT; + g_arenaservers.banner.generic.flags = QMF_CENTER_JUSTIFY; + g_arenaservers.banner.generic.x = 320; + g_arenaservers.banner.generic.y = 16; + g_arenaservers.banner.string = "ARENA SERVERS"; + g_arenaservers.banner.style = UI_CENTER; + g_arenaservers.banner.color = color_white; + + y = 80; + g_arenaservers.master.generic.type = MTYPE_SPINCONTROL; + g_arenaservers.master.generic.name = "Servers:"; + g_arenaservers.master.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + g_arenaservers.master.generic.callback = ArenaServers_Event; + g_arenaservers.master.generic.id = ID_MASTER; + g_arenaservers.master.generic.x = 320; + g_arenaservers.master.generic.y = y; + g_arenaservers.master.itemnames = master_items; + + y += SMALLCHAR_HEIGHT; + g_arenaservers.gametype.generic.type = MTYPE_SPINCONTROL; + g_arenaservers.gametype.generic.name = "Game Type:"; + g_arenaservers.gametype.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + g_arenaservers.gametype.generic.callback = ArenaServers_Event; + g_arenaservers.gametype.generic.id = ID_GAMETYPE; + g_arenaservers.gametype.generic.x = 320; + g_arenaservers.gametype.generic.y = y; + g_arenaservers.gametype.itemnames = servertype_items; + + y += SMALLCHAR_HEIGHT; + g_arenaservers.sortkey.generic.type = MTYPE_SPINCONTROL; + g_arenaservers.sortkey.generic.name = "Sort By:"; + g_arenaservers.sortkey.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + g_arenaservers.sortkey.generic.callback = ArenaServers_Event; + g_arenaservers.sortkey.generic.id = ID_SORTKEY; + g_arenaservers.sortkey.generic.x = 320; + g_arenaservers.sortkey.generic.y = y; + g_arenaservers.sortkey.itemnames = sortkey_items; + + y += SMALLCHAR_HEIGHT; + g_arenaservers.showfull.generic.type = MTYPE_RADIOBUTTON; + g_arenaservers.showfull.generic.name = "Show Full:"; + g_arenaservers.showfull.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + g_arenaservers.showfull.generic.callback = ArenaServers_Event; + g_arenaservers.showfull.generic.id = ID_SHOW_FULL; + g_arenaservers.showfull.generic.x = 320; + g_arenaservers.showfull.generic.y = y; + + y += SMALLCHAR_HEIGHT; + g_arenaservers.showempty.generic.type = MTYPE_RADIOBUTTON; + g_arenaservers.showempty.generic.name = "Show Empty:"; + g_arenaservers.showempty.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + g_arenaservers.showempty.generic.callback = ArenaServers_Event; + g_arenaservers.showempty.generic.id = ID_SHOW_EMPTY; + g_arenaservers.showempty.generic.x = 320; + g_arenaservers.showempty.generic.y = y; + + y += 3 * SMALLCHAR_HEIGHT; + g_arenaservers.list.generic.type = MTYPE_SCROLLLIST; + g_arenaservers.list.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; + g_arenaservers.list.generic.id = ID_LIST; + g_arenaservers.list.generic.callback = ArenaServers_Event; + g_arenaservers.list.generic.x = 72; + g_arenaservers.list.generic.y = y; + g_arenaservers.list.width = MAX_LISTBOXWIDTH; + g_arenaservers.list.height = 11; + g_arenaservers.list.itemnames = (const char **)g_arenaservers.items; + for( i = 0; i < MAX_LISTBOXITEMS; i++ ) { + g_arenaservers.items[i] = g_arenaservers.table[i].buff; + } + + g_arenaservers.mappic.generic.type = MTYPE_BITMAP; + g_arenaservers.mappic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + g_arenaservers.mappic.generic.x = 72; + g_arenaservers.mappic.generic.y = 80; + g_arenaservers.mappic.width = 128; + g_arenaservers.mappic.height = 96; + g_arenaservers.mappic.errorpic = ART_UNKNOWNMAP; + + g_arenaservers.arrows.generic.type = MTYPE_BITMAP; + g_arenaservers.arrows.generic.name = ART_ARROWS0; + g_arenaservers.arrows.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + g_arenaservers.arrows.generic.callback = ArenaServers_Event; + g_arenaservers.arrows.generic.x = 512+48; + g_arenaservers.arrows.generic.y = 240-64+16; + g_arenaservers.arrows.width = 64; + g_arenaservers.arrows.height = 128; + + g_arenaservers.up.generic.type = MTYPE_BITMAP; + g_arenaservers.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + g_arenaservers.up.generic.callback = ArenaServers_Event; + g_arenaservers.up.generic.id = ID_SCROLL_UP; + g_arenaservers.up.generic.x = 512+48; + g_arenaservers.up.generic.y = 240-64+16; + g_arenaservers.up.width = 64; + g_arenaservers.up.height = 64; + g_arenaservers.up.focuspic = ART_ARROWS_UP; + + g_arenaservers.down.generic.type = MTYPE_BITMAP; + g_arenaservers.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + g_arenaservers.down.generic.callback = ArenaServers_Event; + g_arenaservers.down.generic.id = ID_SCROLL_DOWN; + g_arenaservers.down.generic.x = 512+48; + g_arenaservers.down.generic.y = 240+16; + g_arenaservers.down.width = 64; + g_arenaservers.down.height = 64; + g_arenaservers.down.focuspic = ART_ARROWS_DOWN; + + y = 376; + g_arenaservers.status.generic.type = MTYPE_TEXT; + g_arenaservers.status.generic.x = 320; + g_arenaservers.status.generic.y = y; + g_arenaservers.status.string = statusbuffer; + g_arenaservers.status.style = UI_CENTER|UI_SMALLFONT; + g_arenaservers.status.color = menu_text_color; + + y += SMALLCHAR_HEIGHT; + g_arenaservers.statusbar.generic.type = MTYPE_TEXT; + g_arenaservers.statusbar.generic.x = 320; + g_arenaservers.statusbar.generic.y = y; + g_arenaservers.statusbar.string = ""; + g_arenaservers.statusbar.style = UI_CENTER|UI_SMALLFONT; + g_arenaservers.statusbar.color = text_color_normal; + + g_arenaservers.remove.generic.type = MTYPE_BITMAP; + g_arenaservers.remove.generic.name = ART_REMOVE0; + g_arenaservers.remove.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + g_arenaservers.remove.generic.callback = ArenaServers_Event; + g_arenaservers.remove.generic.id = ID_REMOVE; + g_arenaservers.remove.generic.x = 450; + g_arenaservers.remove.generic.y = 86; + g_arenaservers.remove.width = 96; + g_arenaservers.remove.height = 48; + g_arenaservers.remove.focuspic = ART_REMOVE1; + + g_arenaservers.back.generic.type = MTYPE_BITMAP; + g_arenaservers.back.generic.name = ART_BACK0; + g_arenaservers.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + g_arenaservers.back.generic.callback = ArenaServers_Event; + g_arenaservers.back.generic.id = ID_BACK; + g_arenaservers.back.generic.x = 0; + g_arenaservers.back.generic.y = 480-64; + g_arenaservers.back.width = 128; + g_arenaservers.back.height = 64; + g_arenaservers.back.focuspic = ART_BACK1; + + g_arenaservers.specify.generic.type = MTYPE_BITMAP; + g_arenaservers.specify.generic.name = ART_SPECIFY0; + g_arenaservers.specify.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + g_arenaservers.specify.generic.callback = ArenaServers_Event; + g_arenaservers.specify.generic.id = ID_SPECIFY; + g_arenaservers.specify.generic.x = 128; + g_arenaservers.specify.generic.y = 480-64; + g_arenaservers.specify.width = 128; + g_arenaservers.specify.height = 64; + g_arenaservers.specify.focuspic = ART_SPECIFY1; + + g_arenaservers.refresh.generic.type = MTYPE_BITMAP; + g_arenaservers.refresh.generic.name = ART_REFRESH0; + g_arenaservers.refresh.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + g_arenaservers.refresh.generic.callback = ArenaServers_Event; + g_arenaservers.refresh.generic.id = ID_REFRESH; + g_arenaservers.refresh.generic.x = 256; + g_arenaservers.refresh.generic.y = 480-64; + g_arenaservers.refresh.width = 128; + g_arenaservers.refresh.height = 64; + g_arenaservers.refresh.focuspic = ART_REFRESH1; + + g_arenaservers.create.generic.type = MTYPE_BITMAP; + g_arenaservers.create.generic.name = ART_CREATE0; + g_arenaservers.create.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + g_arenaservers.create.generic.callback = ArenaServers_Event; + g_arenaservers.create.generic.id = ID_CREATE; + g_arenaservers.create.generic.x = 384; + g_arenaservers.create.generic.y = 480-64; + g_arenaservers.create.width = 128; + g_arenaservers.create.height = 64; + g_arenaservers.create.focuspic = ART_CREATE1; + + g_arenaservers.go.generic.type = MTYPE_BITMAP; + g_arenaservers.go.generic.name = ART_CONNECT0; + g_arenaservers.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + g_arenaservers.go.generic.callback = ArenaServers_Event; + g_arenaservers.go.generic.id = ID_CONNECT; + g_arenaservers.go.generic.x = 640; + g_arenaservers.go.generic.y = 480-64; + g_arenaservers.go.width = 128; + g_arenaservers.go.height = 64; + g_arenaservers.go.focuspic = ART_CONNECT1; + + g_arenaservers.punkbuster.generic.type = MTYPE_SPINCONTROL; + g_arenaservers.punkbuster.generic.name = "Punkbuster:"; + g_arenaservers.punkbuster.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + g_arenaservers.punkbuster.generic.callback = ArenaServers_Event; + g_arenaservers.punkbuster.generic.id = ID_PUNKBUSTER; + g_arenaservers.punkbuster.generic.x = 480+32; + g_arenaservers.punkbuster.generic.y = 144; + g_arenaservers.punkbuster.itemnames = punkbuster_items; + + g_arenaservers.pblogo.generic.type = MTYPE_BITMAP; + g_arenaservers.pblogo.generic.name = ART_PUNKBUSTER; + g_arenaservers.pblogo.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + g_arenaservers.pblogo.generic.x = 526; + g_arenaservers.pblogo.generic.y = 176; + g_arenaservers.pblogo.width = 32; + g_arenaservers.pblogo.height = 16; + g_arenaservers.pblogo.errorpic = ART_UNKNOWNMAP; + + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.banner ); + + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.master ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.gametype ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.sortkey ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.showfull); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.showempty ); + + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.mappic ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.list ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.status ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.statusbar ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.arrows ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.up ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.down ); + + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.remove ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.back ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.specify ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.refresh ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.create ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.go ); + + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.punkbuster ); + Menu_AddItem( &g_arenaservers.menu, (void*) &g_arenaservers.pblogo ); + + ArenaServers_LoadFavorites(); + + g_servertype = Com_Clamp( 0, 3, ui_browserMaster.integer ); + // hack to get rid of MPlayer stuff + value = g_servertype; + if (value >= 1) + value--; + g_arenaservers.master.curvalue = value; + + g_gametype = Com_Clamp( 0, 4, ui_browserGameType.integer ); + g_arenaservers.gametype.curvalue = g_gametype; + + g_sortkey = Com_Clamp( 0, 4, ui_browserSortKey.integer ); + g_arenaservers.sortkey.curvalue = g_sortkey; + + g_fullservers = Com_Clamp( 0, 1, ui_browserShowFull.integer ); + g_arenaservers.showfull.curvalue = g_fullservers; + + g_emptyservers = Com_Clamp( 0, 1, ui_browserShowEmpty.integer ); + g_arenaservers.showempty.curvalue = g_emptyservers; + + g_arenaservers.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "cl_punkbuster" ) ); + + // force to initial state and refresh + type = g_servertype; + g_servertype = -1; + ArenaServers_SetType( type ); + + trap_Cvar_Register(NULL, "debug_protocol", "", 0 ); +} + + +/* +================= +ArenaServers_Cache +================= +*/ +void ArenaServers_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_CREATE0 ); + trap_R_RegisterShaderNoMip( ART_CREATE1 ); + trap_R_RegisterShaderNoMip( ART_SPECIFY0 ); + trap_R_RegisterShaderNoMip( ART_SPECIFY1 ); + trap_R_RegisterShaderNoMip( ART_REFRESH0 ); + trap_R_RegisterShaderNoMip( ART_REFRESH1 ); + trap_R_RegisterShaderNoMip( ART_CONNECT0 ); + trap_R_RegisterShaderNoMip( ART_CONNECT1 ); + trap_R_RegisterShaderNoMip( ART_ARROWS0 ); + trap_R_RegisterShaderNoMip( ART_ARROWS_UP ); + trap_R_RegisterShaderNoMip( ART_ARROWS_DOWN ); + trap_R_RegisterShaderNoMip( ART_UNKNOWNMAP ); + trap_R_RegisterShaderNoMip( ART_PUNKBUSTER ); +} + + +/* +================= +UI_ArenaServersMenu +================= +*/ +void UI_ArenaServersMenu( void ) { + ArenaServers_MenuInit(); + UI_PushMenu( &g_arenaservers.menu ); +} diff --git a/code/q3_ui/ui_setup.c b/code/q3_ui/ui_setup.c index 25e01d5..cf7f172 100755 --- a/code/q3_ui/ui_setup.c +++ b/code/q3_ui/ui_setup.c @@ -1,327 +1,327 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -SETUP MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define SETUP_MENU_VERTICAL_SPACING 34 - -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" - -#define ID_CUSTOMIZEPLAYER 10 -#define ID_CUSTOMIZECONTROLS 11 -#define ID_SYSTEMCONFIG 12 -#define ID_GAME 13 -#define ID_CDKEY 14 -#define ID_LOAD 15 -#define ID_SAVE 16 -#define ID_DEFAULTS 17 -#define ID_BACK 18 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - menutext_s setupplayer; - menutext_s setupcontrols; - menutext_s setupsystem; - menutext_s game; - menutext_s cdkey; -// menutext_s load; -// menutext_s save; - menutext_s defaults; - menubitmap_s back; -} setupMenuInfo_t; - -static setupMenuInfo_t setupMenuInfo; - - -/* -================= -Setup_ResetDefaults_Action -================= -*/ -static void Setup_ResetDefaults_Action( qboolean result ) { - if( !result ) { - return; - } - trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n"); - trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n"); - trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); -} - - -/* -================= -Setup_ResetDefaults_Draw -================= -*/ -static void Setup_ResetDefaults_Draw( void ) { - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This will reset *ALL*", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "options to their default values.", UI_CENTER|UI_SMALLFONT, color_yellow ); -} - - -/* -=============== -UI_SetupMenu_Event -=============== -*/ -static void UI_SetupMenu_Event( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_CUSTOMIZEPLAYER: - UI_PlayerSettingsMenu(); - break; - - case ID_CUSTOMIZECONTROLS: - UI_ControlsMenu(); - break; - - case ID_SYSTEMCONFIG: - UI_GraphicsOptionsMenu(); - break; - - case ID_GAME: - UI_PreferencesMenu(); - break; - - case ID_CDKEY: - UI_CDKeyMenu(); - break; - -// case ID_LOAD: -// UI_LoadConfigMenu(); -// break; - -// case ID_SAVE: -// UI_SaveConfigMenu(); -// break; - - case ID_DEFAULTS: - UI_ConfirmMenu( "SET TO DEFAULTS?", Setup_ResetDefaults_Draw, Setup_ResetDefaults_Action ); - break; - - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -UI_SetupMenu_Init -=============== -*/ -static void UI_SetupMenu_Init( void ) { - int y; - - UI_SetupMenu_Cache(); - - memset( &setupMenuInfo, 0, sizeof(setupMenuInfo) ); - setupMenuInfo.menu.wrapAround = qtrue; - setupMenuInfo.menu.fullscreen = qtrue; - - setupMenuInfo.banner.generic.type = MTYPE_BTEXT; - setupMenuInfo.banner.generic.x = 320; - setupMenuInfo.banner.generic.y = 16; - setupMenuInfo.banner.string = "SETUP"; - setupMenuInfo.banner.color = color_white; - setupMenuInfo.banner.style = UI_CENTER; - - setupMenuInfo.framel.generic.type = MTYPE_BITMAP; - setupMenuInfo.framel.generic.name = ART_FRAMEL; - setupMenuInfo.framel.generic.flags = QMF_INACTIVE; - setupMenuInfo.framel.generic.x = 0; - setupMenuInfo.framel.generic.y = 78; - setupMenuInfo.framel.width = 256; - setupMenuInfo.framel.height = 329; - - setupMenuInfo.framer.generic.type = MTYPE_BITMAP; - setupMenuInfo.framer.generic.name = ART_FRAMER; - setupMenuInfo.framer.generic.flags = QMF_INACTIVE; - setupMenuInfo.framer.generic.x = 376; - setupMenuInfo.framer.generic.y = 76; - setupMenuInfo.framer.width = 256; - setupMenuInfo.framer.height = 334; - - y = 134; - setupMenuInfo.setupplayer.generic.type = MTYPE_PTEXT; - setupMenuInfo.setupplayer.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.setupplayer.generic.x = 320; - setupMenuInfo.setupplayer.generic.y = y; - setupMenuInfo.setupplayer.generic.id = ID_CUSTOMIZEPLAYER; - setupMenuInfo.setupplayer.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.setupplayer.string = "PLAYER"; - setupMenuInfo.setupplayer.color = color_red; - setupMenuInfo.setupplayer.style = UI_CENTER; - - y += SETUP_MENU_VERTICAL_SPACING; - setupMenuInfo.setupcontrols.generic.type = MTYPE_PTEXT; - setupMenuInfo.setupcontrols.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.setupcontrols.generic.x = 320; - setupMenuInfo.setupcontrols.generic.y = y; - setupMenuInfo.setupcontrols.generic.id = ID_CUSTOMIZECONTROLS; - setupMenuInfo.setupcontrols.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.setupcontrols.string = "CONTROLS"; - setupMenuInfo.setupcontrols.color = color_red; - setupMenuInfo.setupcontrols.style = UI_CENTER; - - y += SETUP_MENU_VERTICAL_SPACING; - setupMenuInfo.setupsystem.generic.type = MTYPE_PTEXT; - setupMenuInfo.setupsystem.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.setupsystem.generic.x = 320; - setupMenuInfo.setupsystem.generic.y = y; - setupMenuInfo.setupsystem.generic.id = ID_SYSTEMCONFIG; - setupMenuInfo.setupsystem.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.setupsystem.string = "SYSTEM"; - setupMenuInfo.setupsystem.color = color_red; - setupMenuInfo.setupsystem.style = UI_CENTER; - - y += SETUP_MENU_VERTICAL_SPACING; - setupMenuInfo.game.generic.type = MTYPE_PTEXT; - setupMenuInfo.game.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.game.generic.x = 320; - setupMenuInfo.game.generic.y = y; - setupMenuInfo.game.generic.id = ID_GAME; - setupMenuInfo.game.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.game.string = "GAME OPTIONS"; - setupMenuInfo.game.color = color_red; - setupMenuInfo.game.style = UI_CENTER; - - y += SETUP_MENU_VERTICAL_SPACING; - setupMenuInfo.cdkey.generic.type = MTYPE_PTEXT; - setupMenuInfo.cdkey.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.cdkey.generic.x = 320; - setupMenuInfo.cdkey.generic.y = y; - setupMenuInfo.cdkey.generic.id = ID_CDKEY; - setupMenuInfo.cdkey.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.cdkey.string = "CD Key"; - setupMenuInfo.cdkey.color = color_red; - setupMenuInfo.cdkey.style = UI_CENTER; - - if( !trap_Cvar_VariableValue( "cl_paused" ) ) { -#if 0 - y += SETUP_MENU_VERTICAL_SPACING; - setupMenuInfo.load.generic.type = MTYPE_PTEXT; - setupMenuInfo.load.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.load.generic.x = 320; - setupMenuInfo.load.generic.y = y; - setupMenuInfo.load.generic.id = ID_LOAD; - setupMenuInfo.load.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.load.string = "LOAD"; - setupMenuInfo.load.color = color_red; - setupMenuInfo.load.style = UI_CENTER; - - y += SETUP_MENU_VERTICAL_SPACING; - setupMenuInfo.save.generic.type = MTYPE_PTEXT; - setupMenuInfo.save.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.save.generic.x = 320; - setupMenuInfo.save.generic.y = y; - setupMenuInfo.save.generic.id = ID_SAVE; - setupMenuInfo.save.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.save.string = "SAVE"; - setupMenuInfo.save.color = color_red; - setupMenuInfo.save.style = UI_CENTER; -#endif - - y += SETUP_MENU_VERTICAL_SPACING; - setupMenuInfo.defaults.generic.type = MTYPE_PTEXT; - setupMenuInfo.defaults.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.defaults.generic.x = 320; - setupMenuInfo.defaults.generic.y = y; - setupMenuInfo.defaults.generic.id = ID_DEFAULTS; - setupMenuInfo.defaults.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.defaults.string = "DEFAULTS"; - setupMenuInfo.defaults.color = color_red; - setupMenuInfo.defaults.style = UI_CENTER; - } - - setupMenuInfo.back.generic.type = MTYPE_BITMAP; - setupMenuInfo.back.generic.name = ART_BACK0; - setupMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - setupMenuInfo.back.generic.id = ID_BACK; - setupMenuInfo.back.generic.callback = UI_SetupMenu_Event; - setupMenuInfo.back.generic.x = 0; - setupMenuInfo.back.generic.y = 480-64; - setupMenuInfo.back.width = 128; - setupMenuInfo.back.height = 64; - setupMenuInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.banner ); - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.framel ); - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.framer ); - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.setupplayer ); - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.setupcontrols ); - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.setupsystem ); - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.game ); - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.cdkey ); -// Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.load ); -// Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.save ); - if( !trap_Cvar_VariableValue( "cl_paused" ) ) { - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.defaults ); - } - Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.back ); -} - - -/* -================= -UI_SetupMenu_Cache -================= -*/ -void UI_SetupMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); -} - - -/* -=============== -UI_SetupMenu -=============== -*/ -void UI_SetupMenu( void ) { - UI_SetupMenu_Init(); - UI_PushMenu( &setupMenuInfo.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +SETUP MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define SETUP_MENU_VERTICAL_SPACING 34 + +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" + +#define ID_CUSTOMIZEPLAYER 10 +#define ID_CUSTOMIZECONTROLS 11 +#define ID_SYSTEMCONFIG 12 +#define ID_GAME 13 +#define ID_CDKEY 14 +#define ID_LOAD 15 +#define ID_SAVE 16 +#define ID_DEFAULTS 17 +#define ID_BACK 18 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + menutext_s setupplayer; + menutext_s setupcontrols; + menutext_s setupsystem; + menutext_s game; + menutext_s cdkey; +// menutext_s load; +// menutext_s save; + menutext_s defaults; + menubitmap_s back; +} setupMenuInfo_t; + +static setupMenuInfo_t setupMenuInfo; + + +/* +================= +Setup_ResetDefaults_Action +================= +*/ +static void Setup_ResetDefaults_Action( qboolean result ) { + if( !result ) { + return; + } + trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n"); + trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n"); + trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); +} + + +/* +================= +Setup_ResetDefaults_Draw +================= +*/ +static void Setup_ResetDefaults_Draw( void ) { + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This will reset *ALL*", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "options to their default values.", UI_CENTER|UI_SMALLFONT, color_yellow ); +} + + +/* +=============== +UI_SetupMenu_Event +=============== +*/ +static void UI_SetupMenu_Event( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_CUSTOMIZEPLAYER: + UI_PlayerSettingsMenu(); + break; + + case ID_CUSTOMIZECONTROLS: + UI_ControlsMenu(); + break; + + case ID_SYSTEMCONFIG: + UI_GraphicsOptionsMenu(); + break; + + case ID_GAME: + UI_PreferencesMenu(); + break; + + case ID_CDKEY: + UI_CDKeyMenu(); + break; + +// case ID_LOAD: +// UI_LoadConfigMenu(); +// break; + +// case ID_SAVE: +// UI_SaveConfigMenu(); +// break; + + case ID_DEFAULTS: + UI_ConfirmMenu( "SET TO DEFAULTS?", Setup_ResetDefaults_Draw, Setup_ResetDefaults_Action ); + break; + + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +UI_SetupMenu_Init +=============== +*/ +static void UI_SetupMenu_Init( void ) { + int y; + + UI_SetupMenu_Cache(); + + memset( &setupMenuInfo, 0, sizeof(setupMenuInfo) ); + setupMenuInfo.menu.wrapAround = qtrue; + setupMenuInfo.menu.fullscreen = qtrue; + + setupMenuInfo.banner.generic.type = MTYPE_BTEXT; + setupMenuInfo.banner.generic.x = 320; + setupMenuInfo.banner.generic.y = 16; + setupMenuInfo.banner.string = "SETUP"; + setupMenuInfo.banner.color = color_white; + setupMenuInfo.banner.style = UI_CENTER; + + setupMenuInfo.framel.generic.type = MTYPE_BITMAP; + setupMenuInfo.framel.generic.name = ART_FRAMEL; + setupMenuInfo.framel.generic.flags = QMF_INACTIVE; + setupMenuInfo.framel.generic.x = 0; + setupMenuInfo.framel.generic.y = 78; + setupMenuInfo.framel.width = 256; + setupMenuInfo.framel.height = 329; + + setupMenuInfo.framer.generic.type = MTYPE_BITMAP; + setupMenuInfo.framer.generic.name = ART_FRAMER; + setupMenuInfo.framer.generic.flags = QMF_INACTIVE; + setupMenuInfo.framer.generic.x = 376; + setupMenuInfo.framer.generic.y = 76; + setupMenuInfo.framer.width = 256; + setupMenuInfo.framer.height = 334; + + y = 134; + setupMenuInfo.setupplayer.generic.type = MTYPE_PTEXT; + setupMenuInfo.setupplayer.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.setupplayer.generic.x = 320; + setupMenuInfo.setupplayer.generic.y = y; + setupMenuInfo.setupplayer.generic.id = ID_CUSTOMIZEPLAYER; + setupMenuInfo.setupplayer.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.setupplayer.string = "PLAYER"; + setupMenuInfo.setupplayer.color = color_red; + setupMenuInfo.setupplayer.style = UI_CENTER; + + y += SETUP_MENU_VERTICAL_SPACING; + setupMenuInfo.setupcontrols.generic.type = MTYPE_PTEXT; + setupMenuInfo.setupcontrols.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.setupcontrols.generic.x = 320; + setupMenuInfo.setupcontrols.generic.y = y; + setupMenuInfo.setupcontrols.generic.id = ID_CUSTOMIZECONTROLS; + setupMenuInfo.setupcontrols.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.setupcontrols.string = "CONTROLS"; + setupMenuInfo.setupcontrols.color = color_red; + setupMenuInfo.setupcontrols.style = UI_CENTER; + + y += SETUP_MENU_VERTICAL_SPACING; + setupMenuInfo.setupsystem.generic.type = MTYPE_PTEXT; + setupMenuInfo.setupsystem.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.setupsystem.generic.x = 320; + setupMenuInfo.setupsystem.generic.y = y; + setupMenuInfo.setupsystem.generic.id = ID_SYSTEMCONFIG; + setupMenuInfo.setupsystem.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.setupsystem.string = "SYSTEM"; + setupMenuInfo.setupsystem.color = color_red; + setupMenuInfo.setupsystem.style = UI_CENTER; + + y += SETUP_MENU_VERTICAL_SPACING; + setupMenuInfo.game.generic.type = MTYPE_PTEXT; + setupMenuInfo.game.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.game.generic.x = 320; + setupMenuInfo.game.generic.y = y; + setupMenuInfo.game.generic.id = ID_GAME; + setupMenuInfo.game.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.game.string = "GAME OPTIONS"; + setupMenuInfo.game.color = color_red; + setupMenuInfo.game.style = UI_CENTER; + + y += SETUP_MENU_VERTICAL_SPACING; + setupMenuInfo.cdkey.generic.type = MTYPE_PTEXT; + setupMenuInfo.cdkey.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.cdkey.generic.x = 320; + setupMenuInfo.cdkey.generic.y = y; + setupMenuInfo.cdkey.generic.id = ID_CDKEY; + setupMenuInfo.cdkey.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.cdkey.string = "CD Key"; + setupMenuInfo.cdkey.color = color_red; + setupMenuInfo.cdkey.style = UI_CENTER; + + if( !trap_Cvar_VariableValue( "cl_paused" ) ) { +#if 0 + y += SETUP_MENU_VERTICAL_SPACING; + setupMenuInfo.load.generic.type = MTYPE_PTEXT; + setupMenuInfo.load.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.load.generic.x = 320; + setupMenuInfo.load.generic.y = y; + setupMenuInfo.load.generic.id = ID_LOAD; + setupMenuInfo.load.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.load.string = "LOAD"; + setupMenuInfo.load.color = color_red; + setupMenuInfo.load.style = UI_CENTER; + + y += SETUP_MENU_VERTICAL_SPACING; + setupMenuInfo.save.generic.type = MTYPE_PTEXT; + setupMenuInfo.save.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.save.generic.x = 320; + setupMenuInfo.save.generic.y = y; + setupMenuInfo.save.generic.id = ID_SAVE; + setupMenuInfo.save.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.save.string = "SAVE"; + setupMenuInfo.save.color = color_red; + setupMenuInfo.save.style = UI_CENTER; +#endif + + y += SETUP_MENU_VERTICAL_SPACING; + setupMenuInfo.defaults.generic.type = MTYPE_PTEXT; + setupMenuInfo.defaults.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.defaults.generic.x = 320; + setupMenuInfo.defaults.generic.y = y; + setupMenuInfo.defaults.generic.id = ID_DEFAULTS; + setupMenuInfo.defaults.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.defaults.string = "DEFAULTS"; + setupMenuInfo.defaults.color = color_red; + setupMenuInfo.defaults.style = UI_CENTER; + } + + setupMenuInfo.back.generic.type = MTYPE_BITMAP; + setupMenuInfo.back.generic.name = ART_BACK0; + setupMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + setupMenuInfo.back.generic.id = ID_BACK; + setupMenuInfo.back.generic.callback = UI_SetupMenu_Event; + setupMenuInfo.back.generic.x = 0; + setupMenuInfo.back.generic.y = 480-64; + setupMenuInfo.back.width = 128; + setupMenuInfo.back.height = 64; + setupMenuInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.banner ); + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.framel ); + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.framer ); + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.setupplayer ); + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.setupcontrols ); + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.setupsystem ); + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.game ); + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.cdkey ); +// Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.load ); +// Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.save ); + if( !trap_Cvar_VariableValue( "cl_paused" ) ) { + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.defaults ); + } + Menu_AddItem( &setupMenuInfo.menu, &setupMenuInfo.back ); +} + + +/* +================= +UI_SetupMenu_Cache +================= +*/ +void UI_SetupMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); +} + + +/* +=============== +UI_SetupMenu +=============== +*/ +void UI_SetupMenu( void ) { + UI_SetupMenu_Init(); + UI_PushMenu( &setupMenuInfo.menu ); +} diff --git a/code/q3_ui/ui_signup.c b/code/q3_ui/ui_signup.c index efe9529..e169b37 100755 --- a/code/q3_ui/ui_signup.c +++ b/code/q3_ui/ui_signup.c @@ -1,286 +1,286 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -// -// ui_signup.c -// - -#include "ui_local.h" - - -#define SIGNUP_FRAME "menu/art/cut_frame" - -#define ID_NAME 100 -#define ID_NAME_BOX 101 -#define ID_PASSWORD 102 -#define ID_PASSWORD_BOX 103 -#define ID_AGAIN 104 -#define ID_AGAIN_BOX 105 -#define ID_EMAIL 106 -#define ID_EMAIL_BOX 107 -#define ID_SIGNUP 108 -#define ID_CANCEL 109 - - -typedef struct -{ - menuframework_s menu; - menubitmap_s frame; - menutext_s name; - menufield_s name_box; - menutext_s password; - menufield_s password_box; - menutext_s again; - menufield_s again_box; - menutext_s email; - menufield_s email_box; - menutext_s signup; - menutext_s cancel; -} signup_t; - -static signup_t s_signup; - -static menuframework_s s_signup_menu; -static menuaction_s s_signup_signup; -static menuaction_s s_signup_cancel; - -static vec4_t s_signup_color_prompt = {1.00, 0.43, 0.00, 1.00}; - -/* -=============== -Signup_MenuEvent -=============== -*/ -static void Signup_MenuEvent( void* ptr, int event ) { - //char cmd[1024]; - - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_SIGNUP: - if( strcmp(s_signup.password_box.field.buffer, - s_signup.again_box.field.buffer) != 0 ) - { - // GRANK_FIXME - password mismatch - break; - } - // set name - //trap_Cvar_Set( "name", s_signup.name_box.field.buffer ); - /* - trap_Cvar_Set( "rank_name", s_signup.name_box.field.buffer ); - trap_Cvar_Set( "rank_pwd", s_signup.password_box.field.buffer ); - */ - - // create account - /* - sprintf( cmd, "cmd rank_create \"%s\" \"%s\" \"%s\"\n", - s_signup.name_box.field.buffer, - s_signup.password_box.field.buffer, - s_signup.email_box.field.buffer ); - trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); - */ - trap_CL_UI_RankUserCreate( - s_signup.name_box.field.buffer, - s_signup.password_box.field.buffer, - s_signup.email_box.field.buffer ); - - UI_ForceMenuOff(); - break; - - case ID_CANCEL: - UI_PopMenu(); - break; - } -} - -/* -=============== -Signup_MenuInit -=============== -*/ -void Signup_MenuInit( void ) { - grank_status_t status; - int y; - - memset( &s_signup, 0, sizeof(s_signup) ); - - Signup_Cache(); - - s_signup.menu.wrapAround = qtrue; - s_signup.menu.fullscreen = qfalse; - - s_signup.frame.generic.type = MTYPE_BITMAP; - s_signup.frame.generic.flags = QMF_INACTIVE; - s_signup.frame.generic.name = SIGNUP_FRAME; - s_signup.frame.generic.x = 142; //320-233; - s_signup.frame.generic.y = 118; //240-166; - s_signup.frame.width = 359; //466; - s_signup.frame.height = 256; //332; - - y = 194; - - s_signup.name.generic.type = MTYPE_PTEXT; - s_signup.name.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; - s_signup.name.generic.id = ID_NAME; - s_signup.name.generic.x = 310; - s_signup.name.generic.y = y; - s_signup.name.string = "NAME"; - s_signup.name.style = UI_RIGHT|UI_SMALLFONT; - s_signup.name.color = s_signup_color_prompt; - - s_signup.name_box.generic.type = MTYPE_FIELD; - s_signup.name_box.generic.ownerdraw = Rankings_DrawName; - s_signup.name_box.generic.name = ""; - s_signup.name_box.generic.flags = 0; - s_signup.name_box.generic.x = 330; - s_signup.name_box.generic.y = y; - s_signup.name_box.field.widthInChars = 16; - s_signup.name_box.field.maxchars = 16; - y += 20; - - s_signup.password.generic.type = MTYPE_PTEXT; - s_signup.password.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; - s_signup.password.generic.id = ID_PASSWORD; - s_signup.password.generic.x = 310; - s_signup.password.generic.y = y; - s_signup.password.string = "PASSWORD"; - s_signup.password.style = UI_RIGHT|UI_SMALLFONT; - s_signup.password.color = s_signup_color_prompt; - - s_signup.password_box.generic.type = MTYPE_FIELD; - s_signup.password_box.generic.ownerdraw = Rankings_DrawPassword; - s_signup.password_box.generic.name = ""; - s_signup.password_box.generic.flags = 0; - s_signup.password_box.generic.x = 330; - s_signup.password_box.generic.y = y; - s_signup.password_box.field.widthInChars = 16; - s_signup.password_box.field.maxchars = 16; - y += 20; - - s_signup.again.generic.type = MTYPE_PTEXT; - s_signup.again.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; - s_signup.again.generic.id = ID_AGAIN; - s_signup.again.generic.x = 310; - s_signup.again.generic.y = y; - s_signup.again.string = "(AGAIN)"; - s_signup.again.style = UI_RIGHT|UI_SMALLFONT; - s_signup.again.color = s_signup_color_prompt; - - s_signup.again_box.generic.type = MTYPE_FIELD; - s_signup.again_box.generic.ownerdraw = Rankings_DrawPassword; - s_signup.again_box.generic.name = ""; - s_signup.again_box.generic.flags = 0; - s_signup.again_box.generic.x = 330; - s_signup.again_box.generic.y = y; - s_signup.again_box.field.widthInChars = 16; - s_signup.again_box.field.maxchars = 16; - y += 20; - - s_signup.email.generic.type = MTYPE_PTEXT; - s_signup.email.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; - s_signup.email.generic.id = ID_EMAIL; - s_signup.email.generic.x = 310; - s_signup.email.generic.y = y; - s_signup.email.string = "EMAIL"; - s_signup.email.style = UI_RIGHT|UI_SMALLFONT; - s_signup.email.color = s_signup_color_prompt; - - s_signup.email_box.generic.type = MTYPE_FIELD; - s_signup.email_box.generic.ownerdraw = Rankings_DrawText; - s_signup.email_box.generic.name = ""; - s_signup.email_box.generic.flags = 0; - s_signup.email_box.generic.x = 330; - s_signup.email_box.generic.y = y; - s_signup.email_box.field.widthInChars = 16; - s_signup.email_box.field.maxchars = MAX_EDIT_LINE; - y += 40; - - s_signup.signup.generic.type = MTYPE_PTEXT; - s_signup.signup.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_signup.signup.generic.id = ID_SIGNUP; - s_signup.signup.generic.callback = Signup_MenuEvent; - s_signup.signup.generic.x = 310; - s_signup.signup.generic.y = y; - s_signup.signup.string = "SIGN UP"; - s_signup.signup.style = UI_RIGHT|UI_SMALLFONT; - s_signup.signup.color = colorRed; - - s_signup.cancel.generic.type = MTYPE_PTEXT; - s_signup.cancel.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_signup.cancel.generic.id = ID_CANCEL; - s_signup.cancel.generic.callback = Signup_MenuEvent; - s_signup.cancel.generic.x = 330; - s_signup.cancel.generic.y = y; - s_signup.cancel.string = "CANCEL"; - s_signup.cancel.style = UI_LEFT|UI_SMALLFONT; - s_signup.cancel.color = colorRed; - y += 20; - - status = (grank_status_t)trap_Cvar_VariableValue("client_status"); - if( (status != QGR_STATUS_NEW) && (status != QGR_STATUS_SPECTATOR) ) - { - s_signup.name_box.generic.flags |= QMF_INACTIVE; - s_signup.password_box.generic.flags |= QMF_INACTIVE; - s_signup.again_box.generic.flags |= QMF_INACTIVE; - s_signup.email_box.generic.flags |= QMF_INACTIVE; - s_signup.signup.generic.flags |= QMF_INACTIVE; - - s_signup.signup.color = colorMdGrey; - } - - Menu_AddItem( &s_signup.menu, (void*) &s_signup.frame ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.name ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.name_box ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.password ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.password_box ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.again ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.again_box ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.email ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.email_box ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.signup ); - Menu_AddItem( &s_signup.menu, (void*) &s_signup.cancel ); -} - - -/* -=============== -Signup_Cache -=============== -*/ -void Signup_Cache( void ) { - trap_R_RegisterShaderNoMip( SIGNUP_FRAME ); -} - - -/* -=============== -UI_SignupMenu -=============== -*/ -void UI_SignupMenu( void ) { - Signup_MenuInit(); - UI_PushMenu ( &s_signup.menu ); -} - - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +// +// ui_signup.c +// + +#include "ui_local.h" + + +#define SIGNUP_FRAME "menu/art/cut_frame" + +#define ID_NAME 100 +#define ID_NAME_BOX 101 +#define ID_PASSWORD 102 +#define ID_PASSWORD_BOX 103 +#define ID_AGAIN 104 +#define ID_AGAIN_BOX 105 +#define ID_EMAIL 106 +#define ID_EMAIL_BOX 107 +#define ID_SIGNUP 108 +#define ID_CANCEL 109 + + +typedef struct +{ + menuframework_s menu; + menubitmap_s frame; + menutext_s name; + menufield_s name_box; + menutext_s password; + menufield_s password_box; + menutext_s again; + menufield_s again_box; + menutext_s email; + menufield_s email_box; + menutext_s signup; + menutext_s cancel; +} signup_t; + +static signup_t s_signup; + +static menuframework_s s_signup_menu; +static menuaction_s s_signup_signup; +static menuaction_s s_signup_cancel; + +static vec4_t s_signup_color_prompt = {1.00, 0.43, 0.00, 1.00}; + +/* +=============== +Signup_MenuEvent +=============== +*/ +static void Signup_MenuEvent( void* ptr, int event ) { + //char cmd[1024]; + + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_SIGNUP: + if( strcmp(s_signup.password_box.field.buffer, + s_signup.again_box.field.buffer) != 0 ) + { + // GRANK_FIXME - password mismatch + break; + } + // set name + //trap_Cvar_Set( "name", s_signup.name_box.field.buffer ); + /* + trap_Cvar_Set( "rank_name", s_signup.name_box.field.buffer ); + trap_Cvar_Set( "rank_pwd", s_signup.password_box.field.buffer ); + */ + + // create account + /* + sprintf( cmd, "cmd rank_create \"%s\" \"%s\" \"%s\"\n", + s_signup.name_box.field.buffer, + s_signup.password_box.field.buffer, + s_signup.email_box.field.buffer ); + trap_Cmd_ExecuteText( EXEC_APPEND, cmd ); + */ + trap_CL_UI_RankUserCreate( + s_signup.name_box.field.buffer, + s_signup.password_box.field.buffer, + s_signup.email_box.field.buffer ); + + UI_ForceMenuOff(); + break; + + case ID_CANCEL: + UI_PopMenu(); + break; + } +} + +/* +=============== +Signup_MenuInit +=============== +*/ +void Signup_MenuInit( void ) { + grank_status_t status; + int y; + + memset( &s_signup, 0, sizeof(s_signup) ); + + Signup_Cache(); + + s_signup.menu.wrapAround = qtrue; + s_signup.menu.fullscreen = qfalse; + + s_signup.frame.generic.type = MTYPE_BITMAP; + s_signup.frame.generic.flags = QMF_INACTIVE; + s_signup.frame.generic.name = SIGNUP_FRAME; + s_signup.frame.generic.x = 142; //320-233; + s_signup.frame.generic.y = 118; //240-166; + s_signup.frame.width = 359; //466; + s_signup.frame.height = 256; //332; + + y = 194; + + s_signup.name.generic.type = MTYPE_PTEXT; + s_signup.name.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; + s_signup.name.generic.id = ID_NAME; + s_signup.name.generic.x = 310; + s_signup.name.generic.y = y; + s_signup.name.string = "NAME"; + s_signup.name.style = UI_RIGHT|UI_SMALLFONT; + s_signup.name.color = s_signup_color_prompt; + + s_signup.name_box.generic.type = MTYPE_FIELD; + s_signup.name_box.generic.ownerdraw = Rankings_DrawName; + s_signup.name_box.generic.name = ""; + s_signup.name_box.generic.flags = 0; + s_signup.name_box.generic.x = 330; + s_signup.name_box.generic.y = y; + s_signup.name_box.field.widthInChars = 16; + s_signup.name_box.field.maxchars = 16; + y += 20; + + s_signup.password.generic.type = MTYPE_PTEXT; + s_signup.password.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; + s_signup.password.generic.id = ID_PASSWORD; + s_signup.password.generic.x = 310; + s_signup.password.generic.y = y; + s_signup.password.string = "PASSWORD"; + s_signup.password.style = UI_RIGHT|UI_SMALLFONT; + s_signup.password.color = s_signup_color_prompt; + + s_signup.password_box.generic.type = MTYPE_FIELD; + s_signup.password_box.generic.ownerdraw = Rankings_DrawPassword; + s_signup.password_box.generic.name = ""; + s_signup.password_box.generic.flags = 0; + s_signup.password_box.generic.x = 330; + s_signup.password_box.generic.y = y; + s_signup.password_box.field.widthInChars = 16; + s_signup.password_box.field.maxchars = 16; + y += 20; + + s_signup.again.generic.type = MTYPE_PTEXT; + s_signup.again.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; + s_signup.again.generic.id = ID_AGAIN; + s_signup.again.generic.x = 310; + s_signup.again.generic.y = y; + s_signup.again.string = "(AGAIN)"; + s_signup.again.style = UI_RIGHT|UI_SMALLFONT; + s_signup.again.color = s_signup_color_prompt; + + s_signup.again_box.generic.type = MTYPE_FIELD; + s_signup.again_box.generic.ownerdraw = Rankings_DrawPassword; + s_signup.again_box.generic.name = ""; + s_signup.again_box.generic.flags = 0; + s_signup.again_box.generic.x = 330; + s_signup.again_box.generic.y = y; + s_signup.again_box.field.widthInChars = 16; + s_signup.again_box.field.maxchars = 16; + y += 20; + + s_signup.email.generic.type = MTYPE_PTEXT; + s_signup.email.generic.flags = QMF_RIGHT_JUSTIFY|QMF_INACTIVE; + s_signup.email.generic.id = ID_EMAIL; + s_signup.email.generic.x = 310; + s_signup.email.generic.y = y; + s_signup.email.string = "EMAIL"; + s_signup.email.style = UI_RIGHT|UI_SMALLFONT; + s_signup.email.color = s_signup_color_prompt; + + s_signup.email_box.generic.type = MTYPE_FIELD; + s_signup.email_box.generic.ownerdraw = Rankings_DrawText; + s_signup.email_box.generic.name = ""; + s_signup.email_box.generic.flags = 0; + s_signup.email_box.generic.x = 330; + s_signup.email_box.generic.y = y; + s_signup.email_box.field.widthInChars = 16; + s_signup.email_box.field.maxchars = MAX_EDIT_LINE; + y += 40; + + s_signup.signup.generic.type = MTYPE_PTEXT; + s_signup.signup.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_signup.signup.generic.id = ID_SIGNUP; + s_signup.signup.generic.callback = Signup_MenuEvent; + s_signup.signup.generic.x = 310; + s_signup.signup.generic.y = y; + s_signup.signup.string = "SIGN UP"; + s_signup.signup.style = UI_RIGHT|UI_SMALLFONT; + s_signup.signup.color = colorRed; + + s_signup.cancel.generic.type = MTYPE_PTEXT; + s_signup.cancel.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_signup.cancel.generic.id = ID_CANCEL; + s_signup.cancel.generic.callback = Signup_MenuEvent; + s_signup.cancel.generic.x = 330; + s_signup.cancel.generic.y = y; + s_signup.cancel.string = "CANCEL"; + s_signup.cancel.style = UI_LEFT|UI_SMALLFONT; + s_signup.cancel.color = colorRed; + y += 20; + + status = (grank_status_t)trap_Cvar_VariableValue("client_status"); + if( (status != QGR_STATUS_NEW) && (status != QGR_STATUS_SPECTATOR) ) + { + s_signup.name_box.generic.flags |= QMF_INACTIVE; + s_signup.password_box.generic.flags |= QMF_INACTIVE; + s_signup.again_box.generic.flags |= QMF_INACTIVE; + s_signup.email_box.generic.flags |= QMF_INACTIVE; + s_signup.signup.generic.flags |= QMF_INACTIVE; + + s_signup.signup.color = colorMdGrey; + } + + Menu_AddItem( &s_signup.menu, (void*) &s_signup.frame ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.name ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.name_box ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.password ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.password_box ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.again ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.again_box ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.email ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.email_box ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.signup ); + Menu_AddItem( &s_signup.menu, (void*) &s_signup.cancel ); +} + + +/* +=============== +Signup_Cache +=============== +*/ +void Signup_Cache( void ) { + trap_R_RegisterShaderNoMip( SIGNUP_FRAME ); +} + + +/* +=============== +UI_SignupMenu +=============== +*/ +void UI_SignupMenu( void ) { + Signup_MenuInit(); + UI_PushMenu ( &s_signup.menu ); +} + + diff --git a/code/q3_ui/ui_sound.c b/code/q3_ui/ui_sound.c index 60040f0..e09e463 100755 --- a/code/q3_ui/ui_sound.c +++ b/code/q3_ui/ui_sound.c @@ -1,316 +1,316 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -SOUND OPTIONS MENU - -======================================================================= -*/ - -#include "ui_local.h" - - -#define ART_FRAMEL "menu/art/frame2_l" -#define ART_FRAMER "menu/art/frame1_r" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" - -#define ID_GRAPHICS 10 -#define ID_DISPLAY 11 -#define ID_SOUND 12 -#define ID_NETWORK 13 -#define ID_EFFECTSVOLUME 14 -#define ID_MUSICVOLUME 15 -#define ID_QUALITY 16 -//#define ID_A3D 17 -#define ID_BACK 18 - - -static const char *quality_items[] = { - "Low", "High", 0 -}; - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menutext_s graphics; - menutext_s display; - menutext_s sound; - menutext_s network; - - menuslider_s sfxvolume; - menuslider_s musicvolume; - menulist_s quality; -// menuradiobutton_s a3d; - - menubitmap_s back; -} soundOptionsInfo_t; - -static soundOptionsInfo_t soundOptionsInfo; - - -/* -================= -UI_SoundOptionsMenu_Event -================= -*/ -static void UI_SoundOptionsMenu_Event( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_GRAPHICS: - UI_PopMenu(); - UI_GraphicsOptionsMenu(); - break; - - case ID_DISPLAY: - UI_PopMenu(); - UI_DisplayOptionsMenu(); - break; - - case ID_SOUND: - break; - - case ID_NETWORK: - UI_PopMenu(); - UI_NetworkOptionsMenu(); - break; - - case ID_EFFECTSVOLUME: - trap_Cvar_SetValue( "s_volume", soundOptionsInfo.sfxvolume.curvalue / 10 ); - break; - - case ID_MUSICVOLUME: - trap_Cvar_SetValue( "s_musicvolume", soundOptionsInfo.musicvolume.curvalue / 10 ); - break; - - case ID_QUALITY: - if( soundOptionsInfo.quality.curvalue ) { - trap_Cvar_SetValue( "s_khz", 22 ); - trap_Cvar_SetValue( "s_compression", 0 ); - } - else { - trap_Cvar_SetValue( "s_khz", 11 ); - trap_Cvar_SetValue( "s_compression", 1 ); - } - UI_ForceMenuOff(); - trap_Cmd_ExecuteText( EXEC_APPEND, "snd_restart\n" ); - break; -/* - case ID_A3D: - if( soundOptionsInfo.a3d.curvalue ) { - trap_Cmd_ExecuteText( EXEC_NOW, "s_enable_a3d\n" ); - } - else { - trap_Cmd_ExecuteText( EXEC_NOW, "s_disable_a3d\n" ); - } - soundOptionsInfo.a3d.curvalue = (int)trap_Cvar_VariableValue( "s_usingA3D" ); - break; -*/ - case ID_BACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -UI_SoundOptionsMenu_Init -=============== -*/ -static void UI_SoundOptionsMenu_Init( void ) { - int y; - - memset( &soundOptionsInfo, 0, sizeof(soundOptionsInfo) ); - - UI_SoundOptionsMenu_Cache(); - soundOptionsInfo.menu.wrapAround = qtrue; - soundOptionsInfo.menu.fullscreen = qtrue; - - soundOptionsInfo.banner.generic.type = MTYPE_BTEXT; - soundOptionsInfo.banner.generic.flags = QMF_CENTER_JUSTIFY; - soundOptionsInfo.banner.generic.x = 320; - soundOptionsInfo.banner.generic.y = 16; - soundOptionsInfo.banner.string = "SYSTEM SETUP"; - soundOptionsInfo.banner.color = color_white; - soundOptionsInfo.banner.style = UI_CENTER; - - soundOptionsInfo.framel.generic.type = MTYPE_BITMAP; - soundOptionsInfo.framel.generic.name = ART_FRAMEL; - soundOptionsInfo.framel.generic.flags = QMF_INACTIVE; - soundOptionsInfo.framel.generic.x = 0; - soundOptionsInfo.framel.generic.y = 78; - soundOptionsInfo.framel.width = 256; - soundOptionsInfo.framel.height = 329; - - soundOptionsInfo.framer.generic.type = MTYPE_BITMAP; - soundOptionsInfo.framer.generic.name = ART_FRAMER; - soundOptionsInfo.framer.generic.flags = QMF_INACTIVE; - soundOptionsInfo.framer.generic.x = 376; - soundOptionsInfo.framer.generic.y = 76; - soundOptionsInfo.framer.width = 256; - soundOptionsInfo.framer.height = 334; - - soundOptionsInfo.graphics.generic.type = MTYPE_PTEXT; - soundOptionsInfo.graphics.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - soundOptionsInfo.graphics.generic.id = ID_GRAPHICS; - soundOptionsInfo.graphics.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.graphics.generic.x = 216; - soundOptionsInfo.graphics.generic.y = 240 - 2 * PROP_HEIGHT; - soundOptionsInfo.graphics.string = "GRAPHICS"; - soundOptionsInfo.graphics.style = UI_RIGHT; - soundOptionsInfo.graphics.color = color_red; - - soundOptionsInfo.display.generic.type = MTYPE_PTEXT; - soundOptionsInfo.display.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - soundOptionsInfo.display.generic.id = ID_DISPLAY; - soundOptionsInfo.display.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.display.generic.x = 216; - soundOptionsInfo.display.generic.y = 240 - PROP_HEIGHT; - soundOptionsInfo.display.string = "DISPLAY"; - soundOptionsInfo.display.style = UI_RIGHT; - soundOptionsInfo.display.color = color_red; - - soundOptionsInfo.sound.generic.type = MTYPE_PTEXT; - soundOptionsInfo.sound.generic.flags = QMF_RIGHT_JUSTIFY; - soundOptionsInfo.sound.generic.id = ID_SOUND; - soundOptionsInfo.sound.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.sound.generic.x = 216; - soundOptionsInfo.sound.generic.y = 240; - soundOptionsInfo.sound.string = "SOUND"; - soundOptionsInfo.sound.style = UI_RIGHT; - soundOptionsInfo.sound.color = color_red; - - soundOptionsInfo.network.generic.type = MTYPE_PTEXT; - soundOptionsInfo.network.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - soundOptionsInfo.network.generic.id = ID_NETWORK; - soundOptionsInfo.network.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.network.generic.x = 216; - soundOptionsInfo.network.generic.y = 240 + PROP_HEIGHT; - soundOptionsInfo.network.string = "NETWORK"; - soundOptionsInfo.network.style = UI_RIGHT; - soundOptionsInfo.network.color = color_red; - - y = 240 - 1.5 * (BIGCHAR_HEIGHT + 2); - soundOptionsInfo.sfxvolume.generic.type = MTYPE_SLIDER; - soundOptionsInfo.sfxvolume.generic.name = "Effects Volume:"; - soundOptionsInfo.sfxvolume.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - soundOptionsInfo.sfxvolume.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.sfxvolume.generic.id = ID_EFFECTSVOLUME; - soundOptionsInfo.sfxvolume.generic.x = 400; - soundOptionsInfo.sfxvolume.generic.y = y; - soundOptionsInfo.sfxvolume.minvalue = 0; - soundOptionsInfo.sfxvolume.maxvalue = 10; - - y += BIGCHAR_HEIGHT+2; - soundOptionsInfo.musicvolume.generic.type = MTYPE_SLIDER; - soundOptionsInfo.musicvolume.generic.name = "Music Volume:"; - soundOptionsInfo.musicvolume.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - soundOptionsInfo.musicvolume.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.musicvolume.generic.id = ID_MUSICVOLUME; - soundOptionsInfo.musicvolume.generic.x = 400; - soundOptionsInfo.musicvolume.generic.y = y; - soundOptionsInfo.musicvolume.minvalue = 0; - soundOptionsInfo.musicvolume.maxvalue = 10; - - y += BIGCHAR_HEIGHT+2; - soundOptionsInfo.quality.generic.type = MTYPE_SPINCONTROL; - soundOptionsInfo.quality.generic.name = "Sound Quality:"; - soundOptionsInfo.quality.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - soundOptionsInfo.quality.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.quality.generic.id = ID_QUALITY; - soundOptionsInfo.quality.generic.x = 400; - soundOptionsInfo.quality.generic.y = y; - soundOptionsInfo.quality.itemnames = quality_items; -/* - y += BIGCHAR_HEIGHT+2; - soundOptionsInfo.a3d.generic.type = MTYPE_RADIOBUTTON; - soundOptionsInfo.a3d.generic.name = "A3D:"; - soundOptionsInfo.a3d.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - soundOptionsInfo.a3d.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.a3d.generic.id = ID_A3D; - soundOptionsInfo.a3d.generic.x = 400; - soundOptionsInfo.a3d.generic.y = y; -*/ - soundOptionsInfo.back.generic.type = MTYPE_BITMAP; - soundOptionsInfo.back.generic.name = ART_BACK0; - soundOptionsInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - soundOptionsInfo.back.generic.callback = UI_SoundOptionsMenu_Event; - soundOptionsInfo.back.generic.id = ID_BACK; - soundOptionsInfo.back.generic.x = 0; - soundOptionsInfo.back.generic.y = 480-64; - soundOptionsInfo.back.width = 128; - soundOptionsInfo.back.height = 64; - soundOptionsInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.banner ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.framel ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.framer ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.graphics ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.display ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.sound ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.network ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.sfxvolume ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.musicvolume ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.quality ); -// Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.a3d ); - Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.back ); - - soundOptionsInfo.sfxvolume.curvalue = trap_Cvar_VariableValue( "s_volume" ) * 10; - soundOptionsInfo.musicvolume.curvalue = trap_Cvar_VariableValue( "s_musicvolume" ) * 10; - soundOptionsInfo.quality.curvalue = !trap_Cvar_VariableValue( "s_compression" ); -// soundOptionsInfo.a3d.curvalue = (int)trap_Cvar_VariableValue( "s_usingA3D" ); -} - - -/* -=============== -UI_SoundOptionsMenu_Cache -=============== -*/ -void UI_SoundOptionsMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAMEL ); - trap_R_RegisterShaderNoMip( ART_FRAMER ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); -} - - -/* -=============== -UI_SoundOptionsMenu -=============== -*/ -void UI_SoundOptionsMenu( void ) { - UI_SoundOptionsMenu_Init(); - UI_PushMenu( &soundOptionsInfo.menu ); - Menu_SetCursorToItem( &soundOptionsInfo.menu, &soundOptionsInfo.sound ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +SOUND OPTIONS MENU + +======================================================================= +*/ + +#include "ui_local.h" + + +#define ART_FRAMEL "menu/art/frame2_l" +#define ART_FRAMER "menu/art/frame1_r" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" + +#define ID_GRAPHICS 10 +#define ID_DISPLAY 11 +#define ID_SOUND 12 +#define ID_NETWORK 13 +#define ID_EFFECTSVOLUME 14 +#define ID_MUSICVOLUME 15 +#define ID_QUALITY 16 +//#define ID_A3D 17 +#define ID_BACK 18 + + +static const char *quality_items[] = { + "Low", "High", 0 +}; + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menutext_s graphics; + menutext_s display; + menutext_s sound; + menutext_s network; + + menuslider_s sfxvolume; + menuslider_s musicvolume; + menulist_s quality; +// menuradiobutton_s a3d; + + menubitmap_s back; +} soundOptionsInfo_t; + +static soundOptionsInfo_t soundOptionsInfo; + + +/* +================= +UI_SoundOptionsMenu_Event +================= +*/ +static void UI_SoundOptionsMenu_Event( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_GRAPHICS: + UI_PopMenu(); + UI_GraphicsOptionsMenu(); + break; + + case ID_DISPLAY: + UI_PopMenu(); + UI_DisplayOptionsMenu(); + break; + + case ID_SOUND: + break; + + case ID_NETWORK: + UI_PopMenu(); + UI_NetworkOptionsMenu(); + break; + + case ID_EFFECTSVOLUME: + trap_Cvar_SetValue( "s_volume", soundOptionsInfo.sfxvolume.curvalue / 10 ); + break; + + case ID_MUSICVOLUME: + trap_Cvar_SetValue( "s_musicvolume", soundOptionsInfo.musicvolume.curvalue / 10 ); + break; + + case ID_QUALITY: + if( soundOptionsInfo.quality.curvalue ) { + trap_Cvar_SetValue( "s_khz", 22 ); + trap_Cvar_SetValue( "s_compression", 0 ); + } + else { + trap_Cvar_SetValue( "s_khz", 11 ); + trap_Cvar_SetValue( "s_compression", 1 ); + } + UI_ForceMenuOff(); + trap_Cmd_ExecuteText( EXEC_APPEND, "snd_restart\n" ); + break; +/* + case ID_A3D: + if( soundOptionsInfo.a3d.curvalue ) { + trap_Cmd_ExecuteText( EXEC_NOW, "s_enable_a3d\n" ); + } + else { + trap_Cmd_ExecuteText( EXEC_NOW, "s_disable_a3d\n" ); + } + soundOptionsInfo.a3d.curvalue = (int)trap_Cvar_VariableValue( "s_usingA3D" ); + break; +*/ + case ID_BACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +UI_SoundOptionsMenu_Init +=============== +*/ +static void UI_SoundOptionsMenu_Init( void ) { + int y; + + memset( &soundOptionsInfo, 0, sizeof(soundOptionsInfo) ); + + UI_SoundOptionsMenu_Cache(); + soundOptionsInfo.menu.wrapAround = qtrue; + soundOptionsInfo.menu.fullscreen = qtrue; + + soundOptionsInfo.banner.generic.type = MTYPE_BTEXT; + soundOptionsInfo.banner.generic.flags = QMF_CENTER_JUSTIFY; + soundOptionsInfo.banner.generic.x = 320; + soundOptionsInfo.banner.generic.y = 16; + soundOptionsInfo.banner.string = "SYSTEM SETUP"; + soundOptionsInfo.banner.color = color_white; + soundOptionsInfo.banner.style = UI_CENTER; + + soundOptionsInfo.framel.generic.type = MTYPE_BITMAP; + soundOptionsInfo.framel.generic.name = ART_FRAMEL; + soundOptionsInfo.framel.generic.flags = QMF_INACTIVE; + soundOptionsInfo.framel.generic.x = 0; + soundOptionsInfo.framel.generic.y = 78; + soundOptionsInfo.framel.width = 256; + soundOptionsInfo.framel.height = 329; + + soundOptionsInfo.framer.generic.type = MTYPE_BITMAP; + soundOptionsInfo.framer.generic.name = ART_FRAMER; + soundOptionsInfo.framer.generic.flags = QMF_INACTIVE; + soundOptionsInfo.framer.generic.x = 376; + soundOptionsInfo.framer.generic.y = 76; + soundOptionsInfo.framer.width = 256; + soundOptionsInfo.framer.height = 334; + + soundOptionsInfo.graphics.generic.type = MTYPE_PTEXT; + soundOptionsInfo.graphics.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + soundOptionsInfo.graphics.generic.id = ID_GRAPHICS; + soundOptionsInfo.graphics.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.graphics.generic.x = 216; + soundOptionsInfo.graphics.generic.y = 240 - 2 * PROP_HEIGHT; + soundOptionsInfo.graphics.string = "GRAPHICS"; + soundOptionsInfo.graphics.style = UI_RIGHT; + soundOptionsInfo.graphics.color = color_red; + + soundOptionsInfo.display.generic.type = MTYPE_PTEXT; + soundOptionsInfo.display.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + soundOptionsInfo.display.generic.id = ID_DISPLAY; + soundOptionsInfo.display.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.display.generic.x = 216; + soundOptionsInfo.display.generic.y = 240 - PROP_HEIGHT; + soundOptionsInfo.display.string = "DISPLAY"; + soundOptionsInfo.display.style = UI_RIGHT; + soundOptionsInfo.display.color = color_red; + + soundOptionsInfo.sound.generic.type = MTYPE_PTEXT; + soundOptionsInfo.sound.generic.flags = QMF_RIGHT_JUSTIFY; + soundOptionsInfo.sound.generic.id = ID_SOUND; + soundOptionsInfo.sound.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.sound.generic.x = 216; + soundOptionsInfo.sound.generic.y = 240; + soundOptionsInfo.sound.string = "SOUND"; + soundOptionsInfo.sound.style = UI_RIGHT; + soundOptionsInfo.sound.color = color_red; + + soundOptionsInfo.network.generic.type = MTYPE_PTEXT; + soundOptionsInfo.network.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + soundOptionsInfo.network.generic.id = ID_NETWORK; + soundOptionsInfo.network.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.network.generic.x = 216; + soundOptionsInfo.network.generic.y = 240 + PROP_HEIGHT; + soundOptionsInfo.network.string = "NETWORK"; + soundOptionsInfo.network.style = UI_RIGHT; + soundOptionsInfo.network.color = color_red; + + y = 240 - 1.5 * (BIGCHAR_HEIGHT + 2); + soundOptionsInfo.sfxvolume.generic.type = MTYPE_SLIDER; + soundOptionsInfo.sfxvolume.generic.name = "Effects Volume:"; + soundOptionsInfo.sfxvolume.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + soundOptionsInfo.sfxvolume.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.sfxvolume.generic.id = ID_EFFECTSVOLUME; + soundOptionsInfo.sfxvolume.generic.x = 400; + soundOptionsInfo.sfxvolume.generic.y = y; + soundOptionsInfo.sfxvolume.minvalue = 0; + soundOptionsInfo.sfxvolume.maxvalue = 10; + + y += BIGCHAR_HEIGHT+2; + soundOptionsInfo.musicvolume.generic.type = MTYPE_SLIDER; + soundOptionsInfo.musicvolume.generic.name = "Music Volume:"; + soundOptionsInfo.musicvolume.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + soundOptionsInfo.musicvolume.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.musicvolume.generic.id = ID_MUSICVOLUME; + soundOptionsInfo.musicvolume.generic.x = 400; + soundOptionsInfo.musicvolume.generic.y = y; + soundOptionsInfo.musicvolume.minvalue = 0; + soundOptionsInfo.musicvolume.maxvalue = 10; + + y += BIGCHAR_HEIGHT+2; + soundOptionsInfo.quality.generic.type = MTYPE_SPINCONTROL; + soundOptionsInfo.quality.generic.name = "Sound Quality:"; + soundOptionsInfo.quality.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + soundOptionsInfo.quality.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.quality.generic.id = ID_QUALITY; + soundOptionsInfo.quality.generic.x = 400; + soundOptionsInfo.quality.generic.y = y; + soundOptionsInfo.quality.itemnames = quality_items; +/* + y += BIGCHAR_HEIGHT+2; + soundOptionsInfo.a3d.generic.type = MTYPE_RADIOBUTTON; + soundOptionsInfo.a3d.generic.name = "A3D:"; + soundOptionsInfo.a3d.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + soundOptionsInfo.a3d.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.a3d.generic.id = ID_A3D; + soundOptionsInfo.a3d.generic.x = 400; + soundOptionsInfo.a3d.generic.y = y; +*/ + soundOptionsInfo.back.generic.type = MTYPE_BITMAP; + soundOptionsInfo.back.generic.name = ART_BACK0; + soundOptionsInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + soundOptionsInfo.back.generic.callback = UI_SoundOptionsMenu_Event; + soundOptionsInfo.back.generic.id = ID_BACK; + soundOptionsInfo.back.generic.x = 0; + soundOptionsInfo.back.generic.y = 480-64; + soundOptionsInfo.back.width = 128; + soundOptionsInfo.back.height = 64; + soundOptionsInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.banner ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.framel ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.framer ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.graphics ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.display ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.sound ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.network ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.sfxvolume ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.musicvolume ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.quality ); +// Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.a3d ); + Menu_AddItem( &soundOptionsInfo.menu, ( void * ) &soundOptionsInfo.back ); + + soundOptionsInfo.sfxvolume.curvalue = trap_Cvar_VariableValue( "s_volume" ) * 10; + soundOptionsInfo.musicvolume.curvalue = trap_Cvar_VariableValue( "s_musicvolume" ) * 10; + soundOptionsInfo.quality.curvalue = !trap_Cvar_VariableValue( "s_compression" ); +// soundOptionsInfo.a3d.curvalue = (int)trap_Cvar_VariableValue( "s_usingA3D" ); +} + + +/* +=============== +UI_SoundOptionsMenu_Cache +=============== +*/ +void UI_SoundOptionsMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAMEL ); + trap_R_RegisterShaderNoMip( ART_FRAMER ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); +} + + +/* +=============== +UI_SoundOptionsMenu +=============== +*/ +void UI_SoundOptionsMenu( void ) { + UI_SoundOptionsMenu_Init(); + UI_PushMenu( &soundOptionsInfo.menu ); + Menu_SetCursorToItem( &soundOptionsInfo.menu, &soundOptionsInfo.sound ); +} diff --git a/code/q3_ui/ui_sparena.c b/code/q3_ui/ui_sparena.c index 44970f6..3ca1a97 100755 --- a/code/q3_ui/ui_sparena.c +++ b/code/q3_ui/ui_sparena.c @@ -1,50 +1,50 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -void UI_SPArena_Start( const char *arenaInfo ) { - char *map; - int level; - int n; - char *txt; - - n = (int)trap_Cvar_VariableValue( "sv_maxclients" ); - if ( n < 8 ) { - trap_Cvar_SetValue( "sv_maxclients", 8 ); - } - - level = atoi( Info_ValueForKey( arenaInfo, "num" ) ); - txt = Info_ValueForKey( arenaInfo, "special" ); - if( txt[0] ) { - if( Q_stricmp( txt, "training" ) == 0 ) { - level = -4; - } - else if( Q_stricmp( txt, "final" ) == 0 ) { - level = UI_GetNumSPTiers() * ARENAS_PER_TIER; - } - } - trap_Cvar_SetValue( "ui_spSelection", level ); - - map = Info_ValueForKey( arenaInfo, "map" ); - trap_Cmd_ExecuteText( EXEC_APPEND, va( "spmap %s\n", map ) ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +void UI_SPArena_Start( const char *arenaInfo ) { + char *map; + int level; + int n; + char *txt; + + n = (int)trap_Cvar_VariableValue( "sv_maxclients" ); + if ( n < 8 ) { + trap_Cvar_SetValue( "sv_maxclients", 8 ); + } + + level = atoi( Info_ValueForKey( arenaInfo, "num" ) ); + txt = Info_ValueForKey( arenaInfo, "special" ); + if( txt[0] ) { + if( Q_stricmp( txt, "training" ) == 0 ) { + level = -4; + } + else if( Q_stricmp( txt, "final" ) == 0 ) { + level = UI_GetNumSPTiers() * ARENAS_PER_TIER; + } + } + trap_Cvar_SetValue( "ui_spSelection", level ); + + map = Info_ValueForKey( arenaInfo, "map" ); + trap_Cmd_ExecuteText( EXEC_APPEND, va( "spmap %s\n", map ) ); +} diff --git a/code/q3_ui/ui_specifyleague.c b/code/q3_ui/ui_specifyleague.c index 4e0a8b0..08d8932 100755 --- a/code/q3_ui/ui_specifyleague.c +++ b/code/q3_ui/ui_specifyleague.c @@ -1,333 +1,333 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -/********************************************************************************* - SPECIFY SERVER -*********************************************************************************/ - -#define MAX_LISTBOXITEMS 128 -#define MAX_LISTBOXWIDTH 40 -#define MAX_LEAGUENAME 80 - -#define SPECIFYLEAGUE_FRAMEL "menu/art/frame2_l" -#define SPECIFYLEAGUE_FRAMER "menu/art/frame1_r" -#define SPECIFYLEAGUE_BACK0 "menu/art/back_0" -#define SPECIFYLEAGUE_BACK1 "menu/art/back_1" -#define SPECIFYLEAGUE_ARROWS0 "menu/art/arrows_vert_0" -#define SPECIFYLEAGUE_UP "menu/art/arrows_vert_top" -#define SPECIFYLEAGUE_DOWN "menu/art/arrows_vert_bot" -#define GLOBALRANKINGS_LOGO "menu/art/gr/grlogo" -#define GLOBALRANKINGS_LETTERS "menu/art/gr/grletters" - -#define ID_SPECIFYLEAGUENAME 100 -#define ID_SPECIFYLEAGUELIST 101 -#define ID_SPECIFYLEAGUEUP 102 -#define ID_SPECIFYLEAGUEDOWN 103 -#define ID_SPECIFYLEAGUEBACK 104 - -static char* specifyleague_artlist[] = -{ - SPECIFYLEAGUE_FRAMEL, - SPECIFYLEAGUE_FRAMER, - SPECIFYLEAGUE_ARROWS0, - SPECIFYLEAGUE_UP, - SPECIFYLEAGUE_DOWN, - SPECIFYLEAGUE_BACK0, - SPECIFYLEAGUE_BACK1, - GLOBALRANKINGS_LOGO, - GLOBALRANKINGS_LETTERS, - NULL -}; - -static char playername[80]; - -typedef struct -{ - menuframework_s menu; - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - menufield_s rankname; - menulist_s list; - menubitmap_s arrows; - menubitmap_s up; - menubitmap_s down; - menubitmap_s back; - menubitmap_s grlogo; - menubitmap_s grletters; -} specifyleague_t; - -static specifyleague_t s_specifyleague; - - -typedef struct { - char buff[MAX_LISTBOXWIDTH]; - char leaguename[MAX_LEAGUENAME]; -} table_t; - -table_t league_table[MAX_LISTBOXITEMS]; -char *leaguename_items[MAX_LISTBOXITEMS]; - - -static void SpecifyLeague_GetList() -{ - int count = 0; - int i; - /* The Player Name has changed. We need to perform another search */ - Q_strncpyz( playername, - s_specifyleague.rankname.field.buffer, - sizeof(playername) ); - - count = trap_CL_UI_RankGetLeauges( playername ); - - for(i = 0; i < count; i++) - { - char s[MAX_LEAGUENAME]; - const char *var; - var = va( "leaguename%i", i+1 ); - trap_Cvar_VariableStringBuffer( var, s, sizeof(s) ); - Q_strncpyz(league_table[i].leaguename, s, sizeof(league_table[i].leaguename) ); - Q_strncpyz(league_table[i].buff, league_table[i].leaguename, sizeof(league_table[i].buff) ); - } - - s_specifyleague.list.numitems = count; -} - -/* -================= -SpecifyLeague_Event -================= -*/ -static void SpecifyLeague_Event( void* ptr, int event ) -{ - int id; - id = ((menucommon_s*)ptr)->id; - //if( event != QM_ACTIVATED && id != ID_SPECIFYLEAGUELIST ) { - // return; - //} - - switch (id) - { - case ID_SPECIFYLEAGUELIST: - if( event == QM_GOTFOCUS ) { - //ArenaServers_UpdatePicture(); - } - break; - - case ID_SPECIFYLEAGUEUP: - if( event == QM_ACTIVATED ) - ScrollList_Key( &s_specifyleague.list, K_UPARROW ); - break; - - case ID_SPECIFYLEAGUEDOWN: - if( event == QM_ACTIVATED ) - ScrollList_Key( &s_specifyleague.list, K_DOWNARROW ); - break; - - case ID_SPECIFYLEAGUENAME: - if( (event == QM_LOSTFOCUS) && - (Q_strncmp(playername, - s_specifyleague.rankname.field.buffer, - strlen(s_specifyleague.rankname.field.buffer)) != 0)) - { - SpecifyLeague_GetList(); - } - break; - - case ID_SPECIFYLEAGUEBACK: - if( event == QM_ACTIVATED ) - { - trap_Cvar_Set( "sv_leagueName", league_table[s_specifyleague.list.curvalue].leaguename); - UI_PopMenu(); - } - break; - } -} - -/* -================= -SpecifyLeague_MenuInit -================= -*/ -void SpecifyLeague_MenuInit( void ) -{ - int i; - // zero set all our globals - memset( &s_specifyleague, 0 ,sizeof(specifyleague_t) ); - - SpecifyLeague_Cache(); - - s_specifyleague.menu.wrapAround = qtrue; - s_specifyleague.menu.fullscreen = qtrue; - - s_specifyleague.banner.generic.type = MTYPE_BTEXT; - s_specifyleague.banner.generic.x = 320; - s_specifyleague.banner.generic.y = 16; - s_specifyleague.banner.string = "CHOOSE LEAGUE"; - s_specifyleague.banner.color = color_white; - s_specifyleague.banner.style = UI_CENTER; - - s_specifyleague.framel.generic.type = MTYPE_BITMAP; - s_specifyleague.framel.generic.name = SPECIFYLEAGUE_FRAMEL; - s_specifyleague.framel.generic.flags = QMF_INACTIVE; - s_specifyleague.framel.generic.x = 0; - s_specifyleague.framel.generic.y = 78; - s_specifyleague.framel.width = 256; - s_specifyleague.framel.height = 334; - - s_specifyleague.framer.generic.type = MTYPE_BITMAP; - s_specifyleague.framer.generic.name = SPECIFYLEAGUE_FRAMER; - s_specifyleague.framer.generic.flags = QMF_INACTIVE; - s_specifyleague.framer.generic.x = 376; - s_specifyleague.framer.generic.y = 76; - s_specifyleague.framer.width = 256; - s_specifyleague.framer.height = 334; - - s_specifyleague.grlogo.generic.type = MTYPE_BITMAP; - s_specifyleague.grlogo.generic.name = GLOBALRANKINGS_LOGO; - s_specifyleague.grlogo.generic.flags = QMF_INACTIVE; - s_specifyleague.grlogo.generic.x = 0; - s_specifyleague.grlogo.generic.y = 0; - s_specifyleague.grlogo.width = 64; - s_specifyleague.grlogo.height = 128; - - s_specifyleague.rankname.generic.type = MTYPE_FIELD; - s_specifyleague.rankname.generic.name = "Player Name:"; - s_specifyleague.rankname.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_specifyleague.rankname.generic.callback = SpecifyLeague_Event; - s_specifyleague.rankname.generic.id = ID_SPECIFYLEAGUENAME; - s_specifyleague.rankname.generic.x = 226; - s_specifyleague.rankname.generic.y = 128; - s_specifyleague.rankname.field.widthInChars = 32; - s_specifyleague.rankname.field.maxchars = 80; - - s_specifyleague.list.generic.type = MTYPE_SCROLLLIST; - s_specifyleague.list.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; - s_specifyleague.list.generic.id = ID_SPECIFYLEAGUELIST; - s_specifyleague.list.generic.callback = SpecifyLeague_Event; - s_specifyleague.list.generic.x = 160; - s_specifyleague.list.generic.y = 200; - s_specifyleague.list.width = MAX_LISTBOXWIDTH; - s_specifyleague.list.height = 8; - s_specifyleague.list.itemnames = (const char **)leaguename_items; - s_specifyleague.list.numitems = 0; - for( i = 0; i < MAX_LISTBOXITEMS; i++ ) { - league_table[i].buff[0] = 0; - league_table[i].leaguename[0] = 0; - leaguename_items[i] = league_table[i].buff; - } - - s_specifyleague.arrows.generic.type = MTYPE_BITMAP; - s_specifyleague.arrows.generic.name = SPECIFYLEAGUE_ARROWS0; - s_specifyleague.arrows.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_specifyleague.arrows.generic.callback = SpecifyLeague_Event; - s_specifyleague.arrows.generic.x = 512; - s_specifyleague.arrows.generic.y = 240-64+16; - s_specifyleague.arrows.width = 64; - s_specifyleague.arrows.height = 128; - - s_specifyleague.up.generic.type = MTYPE_BITMAP; - s_specifyleague.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - s_specifyleague.up.generic.callback = SpecifyLeague_Event; - s_specifyleague.up.generic.id = ID_SPECIFYLEAGUEUP; - s_specifyleague.up.generic.x = 512; - s_specifyleague.up.generic.y = 240-64+16; - s_specifyleague.up.width = 64; - s_specifyleague.up.height = 64; - s_specifyleague.up.focuspic = SPECIFYLEAGUE_UP; - - s_specifyleague.down.generic.type = MTYPE_BITMAP; - s_specifyleague.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; - s_specifyleague.down.generic.callback = SpecifyLeague_Event; - s_specifyleague.down.generic.id = ID_SPECIFYLEAGUEDOWN; - s_specifyleague.down.generic.x = 512; - s_specifyleague.down.generic.y = 240+16; - s_specifyleague.down.width = 64; - s_specifyleague.down.height = 64; - s_specifyleague.down.focuspic = SPECIFYLEAGUE_DOWN; - - s_specifyleague.back.generic.type = MTYPE_BITMAP; - s_specifyleague.back.generic.name = SPECIFYLEAGUE_BACK0; - s_specifyleague.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_specifyleague.back.generic.callback = SpecifyLeague_Event; - s_specifyleague.back.generic.id = ID_SPECIFYLEAGUEBACK; - s_specifyleague.back.generic.x = 0; - s_specifyleague.back.generic.y = 480-64; - s_specifyleague.back.width = 128; - s_specifyleague.back.height = 64; - s_specifyleague.back.focuspic = SPECIFYLEAGUE_BACK1; - - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.banner ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.framel ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.framer ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.grlogo ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.rankname ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.list ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.arrows ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.up ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.down ); - Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.back ); - - - // initialize any menu variables - Q_strncpyz( s_specifyleague.rankname.field.buffer, - UI_Cvar_VariableString("name"), - sizeof(s_specifyleague.rankname.field.buffer) ); - - Q_strncpyz( playername, - UI_Cvar_VariableString("name"), - sizeof(playername) ); - - SpecifyLeague_GetList(); -} - -/* -================= -SpecifyLeague_Cache -================= -*/ -void SpecifyLeague_Cache( void ) -{ - int i; - - // touch all our pics - for (i=0; ;i++) - { - if (!specifyleague_artlist[i]) - break; - trap_R_RegisterShaderNoMip(specifyleague_artlist[i]); - } -} - -/* -================= -UI_SpecifyLeagueMenu -================= -*/ -void UI_SpecifyLeagueMenu( void ) -{ - SpecifyLeague_MenuInit(); - UI_PushMenu( &s_specifyleague.menu ); -} - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +/********************************************************************************* + SPECIFY SERVER +*********************************************************************************/ + +#define MAX_LISTBOXITEMS 128 +#define MAX_LISTBOXWIDTH 40 +#define MAX_LEAGUENAME 80 + +#define SPECIFYLEAGUE_FRAMEL "menu/art/frame2_l" +#define SPECIFYLEAGUE_FRAMER "menu/art/frame1_r" +#define SPECIFYLEAGUE_BACK0 "menu/art/back_0" +#define SPECIFYLEAGUE_BACK1 "menu/art/back_1" +#define SPECIFYLEAGUE_ARROWS0 "menu/art/arrows_vert_0" +#define SPECIFYLEAGUE_UP "menu/art/arrows_vert_top" +#define SPECIFYLEAGUE_DOWN "menu/art/arrows_vert_bot" +#define GLOBALRANKINGS_LOGO "menu/art/gr/grlogo" +#define GLOBALRANKINGS_LETTERS "menu/art/gr/grletters" + +#define ID_SPECIFYLEAGUENAME 100 +#define ID_SPECIFYLEAGUELIST 101 +#define ID_SPECIFYLEAGUEUP 102 +#define ID_SPECIFYLEAGUEDOWN 103 +#define ID_SPECIFYLEAGUEBACK 104 + +static char* specifyleague_artlist[] = +{ + SPECIFYLEAGUE_FRAMEL, + SPECIFYLEAGUE_FRAMER, + SPECIFYLEAGUE_ARROWS0, + SPECIFYLEAGUE_UP, + SPECIFYLEAGUE_DOWN, + SPECIFYLEAGUE_BACK0, + SPECIFYLEAGUE_BACK1, + GLOBALRANKINGS_LOGO, + GLOBALRANKINGS_LETTERS, + NULL +}; + +static char playername[80]; + +typedef struct +{ + menuframework_s menu; + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + menufield_s rankname; + menulist_s list; + menubitmap_s arrows; + menubitmap_s up; + menubitmap_s down; + menubitmap_s back; + menubitmap_s grlogo; + menubitmap_s grletters; +} specifyleague_t; + +static specifyleague_t s_specifyleague; + + +typedef struct { + char buff[MAX_LISTBOXWIDTH]; + char leaguename[MAX_LEAGUENAME]; +} table_t; + +table_t league_table[MAX_LISTBOXITEMS]; +char *leaguename_items[MAX_LISTBOXITEMS]; + + +static void SpecifyLeague_GetList() +{ + int count = 0; + int i; + /* The Player Name has changed. We need to perform another search */ + Q_strncpyz( playername, + s_specifyleague.rankname.field.buffer, + sizeof(playername) ); + + count = trap_CL_UI_RankGetLeauges( playername ); + + for(i = 0; i < count; i++) + { + char s[MAX_LEAGUENAME]; + const char *var; + var = va( "leaguename%i", i+1 ); + trap_Cvar_VariableStringBuffer( var, s, sizeof(s) ); + Q_strncpyz(league_table[i].leaguename, s, sizeof(league_table[i].leaguename) ); + Q_strncpyz(league_table[i].buff, league_table[i].leaguename, sizeof(league_table[i].buff) ); + } + + s_specifyleague.list.numitems = count; +} + +/* +================= +SpecifyLeague_Event +================= +*/ +static void SpecifyLeague_Event( void* ptr, int event ) +{ + int id; + id = ((menucommon_s*)ptr)->id; + //if( event != QM_ACTIVATED && id != ID_SPECIFYLEAGUELIST ) { + // return; + //} + + switch (id) + { + case ID_SPECIFYLEAGUELIST: + if( event == QM_GOTFOCUS ) { + //ArenaServers_UpdatePicture(); + } + break; + + case ID_SPECIFYLEAGUEUP: + if( event == QM_ACTIVATED ) + ScrollList_Key( &s_specifyleague.list, K_UPARROW ); + break; + + case ID_SPECIFYLEAGUEDOWN: + if( event == QM_ACTIVATED ) + ScrollList_Key( &s_specifyleague.list, K_DOWNARROW ); + break; + + case ID_SPECIFYLEAGUENAME: + if( (event == QM_LOSTFOCUS) && + (Q_strncmp(playername, + s_specifyleague.rankname.field.buffer, + strlen(s_specifyleague.rankname.field.buffer)) != 0)) + { + SpecifyLeague_GetList(); + } + break; + + case ID_SPECIFYLEAGUEBACK: + if( event == QM_ACTIVATED ) + { + trap_Cvar_Set( "sv_leagueName", league_table[s_specifyleague.list.curvalue].leaguename); + UI_PopMenu(); + } + break; + } +} + +/* +================= +SpecifyLeague_MenuInit +================= +*/ +void SpecifyLeague_MenuInit( void ) +{ + int i; + // zero set all our globals + memset( &s_specifyleague, 0 ,sizeof(specifyleague_t) ); + + SpecifyLeague_Cache(); + + s_specifyleague.menu.wrapAround = qtrue; + s_specifyleague.menu.fullscreen = qtrue; + + s_specifyleague.banner.generic.type = MTYPE_BTEXT; + s_specifyleague.banner.generic.x = 320; + s_specifyleague.banner.generic.y = 16; + s_specifyleague.banner.string = "CHOOSE LEAGUE"; + s_specifyleague.banner.color = color_white; + s_specifyleague.banner.style = UI_CENTER; + + s_specifyleague.framel.generic.type = MTYPE_BITMAP; + s_specifyleague.framel.generic.name = SPECIFYLEAGUE_FRAMEL; + s_specifyleague.framel.generic.flags = QMF_INACTIVE; + s_specifyleague.framel.generic.x = 0; + s_specifyleague.framel.generic.y = 78; + s_specifyleague.framel.width = 256; + s_specifyleague.framel.height = 334; + + s_specifyleague.framer.generic.type = MTYPE_BITMAP; + s_specifyleague.framer.generic.name = SPECIFYLEAGUE_FRAMER; + s_specifyleague.framer.generic.flags = QMF_INACTIVE; + s_specifyleague.framer.generic.x = 376; + s_specifyleague.framer.generic.y = 76; + s_specifyleague.framer.width = 256; + s_specifyleague.framer.height = 334; + + s_specifyleague.grlogo.generic.type = MTYPE_BITMAP; + s_specifyleague.grlogo.generic.name = GLOBALRANKINGS_LOGO; + s_specifyleague.grlogo.generic.flags = QMF_INACTIVE; + s_specifyleague.grlogo.generic.x = 0; + s_specifyleague.grlogo.generic.y = 0; + s_specifyleague.grlogo.width = 64; + s_specifyleague.grlogo.height = 128; + + s_specifyleague.rankname.generic.type = MTYPE_FIELD; + s_specifyleague.rankname.generic.name = "Player Name:"; + s_specifyleague.rankname.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_specifyleague.rankname.generic.callback = SpecifyLeague_Event; + s_specifyleague.rankname.generic.id = ID_SPECIFYLEAGUENAME; + s_specifyleague.rankname.generic.x = 226; + s_specifyleague.rankname.generic.y = 128; + s_specifyleague.rankname.field.widthInChars = 32; + s_specifyleague.rankname.field.maxchars = 80; + + s_specifyleague.list.generic.type = MTYPE_SCROLLLIST; + s_specifyleague.list.generic.flags = QMF_HIGHLIGHT_IF_FOCUS; + s_specifyleague.list.generic.id = ID_SPECIFYLEAGUELIST; + s_specifyleague.list.generic.callback = SpecifyLeague_Event; + s_specifyleague.list.generic.x = 160; + s_specifyleague.list.generic.y = 200; + s_specifyleague.list.width = MAX_LISTBOXWIDTH; + s_specifyleague.list.height = 8; + s_specifyleague.list.itemnames = (const char **)leaguename_items; + s_specifyleague.list.numitems = 0; + for( i = 0; i < MAX_LISTBOXITEMS; i++ ) { + league_table[i].buff[0] = 0; + league_table[i].leaguename[0] = 0; + leaguename_items[i] = league_table[i].buff; + } + + s_specifyleague.arrows.generic.type = MTYPE_BITMAP; + s_specifyleague.arrows.generic.name = SPECIFYLEAGUE_ARROWS0; + s_specifyleague.arrows.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_specifyleague.arrows.generic.callback = SpecifyLeague_Event; + s_specifyleague.arrows.generic.x = 512; + s_specifyleague.arrows.generic.y = 240-64+16; + s_specifyleague.arrows.width = 64; + s_specifyleague.arrows.height = 128; + + s_specifyleague.up.generic.type = MTYPE_BITMAP; + s_specifyleague.up.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + s_specifyleague.up.generic.callback = SpecifyLeague_Event; + s_specifyleague.up.generic.id = ID_SPECIFYLEAGUEUP; + s_specifyleague.up.generic.x = 512; + s_specifyleague.up.generic.y = 240-64+16; + s_specifyleague.up.width = 64; + s_specifyleague.up.height = 64; + s_specifyleague.up.focuspic = SPECIFYLEAGUE_UP; + + s_specifyleague.down.generic.type = MTYPE_BITMAP; + s_specifyleague.down.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_MOUSEONLY; + s_specifyleague.down.generic.callback = SpecifyLeague_Event; + s_specifyleague.down.generic.id = ID_SPECIFYLEAGUEDOWN; + s_specifyleague.down.generic.x = 512; + s_specifyleague.down.generic.y = 240+16; + s_specifyleague.down.width = 64; + s_specifyleague.down.height = 64; + s_specifyleague.down.focuspic = SPECIFYLEAGUE_DOWN; + + s_specifyleague.back.generic.type = MTYPE_BITMAP; + s_specifyleague.back.generic.name = SPECIFYLEAGUE_BACK0; + s_specifyleague.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_specifyleague.back.generic.callback = SpecifyLeague_Event; + s_specifyleague.back.generic.id = ID_SPECIFYLEAGUEBACK; + s_specifyleague.back.generic.x = 0; + s_specifyleague.back.generic.y = 480-64; + s_specifyleague.back.width = 128; + s_specifyleague.back.height = 64; + s_specifyleague.back.focuspic = SPECIFYLEAGUE_BACK1; + + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.banner ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.framel ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.framer ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.grlogo ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.rankname ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.list ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.arrows ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.up ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.down ); + Menu_AddItem( &s_specifyleague.menu, &s_specifyleague.back ); + + + // initialize any menu variables + Q_strncpyz( s_specifyleague.rankname.field.buffer, + UI_Cvar_VariableString("name"), + sizeof(s_specifyleague.rankname.field.buffer) ); + + Q_strncpyz( playername, + UI_Cvar_VariableString("name"), + sizeof(playername) ); + + SpecifyLeague_GetList(); +} + +/* +================= +SpecifyLeague_Cache +================= +*/ +void SpecifyLeague_Cache( void ) +{ + int i; + + // touch all our pics + for (i=0; ;i++) + { + if (!specifyleague_artlist[i]) + break; + trap_R_RegisterShaderNoMip(specifyleague_artlist[i]); + } +} + +/* +================= +UI_SpecifyLeagueMenu +================= +*/ +void UI_SpecifyLeagueMenu( void ) +{ + SpecifyLeague_MenuInit(); + UI_PushMenu( &s_specifyleague.menu ); +} + diff --git a/code/q3_ui/ui_specifyserver.c b/code/q3_ui/ui_specifyserver.c index 2df4418..5e124a5 100755 --- a/code/q3_ui/ui_specifyserver.c +++ b/code/q3_ui/ui_specifyserver.c @@ -1,213 +1,213 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -/********************************************************************************* - SPECIFY SERVER -*********************************************************************************/ - -#define SPECIFYSERVER_FRAMEL "menu/art/frame2_l" -#define SPECIFYSERVER_FRAMER "menu/art/frame1_r" -#define SPECIFYSERVER_BACK0 "menu/art/back_0" -#define SPECIFYSERVER_BACK1 "menu/art/back_1" -#define SPECIFYSERVER_FIGHT0 "menu/art/fight_0" -#define SPECIFYSERVER_FIGHT1 "menu/art/fight_1" - -#define ID_SPECIFYSERVERBACK 102 -#define ID_SPECIFYSERVERGO 103 - -static char* specifyserver_artlist[] = -{ - SPECIFYSERVER_FRAMEL, - SPECIFYSERVER_FRAMER, - SPECIFYSERVER_BACK0, - SPECIFYSERVER_BACK1, - SPECIFYSERVER_FIGHT0, - SPECIFYSERVER_FIGHT1, - NULL -}; - -typedef struct -{ - menuframework_s menu; - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - menufield_s domain; - menufield_s port; - menubitmap_s go; - menubitmap_s back; -} specifyserver_t; - -static specifyserver_t s_specifyserver; - -/* -================= -SpecifyServer_Event -================= -*/ -static void SpecifyServer_Event( void* ptr, int event ) -{ - char buff[256]; - - switch (((menucommon_s*)ptr)->id) - { - case ID_SPECIFYSERVERGO: - if (event != QM_ACTIVATED) - break; - - if (s_specifyserver.domain.field.buffer[0]) - { - strcpy(buff,s_specifyserver.domain.field.buffer); - if (s_specifyserver.port.field.buffer[0]) - Com_sprintf( buff+strlen(buff), 128, ":%s", s_specifyserver.port.field.buffer ); - - trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) ); - } - break; - - case ID_SPECIFYSERVERBACK: - if (event != QM_ACTIVATED) - break; - - UI_PopMenu(); - break; - } -} - -/* -================= -SpecifyServer_MenuInit -================= -*/ -void SpecifyServer_MenuInit( void ) -{ - // zero set all our globals - memset( &s_specifyserver, 0 ,sizeof(specifyserver_t) ); - - SpecifyServer_Cache(); - - s_specifyserver.menu.wrapAround = qtrue; - s_specifyserver.menu.fullscreen = qtrue; - - s_specifyserver.banner.generic.type = MTYPE_BTEXT; - s_specifyserver.banner.generic.x = 320; - s_specifyserver.banner.generic.y = 16; - s_specifyserver.banner.string = "SPECIFY SERVER"; - s_specifyserver.banner.color = color_white; - s_specifyserver.banner.style = UI_CENTER; - - s_specifyserver.framel.generic.type = MTYPE_BITMAP; - s_specifyserver.framel.generic.name = SPECIFYSERVER_FRAMEL; - s_specifyserver.framel.generic.flags = QMF_INACTIVE; - s_specifyserver.framel.generic.x = 0; - s_specifyserver.framel.generic.y = 78; - s_specifyserver.framel.width = 256; - s_specifyserver.framel.height = 329; - - s_specifyserver.framer.generic.type = MTYPE_BITMAP; - s_specifyserver.framer.generic.name = SPECIFYSERVER_FRAMER; - s_specifyserver.framer.generic.flags = QMF_INACTIVE; - s_specifyserver.framer.generic.x = 376; - s_specifyserver.framer.generic.y = 76; - s_specifyserver.framer.width = 256; - s_specifyserver.framer.height = 334; - - s_specifyserver.domain.generic.type = MTYPE_FIELD; - s_specifyserver.domain.generic.name = "Address:"; - s_specifyserver.domain.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_specifyserver.domain.generic.x = 206; - s_specifyserver.domain.generic.y = 220; - s_specifyserver.domain.field.widthInChars = 38; - s_specifyserver.domain.field.maxchars = 80; - - s_specifyserver.port.generic.type = MTYPE_FIELD; - s_specifyserver.port.generic.name = "Port:"; - s_specifyserver.port.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT|QMF_NUMBERSONLY; - s_specifyserver.port.generic.x = 206; - s_specifyserver.port.generic.y = 250; - s_specifyserver.port.field.widthInChars = 6; - s_specifyserver.port.field.maxchars = 5; - - s_specifyserver.go.generic.type = MTYPE_BITMAP; - s_specifyserver.go.generic.name = SPECIFYSERVER_FIGHT0; - s_specifyserver.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_specifyserver.go.generic.callback = SpecifyServer_Event; - s_specifyserver.go.generic.id = ID_SPECIFYSERVERGO; - s_specifyserver.go.generic.x = 640; - s_specifyserver.go.generic.y = 480-64; - s_specifyserver.go.width = 128; - s_specifyserver.go.height = 64; - s_specifyserver.go.focuspic = SPECIFYSERVER_FIGHT1; - - s_specifyserver.back.generic.type = MTYPE_BITMAP; - s_specifyserver.back.generic.name = SPECIFYSERVER_BACK0; - s_specifyserver.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_specifyserver.back.generic.callback = SpecifyServer_Event; - s_specifyserver.back.generic.id = ID_SPECIFYSERVERBACK; - s_specifyserver.back.generic.x = 0; - s_specifyserver.back.generic.y = 480-64; - s_specifyserver.back.width = 128; - s_specifyserver.back.height = 64; - s_specifyserver.back.focuspic = SPECIFYSERVER_BACK1; - - Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.banner ); - Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.framel ); - Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.framer ); - Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.domain ); - Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.port ); - Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.go ); - Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.back ); - - Com_sprintf( s_specifyserver.port.field.buffer, 6, "%i", 27960 ); -} - -/* -================= -SpecifyServer_Cache -================= -*/ -void SpecifyServer_Cache( void ) -{ - int i; - - // touch all our pics - for (i=0; ;i++) - { - if (!specifyserver_artlist[i]) - break; - trap_R_RegisterShaderNoMip(specifyserver_artlist[i]); - } -} - -/* -================= -UI_SpecifyServerMenu -================= -*/ -void UI_SpecifyServerMenu( void ) -{ - SpecifyServer_MenuInit(); - UI_PushMenu( &s_specifyserver.menu ); -} - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +/********************************************************************************* + SPECIFY SERVER +*********************************************************************************/ + +#define SPECIFYSERVER_FRAMEL "menu/art/frame2_l" +#define SPECIFYSERVER_FRAMER "menu/art/frame1_r" +#define SPECIFYSERVER_BACK0 "menu/art/back_0" +#define SPECIFYSERVER_BACK1 "menu/art/back_1" +#define SPECIFYSERVER_FIGHT0 "menu/art/fight_0" +#define SPECIFYSERVER_FIGHT1 "menu/art/fight_1" + +#define ID_SPECIFYSERVERBACK 102 +#define ID_SPECIFYSERVERGO 103 + +static char* specifyserver_artlist[] = +{ + SPECIFYSERVER_FRAMEL, + SPECIFYSERVER_FRAMER, + SPECIFYSERVER_BACK0, + SPECIFYSERVER_BACK1, + SPECIFYSERVER_FIGHT0, + SPECIFYSERVER_FIGHT1, + NULL +}; + +typedef struct +{ + menuframework_s menu; + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + menufield_s domain; + menufield_s port; + menubitmap_s go; + menubitmap_s back; +} specifyserver_t; + +static specifyserver_t s_specifyserver; + +/* +================= +SpecifyServer_Event +================= +*/ +static void SpecifyServer_Event( void* ptr, int event ) +{ + char buff[256]; + + switch (((menucommon_s*)ptr)->id) + { + case ID_SPECIFYSERVERGO: + if (event != QM_ACTIVATED) + break; + + if (s_specifyserver.domain.field.buffer[0]) + { + strcpy(buff,s_specifyserver.domain.field.buffer); + if (s_specifyserver.port.field.buffer[0]) + Com_sprintf( buff+strlen(buff), 128, ":%s", s_specifyserver.port.field.buffer ); + + trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) ); + } + break; + + case ID_SPECIFYSERVERBACK: + if (event != QM_ACTIVATED) + break; + + UI_PopMenu(); + break; + } +} + +/* +================= +SpecifyServer_MenuInit +================= +*/ +void SpecifyServer_MenuInit( void ) +{ + // zero set all our globals + memset( &s_specifyserver, 0 ,sizeof(specifyserver_t) ); + + SpecifyServer_Cache(); + + s_specifyserver.menu.wrapAround = qtrue; + s_specifyserver.menu.fullscreen = qtrue; + + s_specifyserver.banner.generic.type = MTYPE_BTEXT; + s_specifyserver.banner.generic.x = 320; + s_specifyserver.banner.generic.y = 16; + s_specifyserver.banner.string = "SPECIFY SERVER"; + s_specifyserver.banner.color = color_white; + s_specifyserver.banner.style = UI_CENTER; + + s_specifyserver.framel.generic.type = MTYPE_BITMAP; + s_specifyserver.framel.generic.name = SPECIFYSERVER_FRAMEL; + s_specifyserver.framel.generic.flags = QMF_INACTIVE; + s_specifyserver.framel.generic.x = 0; + s_specifyserver.framel.generic.y = 78; + s_specifyserver.framel.width = 256; + s_specifyserver.framel.height = 329; + + s_specifyserver.framer.generic.type = MTYPE_BITMAP; + s_specifyserver.framer.generic.name = SPECIFYSERVER_FRAMER; + s_specifyserver.framer.generic.flags = QMF_INACTIVE; + s_specifyserver.framer.generic.x = 376; + s_specifyserver.framer.generic.y = 76; + s_specifyserver.framer.width = 256; + s_specifyserver.framer.height = 334; + + s_specifyserver.domain.generic.type = MTYPE_FIELD; + s_specifyserver.domain.generic.name = "Address:"; + s_specifyserver.domain.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_specifyserver.domain.generic.x = 206; + s_specifyserver.domain.generic.y = 220; + s_specifyserver.domain.field.widthInChars = 38; + s_specifyserver.domain.field.maxchars = 80; + + s_specifyserver.port.generic.type = MTYPE_FIELD; + s_specifyserver.port.generic.name = "Port:"; + s_specifyserver.port.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT|QMF_NUMBERSONLY; + s_specifyserver.port.generic.x = 206; + s_specifyserver.port.generic.y = 250; + s_specifyserver.port.field.widthInChars = 6; + s_specifyserver.port.field.maxchars = 5; + + s_specifyserver.go.generic.type = MTYPE_BITMAP; + s_specifyserver.go.generic.name = SPECIFYSERVER_FIGHT0; + s_specifyserver.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_specifyserver.go.generic.callback = SpecifyServer_Event; + s_specifyserver.go.generic.id = ID_SPECIFYSERVERGO; + s_specifyserver.go.generic.x = 640; + s_specifyserver.go.generic.y = 480-64; + s_specifyserver.go.width = 128; + s_specifyserver.go.height = 64; + s_specifyserver.go.focuspic = SPECIFYSERVER_FIGHT1; + + s_specifyserver.back.generic.type = MTYPE_BITMAP; + s_specifyserver.back.generic.name = SPECIFYSERVER_BACK0; + s_specifyserver.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_specifyserver.back.generic.callback = SpecifyServer_Event; + s_specifyserver.back.generic.id = ID_SPECIFYSERVERBACK; + s_specifyserver.back.generic.x = 0; + s_specifyserver.back.generic.y = 480-64; + s_specifyserver.back.width = 128; + s_specifyserver.back.height = 64; + s_specifyserver.back.focuspic = SPECIFYSERVER_BACK1; + + Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.banner ); + Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.framel ); + Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.framer ); + Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.domain ); + Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.port ); + Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.go ); + Menu_AddItem( &s_specifyserver.menu, &s_specifyserver.back ); + + Com_sprintf( s_specifyserver.port.field.buffer, 6, "%i", 27960 ); +} + +/* +================= +SpecifyServer_Cache +================= +*/ +void SpecifyServer_Cache( void ) +{ + int i; + + // touch all our pics + for (i=0; ;i++) + { + if (!specifyserver_artlist[i]) + break; + trap_R_RegisterShaderNoMip(specifyserver_artlist[i]); + } +} + +/* +================= +UI_SpecifyServerMenu +================= +*/ +void UI_SpecifyServerMenu( void ) +{ + SpecifyServer_MenuInit(); + UI_PushMenu( &s_specifyserver.menu ); +} + diff --git a/code/q3_ui/ui_splevel.c b/code/q3_ui/ui_splevel.c index 0c57500..14f96a8 100755 --- a/code/q3_ui/ui_splevel.c +++ b/code/q3_ui/ui_splevel.c @@ -1,1008 +1,1008 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -============================================================================= - -SINGLE PLAYER LEVEL SELECT MENU - -============================================================================= -*/ - -#include "ui_local.h" - - -#define ART_LEVELFRAME_FOCUS "menu/art/maps_select" -#define ART_LEVELFRAME_SELECTED "menu/art/maps_selected" -#define ART_ARROW "menu/art/narrow_0" -#define ART_ARROW_FOCUS "menu/art/narrow_1" -#define ART_MAP_UNKNOWN "menu/art/unknownmap" -#define ART_MAP_COMPLETE1 "menu/art/level_complete1" -#define ART_MAP_COMPLETE2 "menu/art/level_complete2" -#define ART_MAP_COMPLETE3 "menu/art/level_complete3" -#define ART_MAP_COMPLETE4 "menu/art/level_complete4" -#define ART_MAP_COMPLETE5 "menu/art/level_complete5" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" -#define ART_FIGHT0 "menu/art/fight_0" -#define ART_FIGHT1 "menu/art/fight_1" -#define ART_RESET0 "menu/art/reset_0" -#define ART_RESET1 "menu/art/reset_1" -#define ART_CUSTOM0 "menu/art/skirmish_0" -#define ART_CUSTOM1 "menu/art/skirmish_1" - -#define ID_LEFTARROW 10 -#define ID_PICTURE0 11 -#define ID_PICTURE1 12 -#define ID_PICTURE2 13 -#define ID_PICTURE3 14 -#define ID_RIGHTARROW 15 -#define ID_PLAYERPIC 16 -#define ID_AWARD1 17 -#define ID_AWARD2 18 -#define ID_AWARD3 19 -#define ID_AWARD4 20 -#define ID_AWARD5 21 -#define ID_AWARD6 22 -#define ID_BACK 23 -#define ID_RESET 24 -#define ID_CUSTOM 25 -#define ID_NEXT 26 - -#define PLAYER_Y 314 -#define AWARDS_Y (PLAYER_Y + 26) - - -typedef struct { - menuframework_s menu; - menutext_s item_banner; - menubitmap_s item_leftarrow; - menubitmap_s item_maps[4]; - menubitmap_s item_rightarrow; - menubitmap_s item_player; - menubitmap_s item_awards[6]; - menubitmap_s item_back; - menubitmap_s item_reset; - menubitmap_s item_custom; - menubitmap_s item_next; - menubitmap_s item_null; - - qboolean reinit; - - const char * selectedArenaInfo; - int numMaps; - char levelPicNames[4][MAX_QPATH]; - char levelNames[4][16]; - int levelScores[4]; - int levelScoresSkill[4]; - qhandle_t levelSelectedPic; - qhandle_t levelFocusPic; - qhandle_t levelCompletePic[5]; - - char playerModel[MAX_QPATH]; - char playerPicName[MAX_QPATH]; - int awardLevels[6]; - sfxHandle_t awardSounds[6]; - - int numBots; - qhandle_t botPics[7]; - char botNames[7][10]; -} levelMenuInfo_t; - -static levelMenuInfo_t levelMenuInfo; - -static int selectedArenaSet; -static int selectedArena; -static int currentSet; -static int currentGame; -static int trainingTier; -static int finalTier; -static int minTier; -static int maxTier; - - -/* -================= -PlayerIcon -================= -*/ -static void PlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) { - char *skin; - char model[MAX_QPATH]; - - Q_strncpyz( model, modelAndSkin, sizeof(model)); - skin = Q_strrchr( model, '/' ); - if ( skin ) { - *skin++ = '\0'; - } - else { - skin = "default"; - } - - Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin ); - - if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) { - Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model ); - } -} - - -/* -================= -PlayerIconhandle -================= -*/ -static qhandle_t PlayerIconHandle( const char *modelAndSkin ) { - char iconName[MAX_QPATH]; - - PlayerIcon( modelAndSkin, iconName, sizeof(iconName) ); - return trap_R_RegisterShaderNoMip( iconName ); -} - - -/* -================= -UI_SPLevelMenu_SetBots -================= -*/ -static void UI_SPLevelMenu_SetBots( void ) { - char *p; - char *bot; - char *botInfo; - char bots[MAX_INFO_STRING]; - - levelMenuInfo.numBots = 0; - if ( selectedArenaSet > currentSet ) { - return; - } - - Q_strncpyz( bots, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "bots" ), sizeof(bots) ); - - p = &bots[0]; - while( *p && levelMenuInfo.numBots < 7 ) { - //skip spaces - while( *p && *p == ' ' ) { - p++; - } - if( !p ) { - break; - } - - // mark start of bot name - bot = p; - - // skip until space of null - while( *p && *p != ' ' ) { - p++; - } - if( *p ) { - *p++ = 0; - } - - botInfo = UI_GetBotInfoByName( bot ); - if( botInfo ) { - levelMenuInfo.botPics[levelMenuInfo.numBots] = PlayerIconHandle( Info_ValueForKey( botInfo, "model" ) ); - Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], Info_ValueForKey( botInfo, "name" ), 10 ); - } - else { - levelMenuInfo.botPics[levelMenuInfo.numBots] = 0; - Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], bot, 10 ); - } - Q_CleanStr( levelMenuInfo.botNames[levelMenuInfo.numBots] ); - levelMenuInfo.numBots++; - } -} - - -/* -================= -UI_SPLevelMenu_SetMenuItems -================= -*/ -static void UI_SPLevelMenu_SetMenuArena( int n, int level, const char *arenaInfo ) { - char map[MAX_QPATH]; - - Q_strncpyz( map, Info_ValueForKey( arenaInfo, "map" ), sizeof(map) ); - - Q_strncpyz( levelMenuInfo.levelNames[n], map, sizeof(levelMenuInfo.levelNames[n]) ); - Q_strupr( levelMenuInfo.levelNames[n] ); - - UI_GetBestScore( level, &levelMenuInfo.levelScores[n], &levelMenuInfo.levelScoresSkill[n] ); - if( levelMenuInfo.levelScores[n] > 8 ) { - levelMenuInfo.levelScores[n] = 8; - } - - strcpy( levelMenuInfo.levelPicNames[n], va( "levelshots/%s.tga", map ) ); - if( !trap_R_RegisterShaderNoMip( levelMenuInfo.levelPicNames[n] ) ) { - strcpy( levelMenuInfo.levelPicNames[n], ART_MAP_UNKNOWN ); - } - levelMenuInfo.item_maps[n].shader = 0; - if ( selectedArenaSet > currentSet ) { - levelMenuInfo.item_maps[n].generic.flags |= QMF_GRAYED; - } - else { - levelMenuInfo.item_maps[n].generic.flags &= ~QMF_GRAYED; - } - - levelMenuInfo.item_maps[n].generic.flags &= ~QMF_INACTIVE; -} - -static void UI_SPLevelMenu_SetMenuItems( void ) { - int n; - int level; - const char *arenaInfo; - - if ( selectedArenaSet > currentSet ) { - selectedArena = -1; - } - else if ( selectedArena == -1 ) { - selectedArena = 0; - } - - if( selectedArenaSet == trainingTier || selectedArenaSet == finalTier ) { - selectedArena = 0; - } - - if( selectedArena != -1 ) { - trap_Cvar_SetValue( "ui_spSelection", selectedArenaSet * ARENAS_PER_TIER + selectedArena ); - } - - if( selectedArenaSet == trainingTier ) { - arenaInfo = UI_GetSpecialArenaInfo( "training" ); - level = atoi( Info_ValueForKey( arenaInfo, "num" ) ); - UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo ); - levelMenuInfo.selectedArenaInfo = arenaInfo; - - levelMenuInfo.item_maps[0].generic.x = 256; - Bitmap_Init( &levelMenuInfo.item_maps[0] ); - levelMenuInfo.item_maps[0].generic.bottom += 32; - levelMenuInfo.numMaps = 1; - - levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE; - levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE; - levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE; - levelMenuInfo.levelPicNames[1][0] = 0; - levelMenuInfo.levelPicNames[2][0] = 0; - levelMenuInfo.levelPicNames[3][0] = 0; - levelMenuInfo.item_maps[1].shader = 0; - levelMenuInfo.item_maps[2].shader = 0; - levelMenuInfo.item_maps[3].shader = 0; - } - else if( selectedArenaSet == finalTier ) { - arenaInfo = UI_GetSpecialArenaInfo( "final" ); - level = atoi( Info_ValueForKey( arenaInfo, "num" ) ); - UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo ); - levelMenuInfo.selectedArenaInfo = arenaInfo; - - levelMenuInfo.item_maps[0].generic.x = 256; - Bitmap_Init( &levelMenuInfo.item_maps[0] ); - levelMenuInfo.item_maps[0].generic.bottom += 32; - levelMenuInfo.numMaps = 1; - - levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE; - levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE; - levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE; - levelMenuInfo.levelPicNames[1][0] = 0; - levelMenuInfo.levelPicNames[2][0] = 0; - levelMenuInfo.levelPicNames[3][0] = 0; - levelMenuInfo.item_maps[1].shader = 0; - levelMenuInfo.item_maps[2].shader = 0; - levelMenuInfo.item_maps[3].shader = 0; - } - else { - levelMenuInfo.item_maps[0].generic.x = 46; - Bitmap_Init( &levelMenuInfo.item_maps[0] ); - levelMenuInfo.item_maps[0].generic.bottom += 18; - levelMenuInfo.numMaps = 4; - - for ( n = 0; n < 4; n++ ) { - level = selectedArenaSet * ARENAS_PER_TIER + n; - arenaInfo = UI_GetArenaInfoByNumber( level ); - UI_SPLevelMenu_SetMenuArena( n, level, arenaInfo ); - } - - if( selectedArena != -1 ) { - levelMenuInfo.selectedArenaInfo = UI_GetArenaInfoByNumber( selectedArenaSet * ARENAS_PER_TIER + selectedArena ); - } - } - - // enable/disable arrows when they are valid/invalid - if ( selectedArenaSet == minTier ) { - levelMenuInfo.item_leftarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN ); - } - else { - levelMenuInfo.item_leftarrow.generic.flags &= ~( QMF_INACTIVE | QMF_HIDDEN ); - } - - if ( selectedArenaSet == maxTier ) { - levelMenuInfo.item_rightarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN ); - } - else { - levelMenuInfo.item_rightarrow.generic.flags &= ~( QMF_INACTIVE | QMF_HIDDEN ); - } - - UI_SPLevelMenu_SetBots(); -} - - -/* -================= -UI_SPLevelMenu_ResetEvent -================= -*/ -static void UI_SPLevelMenu_ResetDraw( void ) { - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This resets all of the", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "single player game variables.", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 2, "Do this only if you want to", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 3, "start over from the beginning.", UI_CENTER|UI_SMALLFONT, color_yellow ); -} - -static void UI_SPLevelMenu_ResetAction( qboolean result ) { - if( !result ) { - return; - } - - // clear game variables - UI_NewGame(); - trap_Cvar_SetValue( "ui_spSelection", -4 ); - - // make the level select menu re-initialize - UI_PopMenu(); - UI_SPLevelMenu(); -} - -static void UI_SPLevelMenu_ResetEvent( void* ptr, int event ) -{ - if (event != QM_ACTIVATED) { - return; - } - - UI_ConfirmMenu( "RESET GAME?", UI_SPLevelMenu_ResetDraw, UI_SPLevelMenu_ResetAction ); -} - - -/* -================= -UI_SPLevelMenu_LevelEvent -================= -*/ -static void UI_SPLevelMenu_LevelEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - if ( selectedArenaSet == trainingTier || selectedArenaSet == finalTier ) { - return; - } - - selectedArena = ((menucommon_s*)ptr)->id - ID_PICTURE0; - levelMenuInfo.selectedArenaInfo = UI_GetArenaInfoByNumber( selectedArenaSet * ARENAS_PER_TIER + selectedArena ); - UI_SPLevelMenu_SetBots(); - - trap_Cvar_SetValue( "ui_spSelection", selectedArenaSet * ARENAS_PER_TIER + selectedArena ); -} - - -/* -================= -UI_SPLevelMenu_LeftArrowEvent -================= -*/ -static void UI_SPLevelMenu_LeftArrowEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - if ( selectedArenaSet == minTier ) { - return; - } - - selectedArenaSet--; - UI_SPLevelMenu_SetMenuItems(); -} - - -/* -================= -UI_SPLevelMenu_RightArrowEvent -================= -*/ -static void UI_SPLevelMenu_RightArrowEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - if ( selectedArenaSet == maxTier ) { - return; - } - - selectedArenaSet++; - UI_SPLevelMenu_SetMenuItems(); -} - - -/* -================= -UI_SPLevelMenu_PlayerEvent -================= -*/ -static void UI_SPLevelMenu_PlayerEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - UI_PlayerSettingsMenu(); -} - - -/* -================= -UI_SPLevelMenu_AwardEvent -================= -*/ -static void UI_SPLevelMenu_AwardEvent( void* ptr, int notification ) { - int n; - - if (notification != QM_ACTIVATED) { - return; - } - - n = ((menucommon_s*)ptr)->id - ID_AWARD1; - trap_S_StartLocalSound( levelMenuInfo.awardSounds[n], CHAN_ANNOUNCER ); -} - - -/* -================= -UI_SPLevelMenu_NextEvent -================= -*/ -static void UI_SPLevelMenu_NextEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - if ( selectedArenaSet > currentSet ) { - return; - } - - if ( selectedArena == -1 ) { - selectedArena = 0; - } - - UI_SPSkillMenu( levelMenuInfo.selectedArenaInfo ); -} - - -/* -================= -UI_SPLevelMenu_BackEvent -================= -*/ -static void UI_SPLevelMenu_BackEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - if ( selectedArena == -1 ) { - selectedArena = 0; - } - - UI_PopMenu(); -} - - -/* -================= -UI_SPLevelMenu_CustomEvent -================= -*/ -static void UI_SPLevelMenu_CustomEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - UI_StartServerMenu( qfalse ); -} - - -/* -================= -UI_SPLevelMenu_MenuDraw -================= -*/ -#define LEVEL_DESC_LEFT_MARGIN 332 - -static void UI_SPLevelMenu_MenuDraw( void ) { - int n, i; - int x, y; - vec4_t color; - int level; -// int fraglimit; - int pad; - char buf[MAX_INFO_VALUE]; - char string[64]; - - if( levelMenuInfo.reinit ) { - UI_PopMenu(); - UI_SPLevelMenu(); - return; - } - - // draw player name - trap_Cvar_VariableStringBuffer( "name", string, 32 ); - Q_CleanStr( string ); - UI_DrawProportionalString( 320, PLAYER_Y, string, UI_CENTER|UI_SMALLFONT, color_orange ); - - // check for model changes - trap_Cvar_VariableStringBuffer( "model", buf, sizeof(buf) ); - if( Q_stricmp( buf, levelMenuInfo.playerModel ) != 0 ) { - Q_strncpyz( levelMenuInfo.playerModel, buf, sizeof(levelMenuInfo.playerModel) ); - PlayerIcon( levelMenuInfo.playerModel, levelMenuInfo.playerPicName, sizeof(levelMenuInfo.playerPicName) ); - levelMenuInfo.item_player.shader = 0; - } - - // standard menu drawing - Menu_Draw( &levelMenuInfo.menu ); - - // draw player award levels - y = AWARDS_Y; - i = 0; - for( n = 0; n < 6; n++ ) { - level = levelMenuInfo.awardLevels[n]; - if( level > 0 ) { - if( i & 1 ) { - x = 224 - (i - 1 ) / 2 * (48 + 16); - } - else { - x = 368 + i / 2 * (48 + 16); - } - i++; - - if( level == 1 ) { - continue; - } - - if( level >= 1000000 ) { - Com_sprintf( string, sizeof(string), "%im", level / 1000000 ); - } - else if( level >= 1000 ) { - Com_sprintf( string, sizeof(string), "%ik", level / 1000 ); - } - else { - Com_sprintf( string, sizeof(string), "%i", level ); - } - - UI_DrawString( x + 24, y + 48, string, UI_CENTER, color_yellow ); - } - } - - UI_DrawProportionalString( 18, 38, va( "Tier %i", selectedArenaSet + 1 ), UI_LEFT|UI_SMALLFONT, color_orange ); - - for ( n = 0; n < levelMenuInfo.numMaps; n++ ) { - x = levelMenuInfo.item_maps[n].generic.x; - y = levelMenuInfo.item_maps[n].generic.y; - UI_FillRect( x, y + 96, 128, 18, color_black ); - } - - if ( selectedArenaSet > currentSet ) { - UI_DrawProportionalString( 320, 216, "ACCESS DENIED", UI_CENTER|UI_BIGFONT, color_red ); - return; - } - - // show levelshots for levels of current tier - Vector4Copy( color_white, color ); - color[3] = 0.5+0.5*sin(uis.realtime/PULSE_DIVISOR); - for ( n = 0; n < levelMenuInfo.numMaps; n++ ) { - x = levelMenuInfo.item_maps[n].generic.x; - y = levelMenuInfo.item_maps[n].generic.y; - - UI_DrawString( x + 64, y + 96, levelMenuInfo.levelNames[n], UI_CENTER|UI_SMALLFONT, color_orange ); - - if( levelMenuInfo.levelScores[n] == 1 ) { - UI_DrawHandlePic( x, y, 128, 96, levelMenuInfo.levelCompletePic[levelMenuInfo.levelScoresSkill[n] - 1] ); - } - - if ( n == selectedArena ) { - if( Menu_ItemAtCursor( &levelMenuInfo.menu ) == &levelMenuInfo.item_maps[n] ) { - trap_R_SetColor( color ); - } - UI_DrawHandlePic( x-1, y-1, 130, 130 - 14, levelMenuInfo.levelSelectedPic ); - trap_R_SetColor( NULL ); - } - else if( Menu_ItemAtCursor( &levelMenuInfo.menu ) == &levelMenuInfo.item_maps[n] ) { - trap_R_SetColor( color ); - UI_DrawHandlePic( x-31, y-30, 256, 256-27, levelMenuInfo.levelFocusPic); - trap_R_SetColor( NULL ); - } - } - - // show map name and long name of selected level - y = 192; - Q_strncpyz( buf, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "map" ), 20 ); - Q_strupr( buf ); - Com_sprintf( string, sizeof(string), "%s: %s", buf, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "longname" ) ); - UI_DrawProportionalString( 320, y, string, UI_CENTER|UI_SMALLFONT, color_orange ); - -// fraglimit = atoi( Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "fraglimit" ) ); -// UI_DrawString( 18, 212, va("Frags %i", fraglimit) , UI_LEFT|UI_SMALLFONT, color_orange ); - - // draw bot opponents - y += 24; - pad = (7 - levelMenuInfo.numBots) * (64 + 26) / 2; - for( n = 0; n < levelMenuInfo.numBots; n++ ) { - x = 18 + pad + (64 + 26) * n; - if( levelMenuInfo.botPics[n] ) { - UI_DrawHandlePic( x, y, 64, 64, levelMenuInfo.botPics[n]); - } - else { - UI_FillRect( x, y, 64, 64, color_black ); - UI_DrawProportionalString( x+22, y+18, "?", UI_BIGFONT, color_orange ); - } - UI_DrawString( x, y + 64, levelMenuInfo.botNames[n], UI_SMALLFONT|UI_LEFT, color_orange ); - } -} - - -/* -================= -UI_SPLevelMenu_Cache -================= -*/ -void UI_SPLevelMenu_Cache( void ) { - int n; - - trap_R_RegisterShaderNoMip( ART_LEVELFRAME_FOCUS ); - trap_R_RegisterShaderNoMip( ART_LEVELFRAME_SELECTED ); - trap_R_RegisterShaderNoMip( ART_ARROW ); - trap_R_RegisterShaderNoMip( ART_ARROW_FOCUS ); - trap_R_RegisterShaderNoMip( ART_MAP_UNKNOWN ); - trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 ); - trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 ); - trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 ); - trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 ); - trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); - trap_R_RegisterShaderNoMip( ART_FIGHT0 ); - trap_R_RegisterShaderNoMip( ART_FIGHT1 ); - trap_R_RegisterShaderNoMip( ART_RESET0 ); - trap_R_RegisterShaderNoMip( ART_RESET1 ); - trap_R_RegisterShaderNoMip( ART_CUSTOM0 ); - trap_R_RegisterShaderNoMip( ART_CUSTOM1 ); - - for( n = 0; n < 6; n++ ) { - trap_R_RegisterShaderNoMip( ui_medalPicNames[n] ); - levelMenuInfo.awardSounds[n] = trap_S_RegisterSound( ui_medalSounds[n], qfalse ); - } - - levelMenuInfo.levelSelectedPic = trap_R_RegisterShaderNoMip( ART_LEVELFRAME_SELECTED ); - levelMenuInfo.levelFocusPic = trap_R_RegisterShaderNoMip( ART_LEVELFRAME_FOCUS ); - levelMenuInfo.levelCompletePic[0] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 ); - levelMenuInfo.levelCompletePic[1] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 ); - levelMenuInfo.levelCompletePic[2] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 ); - levelMenuInfo.levelCompletePic[3] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 ); - levelMenuInfo.levelCompletePic[4] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 ); -} - - -/* -================= -UI_SPLevelMenu_Init -================= -*/ -static void UI_SPLevelMenu_Init( void ) { - int skill; - int n; - int x, y; - int count; - char buf[MAX_QPATH]; - - skill = (int)trap_Cvar_VariableValue( "g_spSkill" ); - if( skill < 1 || skill > 5 ) { - trap_Cvar_Set( "g_spSkill", "2" ); - skill = 2; - } - - memset( &levelMenuInfo, 0, sizeof(levelMenuInfo) ); - levelMenuInfo.menu.fullscreen = qtrue; - levelMenuInfo.menu.wrapAround = qtrue; - levelMenuInfo.menu.draw = UI_SPLevelMenu_MenuDraw; - - UI_SPLevelMenu_Cache(); - - levelMenuInfo.item_banner.generic.type = MTYPE_BTEXT; - levelMenuInfo.item_banner.generic.x = 320; - levelMenuInfo.item_banner.generic.y = 16; - levelMenuInfo.item_banner.string = "CHOOSE LEVEL"; - levelMenuInfo.item_banner.color = color_red; - levelMenuInfo.item_banner.style = UI_CENTER; - - levelMenuInfo.item_leftarrow.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_leftarrow.generic.name = ART_ARROW; - levelMenuInfo.item_leftarrow.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - levelMenuInfo.item_leftarrow.generic.x = 18; - levelMenuInfo.item_leftarrow.generic.y = 64; - levelMenuInfo.item_leftarrow.generic.callback = UI_SPLevelMenu_LeftArrowEvent; - levelMenuInfo.item_leftarrow.generic.id = ID_LEFTARROW; - levelMenuInfo.item_leftarrow.width = 16; - levelMenuInfo.item_leftarrow.height = 114; - levelMenuInfo.item_leftarrow.focuspic = ART_ARROW_FOCUS; - - levelMenuInfo.item_maps[0].generic.type = MTYPE_BITMAP; - levelMenuInfo.item_maps[0].generic.name = levelMenuInfo.levelPicNames[0]; - levelMenuInfo.item_maps[0].generic.flags = QMF_LEFT_JUSTIFY; - levelMenuInfo.item_maps[0].generic.x = 46; - levelMenuInfo.item_maps[0].generic.y = 64; - levelMenuInfo.item_maps[0].generic.id = ID_PICTURE0; - levelMenuInfo.item_maps[0].generic.callback = UI_SPLevelMenu_LevelEvent; - levelMenuInfo.item_maps[0].width = 128; - levelMenuInfo.item_maps[0].height = 96; - - levelMenuInfo.item_maps[1].generic.type = MTYPE_BITMAP; - levelMenuInfo.item_maps[1].generic.name = levelMenuInfo.levelPicNames[1]; - levelMenuInfo.item_maps[1].generic.flags = QMF_LEFT_JUSTIFY; - levelMenuInfo.item_maps[1].generic.x = 186; - levelMenuInfo.item_maps[1].generic.y = 64; - levelMenuInfo.item_maps[1].generic.id = ID_PICTURE1; - levelMenuInfo.item_maps[1].generic.callback = UI_SPLevelMenu_LevelEvent; - levelMenuInfo.item_maps[1].width = 128; - levelMenuInfo.item_maps[1].height = 96; - - levelMenuInfo.item_maps[2].generic.type = MTYPE_BITMAP; - levelMenuInfo.item_maps[2].generic.name = levelMenuInfo.levelPicNames[2]; - levelMenuInfo.item_maps[2].generic.flags = QMF_LEFT_JUSTIFY; - levelMenuInfo.item_maps[2].generic.x = 326; - levelMenuInfo.item_maps[2].generic.y = 64; - levelMenuInfo.item_maps[2].generic.id = ID_PICTURE2; - levelMenuInfo.item_maps[2].generic.callback = UI_SPLevelMenu_LevelEvent; - levelMenuInfo.item_maps[2].width = 128; - levelMenuInfo.item_maps[2].height = 96; - - levelMenuInfo.item_maps[3].generic.type = MTYPE_BITMAP; - levelMenuInfo.item_maps[3].generic.name = levelMenuInfo.levelPicNames[3]; - levelMenuInfo.item_maps[3].generic.flags = QMF_LEFT_JUSTIFY; - levelMenuInfo.item_maps[3].generic.x = 466; - levelMenuInfo.item_maps[3].generic.y = 64; - levelMenuInfo.item_maps[3].generic.id = ID_PICTURE3; - levelMenuInfo.item_maps[3].generic.callback = UI_SPLevelMenu_LevelEvent; - levelMenuInfo.item_maps[3].width = 128; - levelMenuInfo.item_maps[3].height = 96; - - levelMenuInfo.item_rightarrow.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_rightarrow.generic.name = ART_ARROW; - levelMenuInfo.item_rightarrow.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - levelMenuInfo.item_rightarrow.generic.x = 606; - levelMenuInfo.item_rightarrow.generic.y = 64; - levelMenuInfo.item_rightarrow.generic.callback = UI_SPLevelMenu_RightArrowEvent; - levelMenuInfo.item_rightarrow.generic.id = ID_RIGHTARROW; - levelMenuInfo.item_rightarrow.width = -16; - levelMenuInfo.item_rightarrow.height = 114; - levelMenuInfo.item_rightarrow.focuspic = ART_ARROW_FOCUS; - - trap_Cvar_VariableStringBuffer( "model", levelMenuInfo.playerModel, sizeof(levelMenuInfo.playerModel) ); - PlayerIcon( levelMenuInfo.playerModel, levelMenuInfo.playerPicName, sizeof(levelMenuInfo.playerPicName) ); - levelMenuInfo.item_player.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_player.generic.name = levelMenuInfo.playerPicName; - levelMenuInfo.item_player.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY; - levelMenuInfo.item_player.generic.x = 288; - levelMenuInfo.item_player.generic.y = AWARDS_Y; - levelMenuInfo.item_player.generic.id = ID_PLAYERPIC; - levelMenuInfo.item_player.generic.callback = UI_SPLevelMenu_PlayerEvent; - levelMenuInfo.item_player.width = 64; - levelMenuInfo.item_player.height = 64; - - for( n = 0; n < 6; n++ ) { - levelMenuInfo.awardLevels[n] = UI_GetAwardLevel( n ); - } - levelMenuInfo.awardLevels[AWARD_FRAGS] = 100 * (levelMenuInfo.awardLevels[AWARD_FRAGS] / 100); - - y = AWARDS_Y; - count = 0; - for( n = 0; n < 6; n++ ) { - if( levelMenuInfo.awardLevels[n] ) { - if( count & 1 ) { - x = 224 - (count - 1 ) / 2 * (48 + 16); - } - else { - x = 368 + count / 2 * (48 + 16); - } - - levelMenuInfo.item_awards[count].generic.type = MTYPE_BITMAP; - levelMenuInfo.item_awards[count].generic.name = ui_medalPicNames[n]; - levelMenuInfo.item_awards[count].generic.flags = QMF_LEFT_JUSTIFY|QMF_SILENT|QMF_MOUSEONLY; - levelMenuInfo.item_awards[count].generic.x = x; - levelMenuInfo.item_awards[count].generic.y = y; - levelMenuInfo.item_awards[count].generic.id = ID_AWARD1 + n; - levelMenuInfo.item_awards[count].generic.callback = UI_SPLevelMenu_AwardEvent; - levelMenuInfo.item_awards[count].width = 48; - levelMenuInfo.item_awards[count].height = 48; - count++; - } - } - - levelMenuInfo.item_back.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_back.generic.name = ART_BACK0; - levelMenuInfo.item_back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - levelMenuInfo.item_back.generic.x = 0; - levelMenuInfo.item_back.generic.y = 480-64; - levelMenuInfo.item_back.generic.callback = UI_SPLevelMenu_BackEvent; - levelMenuInfo.item_back.generic.id = ID_BACK; - levelMenuInfo.item_back.width = 128; - levelMenuInfo.item_back.height = 64; - levelMenuInfo.item_back.focuspic = ART_BACK1; - - levelMenuInfo.item_reset.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_reset.generic.name = ART_RESET0; - levelMenuInfo.item_reset.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - levelMenuInfo.item_reset.generic.x = 170; - levelMenuInfo.item_reset.generic.y = 480-64; - levelMenuInfo.item_reset.generic.callback = UI_SPLevelMenu_ResetEvent; - levelMenuInfo.item_reset.generic.id = ID_RESET; - levelMenuInfo.item_reset.width = 128; - levelMenuInfo.item_reset.height = 64; - levelMenuInfo.item_reset.focuspic = ART_RESET1; - - levelMenuInfo.item_custom.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_custom.generic.name = ART_CUSTOM0; - levelMenuInfo.item_custom.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - levelMenuInfo.item_custom.generic.x = 342; - levelMenuInfo.item_custom.generic.y = 480-64; - levelMenuInfo.item_custom.generic.callback = UI_SPLevelMenu_CustomEvent; - levelMenuInfo.item_custom.generic.id = ID_CUSTOM; - levelMenuInfo.item_custom.width = 128; - levelMenuInfo.item_custom.height = 64; - levelMenuInfo.item_custom.focuspic = ART_CUSTOM1; - - levelMenuInfo.item_next.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_next.generic.name = ART_FIGHT0; - levelMenuInfo.item_next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - levelMenuInfo.item_next.generic.x = 640; - levelMenuInfo.item_next.generic.y = 480-64; - levelMenuInfo.item_next.generic.callback = UI_SPLevelMenu_NextEvent; - levelMenuInfo.item_next.generic.id = ID_NEXT; - levelMenuInfo.item_next.width = 128; - levelMenuInfo.item_next.height = 64; - levelMenuInfo.item_next.focuspic = ART_FIGHT1; - - levelMenuInfo.item_null.generic.type = MTYPE_BITMAP; - levelMenuInfo.item_null.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY|QMF_SILENT; - levelMenuInfo.item_null.generic.x = 0; - levelMenuInfo.item_null.generic.y = 0; - levelMenuInfo.item_null.width = 640; - levelMenuInfo.item_null.height = 480; - - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_banner ); - - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_leftarrow ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[0] ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[1] ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[2] ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[3] ); - levelMenuInfo.item_maps[0].generic.bottom += 18; - levelMenuInfo.item_maps[1].generic.bottom += 18; - levelMenuInfo.item_maps[2].generic.bottom += 18; - levelMenuInfo.item_maps[3].generic.bottom += 18; - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_rightarrow ); - - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_player ); - - for( n = 0; n < count; n++ ) { - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_awards[n] ); - } - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_back ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_reset ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_custom ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_next ); - Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_null ); - - trap_Cvar_VariableStringBuffer( "ui_spSelection", buf, sizeof(buf) ); - if( *buf ) { - n = atoi( buf ); - selectedArenaSet = n / ARENAS_PER_TIER; - selectedArena = n % ARENAS_PER_TIER; - } - else { - selectedArenaSet = currentSet; - selectedArena = currentGame; - } - - UI_SPLevelMenu_SetMenuItems(); -} - - -/* -================= -UI_SPLevelMenu -================= -*/ -void UI_SPLevelMenu( void ) { - int level; - int trainingLevel; - const char *arenaInfo; - - trainingTier = -1; - arenaInfo = UI_GetSpecialArenaInfo( "training" ); - if( arenaInfo ) { - minTier = trainingTier; - trainingLevel = atoi( Info_ValueForKey( arenaInfo, "num" ) ); - } - else { - minTier = 0; - trainingLevel = -2; - } - - finalTier = UI_GetNumSPTiers(); - arenaInfo = UI_GetSpecialArenaInfo( "final" ); - if( arenaInfo ) { - maxTier = finalTier; - } - else { - maxTier = finalTier - 1; - if( maxTier < minTier ) { - maxTier = minTier; - } - } - - level = UI_GetCurrentGame(); - if ( level == -1 ) { - level = UI_GetNumSPArenas() - 1; - if( maxTier == finalTier ) { - level++; - } - } - - if( level == trainingLevel ) { - currentSet = -1; - currentGame = 0; - } - else { - currentSet = level / ARENAS_PER_TIER; - currentGame = level % ARENAS_PER_TIER; - } - - UI_SPLevelMenu_Init(); - UI_PushMenu( &levelMenuInfo.menu ); - Menu_SetCursorToItem( &levelMenuInfo.menu, &levelMenuInfo.item_next ); -} - - -/* -================= -UI_SPLevelMenu_f -================= -*/ -void UI_SPLevelMenu_f( void ) { - trap_Key_SetCatcher( KEYCATCH_UI ); - uis.menusp = 0; - UI_SPLevelMenu(); -} - - -/* -================= -UI_SPLevelMenu_ReInit -================= -*/ -void UI_SPLevelMenu_ReInit( void ) { - levelMenuInfo.reinit = qtrue; -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +============================================================================= + +SINGLE PLAYER LEVEL SELECT MENU + +============================================================================= +*/ + +#include "ui_local.h" + + +#define ART_LEVELFRAME_FOCUS "menu/art/maps_select" +#define ART_LEVELFRAME_SELECTED "menu/art/maps_selected" +#define ART_ARROW "menu/art/narrow_0" +#define ART_ARROW_FOCUS "menu/art/narrow_1" +#define ART_MAP_UNKNOWN "menu/art/unknownmap" +#define ART_MAP_COMPLETE1 "menu/art/level_complete1" +#define ART_MAP_COMPLETE2 "menu/art/level_complete2" +#define ART_MAP_COMPLETE3 "menu/art/level_complete3" +#define ART_MAP_COMPLETE4 "menu/art/level_complete4" +#define ART_MAP_COMPLETE5 "menu/art/level_complete5" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" +#define ART_FIGHT0 "menu/art/fight_0" +#define ART_FIGHT1 "menu/art/fight_1" +#define ART_RESET0 "menu/art/reset_0" +#define ART_RESET1 "menu/art/reset_1" +#define ART_CUSTOM0 "menu/art/skirmish_0" +#define ART_CUSTOM1 "menu/art/skirmish_1" + +#define ID_LEFTARROW 10 +#define ID_PICTURE0 11 +#define ID_PICTURE1 12 +#define ID_PICTURE2 13 +#define ID_PICTURE3 14 +#define ID_RIGHTARROW 15 +#define ID_PLAYERPIC 16 +#define ID_AWARD1 17 +#define ID_AWARD2 18 +#define ID_AWARD3 19 +#define ID_AWARD4 20 +#define ID_AWARD5 21 +#define ID_AWARD6 22 +#define ID_BACK 23 +#define ID_RESET 24 +#define ID_CUSTOM 25 +#define ID_NEXT 26 + +#define PLAYER_Y 314 +#define AWARDS_Y (PLAYER_Y + 26) + + +typedef struct { + menuframework_s menu; + menutext_s item_banner; + menubitmap_s item_leftarrow; + menubitmap_s item_maps[4]; + menubitmap_s item_rightarrow; + menubitmap_s item_player; + menubitmap_s item_awards[6]; + menubitmap_s item_back; + menubitmap_s item_reset; + menubitmap_s item_custom; + menubitmap_s item_next; + menubitmap_s item_null; + + qboolean reinit; + + const char * selectedArenaInfo; + int numMaps; + char levelPicNames[4][MAX_QPATH]; + char levelNames[4][16]; + int levelScores[4]; + int levelScoresSkill[4]; + qhandle_t levelSelectedPic; + qhandle_t levelFocusPic; + qhandle_t levelCompletePic[5]; + + char playerModel[MAX_QPATH]; + char playerPicName[MAX_QPATH]; + int awardLevels[6]; + sfxHandle_t awardSounds[6]; + + int numBots; + qhandle_t botPics[7]; + char botNames[7][10]; +} levelMenuInfo_t; + +static levelMenuInfo_t levelMenuInfo; + +static int selectedArenaSet; +static int selectedArena; +static int currentSet; +static int currentGame; +static int trainingTier; +static int finalTier; +static int minTier; +static int maxTier; + + +/* +================= +PlayerIcon +================= +*/ +static void PlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) { + char *skin; + char model[MAX_QPATH]; + + Q_strncpyz( model, modelAndSkin, sizeof(model)); + skin = Q_strrchr( model, '/' ); + if ( skin ) { + *skin++ = '\0'; + } + else { + skin = "default"; + } + + Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin ); + + if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) { + Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model ); + } +} + + +/* +================= +PlayerIconhandle +================= +*/ +static qhandle_t PlayerIconHandle( const char *modelAndSkin ) { + char iconName[MAX_QPATH]; + + PlayerIcon( modelAndSkin, iconName, sizeof(iconName) ); + return trap_R_RegisterShaderNoMip( iconName ); +} + + +/* +================= +UI_SPLevelMenu_SetBots +================= +*/ +static void UI_SPLevelMenu_SetBots( void ) { + char *p; + char *bot; + char *botInfo; + char bots[MAX_INFO_STRING]; + + levelMenuInfo.numBots = 0; + if ( selectedArenaSet > currentSet ) { + return; + } + + Q_strncpyz( bots, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "bots" ), sizeof(bots) ); + + p = &bots[0]; + while( *p && levelMenuInfo.numBots < 7 ) { + //skip spaces + while( *p && *p == ' ' ) { + p++; + } + if( !p ) { + break; + } + + // mark start of bot name + bot = p; + + // skip until space of null + while( *p && *p != ' ' ) { + p++; + } + if( *p ) { + *p++ = 0; + } + + botInfo = UI_GetBotInfoByName( bot ); + if( botInfo ) { + levelMenuInfo.botPics[levelMenuInfo.numBots] = PlayerIconHandle( Info_ValueForKey( botInfo, "model" ) ); + Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], Info_ValueForKey( botInfo, "name" ), 10 ); + } + else { + levelMenuInfo.botPics[levelMenuInfo.numBots] = 0; + Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], bot, 10 ); + } + Q_CleanStr( levelMenuInfo.botNames[levelMenuInfo.numBots] ); + levelMenuInfo.numBots++; + } +} + + +/* +================= +UI_SPLevelMenu_SetMenuItems +================= +*/ +static void UI_SPLevelMenu_SetMenuArena( int n, int level, const char *arenaInfo ) { + char map[MAX_QPATH]; + + Q_strncpyz( map, Info_ValueForKey( arenaInfo, "map" ), sizeof(map) ); + + Q_strncpyz( levelMenuInfo.levelNames[n], map, sizeof(levelMenuInfo.levelNames[n]) ); + Q_strupr( levelMenuInfo.levelNames[n] ); + + UI_GetBestScore( level, &levelMenuInfo.levelScores[n], &levelMenuInfo.levelScoresSkill[n] ); + if( levelMenuInfo.levelScores[n] > 8 ) { + levelMenuInfo.levelScores[n] = 8; + } + + strcpy( levelMenuInfo.levelPicNames[n], va( "levelshots/%s.tga", map ) ); + if( !trap_R_RegisterShaderNoMip( levelMenuInfo.levelPicNames[n] ) ) { + strcpy( levelMenuInfo.levelPicNames[n], ART_MAP_UNKNOWN ); + } + levelMenuInfo.item_maps[n].shader = 0; + if ( selectedArenaSet > currentSet ) { + levelMenuInfo.item_maps[n].generic.flags |= QMF_GRAYED; + } + else { + levelMenuInfo.item_maps[n].generic.flags &= ~QMF_GRAYED; + } + + levelMenuInfo.item_maps[n].generic.flags &= ~QMF_INACTIVE; +} + +static void UI_SPLevelMenu_SetMenuItems( void ) { + int n; + int level; + const char *arenaInfo; + + if ( selectedArenaSet > currentSet ) { + selectedArena = -1; + } + else if ( selectedArena == -1 ) { + selectedArena = 0; + } + + if( selectedArenaSet == trainingTier || selectedArenaSet == finalTier ) { + selectedArena = 0; + } + + if( selectedArena != -1 ) { + trap_Cvar_SetValue( "ui_spSelection", selectedArenaSet * ARENAS_PER_TIER + selectedArena ); + } + + if( selectedArenaSet == trainingTier ) { + arenaInfo = UI_GetSpecialArenaInfo( "training" ); + level = atoi( Info_ValueForKey( arenaInfo, "num" ) ); + UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo ); + levelMenuInfo.selectedArenaInfo = arenaInfo; + + levelMenuInfo.item_maps[0].generic.x = 256; + Bitmap_Init( &levelMenuInfo.item_maps[0] ); + levelMenuInfo.item_maps[0].generic.bottom += 32; + levelMenuInfo.numMaps = 1; + + levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE; + levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE; + levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE; + levelMenuInfo.levelPicNames[1][0] = 0; + levelMenuInfo.levelPicNames[2][0] = 0; + levelMenuInfo.levelPicNames[3][0] = 0; + levelMenuInfo.item_maps[1].shader = 0; + levelMenuInfo.item_maps[2].shader = 0; + levelMenuInfo.item_maps[3].shader = 0; + } + else if( selectedArenaSet == finalTier ) { + arenaInfo = UI_GetSpecialArenaInfo( "final" ); + level = atoi( Info_ValueForKey( arenaInfo, "num" ) ); + UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo ); + levelMenuInfo.selectedArenaInfo = arenaInfo; + + levelMenuInfo.item_maps[0].generic.x = 256; + Bitmap_Init( &levelMenuInfo.item_maps[0] ); + levelMenuInfo.item_maps[0].generic.bottom += 32; + levelMenuInfo.numMaps = 1; + + levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE; + levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE; + levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE; + levelMenuInfo.levelPicNames[1][0] = 0; + levelMenuInfo.levelPicNames[2][0] = 0; + levelMenuInfo.levelPicNames[3][0] = 0; + levelMenuInfo.item_maps[1].shader = 0; + levelMenuInfo.item_maps[2].shader = 0; + levelMenuInfo.item_maps[3].shader = 0; + } + else { + levelMenuInfo.item_maps[0].generic.x = 46; + Bitmap_Init( &levelMenuInfo.item_maps[0] ); + levelMenuInfo.item_maps[0].generic.bottom += 18; + levelMenuInfo.numMaps = 4; + + for ( n = 0; n < 4; n++ ) { + level = selectedArenaSet * ARENAS_PER_TIER + n; + arenaInfo = UI_GetArenaInfoByNumber( level ); + UI_SPLevelMenu_SetMenuArena( n, level, arenaInfo ); + } + + if( selectedArena != -1 ) { + levelMenuInfo.selectedArenaInfo = UI_GetArenaInfoByNumber( selectedArenaSet * ARENAS_PER_TIER + selectedArena ); + } + } + + // enable/disable arrows when they are valid/invalid + if ( selectedArenaSet == minTier ) { + levelMenuInfo.item_leftarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN ); + } + else { + levelMenuInfo.item_leftarrow.generic.flags &= ~( QMF_INACTIVE | QMF_HIDDEN ); + } + + if ( selectedArenaSet == maxTier ) { + levelMenuInfo.item_rightarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN ); + } + else { + levelMenuInfo.item_rightarrow.generic.flags &= ~( QMF_INACTIVE | QMF_HIDDEN ); + } + + UI_SPLevelMenu_SetBots(); +} + + +/* +================= +UI_SPLevelMenu_ResetEvent +================= +*/ +static void UI_SPLevelMenu_ResetDraw( void ) { + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This resets all of the", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "single player game variables.", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 2, "Do this only if you want to", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 3, "start over from the beginning.", UI_CENTER|UI_SMALLFONT, color_yellow ); +} + +static void UI_SPLevelMenu_ResetAction( qboolean result ) { + if( !result ) { + return; + } + + // clear game variables + UI_NewGame(); + trap_Cvar_SetValue( "ui_spSelection", -4 ); + + // make the level select menu re-initialize + UI_PopMenu(); + UI_SPLevelMenu(); +} + +static void UI_SPLevelMenu_ResetEvent( void* ptr, int event ) +{ + if (event != QM_ACTIVATED) { + return; + } + + UI_ConfirmMenu( "RESET GAME?", UI_SPLevelMenu_ResetDraw, UI_SPLevelMenu_ResetAction ); +} + + +/* +================= +UI_SPLevelMenu_LevelEvent +================= +*/ +static void UI_SPLevelMenu_LevelEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + if ( selectedArenaSet == trainingTier || selectedArenaSet == finalTier ) { + return; + } + + selectedArena = ((menucommon_s*)ptr)->id - ID_PICTURE0; + levelMenuInfo.selectedArenaInfo = UI_GetArenaInfoByNumber( selectedArenaSet * ARENAS_PER_TIER + selectedArena ); + UI_SPLevelMenu_SetBots(); + + trap_Cvar_SetValue( "ui_spSelection", selectedArenaSet * ARENAS_PER_TIER + selectedArena ); +} + + +/* +================= +UI_SPLevelMenu_LeftArrowEvent +================= +*/ +static void UI_SPLevelMenu_LeftArrowEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + if ( selectedArenaSet == minTier ) { + return; + } + + selectedArenaSet--; + UI_SPLevelMenu_SetMenuItems(); +} + + +/* +================= +UI_SPLevelMenu_RightArrowEvent +================= +*/ +static void UI_SPLevelMenu_RightArrowEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + if ( selectedArenaSet == maxTier ) { + return; + } + + selectedArenaSet++; + UI_SPLevelMenu_SetMenuItems(); +} + + +/* +================= +UI_SPLevelMenu_PlayerEvent +================= +*/ +static void UI_SPLevelMenu_PlayerEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + UI_PlayerSettingsMenu(); +} + + +/* +================= +UI_SPLevelMenu_AwardEvent +================= +*/ +static void UI_SPLevelMenu_AwardEvent( void* ptr, int notification ) { + int n; + + if (notification != QM_ACTIVATED) { + return; + } + + n = ((menucommon_s*)ptr)->id - ID_AWARD1; + trap_S_StartLocalSound( levelMenuInfo.awardSounds[n], CHAN_ANNOUNCER ); +} + + +/* +================= +UI_SPLevelMenu_NextEvent +================= +*/ +static void UI_SPLevelMenu_NextEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + if ( selectedArenaSet > currentSet ) { + return; + } + + if ( selectedArena == -1 ) { + selectedArena = 0; + } + + UI_SPSkillMenu( levelMenuInfo.selectedArenaInfo ); +} + + +/* +================= +UI_SPLevelMenu_BackEvent +================= +*/ +static void UI_SPLevelMenu_BackEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + if ( selectedArena == -1 ) { + selectedArena = 0; + } + + UI_PopMenu(); +} + + +/* +================= +UI_SPLevelMenu_CustomEvent +================= +*/ +static void UI_SPLevelMenu_CustomEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + UI_StartServerMenu( qfalse ); +} + + +/* +================= +UI_SPLevelMenu_MenuDraw +================= +*/ +#define LEVEL_DESC_LEFT_MARGIN 332 + +static void UI_SPLevelMenu_MenuDraw( void ) { + int n, i; + int x, y; + vec4_t color; + int level; +// int fraglimit; + int pad; + char buf[MAX_INFO_VALUE]; + char string[64]; + + if( levelMenuInfo.reinit ) { + UI_PopMenu(); + UI_SPLevelMenu(); + return; + } + + // draw player name + trap_Cvar_VariableStringBuffer( "name", string, 32 ); + Q_CleanStr( string ); + UI_DrawProportionalString( 320, PLAYER_Y, string, UI_CENTER|UI_SMALLFONT, color_orange ); + + // check for model changes + trap_Cvar_VariableStringBuffer( "model", buf, sizeof(buf) ); + if( Q_stricmp( buf, levelMenuInfo.playerModel ) != 0 ) { + Q_strncpyz( levelMenuInfo.playerModel, buf, sizeof(levelMenuInfo.playerModel) ); + PlayerIcon( levelMenuInfo.playerModel, levelMenuInfo.playerPicName, sizeof(levelMenuInfo.playerPicName) ); + levelMenuInfo.item_player.shader = 0; + } + + // standard menu drawing + Menu_Draw( &levelMenuInfo.menu ); + + // draw player award levels + y = AWARDS_Y; + i = 0; + for( n = 0; n < 6; n++ ) { + level = levelMenuInfo.awardLevels[n]; + if( level > 0 ) { + if( i & 1 ) { + x = 224 - (i - 1 ) / 2 * (48 + 16); + } + else { + x = 368 + i / 2 * (48 + 16); + } + i++; + + if( level == 1 ) { + continue; + } + + if( level >= 1000000 ) { + Com_sprintf( string, sizeof(string), "%im", level / 1000000 ); + } + else if( level >= 1000 ) { + Com_sprintf( string, sizeof(string), "%ik", level / 1000 ); + } + else { + Com_sprintf( string, sizeof(string), "%i", level ); + } + + UI_DrawString( x + 24, y + 48, string, UI_CENTER, color_yellow ); + } + } + + UI_DrawProportionalString( 18, 38, va( "Tier %i", selectedArenaSet + 1 ), UI_LEFT|UI_SMALLFONT, color_orange ); + + for ( n = 0; n < levelMenuInfo.numMaps; n++ ) { + x = levelMenuInfo.item_maps[n].generic.x; + y = levelMenuInfo.item_maps[n].generic.y; + UI_FillRect( x, y + 96, 128, 18, color_black ); + } + + if ( selectedArenaSet > currentSet ) { + UI_DrawProportionalString( 320, 216, "ACCESS DENIED", UI_CENTER|UI_BIGFONT, color_red ); + return; + } + + // show levelshots for levels of current tier + Vector4Copy( color_white, color ); + color[3] = 0.5+0.5*sin(uis.realtime/PULSE_DIVISOR); + for ( n = 0; n < levelMenuInfo.numMaps; n++ ) { + x = levelMenuInfo.item_maps[n].generic.x; + y = levelMenuInfo.item_maps[n].generic.y; + + UI_DrawString( x + 64, y + 96, levelMenuInfo.levelNames[n], UI_CENTER|UI_SMALLFONT, color_orange ); + + if( levelMenuInfo.levelScores[n] == 1 ) { + UI_DrawHandlePic( x, y, 128, 96, levelMenuInfo.levelCompletePic[levelMenuInfo.levelScoresSkill[n] - 1] ); + } + + if ( n == selectedArena ) { + if( Menu_ItemAtCursor( &levelMenuInfo.menu ) == &levelMenuInfo.item_maps[n] ) { + trap_R_SetColor( color ); + } + UI_DrawHandlePic( x-1, y-1, 130, 130 - 14, levelMenuInfo.levelSelectedPic ); + trap_R_SetColor( NULL ); + } + else if( Menu_ItemAtCursor( &levelMenuInfo.menu ) == &levelMenuInfo.item_maps[n] ) { + trap_R_SetColor( color ); + UI_DrawHandlePic( x-31, y-30, 256, 256-27, levelMenuInfo.levelFocusPic); + trap_R_SetColor( NULL ); + } + } + + // show map name and long name of selected level + y = 192; + Q_strncpyz( buf, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "map" ), 20 ); + Q_strupr( buf ); + Com_sprintf( string, sizeof(string), "%s: %s", buf, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "longname" ) ); + UI_DrawProportionalString( 320, y, string, UI_CENTER|UI_SMALLFONT, color_orange ); + +// fraglimit = atoi( Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "fraglimit" ) ); +// UI_DrawString( 18, 212, va("Frags %i", fraglimit) , UI_LEFT|UI_SMALLFONT, color_orange ); + + // draw bot opponents + y += 24; + pad = (7 - levelMenuInfo.numBots) * (64 + 26) / 2; + for( n = 0; n < levelMenuInfo.numBots; n++ ) { + x = 18 + pad + (64 + 26) * n; + if( levelMenuInfo.botPics[n] ) { + UI_DrawHandlePic( x, y, 64, 64, levelMenuInfo.botPics[n]); + } + else { + UI_FillRect( x, y, 64, 64, color_black ); + UI_DrawProportionalString( x+22, y+18, "?", UI_BIGFONT, color_orange ); + } + UI_DrawString( x, y + 64, levelMenuInfo.botNames[n], UI_SMALLFONT|UI_LEFT, color_orange ); + } +} + + +/* +================= +UI_SPLevelMenu_Cache +================= +*/ +void UI_SPLevelMenu_Cache( void ) { + int n; + + trap_R_RegisterShaderNoMip( ART_LEVELFRAME_FOCUS ); + trap_R_RegisterShaderNoMip( ART_LEVELFRAME_SELECTED ); + trap_R_RegisterShaderNoMip( ART_ARROW ); + trap_R_RegisterShaderNoMip( ART_ARROW_FOCUS ); + trap_R_RegisterShaderNoMip( ART_MAP_UNKNOWN ); + trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 ); + trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 ); + trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 ); + trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 ); + trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); + trap_R_RegisterShaderNoMip( ART_FIGHT0 ); + trap_R_RegisterShaderNoMip( ART_FIGHT1 ); + trap_R_RegisterShaderNoMip( ART_RESET0 ); + trap_R_RegisterShaderNoMip( ART_RESET1 ); + trap_R_RegisterShaderNoMip( ART_CUSTOM0 ); + trap_R_RegisterShaderNoMip( ART_CUSTOM1 ); + + for( n = 0; n < 6; n++ ) { + trap_R_RegisterShaderNoMip( ui_medalPicNames[n] ); + levelMenuInfo.awardSounds[n] = trap_S_RegisterSound( ui_medalSounds[n], qfalse ); + } + + levelMenuInfo.levelSelectedPic = trap_R_RegisterShaderNoMip( ART_LEVELFRAME_SELECTED ); + levelMenuInfo.levelFocusPic = trap_R_RegisterShaderNoMip( ART_LEVELFRAME_FOCUS ); + levelMenuInfo.levelCompletePic[0] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 ); + levelMenuInfo.levelCompletePic[1] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 ); + levelMenuInfo.levelCompletePic[2] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 ); + levelMenuInfo.levelCompletePic[3] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 ); + levelMenuInfo.levelCompletePic[4] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 ); +} + + +/* +================= +UI_SPLevelMenu_Init +================= +*/ +static void UI_SPLevelMenu_Init( void ) { + int skill; + int n; + int x, y; + int count; + char buf[MAX_QPATH]; + + skill = (int)trap_Cvar_VariableValue( "g_spSkill" ); + if( skill < 1 || skill > 5 ) { + trap_Cvar_Set( "g_spSkill", "2" ); + skill = 2; + } + + memset( &levelMenuInfo, 0, sizeof(levelMenuInfo) ); + levelMenuInfo.menu.fullscreen = qtrue; + levelMenuInfo.menu.wrapAround = qtrue; + levelMenuInfo.menu.draw = UI_SPLevelMenu_MenuDraw; + + UI_SPLevelMenu_Cache(); + + levelMenuInfo.item_banner.generic.type = MTYPE_BTEXT; + levelMenuInfo.item_banner.generic.x = 320; + levelMenuInfo.item_banner.generic.y = 16; + levelMenuInfo.item_banner.string = "CHOOSE LEVEL"; + levelMenuInfo.item_banner.color = color_red; + levelMenuInfo.item_banner.style = UI_CENTER; + + levelMenuInfo.item_leftarrow.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_leftarrow.generic.name = ART_ARROW; + levelMenuInfo.item_leftarrow.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + levelMenuInfo.item_leftarrow.generic.x = 18; + levelMenuInfo.item_leftarrow.generic.y = 64; + levelMenuInfo.item_leftarrow.generic.callback = UI_SPLevelMenu_LeftArrowEvent; + levelMenuInfo.item_leftarrow.generic.id = ID_LEFTARROW; + levelMenuInfo.item_leftarrow.width = 16; + levelMenuInfo.item_leftarrow.height = 114; + levelMenuInfo.item_leftarrow.focuspic = ART_ARROW_FOCUS; + + levelMenuInfo.item_maps[0].generic.type = MTYPE_BITMAP; + levelMenuInfo.item_maps[0].generic.name = levelMenuInfo.levelPicNames[0]; + levelMenuInfo.item_maps[0].generic.flags = QMF_LEFT_JUSTIFY; + levelMenuInfo.item_maps[0].generic.x = 46; + levelMenuInfo.item_maps[0].generic.y = 64; + levelMenuInfo.item_maps[0].generic.id = ID_PICTURE0; + levelMenuInfo.item_maps[0].generic.callback = UI_SPLevelMenu_LevelEvent; + levelMenuInfo.item_maps[0].width = 128; + levelMenuInfo.item_maps[0].height = 96; + + levelMenuInfo.item_maps[1].generic.type = MTYPE_BITMAP; + levelMenuInfo.item_maps[1].generic.name = levelMenuInfo.levelPicNames[1]; + levelMenuInfo.item_maps[1].generic.flags = QMF_LEFT_JUSTIFY; + levelMenuInfo.item_maps[1].generic.x = 186; + levelMenuInfo.item_maps[1].generic.y = 64; + levelMenuInfo.item_maps[1].generic.id = ID_PICTURE1; + levelMenuInfo.item_maps[1].generic.callback = UI_SPLevelMenu_LevelEvent; + levelMenuInfo.item_maps[1].width = 128; + levelMenuInfo.item_maps[1].height = 96; + + levelMenuInfo.item_maps[2].generic.type = MTYPE_BITMAP; + levelMenuInfo.item_maps[2].generic.name = levelMenuInfo.levelPicNames[2]; + levelMenuInfo.item_maps[2].generic.flags = QMF_LEFT_JUSTIFY; + levelMenuInfo.item_maps[2].generic.x = 326; + levelMenuInfo.item_maps[2].generic.y = 64; + levelMenuInfo.item_maps[2].generic.id = ID_PICTURE2; + levelMenuInfo.item_maps[2].generic.callback = UI_SPLevelMenu_LevelEvent; + levelMenuInfo.item_maps[2].width = 128; + levelMenuInfo.item_maps[2].height = 96; + + levelMenuInfo.item_maps[3].generic.type = MTYPE_BITMAP; + levelMenuInfo.item_maps[3].generic.name = levelMenuInfo.levelPicNames[3]; + levelMenuInfo.item_maps[3].generic.flags = QMF_LEFT_JUSTIFY; + levelMenuInfo.item_maps[3].generic.x = 466; + levelMenuInfo.item_maps[3].generic.y = 64; + levelMenuInfo.item_maps[3].generic.id = ID_PICTURE3; + levelMenuInfo.item_maps[3].generic.callback = UI_SPLevelMenu_LevelEvent; + levelMenuInfo.item_maps[3].width = 128; + levelMenuInfo.item_maps[3].height = 96; + + levelMenuInfo.item_rightarrow.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_rightarrow.generic.name = ART_ARROW; + levelMenuInfo.item_rightarrow.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + levelMenuInfo.item_rightarrow.generic.x = 606; + levelMenuInfo.item_rightarrow.generic.y = 64; + levelMenuInfo.item_rightarrow.generic.callback = UI_SPLevelMenu_RightArrowEvent; + levelMenuInfo.item_rightarrow.generic.id = ID_RIGHTARROW; + levelMenuInfo.item_rightarrow.width = -16; + levelMenuInfo.item_rightarrow.height = 114; + levelMenuInfo.item_rightarrow.focuspic = ART_ARROW_FOCUS; + + trap_Cvar_VariableStringBuffer( "model", levelMenuInfo.playerModel, sizeof(levelMenuInfo.playerModel) ); + PlayerIcon( levelMenuInfo.playerModel, levelMenuInfo.playerPicName, sizeof(levelMenuInfo.playerPicName) ); + levelMenuInfo.item_player.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_player.generic.name = levelMenuInfo.playerPicName; + levelMenuInfo.item_player.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY; + levelMenuInfo.item_player.generic.x = 288; + levelMenuInfo.item_player.generic.y = AWARDS_Y; + levelMenuInfo.item_player.generic.id = ID_PLAYERPIC; + levelMenuInfo.item_player.generic.callback = UI_SPLevelMenu_PlayerEvent; + levelMenuInfo.item_player.width = 64; + levelMenuInfo.item_player.height = 64; + + for( n = 0; n < 6; n++ ) { + levelMenuInfo.awardLevels[n] = UI_GetAwardLevel( n ); + } + levelMenuInfo.awardLevels[AWARD_FRAGS] = 100 * (levelMenuInfo.awardLevels[AWARD_FRAGS] / 100); + + y = AWARDS_Y; + count = 0; + for( n = 0; n < 6; n++ ) { + if( levelMenuInfo.awardLevels[n] ) { + if( count & 1 ) { + x = 224 - (count - 1 ) / 2 * (48 + 16); + } + else { + x = 368 + count / 2 * (48 + 16); + } + + levelMenuInfo.item_awards[count].generic.type = MTYPE_BITMAP; + levelMenuInfo.item_awards[count].generic.name = ui_medalPicNames[n]; + levelMenuInfo.item_awards[count].generic.flags = QMF_LEFT_JUSTIFY|QMF_SILENT|QMF_MOUSEONLY; + levelMenuInfo.item_awards[count].generic.x = x; + levelMenuInfo.item_awards[count].generic.y = y; + levelMenuInfo.item_awards[count].generic.id = ID_AWARD1 + n; + levelMenuInfo.item_awards[count].generic.callback = UI_SPLevelMenu_AwardEvent; + levelMenuInfo.item_awards[count].width = 48; + levelMenuInfo.item_awards[count].height = 48; + count++; + } + } + + levelMenuInfo.item_back.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_back.generic.name = ART_BACK0; + levelMenuInfo.item_back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + levelMenuInfo.item_back.generic.x = 0; + levelMenuInfo.item_back.generic.y = 480-64; + levelMenuInfo.item_back.generic.callback = UI_SPLevelMenu_BackEvent; + levelMenuInfo.item_back.generic.id = ID_BACK; + levelMenuInfo.item_back.width = 128; + levelMenuInfo.item_back.height = 64; + levelMenuInfo.item_back.focuspic = ART_BACK1; + + levelMenuInfo.item_reset.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_reset.generic.name = ART_RESET0; + levelMenuInfo.item_reset.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + levelMenuInfo.item_reset.generic.x = 170; + levelMenuInfo.item_reset.generic.y = 480-64; + levelMenuInfo.item_reset.generic.callback = UI_SPLevelMenu_ResetEvent; + levelMenuInfo.item_reset.generic.id = ID_RESET; + levelMenuInfo.item_reset.width = 128; + levelMenuInfo.item_reset.height = 64; + levelMenuInfo.item_reset.focuspic = ART_RESET1; + + levelMenuInfo.item_custom.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_custom.generic.name = ART_CUSTOM0; + levelMenuInfo.item_custom.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + levelMenuInfo.item_custom.generic.x = 342; + levelMenuInfo.item_custom.generic.y = 480-64; + levelMenuInfo.item_custom.generic.callback = UI_SPLevelMenu_CustomEvent; + levelMenuInfo.item_custom.generic.id = ID_CUSTOM; + levelMenuInfo.item_custom.width = 128; + levelMenuInfo.item_custom.height = 64; + levelMenuInfo.item_custom.focuspic = ART_CUSTOM1; + + levelMenuInfo.item_next.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_next.generic.name = ART_FIGHT0; + levelMenuInfo.item_next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + levelMenuInfo.item_next.generic.x = 640; + levelMenuInfo.item_next.generic.y = 480-64; + levelMenuInfo.item_next.generic.callback = UI_SPLevelMenu_NextEvent; + levelMenuInfo.item_next.generic.id = ID_NEXT; + levelMenuInfo.item_next.width = 128; + levelMenuInfo.item_next.height = 64; + levelMenuInfo.item_next.focuspic = ART_FIGHT1; + + levelMenuInfo.item_null.generic.type = MTYPE_BITMAP; + levelMenuInfo.item_null.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY|QMF_SILENT; + levelMenuInfo.item_null.generic.x = 0; + levelMenuInfo.item_null.generic.y = 0; + levelMenuInfo.item_null.width = 640; + levelMenuInfo.item_null.height = 480; + + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_banner ); + + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_leftarrow ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[0] ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[1] ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[2] ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[3] ); + levelMenuInfo.item_maps[0].generic.bottom += 18; + levelMenuInfo.item_maps[1].generic.bottom += 18; + levelMenuInfo.item_maps[2].generic.bottom += 18; + levelMenuInfo.item_maps[3].generic.bottom += 18; + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_rightarrow ); + + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_player ); + + for( n = 0; n < count; n++ ) { + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_awards[n] ); + } + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_back ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_reset ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_custom ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_next ); + Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_null ); + + trap_Cvar_VariableStringBuffer( "ui_spSelection", buf, sizeof(buf) ); + if( *buf ) { + n = atoi( buf ); + selectedArenaSet = n / ARENAS_PER_TIER; + selectedArena = n % ARENAS_PER_TIER; + } + else { + selectedArenaSet = currentSet; + selectedArena = currentGame; + } + + UI_SPLevelMenu_SetMenuItems(); +} + + +/* +================= +UI_SPLevelMenu +================= +*/ +void UI_SPLevelMenu( void ) { + int level; + int trainingLevel; + const char *arenaInfo; + + trainingTier = -1; + arenaInfo = UI_GetSpecialArenaInfo( "training" ); + if( arenaInfo ) { + minTier = trainingTier; + trainingLevel = atoi( Info_ValueForKey( arenaInfo, "num" ) ); + } + else { + minTier = 0; + trainingLevel = -2; + } + + finalTier = UI_GetNumSPTiers(); + arenaInfo = UI_GetSpecialArenaInfo( "final" ); + if( arenaInfo ) { + maxTier = finalTier; + } + else { + maxTier = finalTier - 1; + if( maxTier < minTier ) { + maxTier = minTier; + } + } + + level = UI_GetCurrentGame(); + if ( level == -1 ) { + level = UI_GetNumSPArenas() - 1; + if( maxTier == finalTier ) { + level++; + } + } + + if( level == trainingLevel ) { + currentSet = -1; + currentGame = 0; + } + else { + currentSet = level / ARENAS_PER_TIER; + currentGame = level % ARENAS_PER_TIER; + } + + UI_SPLevelMenu_Init(); + UI_PushMenu( &levelMenuInfo.menu ); + Menu_SetCursorToItem( &levelMenuInfo.menu, &levelMenuInfo.item_next ); +} + + +/* +================= +UI_SPLevelMenu_f +================= +*/ +void UI_SPLevelMenu_f( void ) { + trap_Key_SetCatcher( KEYCATCH_UI ); + uis.menusp = 0; + UI_SPLevelMenu(); +} + + +/* +================= +UI_SPLevelMenu_ReInit +================= +*/ +void UI_SPLevelMenu_ReInit( void ) { + levelMenuInfo.reinit = qtrue; +} diff --git a/code/q3_ui/ui_sppostgame.c b/code/q3_ui/ui_sppostgame.c index 0f65af8..6f5d29d 100755 --- a/code/q3_ui/ui_sppostgame.c +++ b/code/q3_ui/ui_sppostgame.c @@ -1,644 +1,644 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -============================================================================= - -SINGLE PLAYER POSTGAME MENU - -============================================================================= -*/ - -#include "ui_local.h" - -#define MAX_SCOREBOARD_CLIENTS 8 - -#define AWARD_PRESENTATION_TIME 2000 - -#define ART_MENU0 "menu/art/menu_0" -#define ART_MENU1 "menu/art/menu_1" -#define ART_REPLAY0 "menu/art/replay_0" -#define ART_REPLAY1 "menu/art/replay_1" -#define ART_NEXT0 "menu/art/next_0" -#define ART_NEXT1 "menu/art/next_1" - -#define ID_AGAIN 10 -#define ID_NEXT 11 -#define ID_MENU 12 - -typedef struct { - menuframework_s menu; - menubitmap_s item_again; - menubitmap_s item_next; - menubitmap_s item_menu; - - int phase; - int ignoreKeysTime; - int starttime; - int scoreboardtime; - int serverId; - - int clientNums[MAX_SCOREBOARD_CLIENTS]; - int ranks[MAX_SCOREBOARD_CLIENTS]; - int scores[MAX_SCOREBOARD_CLIENTS]; - - char placeNames[3][64]; - - int level; - int numClients; - int won; - int numAwards; - int awardsEarned[6]; - int awardsLevels[6]; - qboolean playedSound[6]; - int lastTier; - sfxHandle_t winnerSound; -} postgameMenuInfo_t; - -static postgameMenuInfo_t postgameMenuInfo; -static char arenainfo[MAX_INFO_VALUE]; - -char *ui_medalNames[] = {"Accuracy", "Impressive", "Excellent", "Gauntlet", "Frags", "Perfect"}; -char *ui_medalPicNames[] = { - "menu/medals/medal_accuracy", - "menu/medals/medal_impressive", - "menu/medals/medal_excellent", - "menu/medals/medal_gauntlet", - "menu/medals/medal_frags", - "menu/medals/medal_victory" -}; -char *ui_medalSounds[] = { - "sound/feedback/accuracy.wav", - "sound/feedback/impressive_a.wav", - "sound/feedback/excellent_a.wav", - "sound/feedback/gauntlet.wav", - "sound/feedback/frags.wav", - "sound/feedback/perfect.wav" -}; - - -/* -================= -UI_SPPostgameMenu_AgainEvent -================= -*/ -static void UI_SPPostgameMenu_AgainEvent( void* ptr, int event ) -{ - if (event != QM_ACTIVATED) { - return; - } - UI_PopMenu(); - trap_Cmd_ExecuteText( EXEC_APPEND, "map_restart 0\n" ); -} - - -/* -================= -UI_SPPostgameMenu_NextEvent -================= -*/ -static void UI_SPPostgameMenu_NextEvent( void* ptr, int event ) { - int currentSet; - int levelSet; - int level; - int currentLevel; - const char *arenaInfo; - - if (event != QM_ACTIVATED) { - return; - } - UI_PopMenu(); - - // handle specially if we just won the training map - if( postgameMenuInfo.won == 0 ) { - level = 0; - } - else { - level = postgameMenuInfo.level + 1; - } - levelSet = level / ARENAS_PER_TIER; - - currentLevel = UI_GetCurrentGame(); - if( currentLevel == -1 ) { - currentLevel = postgameMenuInfo.level; - } - currentSet = currentLevel / ARENAS_PER_TIER; - - if( levelSet > currentSet || levelSet == UI_GetNumSPTiers() ) { - level = currentLevel; - } - - arenaInfo = UI_GetArenaInfoByNumber( level ); - if ( !arenaInfo ) { - return; - } - - UI_SPArena_Start( arenaInfo ); -} - - -/* -================= -UI_SPPostgameMenu_MenuEvent -================= -*/ -static void UI_SPPostgameMenu_MenuEvent( void* ptr, int event ) -{ - if (event != QM_ACTIVATED) { - return; - } - UI_PopMenu(); - trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; levelselect\n" ); -} - - -/* -================= -UI_SPPostgameMenu_MenuKey -================= -*/ -static sfxHandle_t UI_SPPostgameMenu_MenuKey( int key ) { - if ( uis.realtime < postgameMenuInfo.ignoreKeysTime ) { - return 0; - } - - if( postgameMenuInfo.phase == 1 ) { - trap_Cmd_ExecuteText( EXEC_APPEND, "abort_podium\n" ); - postgameMenuInfo.phase = 2; - postgameMenuInfo.starttime = uis.realtime; - postgameMenuInfo.ignoreKeysTime = uis.realtime + 250; - return 0; - } - - if( postgameMenuInfo.phase == 2 ) { - postgameMenuInfo.phase = 3; - postgameMenuInfo.starttime = uis.realtime; - postgameMenuInfo.ignoreKeysTime = uis.realtime + 250; - return 0; - } - - if( key == K_ESCAPE || key == K_MOUSE2 ) { - return 0; - } - - return Menu_DefaultKey( &postgameMenuInfo.menu, key ); -} - - -static int medalLocations[6] = {144, 448, 88, 504, 32, 560}; - -static void UI_SPPostgameMenu_DrawAwardsMedals( int max ) { - int n; - int medal; - int amount; - int x, y; - char buf[16]; - - for( n = 0; n < max; n++ ) { - x = medalLocations[n]; - y = 64; - medal = postgameMenuInfo.awardsEarned[n]; - amount = postgameMenuInfo.awardsLevels[n]; - - UI_DrawNamedPic( x, y, 48, 48, ui_medalPicNames[medal] ); - - if( medal == AWARD_ACCURACY ) { - Com_sprintf( buf, sizeof(buf), "%i%%", amount ); - } - else { - if( amount == 1 ) { - continue; - } - Com_sprintf( buf, sizeof(buf), "%i", amount ); - } - - UI_DrawString( x + 24, y + 52, buf, UI_CENTER, color_yellow ); - } -} - - -static void UI_SPPostgameMenu_DrawAwardsPresentation( int timer ) { - int awardNum; - int atimer; - vec4_t color; - - awardNum = timer / AWARD_PRESENTATION_TIME; - atimer = timer % AWARD_PRESENTATION_TIME; - - color[0] = color[1] = color[2] = 1.0f; - color[3] = (float)( AWARD_PRESENTATION_TIME - atimer ) / (float)AWARD_PRESENTATION_TIME; - UI_DrawProportionalString( 320, 64, ui_medalNames[postgameMenuInfo.awardsEarned[awardNum]], UI_CENTER, color ); - - UI_SPPostgameMenu_DrawAwardsMedals( awardNum + 1 ); - - if( !postgameMenuInfo.playedSound[awardNum] ) { - postgameMenuInfo.playedSound[awardNum] = qtrue; - trap_S_StartLocalSound( trap_S_RegisterSound( ui_medalSounds[postgameMenuInfo.awardsEarned[awardNum]], qfalse ), CHAN_ANNOUNCER ); - } -} - - -/* -================= -UI_SPPostgameMenu_MenuDrawScoreLine -================= -*/ -static void UI_SPPostgameMenu_MenuDrawScoreLine( int n, int y ) { - int rank; - char name[64]; - char info[MAX_INFO_STRING]; - - if( n > (postgameMenuInfo.numClients + 1) ) { - n -= (postgameMenuInfo.numClients + 2); - } - - if( n >= postgameMenuInfo.numClients ) { - return; - } - - rank = postgameMenuInfo.ranks[n]; - if( rank & RANK_TIED_FLAG ) { - UI_DrawString( 640 - 31 * SMALLCHAR_WIDTH, y, "(tie)", UI_LEFT|UI_SMALLFONT, color_white ); - rank &= ~RANK_TIED_FLAG; - } - trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[n], info, MAX_INFO_STRING ); - Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) ); - Q_CleanStr( name ); - - UI_DrawString( 640 - 25 * SMALLCHAR_WIDTH, y, va( "#%i: %-16s %2i", rank + 1, name, postgameMenuInfo.scores[n] ), UI_LEFT|UI_SMALLFONT, color_white ); -} - - -/* -================= -UI_SPPostgameMenu_MenuDraw -================= -*/ -static void UI_SPPostgameMenu_MenuDraw( void ) { - int timer; - int serverId; - int n; - char info[MAX_INFO_STRING]; - - trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) ); - serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) ); - if( serverId != postgameMenuInfo.serverId ) { - UI_PopMenu(); - return; - } - - // phase 1 - if ( postgameMenuInfo.numClients > 2 ) { - UI_DrawProportionalString( 510, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[2], UI_CENTER, color_white ); - } - UI_DrawProportionalString( 130, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[1], UI_CENTER, color_white ); - UI_DrawProportionalString( 320, 480 - 64 - 2 * PROP_HEIGHT, postgameMenuInfo.placeNames[0], UI_CENTER, color_white ); - - if( postgameMenuInfo.phase == 1 ) { - timer = uis.realtime - postgameMenuInfo.starttime; - - if( timer >= 1000 && postgameMenuInfo.winnerSound ) { - trap_S_StartLocalSound( postgameMenuInfo.winnerSound, CHAN_ANNOUNCER ); - postgameMenuInfo.winnerSound = 0; - } - - if( timer < 5000 ) { - return; - } - postgameMenuInfo.phase = 2; - postgameMenuInfo.starttime = uis.realtime; - } - - // phase 2 - if( postgameMenuInfo.phase == 2 ) { - timer = uis.realtime - postgameMenuInfo.starttime; - if( timer >= ( postgameMenuInfo.numAwards * AWARD_PRESENTATION_TIME ) ) { - - if( timer < 5000 ) { - return; - } - - postgameMenuInfo.phase = 3; - postgameMenuInfo.starttime = uis.realtime; - } - else { - UI_SPPostgameMenu_DrawAwardsPresentation( timer ); - } - } - - // phase 3 - if( postgameMenuInfo.phase == 3 ) { - if( uis.demoversion ) { - if( postgameMenuInfo.won == 1 && UI_ShowTierVideo( 8 )) { - trap_Cvar_Set( "nextmap", "" ); - trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic demoEnd.RoQ\n" ); - return; - } - } - else if( postgameMenuInfo.won > -1 && UI_ShowTierVideo( postgameMenuInfo.won + 1 )) { - if( postgameMenuInfo.won == postgameMenuInfo.lastTier ) { - trap_Cvar_Set( "nextmap", "" ); - trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic end.RoQ\n" ); - return; - } - - trap_Cvar_SetValue( "ui_spSelection", postgameMenuInfo.won * ARENAS_PER_TIER ); - trap_Cvar_Set( "nextmap", "levelselect" ); - trap_Cmd_ExecuteText( EXEC_APPEND, va( "disconnect; cinematic tier%i.RoQ\n", postgameMenuInfo.won + 1 ) ); - return; - } - - postgameMenuInfo.item_again.generic.flags &= ~QMF_INACTIVE; - postgameMenuInfo.item_next.generic.flags &= ~QMF_INACTIVE; - postgameMenuInfo.item_menu.generic.flags &= ~QMF_INACTIVE; - - UI_SPPostgameMenu_DrawAwardsMedals( postgameMenuInfo.numAwards ); - - Menu_Draw( &postgameMenuInfo.menu ); - } - - // draw the scoreboard - if( !trap_Cvar_VariableValue( "ui_spScoreboard" ) ) { - return; - } - - timer = uis.realtime - postgameMenuInfo.scoreboardtime; - if( postgameMenuInfo.numClients <= 3 ) { - n = 0; - } - else { - n = timer / 1500 % (postgameMenuInfo.numClients + 2); - } - UI_SPPostgameMenu_MenuDrawScoreLine( n, 0 ); - UI_SPPostgameMenu_MenuDrawScoreLine( n + 1, 0 + SMALLCHAR_HEIGHT ); - UI_SPPostgameMenu_MenuDrawScoreLine( n + 2, 0 + 2 * SMALLCHAR_HEIGHT ); -} - - -/* -================= -UI_SPPostgameMenu_Cache -================= -*/ -void UI_SPPostgameMenu_Cache( void ) { - int n; - qboolean buildscript; - - buildscript = trap_Cvar_VariableValue("com_buildscript"); - - trap_R_RegisterShaderNoMip( ART_MENU0 ); - trap_R_RegisterShaderNoMip( ART_MENU1 ); - trap_R_RegisterShaderNoMip( ART_REPLAY0 ); - trap_R_RegisterShaderNoMip( ART_REPLAY1 ); - trap_R_RegisterShaderNoMip( ART_NEXT0 ); - trap_R_RegisterShaderNoMip( ART_NEXT1 ); - for( n = 0; n < 6; n++ ) { - trap_R_RegisterShaderNoMip( ui_medalPicNames[n] ); - trap_S_RegisterSound( ui_medalSounds[n], qfalse ); - } - - if( buildscript ) { - trap_S_RegisterSound( "music/loss.wav", qfalse ); - trap_S_RegisterSound( "music/win.wav", qfalse ); - trap_S_RegisterSound( "sound/player/announce/youwin.wav", qfalse ); - } -} - - -/* -================= -UI_SPPostgameMenu_Init -================= -*/ -static void UI_SPPostgameMenu_Init( void ) { - postgameMenuInfo.menu.wrapAround = qtrue; - postgameMenuInfo.menu.key = UI_SPPostgameMenu_MenuKey; - postgameMenuInfo.menu.draw = UI_SPPostgameMenu_MenuDraw; - postgameMenuInfo.ignoreKeysTime = uis.realtime + 1500; - - UI_SPPostgameMenu_Cache(); - - postgameMenuInfo.item_menu.generic.type = MTYPE_BITMAP; - postgameMenuInfo.item_menu.generic.name = ART_MENU0; - postgameMenuInfo.item_menu.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE; - postgameMenuInfo.item_menu.generic.x = 0; - postgameMenuInfo.item_menu.generic.y = 480-64; - postgameMenuInfo.item_menu.generic.callback = UI_SPPostgameMenu_MenuEvent; - postgameMenuInfo.item_menu.generic.id = ID_MENU; - postgameMenuInfo.item_menu.width = 128; - postgameMenuInfo.item_menu.height = 64; - postgameMenuInfo.item_menu.focuspic = ART_MENU1; - - postgameMenuInfo.item_again.generic.type = MTYPE_BITMAP; - postgameMenuInfo.item_again.generic.name = ART_REPLAY0; - postgameMenuInfo.item_again.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE; - postgameMenuInfo.item_again.generic.x = 320; - postgameMenuInfo.item_again.generic.y = 480-64; - postgameMenuInfo.item_again.generic.callback = UI_SPPostgameMenu_AgainEvent; - postgameMenuInfo.item_again.generic.id = ID_AGAIN; - postgameMenuInfo.item_again.width = 128; - postgameMenuInfo.item_again.height = 64; - postgameMenuInfo.item_again.focuspic = ART_REPLAY1; - - postgameMenuInfo.item_next.generic.type = MTYPE_BITMAP; - postgameMenuInfo.item_next.generic.name = ART_NEXT0; - postgameMenuInfo.item_next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE; - postgameMenuInfo.item_next.generic.x = 640; - postgameMenuInfo.item_next.generic.y = 480-64; - postgameMenuInfo.item_next.generic.callback = UI_SPPostgameMenu_NextEvent; - postgameMenuInfo.item_next.generic.id = ID_NEXT; - postgameMenuInfo.item_next.width = 128; - postgameMenuInfo.item_next.height = 64; - postgameMenuInfo.item_next.focuspic = ART_NEXT1; - - Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_menu ); - Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_again ); - Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_next ); -} - - -static void Prepname( int index ) { - int len; - char name[64]; - char info[MAX_INFO_STRING]; - - trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[index], info, MAX_INFO_STRING ); - Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) ); - Q_CleanStr( name ); - len = strlen( name ); - - while( len && UI_ProportionalStringWidth( name ) > 256 ) { - len--; - name[len] = 0; - } - - Q_strncpyz( postgameMenuInfo.placeNames[index], name, sizeof(postgameMenuInfo.placeNames[index]) ); -} - - -/* -================= -UI_SPPostgameMenu_f -================= -*/ -void UI_SPPostgameMenu_f( void ) { - int playerGameRank; - int playerClientNum; - int n; - int oldFrags, newFrags; - const char *arena; - int awardValues[6]; - char map[MAX_QPATH]; - char info[MAX_INFO_STRING]; - - memset( &postgameMenuInfo, 0, sizeof(postgameMenuInfo) ); - - trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) ); - postgameMenuInfo.serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) ); - - trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); - Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) ); - arena = UI_GetArenaInfoByMap( map ); - if ( !arena ) { - return; - } - Q_strncpyz( arenainfo, arena, sizeof(arenainfo) ); - - postgameMenuInfo.level = atoi( Info_ValueForKey( arenainfo, "num" ) ); - - postgameMenuInfo.numClients = atoi( UI_Argv( 1 ) ); - playerClientNum = atoi( UI_Argv( 2 ) ); - playerGameRank = 8; // in case they ended game as a spectator - - if( postgameMenuInfo.numClients > MAX_SCOREBOARD_CLIENTS ) { - postgameMenuInfo.numClients = MAX_SCOREBOARD_CLIENTS; - } - - for( n = 0; n < postgameMenuInfo.numClients; n++ ) { - postgameMenuInfo.clientNums[n] = atoi( UI_Argv( 8 + n * 3 + 1 ) ); - postgameMenuInfo.ranks[n] = atoi( UI_Argv( 8 + n * 3 + 2 ) ); - postgameMenuInfo.scores[n] = atoi( UI_Argv( 8 + n * 3 + 3 ) ); - - if( postgameMenuInfo.clientNums[n] == playerClientNum ) { - playerGameRank = (postgameMenuInfo.ranks[n] & ~RANK_TIED_FLAG) + 1; - } - } - - UI_SetBestScore( postgameMenuInfo.level, playerGameRank ); - - // process award stats and prepare presentation data - awardValues[AWARD_ACCURACY] = atoi( UI_Argv( 3 ) ); - awardValues[AWARD_IMPRESSIVE] = atoi( UI_Argv( 4 ) ); - awardValues[AWARD_EXCELLENT] = atoi( UI_Argv( 5 ) ); - awardValues[AWARD_GAUNTLET] = atoi( UI_Argv( 6 ) ); - awardValues[AWARD_FRAGS] = atoi( UI_Argv( 7 ) ); - awardValues[AWARD_PERFECT] = atoi( UI_Argv( 8 ) ); - - postgameMenuInfo.numAwards = 0; - - if( awardValues[AWARD_ACCURACY] >= 50 ) { - UI_LogAwardData( AWARD_ACCURACY, 1 ); - postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_ACCURACY; - postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_ACCURACY]; - postgameMenuInfo.numAwards++; - } - - if( awardValues[AWARD_IMPRESSIVE] ) { - UI_LogAwardData( AWARD_IMPRESSIVE, awardValues[AWARD_IMPRESSIVE] ); - postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_IMPRESSIVE; - postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_IMPRESSIVE]; - postgameMenuInfo.numAwards++; - } - - if( awardValues[AWARD_EXCELLENT] ) { - UI_LogAwardData( AWARD_EXCELLENT, awardValues[AWARD_EXCELLENT] ); - postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_EXCELLENT; - postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_EXCELLENT]; - postgameMenuInfo.numAwards++; - } - - if( awardValues[AWARD_GAUNTLET] ) { - UI_LogAwardData( AWARD_GAUNTLET, awardValues[AWARD_GAUNTLET] ); - postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_GAUNTLET; - postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_GAUNTLET]; - postgameMenuInfo.numAwards++; - } - - oldFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100; - UI_LogAwardData( AWARD_FRAGS, awardValues[AWARD_FRAGS] ); - newFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100; - if( newFrags > oldFrags ) { - postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_FRAGS; - postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = newFrags * 100; - postgameMenuInfo.numAwards++; - } - - if( awardValues[AWARD_PERFECT] ) { - UI_LogAwardData( AWARD_PERFECT, 1 ); - postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_PERFECT; - postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = 1; - postgameMenuInfo.numAwards++; - } - - if ( playerGameRank == 1 ) { - postgameMenuInfo.won = UI_TierCompleted( postgameMenuInfo.level ); - } - else { - postgameMenuInfo.won = -1; - } - - postgameMenuInfo.starttime = uis.realtime; - postgameMenuInfo.scoreboardtime = uis.realtime; - - trap_Key_SetCatcher( KEYCATCH_UI ); - uis.menusp = 0; - - UI_SPPostgameMenu_Init(); - UI_PushMenu( &postgameMenuInfo.menu ); - - if ( playerGameRank == 1 ) { - Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_next ); - } - else { - Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_again ); - } - - Prepname( 0 ); - Prepname( 1 ); - Prepname( 2 ); - - if ( playerGameRank != 1 ) { - postgameMenuInfo.winnerSound = trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", postgameMenuInfo.placeNames[0] ), qfalse ); - trap_Cmd_ExecuteText( EXEC_APPEND, "music music/loss\n" ); - } - else { - postgameMenuInfo.winnerSound = trap_S_RegisterSound( "sound/player/announce/youwin.wav", qfalse ); - trap_Cmd_ExecuteText( EXEC_APPEND, "music music/win\n" ); - } - - postgameMenuInfo.phase = 1; - - postgameMenuInfo.lastTier = UI_GetNumSPTiers(); - if ( UI_GetSpecialArenaInfo( "final" ) ) { - postgameMenuInfo.lastTier++; - } -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +============================================================================= + +SINGLE PLAYER POSTGAME MENU + +============================================================================= +*/ + +#include "ui_local.h" + +#define MAX_SCOREBOARD_CLIENTS 8 + +#define AWARD_PRESENTATION_TIME 2000 + +#define ART_MENU0 "menu/art/menu_0" +#define ART_MENU1 "menu/art/menu_1" +#define ART_REPLAY0 "menu/art/replay_0" +#define ART_REPLAY1 "menu/art/replay_1" +#define ART_NEXT0 "menu/art/next_0" +#define ART_NEXT1 "menu/art/next_1" + +#define ID_AGAIN 10 +#define ID_NEXT 11 +#define ID_MENU 12 + +typedef struct { + menuframework_s menu; + menubitmap_s item_again; + menubitmap_s item_next; + menubitmap_s item_menu; + + int phase; + int ignoreKeysTime; + int starttime; + int scoreboardtime; + int serverId; + + int clientNums[MAX_SCOREBOARD_CLIENTS]; + int ranks[MAX_SCOREBOARD_CLIENTS]; + int scores[MAX_SCOREBOARD_CLIENTS]; + + char placeNames[3][64]; + + int level; + int numClients; + int won; + int numAwards; + int awardsEarned[6]; + int awardsLevels[6]; + qboolean playedSound[6]; + int lastTier; + sfxHandle_t winnerSound; +} postgameMenuInfo_t; + +static postgameMenuInfo_t postgameMenuInfo; +static char arenainfo[MAX_INFO_VALUE]; + +char *ui_medalNames[] = {"Accuracy", "Impressive", "Excellent", "Gauntlet", "Frags", "Perfect"}; +char *ui_medalPicNames[] = { + "menu/medals/medal_accuracy", + "menu/medals/medal_impressive", + "menu/medals/medal_excellent", + "menu/medals/medal_gauntlet", + "menu/medals/medal_frags", + "menu/medals/medal_victory" +}; +char *ui_medalSounds[] = { + "sound/feedback/accuracy.wav", + "sound/feedback/impressive_a.wav", + "sound/feedback/excellent_a.wav", + "sound/feedback/gauntlet.wav", + "sound/feedback/frags.wav", + "sound/feedback/perfect.wav" +}; + + +/* +================= +UI_SPPostgameMenu_AgainEvent +================= +*/ +static void UI_SPPostgameMenu_AgainEvent( void* ptr, int event ) +{ + if (event != QM_ACTIVATED) { + return; + } + UI_PopMenu(); + trap_Cmd_ExecuteText( EXEC_APPEND, "map_restart 0\n" ); +} + + +/* +================= +UI_SPPostgameMenu_NextEvent +================= +*/ +static void UI_SPPostgameMenu_NextEvent( void* ptr, int event ) { + int currentSet; + int levelSet; + int level; + int currentLevel; + const char *arenaInfo; + + if (event != QM_ACTIVATED) { + return; + } + UI_PopMenu(); + + // handle specially if we just won the training map + if( postgameMenuInfo.won == 0 ) { + level = 0; + } + else { + level = postgameMenuInfo.level + 1; + } + levelSet = level / ARENAS_PER_TIER; + + currentLevel = UI_GetCurrentGame(); + if( currentLevel == -1 ) { + currentLevel = postgameMenuInfo.level; + } + currentSet = currentLevel / ARENAS_PER_TIER; + + if( levelSet > currentSet || levelSet == UI_GetNumSPTiers() ) { + level = currentLevel; + } + + arenaInfo = UI_GetArenaInfoByNumber( level ); + if ( !arenaInfo ) { + return; + } + + UI_SPArena_Start( arenaInfo ); +} + + +/* +================= +UI_SPPostgameMenu_MenuEvent +================= +*/ +static void UI_SPPostgameMenu_MenuEvent( void* ptr, int event ) +{ + if (event != QM_ACTIVATED) { + return; + } + UI_PopMenu(); + trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; levelselect\n" ); +} + + +/* +================= +UI_SPPostgameMenu_MenuKey +================= +*/ +static sfxHandle_t UI_SPPostgameMenu_MenuKey( int key ) { + if ( uis.realtime < postgameMenuInfo.ignoreKeysTime ) { + return 0; + } + + if( postgameMenuInfo.phase == 1 ) { + trap_Cmd_ExecuteText( EXEC_APPEND, "abort_podium\n" ); + postgameMenuInfo.phase = 2; + postgameMenuInfo.starttime = uis.realtime; + postgameMenuInfo.ignoreKeysTime = uis.realtime + 250; + return 0; + } + + if( postgameMenuInfo.phase == 2 ) { + postgameMenuInfo.phase = 3; + postgameMenuInfo.starttime = uis.realtime; + postgameMenuInfo.ignoreKeysTime = uis.realtime + 250; + return 0; + } + + if( key == K_ESCAPE || key == K_MOUSE2 ) { + return 0; + } + + return Menu_DefaultKey( &postgameMenuInfo.menu, key ); +} + + +static int medalLocations[6] = {144, 448, 88, 504, 32, 560}; + +static void UI_SPPostgameMenu_DrawAwardsMedals( int max ) { + int n; + int medal; + int amount; + int x, y; + char buf[16]; + + for( n = 0; n < max; n++ ) { + x = medalLocations[n]; + y = 64; + medal = postgameMenuInfo.awardsEarned[n]; + amount = postgameMenuInfo.awardsLevels[n]; + + UI_DrawNamedPic( x, y, 48, 48, ui_medalPicNames[medal] ); + + if( medal == AWARD_ACCURACY ) { + Com_sprintf( buf, sizeof(buf), "%i%%", amount ); + } + else { + if( amount == 1 ) { + continue; + } + Com_sprintf( buf, sizeof(buf), "%i", amount ); + } + + UI_DrawString( x + 24, y + 52, buf, UI_CENTER, color_yellow ); + } +} + + +static void UI_SPPostgameMenu_DrawAwardsPresentation( int timer ) { + int awardNum; + int atimer; + vec4_t color; + + awardNum = timer / AWARD_PRESENTATION_TIME; + atimer = timer % AWARD_PRESENTATION_TIME; + + color[0] = color[1] = color[2] = 1.0f; + color[3] = (float)( AWARD_PRESENTATION_TIME - atimer ) / (float)AWARD_PRESENTATION_TIME; + UI_DrawProportionalString( 320, 64, ui_medalNames[postgameMenuInfo.awardsEarned[awardNum]], UI_CENTER, color ); + + UI_SPPostgameMenu_DrawAwardsMedals( awardNum + 1 ); + + if( !postgameMenuInfo.playedSound[awardNum] ) { + postgameMenuInfo.playedSound[awardNum] = qtrue; + trap_S_StartLocalSound( trap_S_RegisterSound( ui_medalSounds[postgameMenuInfo.awardsEarned[awardNum]], qfalse ), CHAN_ANNOUNCER ); + } +} + + +/* +================= +UI_SPPostgameMenu_MenuDrawScoreLine +================= +*/ +static void UI_SPPostgameMenu_MenuDrawScoreLine( int n, int y ) { + int rank; + char name[64]; + char info[MAX_INFO_STRING]; + + if( n > (postgameMenuInfo.numClients + 1) ) { + n -= (postgameMenuInfo.numClients + 2); + } + + if( n >= postgameMenuInfo.numClients ) { + return; + } + + rank = postgameMenuInfo.ranks[n]; + if( rank & RANK_TIED_FLAG ) { + UI_DrawString( 640 - 31 * SMALLCHAR_WIDTH, y, "(tie)", UI_LEFT|UI_SMALLFONT, color_white ); + rank &= ~RANK_TIED_FLAG; + } + trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[n], info, MAX_INFO_STRING ); + Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) ); + Q_CleanStr( name ); + + UI_DrawString( 640 - 25 * SMALLCHAR_WIDTH, y, va( "#%i: %-16s %2i", rank + 1, name, postgameMenuInfo.scores[n] ), UI_LEFT|UI_SMALLFONT, color_white ); +} + + +/* +================= +UI_SPPostgameMenu_MenuDraw +================= +*/ +static void UI_SPPostgameMenu_MenuDraw( void ) { + int timer; + int serverId; + int n; + char info[MAX_INFO_STRING]; + + trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) ); + serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) ); + if( serverId != postgameMenuInfo.serverId ) { + UI_PopMenu(); + return; + } + + // phase 1 + if ( postgameMenuInfo.numClients > 2 ) { + UI_DrawProportionalString( 510, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[2], UI_CENTER, color_white ); + } + UI_DrawProportionalString( 130, 480 - 64 - PROP_HEIGHT, postgameMenuInfo.placeNames[1], UI_CENTER, color_white ); + UI_DrawProportionalString( 320, 480 - 64 - 2 * PROP_HEIGHT, postgameMenuInfo.placeNames[0], UI_CENTER, color_white ); + + if( postgameMenuInfo.phase == 1 ) { + timer = uis.realtime - postgameMenuInfo.starttime; + + if( timer >= 1000 && postgameMenuInfo.winnerSound ) { + trap_S_StartLocalSound( postgameMenuInfo.winnerSound, CHAN_ANNOUNCER ); + postgameMenuInfo.winnerSound = 0; + } + + if( timer < 5000 ) { + return; + } + postgameMenuInfo.phase = 2; + postgameMenuInfo.starttime = uis.realtime; + } + + // phase 2 + if( postgameMenuInfo.phase == 2 ) { + timer = uis.realtime - postgameMenuInfo.starttime; + if( timer >= ( postgameMenuInfo.numAwards * AWARD_PRESENTATION_TIME ) ) { + + if( timer < 5000 ) { + return; + } + + postgameMenuInfo.phase = 3; + postgameMenuInfo.starttime = uis.realtime; + } + else { + UI_SPPostgameMenu_DrawAwardsPresentation( timer ); + } + } + + // phase 3 + if( postgameMenuInfo.phase == 3 ) { + if( uis.demoversion ) { + if( postgameMenuInfo.won == 1 && UI_ShowTierVideo( 8 )) { + trap_Cvar_Set( "nextmap", "" ); + trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic demoEnd.RoQ\n" ); + return; + } + } + else if( postgameMenuInfo.won > -1 && UI_ShowTierVideo( postgameMenuInfo.won + 1 )) { + if( postgameMenuInfo.won == postgameMenuInfo.lastTier ) { + trap_Cvar_Set( "nextmap", "" ); + trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect; cinematic end.RoQ\n" ); + return; + } + + trap_Cvar_SetValue( "ui_spSelection", postgameMenuInfo.won * ARENAS_PER_TIER ); + trap_Cvar_Set( "nextmap", "levelselect" ); + trap_Cmd_ExecuteText( EXEC_APPEND, va( "disconnect; cinematic tier%i.RoQ\n", postgameMenuInfo.won + 1 ) ); + return; + } + + postgameMenuInfo.item_again.generic.flags &= ~QMF_INACTIVE; + postgameMenuInfo.item_next.generic.flags &= ~QMF_INACTIVE; + postgameMenuInfo.item_menu.generic.flags &= ~QMF_INACTIVE; + + UI_SPPostgameMenu_DrawAwardsMedals( postgameMenuInfo.numAwards ); + + Menu_Draw( &postgameMenuInfo.menu ); + } + + // draw the scoreboard + if( !trap_Cvar_VariableValue( "ui_spScoreboard" ) ) { + return; + } + + timer = uis.realtime - postgameMenuInfo.scoreboardtime; + if( postgameMenuInfo.numClients <= 3 ) { + n = 0; + } + else { + n = timer / 1500 % (postgameMenuInfo.numClients + 2); + } + UI_SPPostgameMenu_MenuDrawScoreLine( n, 0 ); + UI_SPPostgameMenu_MenuDrawScoreLine( n + 1, 0 + SMALLCHAR_HEIGHT ); + UI_SPPostgameMenu_MenuDrawScoreLine( n + 2, 0 + 2 * SMALLCHAR_HEIGHT ); +} + + +/* +================= +UI_SPPostgameMenu_Cache +================= +*/ +void UI_SPPostgameMenu_Cache( void ) { + int n; + qboolean buildscript; + + buildscript = trap_Cvar_VariableValue("com_buildscript"); + + trap_R_RegisterShaderNoMip( ART_MENU0 ); + trap_R_RegisterShaderNoMip( ART_MENU1 ); + trap_R_RegisterShaderNoMip( ART_REPLAY0 ); + trap_R_RegisterShaderNoMip( ART_REPLAY1 ); + trap_R_RegisterShaderNoMip( ART_NEXT0 ); + trap_R_RegisterShaderNoMip( ART_NEXT1 ); + for( n = 0; n < 6; n++ ) { + trap_R_RegisterShaderNoMip( ui_medalPicNames[n] ); + trap_S_RegisterSound( ui_medalSounds[n], qfalse ); + } + + if( buildscript ) { + trap_S_RegisterSound( "music/loss.wav", qfalse ); + trap_S_RegisterSound( "music/win.wav", qfalse ); + trap_S_RegisterSound( "sound/player/announce/youwin.wav", qfalse ); + } +} + + +/* +================= +UI_SPPostgameMenu_Init +================= +*/ +static void UI_SPPostgameMenu_Init( void ) { + postgameMenuInfo.menu.wrapAround = qtrue; + postgameMenuInfo.menu.key = UI_SPPostgameMenu_MenuKey; + postgameMenuInfo.menu.draw = UI_SPPostgameMenu_MenuDraw; + postgameMenuInfo.ignoreKeysTime = uis.realtime + 1500; + + UI_SPPostgameMenu_Cache(); + + postgameMenuInfo.item_menu.generic.type = MTYPE_BITMAP; + postgameMenuInfo.item_menu.generic.name = ART_MENU0; + postgameMenuInfo.item_menu.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE; + postgameMenuInfo.item_menu.generic.x = 0; + postgameMenuInfo.item_menu.generic.y = 480-64; + postgameMenuInfo.item_menu.generic.callback = UI_SPPostgameMenu_MenuEvent; + postgameMenuInfo.item_menu.generic.id = ID_MENU; + postgameMenuInfo.item_menu.width = 128; + postgameMenuInfo.item_menu.height = 64; + postgameMenuInfo.item_menu.focuspic = ART_MENU1; + + postgameMenuInfo.item_again.generic.type = MTYPE_BITMAP; + postgameMenuInfo.item_again.generic.name = ART_REPLAY0; + postgameMenuInfo.item_again.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE; + postgameMenuInfo.item_again.generic.x = 320; + postgameMenuInfo.item_again.generic.y = 480-64; + postgameMenuInfo.item_again.generic.callback = UI_SPPostgameMenu_AgainEvent; + postgameMenuInfo.item_again.generic.id = ID_AGAIN; + postgameMenuInfo.item_again.width = 128; + postgameMenuInfo.item_again.height = 64; + postgameMenuInfo.item_again.focuspic = ART_REPLAY1; + + postgameMenuInfo.item_next.generic.type = MTYPE_BITMAP; + postgameMenuInfo.item_next.generic.name = ART_NEXT0; + postgameMenuInfo.item_next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE; + postgameMenuInfo.item_next.generic.x = 640; + postgameMenuInfo.item_next.generic.y = 480-64; + postgameMenuInfo.item_next.generic.callback = UI_SPPostgameMenu_NextEvent; + postgameMenuInfo.item_next.generic.id = ID_NEXT; + postgameMenuInfo.item_next.width = 128; + postgameMenuInfo.item_next.height = 64; + postgameMenuInfo.item_next.focuspic = ART_NEXT1; + + Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_menu ); + Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_again ); + Menu_AddItem( &postgameMenuInfo.menu, ( void * )&postgameMenuInfo.item_next ); +} + + +static void Prepname( int index ) { + int len; + char name[64]; + char info[MAX_INFO_STRING]; + + trap_GetConfigString( CS_PLAYERS + postgameMenuInfo.clientNums[index], info, MAX_INFO_STRING ); + Q_strncpyz( name, Info_ValueForKey( info, "n" ), sizeof(name) ); + Q_CleanStr( name ); + len = strlen( name ); + + while( len && UI_ProportionalStringWidth( name ) > 256 ) { + len--; + name[len] = 0; + } + + Q_strncpyz( postgameMenuInfo.placeNames[index], name, sizeof(postgameMenuInfo.placeNames[index]) ); +} + + +/* +================= +UI_SPPostgameMenu_f +================= +*/ +void UI_SPPostgameMenu_f( void ) { + int playerGameRank; + int playerClientNum; + int n; + int oldFrags, newFrags; + const char *arena; + int awardValues[6]; + char map[MAX_QPATH]; + char info[MAX_INFO_STRING]; + + memset( &postgameMenuInfo, 0, sizeof(postgameMenuInfo) ); + + trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) ); + postgameMenuInfo.serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) ); + + trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); + Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) ); + arena = UI_GetArenaInfoByMap( map ); + if ( !arena ) { + return; + } + Q_strncpyz( arenainfo, arena, sizeof(arenainfo) ); + + postgameMenuInfo.level = atoi( Info_ValueForKey( arenainfo, "num" ) ); + + postgameMenuInfo.numClients = atoi( UI_Argv( 1 ) ); + playerClientNum = atoi( UI_Argv( 2 ) ); + playerGameRank = 8; // in case they ended game as a spectator + + if( postgameMenuInfo.numClients > MAX_SCOREBOARD_CLIENTS ) { + postgameMenuInfo.numClients = MAX_SCOREBOARD_CLIENTS; + } + + for( n = 0; n < postgameMenuInfo.numClients; n++ ) { + postgameMenuInfo.clientNums[n] = atoi( UI_Argv( 8 + n * 3 + 1 ) ); + postgameMenuInfo.ranks[n] = atoi( UI_Argv( 8 + n * 3 + 2 ) ); + postgameMenuInfo.scores[n] = atoi( UI_Argv( 8 + n * 3 + 3 ) ); + + if( postgameMenuInfo.clientNums[n] == playerClientNum ) { + playerGameRank = (postgameMenuInfo.ranks[n] & ~RANK_TIED_FLAG) + 1; + } + } + + UI_SetBestScore( postgameMenuInfo.level, playerGameRank ); + + // process award stats and prepare presentation data + awardValues[AWARD_ACCURACY] = atoi( UI_Argv( 3 ) ); + awardValues[AWARD_IMPRESSIVE] = atoi( UI_Argv( 4 ) ); + awardValues[AWARD_EXCELLENT] = atoi( UI_Argv( 5 ) ); + awardValues[AWARD_GAUNTLET] = atoi( UI_Argv( 6 ) ); + awardValues[AWARD_FRAGS] = atoi( UI_Argv( 7 ) ); + awardValues[AWARD_PERFECT] = atoi( UI_Argv( 8 ) ); + + postgameMenuInfo.numAwards = 0; + + if( awardValues[AWARD_ACCURACY] >= 50 ) { + UI_LogAwardData( AWARD_ACCURACY, 1 ); + postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_ACCURACY; + postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_ACCURACY]; + postgameMenuInfo.numAwards++; + } + + if( awardValues[AWARD_IMPRESSIVE] ) { + UI_LogAwardData( AWARD_IMPRESSIVE, awardValues[AWARD_IMPRESSIVE] ); + postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_IMPRESSIVE; + postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_IMPRESSIVE]; + postgameMenuInfo.numAwards++; + } + + if( awardValues[AWARD_EXCELLENT] ) { + UI_LogAwardData( AWARD_EXCELLENT, awardValues[AWARD_EXCELLENT] ); + postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_EXCELLENT; + postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_EXCELLENT]; + postgameMenuInfo.numAwards++; + } + + if( awardValues[AWARD_GAUNTLET] ) { + UI_LogAwardData( AWARD_GAUNTLET, awardValues[AWARD_GAUNTLET] ); + postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_GAUNTLET; + postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_GAUNTLET]; + postgameMenuInfo.numAwards++; + } + + oldFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100; + UI_LogAwardData( AWARD_FRAGS, awardValues[AWARD_FRAGS] ); + newFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100; + if( newFrags > oldFrags ) { + postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_FRAGS; + postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = newFrags * 100; + postgameMenuInfo.numAwards++; + } + + if( awardValues[AWARD_PERFECT] ) { + UI_LogAwardData( AWARD_PERFECT, 1 ); + postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_PERFECT; + postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = 1; + postgameMenuInfo.numAwards++; + } + + if ( playerGameRank == 1 ) { + postgameMenuInfo.won = UI_TierCompleted( postgameMenuInfo.level ); + } + else { + postgameMenuInfo.won = -1; + } + + postgameMenuInfo.starttime = uis.realtime; + postgameMenuInfo.scoreboardtime = uis.realtime; + + trap_Key_SetCatcher( KEYCATCH_UI ); + uis.menusp = 0; + + UI_SPPostgameMenu_Init(); + UI_PushMenu( &postgameMenuInfo.menu ); + + if ( playerGameRank == 1 ) { + Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_next ); + } + else { + Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_again ); + } + + Prepname( 0 ); + Prepname( 1 ); + Prepname( 2 ); + + if ( playerGameRank != 1 ) { + postgameMenuInfo.winnerSound = trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", postgameMenuInfo.placeNames[0] ), qfalse ); + trap_Cmd_ExecuteText( EXEC_APPEND, "music music/loss\n" ); + } + else { + postgameMenuInfo.winnerSound = trap_S_RegisterSound( "sound/player/announce/youwin.wav", qfalse ); + trap_Cmd_ExecuteText( EXEC_APPEND, "music music/win\n" ); + } + + postgameMenuInfo.phase = 1; + + postgameMenuInfo.lastTier = UI_GetNumSPTiers(); + if ( UI_GetSpecialArenaInfo( "final" ) ) { + postgameMenuInfo.lastTier++; + } +} diff --git a/code/q3_ui/ui_spreset.c b/code/q3_ui/ui_spreset.c index 0dc3634..a262cc2 100755 --- a/code/q3_ui/ui_spreset.c +++ b/code/q3_ui/ui_spreset.c @@ -1,194 +1,194 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -/* -======================================================================= - -RESET MENU - -======================================================================= -*/ - -#include "ui_local.h" - - -#define ART_FRAME "menu/art/cut_frame" - -#define ID_NO 100 -#define ID_YES 101 - -typedef struct -{ - menuframework_s menu; - menutext_s no; - menutext_s yes; - int slashX; -} resetMenu_t; - -static resetMenu_t s_reset; - - -/* -================= -Reset_MenuEvent -================= -*/ -void Reset_MenuEvent(void* ptr, int event) { - if( event != QM_ACTIVATED ) { - return; - } - - UI_PopMenu(); - - if( ((menucommon_s*)ptr)->id == ID_NO ) { - return; - } - - // reset the game, pop the level menu and restart it so it updates - UI_NewGame(); - trap_Cvar_SetValue( "ui_spSelection", 0 ); - UI_PopMenu(); - UI_SPLevelMenu(); -} - - -/* -================= -Reset_MenuKey -================= -*/ -static sfxHandle_t Reset_MenuKey( int key ) { - switch ( key ) { - case K_KP_LEFTARROW: - case K_LEFTARROW: - case K_KP_RIGHTARROW: - case K_RIGHTARROW: - key = K_TAB; - break; - - case 'n': - case 'N': - Reset_MenuEvent( &s_reset.no, QM_ACTIVATED ); - break; - - case 'y': - case 'Y': - Reset_MenuEvent( &s_reset.yes, QM_ACTIVATED ); - break; - } - - return Menu_DefaultKey( &s_reset.menu, key ); -} - - -/* -================= -Reset_MenuDraw -================= -*/ -static void Reset_MenuDraw( void ) { - UI_DrawNamedPic( 142, 118, 359, 256, ART_FRAME ); - UI_DrawProportionalString( 320, 194 + 10, "RESET GAME?", UI_CENTER|UI_INVERSE, color_red ); - UI_DrawProportionalString( s_reset.slashX, 265, "/", UI_LEFT|UI_INVERSE, color_red ); - Menu_Draw( &s_reset.menu ); - - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This resets all of the", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "single player game variables.", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 2, "Do this only if you want to", UI_CENTER|UI_SMALLFONT, color_yellow ); - UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 3, "start over from the beginning.", UI_CENTER|UI_SMALLFONT, color_yellow ); -} - - -/* -================= -Reset_Cache -================= -*/ -void Reset_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAME ); -} - - -/* -================= -UI_ResetMenu -================= -*/ -void UI_ResetMenu(void) { - uiClientState_t cstate; - int n1, n2, n3; - int l1, l2, l3; - - // zero set all our globals - memset( &s_reset, 0, sizeof(s_reset) ); - - Reset_Cache(); - - n1 = UI_ProportionalStringWidth( "YES/NO" ); - n2 = UI_ProportionalStringWidth( "YES" ) + PROP_GAP_WIDTH; - n3 = UI_ProportionalStringWidth( "/" ) + PROP_GAP_WIDTH; - l1 = 320 - ( n1 / 2 ); - l2 = l1 + n2; - l3 = l2 + n3; - s_reset.slashX = l2; - - s_reset.menu.draw = Reset_MenuDraw; - s_reset.menu.key = Reset_MenuKey; - s_reset.menu.wrapAround = qtrue; - - trap_GetClientState( &cstate ); - - if ( cstate.connState >= CA_CONNECTED ) { - // float on top of running game - s_reset.menu.fullscreen = qfalse; - } - else { - // game not running - s_reset.menu.fullscreen = qtrue; - } - - s_reset.yes.generic.type = MTYPE_PTEXT; - s_reset.yes.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_reset.yes.generic.callback = Reset_MenuEvent; - s_reset.yes.generic.id = ID_YES; - s_reset.yes.generic.x = l1; - s_reset.yes.generic.y = 264; - s_reset.yes.string = "YES"; - s_reset.yes.color = color_red; - s_reset.yes.style = UI_LEFT; - - s_reset.no.generic.type = MTYPE_PTEXT; - s_reset.no.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_reset.no.generic.callback = Reset_MenuEvent; - s_reset.no.generic.id = ID_NO; - s_reset.no.generic.x = l3; - s_reset.no.generic.y = 264; - s_reset.no.string = "NO"; - s_reset.no.color = color_red; - s_reset.no.style = UI_LEFT; - - Menu_AddItem( &s_reset.menu, &s_reset.yes ); - Menu_AddItem( &s_reset.menu, &s_reset.no ); - - UI_PushMenu( &s_reset.menu ); - - Menu_SetCursorToItem( &s_reset.menu, &s_reset.no ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +/* +======================================================================= + +RESET MENU + +======================================================================= +*/ + +#include "ui_local.h" + + +#define ART_FRAME "menu/art/cut_frame" + +#define ID_NO 100 +#define ID_YES 101 + +typedef struct +{ + menuframework_s menu; + menutext_s no; + menutext_s yes; + int slashX; +} resetMenu_t; + +static resetMenu_t s_reset; + + +/* +================= +Reset_MenuEvent +================= +*/ +void Reset_MenuEvent(void* ptr, int event) { + if( event != QM_ACTIVATED ) { + return; + } + + UI_PopMenu(); + + if( ((menucommon_s*)ptr)->id == ID_NO ) { + return; + } + + // reset the game, pop the level menu and restart it so it updates + UI_NewGame(); + trap_Cvar_SetValue( "ui_spSelection", 0 ); + UI_PopMenu(); + UI_SPLevelMenu(); +} + + +/* +================= +Reset_MenuKey +================= +*/ +static sfxHandle_t Reset_MenuKey( int key ) { + switch ( key ) { + case K_KP_LEFTARROW: + case K_LEFTARROW: + case K_KP_RIGHTARROW: + case K_RIGHTARROW: + key = K_TAB; + break; + + case 'n': + case 'N': + Reset_MenuEvent( &s_reset.no, QM_ACTIVATED ); + break; + + case 'y': + case 'Y': + Reset_MenuEvent( &s_reset.yes, QM_ACTIVATED ); + break; + } + + return Menu_DefaultKey( &s_reset.menu, key ); +} + + +/* +================= +Reset_MenuDraw +================= +*/ +static void Reset_MenuDraw( void ) { + UI_DrawNamedPic( 142, 118, 359, 256, ART_FRAME ); + UI_DrawProportionalString( 320, 194 + 10, "RESET GAME?", UI_CENTER|UI_INVERSE, color_red ); + UI_DrawProportionalString( s_reset.slashX, 265, "/", UI_LEFT|UI_INVERSE, color_red ); + Menu_Draw( &s_reset.menu ); + + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This resets all of the", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "single player game variables.", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 2, "Do this only if you want to", UI_CENTER|UI_SMALLFONT, color_yellow ); + UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 3, "start over from the beginning.", UI_CENTER|UI_SMALLFONT, color_yellow ); +} + + +/* +================= +Reset_Cache +================= +*/ +void Reset_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAME ); +} + + +/* +================= +UI_ResetMenu +================= +*/ +void UI_ResetMenu(void) { + uiClientState_t cstate; + int n1, n2, n3; + int l1, l2, l3; + + // zero set all our globals + memset( &s_reset, 0, sizeof(s_reset) ); + + Reset_Cache(); + + n1 = UI_ProportionalStringWidth( "YES/NO" ); + n2 = UI_ProportionalStringWidth( "YES" ) + PROP_GAP_WIDTH; + n3 = UI_ProportionalStringWidth( "/" ) + PROP_GAP_WIDTH; + l1 = 320 - ( n1 / 2 ); + l2 = l1 + n2; + l3 = l2 + n3; + s_reset.slashX = l2; + + s_reset.menu.draw = Reset_MenuDraw; + s_reset.menu.key = Reset_MenuKey; + s_reset.menu.wrapAround = qtrue; + + trap_GetClientState( &cstate ); + + if ( cstate.connState >= CA_CONNECTED ) { + // float on top of running game + s_reset.menu.fullscreen = qfalse; + } + else { + // game not running + s_reset.menu.fullscreen = qtrue; + } + + s_reset.yes.generic.type = MTYPE_PTEXT; + s_reset.yes.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_reset.yes.generic.callback = Reset_MenuEvent; + s_reset.yes.generic.id = ID_YES; + s_reset.yes.generic.x = l1; + s_reset.yes.generic.y = 264; + s_reset.yes.string = "YES"; + s_reset.yes.color = color_red; + s_reset.yes.style = UI_LEFT; + + s_reset.no.generic.type = MTYPE_PTEXT; + s_reset.no.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_reset.no.generic.callback = Reset_MenuEvent; + s_reset.no.generic.id = ID_NO; + s_reset.no.generic.x = l3; + s_reset.no.generic.y = 264; + s_reset.no.string = "NO"; + s_reset.no.color = color_red; + s_reset.no.style = UI_LEFT; + + Menu_AddItem( &s_reset.menu, &s_reset.yes ); + Menu_AddItem( &s_reset.menu, &s_reset.no ); + + UI_PushMenu( &s_reset.menu ); + + Menu_SetCursorToItem( &s_reset.menu, &s_reset.no ); +} diff --git a/code/q3_ui/ui_spskill.c b/code/q3_ui/ui_spskill.c index 934d832..21bc1ec 100755 --- a/code/q3_ui/ui_spskill.c +++ b/code/q3_ui/ui_spskill.c @@ -1,329 +1,329 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -============================================================================= - -SINGLE PLAYER SKILL MENU - -============================================================================= -*/ - -#include "ui_local.h" - - -#define ART_FRAME "menu/art/cut_frame" -#define ART_BACK "menu/art/back_0.tga" -#define ART_BACK_FOCUS "menu/art/back_1.tga" -#define ART_FIGHT "menu/art/fight_0" -#define ART_FIGHT_FOCUS "menu/art/fight_1" -#define ART_MAP_COMPLETE1 "menu/art/level_complete1" -#define ART_MAP_COMPLETE2 "menu/art/level_complete2" -#define ART_MAP_COMPLETE3 "menu/art/level_complete3" -#define ART_MAP_COMPLETE4 "menu/art/level_complete4" -#define ART_MAP_COMPLETE5 "menu/art/level_complete5" - -#define ID_BABY 10 -#define ID_EASY 11 -#define ID_MEDIUM 12 -#define ID_HARD 13 -#define ID_NIGHTMARE 14 -#define ID_BACK 15 -#define ID_FIGHT 16 - - -typedef struct { - menuframework_s menu; - - menubitmap_s art_frame; - menutext_s art_banner; - - menutext_s item_baby; - menutext_s item_easy; - menutext_s item_medium; - menutext_s item_hard; - menutext_s item_nightmare; - - menubitmap_s art_skillPic; - menubitmap_s item_back; - menubitmap_s item_fight; - - const char *arenaInfo; - qhandle_t skillpics[5]; - sfxHandle_t nightmareSound; - sfxHandle_t silenceSound; -} skillMenuInfo_t; - -static skillMenuInfo_t skillMenuInfo; - - -static void SetSkillColor( int skill, vec4_t color ) { - switch( skill ) { - case 1: - skillMenuInfo.item_baby.color = color; - break; - case 2: - skillMenuInfo.item_easy.color = color; - break; - case 3: - skillMenuInfo.item_medium.color = color; - break; - case 4: - skillMenuInfo.item_hard.color = color; - break; - case 5: - skillMenuInfo.item_nightmare.color = color; - break; - default: - break; - } -} - - -/* -================= -UI_SPSkillMenu_SkillEvent -================= -*/ -static void UI_SPSkillMenu_SkillEvent( void *ptr, int notification ) { - int id; - int skill; - - if (notification != QM_ACTIVATED) - return; - - SetSkillColor( (int)trap_Cvar_VariableValue( "g_spSkill" ), color_red ); - - id = ((menucommon_s*)ptr)->id; - skill = id - ID_BABY + 1; - trap_Cvar_SetValue( "g_spSkill", skill ); - - SetSkillColor( skill, color_white ); - skillMenuInfo.art_skillPic.shader = skillMenuInfo.skillpics[skill - 1]; - - if( id == ID_NIGHTMARE ) { - trap_S_StartLocalSound( skillMenuInfo.nightmareSound, CHAN_ANNOUNCER ); - } - else { - trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); - } -} - - -/* -================= -UI_SPSkillMenu_FightEvent -================= -*/ -static void UI_SPSkillMenu_FightEvent( void *ptr, int notification ) { - if (notification != QM_ACTIVATED) - return; - - UI_SPArena_Start( skillMenuInfo.arenaInfo ); -} - - -/* -================= -UI_SPSkillMenu_BackEvent -================= -*/ -static void UI_SPSkillMenu_BackEvent( void* ptr, int notification ) { - if (notification != QM_ACTIVATED) { - return; - } - - trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); - UI_PopMenu(); -} - - -/* -================= -UI_SPSkillMenu_Key -================= -*/ -static sfxHandle_t UI_SPSkillMenu_Key( int key ) { - if( key == K_MOUSE2 || key == K_ESCAPE ) { - trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); - } - return Menu_DefaultKey( &skillMenuInfo.menu, key ); -} - - -/* -================= -UI_SPSkillMenu_Cache -================= -*/ -void UI_SPSkillMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAME ); - trap_R_RegisterShaderNoMip( ART_BACK ); - trap_R_RegisterShaderNoMip( ART_BACK_FOCUS ); - trap_R_RegisterShaderNoMip( ART_FIGHT ); - trap_R_RegisterShaderNoMip( ART_FIGHT_FOCUS ); - skillMenuInfo.skillpics[0] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 ); - skillMenuInfo.skillpics[1] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 ); - skillMenuInfo.skillpics[2] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 ); - skillMenuInfo.skillpics[3] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 ); - skillMenuInfo.skillpics[4] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 ); - - skillMenuInfo.nightmareSound = trap_S_RegisterSound( "sound/misc/nightmare.wav", qfalse ); - skillMenuInfo.silenceSound = trap_S_RegisterSound( "sound/misc/silence.wav", qfalse ); -} - - -/* -================= -UI_SPSkillMenu_Init -================= -*/ -static void UI_SPSkillMenu_Init( void ) { - int skill; - - memset( &skillMenuInfo, 0, sizeof(skillMenuInfo) ); - skillMenuInfo.menu.fullscreen = qtrue; - skillMenuInfo.menu.key = UI_SPSkillMenu_Key; - - UI_SPSkillMenu_Cache(); - - skillMenuInfo.art_frame.generic.type = MTYPE_BITMAP; - skillMenuInfo.art_frame.generic.name = ART_FRAME; - skillMenuInfo.art_frame.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - skillMenuInfo.art_frame.generic.x = 142; - skillMenuInfo.art_frame.generic.y = 118; - skillMenuInfo.art_frame.width = 359; - skillMenuInfo.art_frame.height = 256; - - skillMenuInfo.art_banner.generic.type = MTYPE_BTEXT; - skillMenuInfo.art_banner.generic.flags = QMF_CENTER_JUSTIFY; - skillMenuInfo.art_banner.generic.x = 320; - skillMenuInfo.art_banner.generic.y = 16; - skillMenuInfo.art_banner.string = "DIFFICULTY"; - skillMenuInfo.art_banner.color = color_white; - skillMenuInfo.art_banner.style = UI_CENTER; - - skillMenuInfo.item_baby.generic.type = MTYPE_PTEXT; - skillMenuInfo.item_baby.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - skillMenuInfo.item_baby.generic.x = 320; - skillMenuInfo.item_baby.generic.y = 170; - skillMenuInfo.item_baby.generic.callback = UI_SPSkillMenu_SkillEvent; - skillMenuInfo.item_baby.generic.id = ID_BABY; - skillMenuInfo.item_baby.string = "I Can Win"; - skillMenuInfo.item_baby.color = color_red; - skillMenuInfo.item_baby.style = UI_CENTER; - - skillMenuInfo.item_easy.generic.type = MTYPE_PTEXT; - skillMenuInfo.item_easy.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - skillMenuInfo.item_easy.generic.x = 320; - skillMenuInfo.item_easy.generic.y = 198; - skillMenuInfo.item_easy.generic.callback = UI_SPSkillMenu_SkillEvent; - skillMenuInfo.item_easy.generic.id = ID_EASY; - skillMenuInfo.item_easy.string = "Bring It On"; - skillMenuInfo.item_easy.color = color_red; - skillMenuInfo.item_easy.style = UI_CENTER; - - skillMenuInfo.item_medium.generic.type = MTYPE_PTEXT; - skillMenuInfo.item_medium.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - skillMenuInfo.item_medium.generic.x = 320; - skillMenuInfo.item_medium.generic.y = 227; - skillMenuInfo.item_medium.generic.callback = UI_SPSkillMenu_SkillEvent; - skillMenuInfo.item_medium.generic.id = ID_MEDIUM; - skillMenuInfo.item_medium.string = "Hurt Me Plenty"; - skillMenuInfo.item_medium.color = color_red; - skillMenuInfo.item_medium.style = UI_CENTER; - - skillMenuInfo.item_hard.generic.type = MTYPE_PTEXT; - skillMenuInfo.item_hard.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - skillMenuInfo.item_hard.generic.x = 320; - skillMenuInfo.item_hard.generic.y = 255; - skillMenuInfo.item_hard.generic.callback = UI_SPSkillMenu_SkillEvent; - skillMenuInfo.item_hard.generic.id = ID_HARD; - skillMenuInfo.item_hard.string = "Hardcore"; - skillMenuInfo.item_hard.color = color_red; - skillMenuInfo.item_hard.style = UI_CENTER; - - skillMenuInfo.item_nightmare.generic.type = MTYPE_PTEXT; - skillMenuInfo.item_nightmare.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - skillMenuInfo.item_nightmare.generic.x = 320; - skillMenuInfo.item_nightmare.generic.y = 283; - skillMenuInfo.item_nightmare.generic.callback = UI_SPSkillMenu_SkillEvent; - skillMenuInfo.item_nightmare.generic.id = ID_NIGHTMARE; - skillMenuInfo.item_nightmare.string = "NIGHTMARE!"; - skillMenuInfo.item_nightmare.color = color_red; - skillMenuInfo.item_nightmare.style = UI_CENTER; - - skillMenuInfo.item_back.generic.type = MTYPE_BITMAP; - skillMenuInfo.item_back.generic.name = ART_BACK; - skillMenuInfo.item_back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - skillMenuInfo.item_back.generic.x = 0; - skillMenuInfo.item_back.generic.y = 480-64; - skillMenuInfo.item_back.generic.callback = UI_SPSkillMenu_BackEvent; - skillMenuInfo.item_back.generic.id = ID_BACK; - skillMenuInfo.item_back.width = 128; - skillMenuInfo.item_back.height = 64; - skillMenuInfo.item_back.focuspic = ART_BACK_FOCUS; - - skillMenuInfo.art_skillPic.generic.type = MTYPE_BITMAP; - skillMenuInfo.art_skillPic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - skillMenuInfo.art_skillPic.generic.x = 320-64; - skillMenuInfo.art_skillPic.generic.y = 368; - skillMenuInfo.art_skillPic.width = 128; - skillMenuInfo.art_skillPic.height = 96; - - skillMenuInfo.item_fight.generic.type = MTYPE_BITMAP; - skillMenuInfo.item_fight.generic.name = ART_FIGHT; - skillMenuInfo.item_fight.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - skillMenuInfo.item_fight.generic.callback = UI_SPSkillMenu_FightEvent; - skillMenuInfo.item_fight.generic.id = ID_FIGHT; - skillMenuInfo.item_fight.generic.x = 640; - skillMenuInfo.item_fight.generic.y = 480-64; - skillMenuInfo.item_fight.width = 128; - skillMenuInfo.item_fight.height = 64; - skillMenuInfo.item_fight.focuspic = ART_FIGHT_FOCUS; - - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_frame ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_banner ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_baby ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_easy ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_medium ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_hard ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_nightmare ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_skillPic ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_back ); - Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_fight ); - - skill = (int)Com_Clamp( 1, 5, trap_Cvar_VariableValue( "g_spSkill" ) ); - SetSkillColor( skill, color_white ); - skillMenuInfo.art_skillPic.shader = skillMenuInfo.skillpics[skill - 1]; - if( skill == 5 ) { - trap_S_StartLocalSound( skillMenuInfo.nightmareSound, CHAN_ANNOUNCER ); - } -} - - -void UI_SPSkillMenu( const char *arenaInfo ) { - UI_SPSkillMenu_Init(); - skillMenuInfo.arenaInfo = arenaInfo; - UI_PushMenu( &skillMenuInfo.menu ); - Menu_SetCursorToItem( &skillMenuInfo.menu, &skillMenuInfo.item_fight ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +============================================================================= + +SINGLE PLAYER SKILL MENU + +============================================================================= +*/ + +#include "ui_local.h" + + +#define ART_FRAME "menu/art/cut_frame" +#define ART_BACK "menu/art/back_0.tga" +#define ART_BACK_FOCUS "menu/art/back_1.tga" +#define ART_FIGHT "menu/art/fight_0" +#define ART_FIGHT_FOCUS "menu/art/fight_1" +#define ART_MAP_COMPLETE1 "menu/art/level_complete1" +#define ART_MAP_COMPLETE2 "menu/art/level_complete2" +#define ART_MAP_COMPLETE3 "menu/art/level_complete3" +#define ART_MAP_COMPLETE4 "menu/art/level_complete4" +#define ART_MAP_COMPLETE5 "menu/art/level_complete5" + +#define ID_BABY 10 +#define ID_EASY 11 +#define ID_MEDIUM 12 +#define ID_HARD 13 +#define ID_NIGHTMARE 14 +#define ID_BACK 15 +#define ID_FIGHT 16 + + +typedef struct { + menuframework_s menu; + + menubitmap_s art_frame; + menutext_s art_banner; + + menutext_s item_baby; + menutext_s item_easy; + menutext_s item_medium; + menutext_s item_hard; + menutext_s item_nightmare; + + menubitmap_s art_skillPic; + menubitmap_s item_back; + menubitmap_s item_fight; + + const char *arenaInfo; + qhandle_t skillpics[5]; + sfxHandle_t nightmareSound; + sfxHandle_t silenceSound; +} skillMenuInfo_t; + +static skillMenuInfo_t skillMenuInfo; + + +static void SetSkillColor( int skill, vec4_t color ) { + switch( skill ) { + case 1: + skillMenuInfo.item_baby.color = color; + break; + case 2: + skillMenuInfo.item_easy.color = color; + break; + case 3: + skillMenuInfo.item_medium.color = color; + break; + case 4: + skillMenuInfo.item_hard.color = color; + break; + case 5: + skillMenuInfo.item_nightmare.color = color; + break; + default: + break; + } +} + + +/* +================= +UI_SPSkillMenu_SkillEvent +================= +*/ +static void UI_SPSkillMenu_SkillEvent( void *ptr, int notification ) { + int id; + int skill; + + if (notification != QM_ACTIVATED) + return; + + SetSkillColor( (int)trap_Cvar_VariableValue( "g_spSkill" ), color_red ); + + id = ((menucommon_s*)ptr)->id; + skill = id - ID_BABY + 1; + trap_Cvar_SetValue( "g_spSkill", skill ); + + SetSkillColor( skill, color_white ); + skillMenuInfo.art_skillPic.shader = skillMenuInfo.skillpics[skill - 1]; + + if( id == ID_NIGHTMARE ) { + trap_S_StartLocalSound( skillMenuInfo.nightmareSound, CHAN_ANNOUNCER ); + } + else { + trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); + } +} + + +/* +================= +UI_SPSkillMenu_FightEvent +================= +*/ +static void UI_SPSkillMenu_FightEvent( void *ptr, int notification ) { + if (notification != QM_ACTIVATED) + return; + + UI_SPArena_Start( skillMenuInfo.arenaInfo ); +} + + +/* +================= +UI_SPSkillMenu_BackEvent +================= +*/ +static void UI_SPSkillMenu_BackEvent( void* ptr, int notification ) { + if (notification != QM_ACTIVATED) { + return; + } + + trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); + UI_PopMenu(); +} + + +/* +================= +UI_SPSkillMenu_Key +================= +*/ +static sfxHandle_t UI_SPSkillMenu_Key( int key ) { + if( key == K_MOUSE2 || key == K_ESCAPE ) { + trap_S_StartLocalSound( skillMenuInfo.silenceSound, CHAN_ANNOUNCER ); + } + return Menu_DefaultKey( &skillMenuInfo.menu, key ); +} + + +/* +================= +UI_SPSkillMenu_Cache +================= +*/ +void UI_SPSkillMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAME ); + trap_R_RegisterShaderNoMip( ART_BACK ); + trap_R_RegisterShaderNoMip( ART_BACK_FOCUS ); + trap_R_RegisterShaderNoMip( ART_FIGHT ); + trap_R_RegisterShaderNoMip( ART_FIGHT_FOCUS ); + skillMenuInfo.skillpics[0] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 ); + skillMenuInfo.skillpics[1] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 ); + skillMenuInfo.skillpics[2] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 ); + skillMenuInfo.skillpics[3] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 ); + skillMenuInfo.skillpics[4] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 ); + + skillMenuInfo.nightmareSound = trap_S_RegisterSound( "sound/misc/nightmare.wav", qfalse ); + skillMenuInfo.silenceSound = trap_S_RegisterSound( "sound/misc/silence.wav", qfalse ); +} + + +/* +================= +UI_SPSkillMenu_Init +================= +*/ +static void UI_SPSkillMenu_Init( void ) { + int skill; + + memset( &skillMenuInfo, 0, sizeof(skillMenuInfo) ); + skillMenuInfo.menu.fullscreen = qtrue; + skillMenuInfo.menu.key = UI_SPSkillMenu_Key; + + UI_SPSkillMenu_Cache(); + + skillMenuInfo.art_frame.generic.type = MTYPE_BITMAP; + skillMenuInfo.art_frame.generic.name = ART_FRAME; + skillMenuInfo.art_frame.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + skillMenuInfo.art_frame.generic.x = 142; + skillMenuInfo.art_frame.generic.y = 118; + skillMenuInfo.art_frame.width = 359; + skillMenuInfo.art_frame.height = 256; + + skillMenuInfo.art_banner.generic.type = MTYPE_BTEXT; + skillMenuInfo.art_banner.generic.flags = QMF_CENTER_JUSTIFY; + skillMenuInfo.art_banner.generic.x = 320; + skillMenuInfo.art_banner.generic.y = 16; + skillMenuInfo.art_banner.string = "DIFFICULTY"; + skillMenuInfo.art_banner.color = color_white; + skillMenuInfo.art_banner.style = UI_CENTER; + + skillMenuInfo.item_baby.generic.type = MTYPE_PTEXT; + skillMenuInfo.item_baby.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + skillMenuInfo.item_baby.generic.x = 320; + skillMenuInfo.item_baby.generic.y = 170; + skillMenuInfo.item_baby.generic.callback = UI_SPSkillMenu_SkillEvent; + skillMenuInfo.item_baby.generic.id = ID_BABY; + skillMenuInfo.item_baby.string = "I Can Win"; + skillMenuInfo.item_baby.color = color_red; + skillMenuInfo.item_baby.style = UI_CENTER; + + skillMenuInfo.item_easy.generic.type = MTYPE_PTEXT; + skillMenuInfo.item_easy.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + skillMenuInfo.item_easy.generic.x = 320; + skillMenuInfo.item_easy.generic.y = 198; + skillMenuInfo.item_easy.generic.callback = UI_SPSkillMenu_SkillEvent; + skillMenuInfo.item_easy.generic.id = ID_EASY; + skillMenuInfo.item_easy.string = "Bring It On"; + skillMenuInfo.item_easy.color = color_red; + skillMenuInfo.item_easy.style = UI_CENTER; + + skillMenuInfo.item_medium.generic.type = MTYPE_PTEXT; + skillMenuInfo.item_medium.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + skillMenuInfo.item_medium.generic.x = 320; + skillMenuInfo.item_medium.generic.y = 227; + skillMenuInfo.item_medium.generic.callback = UI_SPSkillMenu_SkillEvent; + skillMenuInfo.item_medium.generic.id = ID_MEDIUM; + skillMenuInfo.item_medium.string = "Hurt Me Plenty"; + skillMenuInfo.item_medium.color = color_red; + skillMenuInfo.item_medium.style = UI_CENTER; + + skillMenuInfo.item_hard.generic.type = MTYPE_PTEXT; + skillMenuInfo.item_hard.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + skillMenuInfo.item_hard.generic.x = 320; + skillMenuInfo.item_hard.generic.y = 255; + skillMenuInfo.item_hard.generic.callback = UI_SPSkillMenu_SkillEvent; + skillMenuInfo.item_hard.generic.id = ID_HARD; + skillMenuInfo.item_hard.string = "Hardcore"; + skillMenuInfo.item_hard.color = color_red; + skillMenuInfo.item_hard.style = UI_CENTER; + + skillMenuInfo.item_nightmare.generic.type = MTYPE_PTEXT; + skillMenuInfo.item_nightmare.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + skillMenuInfo.item_nightmare.generic.x = 320; + skillMenuInfo.item_nightmare.generic.y = 283; + skillMenuInfo.item_nightmare.generic.callback = UI_SPSkillMenu_SkillEvent; + skillMenuInfo.item_nightmare.generic.id = ID_NIGHTMARE; + skillMenuInfo.item_nightmare.string = "NIGHTMARE!"; + skillMenuInfo.item_nightmare.color = color_red; + skillMenuInfo.item_nightmare.style = UI_CENTER; + + skillMenuInfo.item_back.generic.type = MTYPE_BITMAP; + skillMenuInfo.item_back.generic.name = ART_BACK; + skillMenuInfo.item_back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + skillMenuInfo.item_back.generic.x = 0; + skillMenuInfo.item_back.generic.y = 480-64; + skillMenuInfo.item_back.generic.callback = UI_SPSkillMenu_BackEvent; + skillMenuInfo.item_back.generic.id = ID_BACK; + skillMenuInfo.item_back.width = 128; + skillMenuInfo.item_back.height = 64; + skillMenuInfo.item_back.focuspic = ART_BACK_FOCUS; + + skillMenuInfo.art_skillPic.generic.type = MTYPE_BITMAP; + skillMenuInfo.art_skillPic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + skillMenuInfo.art_skillPic.generic.x = 320-64; + skillMenuInfo.art_skillPic.generic.y = 368; + skillMenuInfo.art_skillPic.width = 128; + skillMenuInfo.art_skillPic.height = 96; + + skillMenuInfo.item_fight.generic.type = MTYPE_BITMAP; + skillMenuInfo.item_fight.generic.name = ART_FIGHT; + skillMenuInfo.item_fight.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + skillMenuInfo.item_fight.generic.callback = UI_SPSkillMenu_FightEvent; + skillMenuInfo.item_fight.generic.id = ID_FIGHT; + skillMenuInfo.item_fight.generic.x = 640; + skillMenuInfo.item_fight.generic.y = 480-64; + skillMenuInfo.item_fight.width = 128; + skillMenuInfo.item_fight.height = 64; + skillMenuInfo.item_fight.focuspic = ART_FIGHT_FOCUS; + + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_frame ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_banner ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_baby ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_easy ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_medium ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_hard ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_nightmare ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.art_skillPic ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_back ); + Menu_AddItem( &skillMenuInfo.menu, ( void * )&skillMenuInfo.item_fight ); + + skill = (int)Com_Clamp( 1, 5, trap_Cvar_VariableValue( "g_spSkill" ) ); + SetSkillColor( skill, color_white ); + skillMenuInfo.art_skillPic.shader = skillMenuInfo.skillpics[skill - 1]; + if( skill == 5 ) { + trap_S_StartLocalSound( skillMenuInfo.nightmareSound, CHAN_ANNOUNCER ); + } +} + + +void UI_SPSkillMenu( const char *arenaInfo ) { + UI_SPSkillMenu_Init(); + skillMenuInfo.arenaInfo = arenaInfo; + UI_PushMenu( &skillMenuInfo.menu ); + Menu_SetCursorToItem( &skillMenuInfo.menu, &skillMenuInfo.item_fight ); +} diff --git a/code/q3_ui/ui_startserver.c b/code/q3_ui/ui_startserver.c index 5bc3680..401f687 100755 --- a/code/q3_ui/ui_startserver.c +++ b/code/q3_ui/ui_startserver.c @@ -1,1968 +1,1968 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -============================================================================= - -START SERVER MENU ***** - -============================================================================= -*/ - - -#include "ui_local.h" - - -#define GAMESERVER_BACK0 "menu/art/back_0" -#define GAMESERVER_BACK1 "menu/art/back_1" -#define GAMESERVER_NEXT0 "menu/art/next_0" -#define GAMESERVER_NEXT1 "menu/art/next_1" -#define GAMESERVER_FRAMEL "menu/art/frame2_l" -#define GAMESERVER_FRAMER "menu/art/frame1_r" -#define GAMESERVER_SELECT "menu/art/maps_select" -#define GAMESERVER_SELECTED "menu/art/maps_selected" -#define GAMESERVER_FIGHT0 "menu/art/fight_0" -#define GAMESERVER_FIGHT1 "menu/art/fight_1" -#define GAMESERVER_UNKNOWNMAP "menu/art/unknownmap" -#define GAMESERVER_ARROWS "menu/art/gs_arrows_0" -#define GAMESERVER_ARROWSL "menu/art/gs_arrows_l" -#define GAMESERVER_ARROWSR "menu/art/gs_arrows_r" - -#define MAX_MAPROWS 2 -#define MAX_MAPCOLS 2 -#define MAX_MAPSPERPAGE 4 - -#define MAX_SERVERSTEXT 8192 - -#define MAX_SERVERMAPS 64 -#define MAX_NAMELENGTH 16 - -#define ID_GAMETYPE 10 -#define ID_PICTURES 11 // 12, 13, 14 -#define ID_PREVPAGE 15 -#define ID_NEXTPAGE 16 -#define ID_STARTSERVERBACK 17 -#define ID_STARTSERVERNEXT 18 - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menulist_s gametype; - menubitmap_s mappics[MAX_MAPSPERPAGE]; - menubitmap_s mapbuttons[MAX_MAPSPERPAGE]; - menubitmap_s arrows; - menubitmap_s prevpage; - menubitmap_s nextpage; - menubitmap_s back; - menubitmap_s next; - - menutext_s mapname; - menubitmap_s item_null; - - qboolean multiplayer; - int currentmap; - int nummaps; - int page; - int maxpages; - char maplist[MAX_SERVERMAPS][MAX_NAMELENGTH]; - int mapGamebits[MAX_SERVERMAPS]; -} startserver_t; - -static startserver_t s_startserver; - -static const char *gametype_items[] = { - "Free For All", - "Team Deathmatch", - "Tournament", - "Capture the Flag", - 0 -}; - -static int gametype_remap[] = {GT_FFA, GT_TEAM, GT_TOURNAMENT, GT_CTF}; -static int gametype_remap2[] = {0, 2, 0, 1, 3}; - -// use ui_servers2.c definition -extern const char* punkbuster_items[]; - -static void UI_ServerOptionsMenu( qboolean multiplayer ); - - -/* -================= -GametypeBits -================= -*/ -static int GametypeBits( char *string ) { - int bits; - char *p; - char *token; - - bits = 0; - p = string; - while( 1 ) { - token = COM_ParseExt( &p, qfalse ); - if( token[0] == 0 ) { - break; - } - - if( Q_stricmp( token, "ffa" ) == 0 ) { - bits |= 1 << GT_FFA; - continue; - } - - if( Q_stricmp( token, "tourney" ) == 0 ) { - bits |= 1 << GT_TOURNAMENT; - continue; - } - - if( Q_stricmp( token, "single" ) == 0 ) { - bits |= 1 << GT_SINGLE_PLAYER; - continue; - } - - if( Q_stricmp( token, "team" ) == 0 ) { - bits |= 1 << GT_TEAM; - continue; - } - - if( Q_stricmp( token, "ctf" ) == 0 ) { - bits |= 1 << GT_CTF; - continue; - } - } - - return bits; -} - - -/* -================= -StartServer_Update -================= -*/ -static void StartServer_Update( void ) { - int i; - int top; - static char picname[MAX_MAPSPERPAGE][64]; - - top = s_startserver.page*MAX_MAPSPERPAGE; - - for (i=0; i= s_startserver.nummaps) - break; - - Com_sprintf( picname[i], sizeof(picname[i]), "levelshots/%s", s_startserver.maplist[top+i] ); - - s_startserver.mappics[i].generic.flags &= ~QMF_HIGHLIGHT; - s_startserver.mappics[i].generic.name = picname[i]; - s_startserver.mappics[i].shader = 0; - - // reset - s_startserver.mapbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; - s_startserver.mapbuttons[i].generic.flags &= ~QMF_INACTIVE; - } - - for (; i=0 && i < MAX_MAPSPERPAGE ) - { - s_startserver.mappics[i].generic.flags |= QMF_HIGHLIGHT; - s_startserver.mapbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; - } - - // set the map name - strcpy( s_startserver.mapname.string, s_startserver.maplist[s_startserver.currentmap] ); - } - - Q_strupr( s_startserver.mapname.string ); -} - - -/* -================= -StartServer_MapEvent -================= -*/ -static void StartServer_MapEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED) { - return; - } - - s_startserver.currentmap = (s_startserver.page*MAX_MAPSPERPAGE) + (((menucommon_s*)ptr)->id - ID_PICTURES); - StartServer_Update(); -} - - -/* -================= -StartServer_GametypeEvent -================= -*/ -static void StartServer_GametypeEvent( void* ptr, int event ) { - int i; - int count; - int gamebits; - int matchbits; - const char *info; - - if( event != QM_ACTIVATED) { - return; - } - - count = UI_GetNumArenas(); - s_startserver.nummaps = 0; - matchbits = 1 << gametype_remap[s_startserver.gametype.curvalue]; - if( gametype_remap[s_startserver.gametype.curvalue] == GT_FFA ) { - matchbits |= ( 1 << GT_SINGLE_PLAYER ); - } - for( i = 0; i < count; i++ ) { - info = UI_GetArenaInfoByNumber( i ); - - gamebits = GametypeBits( Info_ValueForKey( info, "type") ); - if( !( gamebits & matchbits ) ) { - continue; - } - - Q_strncpyz( s_startserver.maplist[s_startserver.nummaps], Info_ValueForKey( info, "map"), MAX_NAMELENGTH ); - Q_strupr( s_startserver.maplist[s_startserver.nummaps] ); - s_startserver.mapGamebits[s_startserver.nummaps] = gamebits; - s_startserver.nummaps++; - } - s_startserver.maxpages = (s_startserver.nummaps + MAX_MAPSPERPAGE-1)/MAX_MAPSPERPAGE; - s_startserver.page = 0; - s_startserver.currentmap = 0; - - StartServer_Update(); -} - - -/* -================= -StartServer_MenuEvent -================= -*/ -static void StartServer_MenuEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_PREVPAGE: - if( s_startserver.page > 0 ) { - s_startserver.page--; - StartServer_Update(); - } - break; - - case ID_NEXTPAGE: - if( s_startserver.page < s_startserver.maxpages - 1 ) { - s_startserver.page++; - StartServer_Update(); - } - break; - - case ID_STARTSERVERNEXT: - trap_Cvar_SetValue( "g_gameType", gametype_remap[s_startserver.gametype.curvalue] ); - UI_ServerOptionsMenu( s_startserver.multiplayer ); - break; - - case ID_STARTSERVERBACK: - UI_PopMenu(); - break; - } -} - - -/* -=============== -StartServer_LevelshotDraw -=============== -*/ -static void StartServer_LevelshotDraw( void *self ) { - menubitmap_s *b; - int x; - int y; - int w; - int h; - int n; - - b = (menubitmap_s *)self; - - if( !b->generic.name ) { - return; - } - - if( b->generic.name && !b->shader ) { - b->shader = trap_R_RegisterShaderNoMip( b->generic.name ); - if( !b->shader && b->errorpic ) { - b->shader = trap_R_RegisterShaderNoMip( b->errorpic ); - } - } - - if( b->focuspic && !b->focusshader ) { - b->focusshader = trap_R_RegisterShaderNoMip( b->focuspic ); - } - - x = b->generic.x; - y = b->generic.y; - w = b->width; - h = b->height; - if( b->shader ) { - UI_DrawHandlePic( x, y, w, h, b->shader ); - } - - x = b->generic.x; - y = b->generic.y + b->height; - UI_FillRect( x, y, b->width, 28, colorBlack ); - - x += b->width / 2; - y += 4; - n = s_startserver.page * MAX_MAPSPERPAGE + b->generic.id - ID_PICTURES; - UI_DrawString( x, y, s_startserver.maplist[n], UI_CENTER|UI_SMALLFONT, color_orange ); - - x = b->generic.x; - y = b->generic.y; - w = b->width; - h = b->height + 28; - if( b->generic.flags & QMF_HIGHLIGHT ) { - UI_DrawHandlePic( x, y, w, h, b->focusshader ); - } -} - - -/* -================= -StartServer_MenuInit -================= -*/ -static void StartServer_MenuInit( void ) { - int i; - int x; - int y; - static char mapnamebuffer[64]; - - // zero set all our globals - memset( &s_startserver, 0 ,sizeof(startserver_t) ); - - StartServer_Cache(); - - s_startserver.menu.wrapAround = qtrue; - s_startserver.menu.fullscreen = qtrue; - - s_startserver.banner.generic.type = MTYPE_BTEXT; - s_startserver.banner.generic.x = 320; - s_startserver.banner.generic.y = 16; - s_startserver.banner.string = "GAME SERVER"; - s_startserver.banner.color = color_white; - s_startserver.banner.style = UI_CENTER; - - s_startserver.framel.generic.type = MTYPE_BITMAP; - s_startserver.framel.generic.name = GAMESERVER_FRAMEL; - s_startserver.framel.generic.flags = QMF_INACTIVE; - s_startserver.framel.generic.x = 0; - s_startserver.framel.generic.y = 78; - s_startserver.framel.width = 256; - s_startserver.framel.height = 329; - - s_startserver.framer.generic.type = MTYPE_BITMAP; - s_startserver.framer.generic.name = GAMESERVER_FRAMER; - s_startserver.framer.generic.flags = QMF_INACTIVE; - s_startserver.framer.generic.x = 376; - s_startserver.framer.generic.y = 76; - s_startserver.framer.width = 256; - s_startserver.framer.height = 334; - - s_startserver.gametype.generic.type = MTYPE_SPINCONTROL; - s_startserver.gametype.generic.name = "Game Type:"; - s_startserver.gametype.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_startserver.gametype.generic.callback = StartServer_GametypeEvent; - s_startserver.gametype.generic.id = ID_GAMETYPE; - s_startserver.gametype.generic.x = 320 - 24; - s_startserver.gametype.generic.y = 368; - s_startserver.gametype.itemnames = gametype_items; - - for (i=0; i= GT_TEAM) && - (s_serveroptions.playerTeam[n].curvalue != s_serveroptions.playerTeam[s_serveroptions.newBotIndex].curvalue ) ) { - continue; - } - if( Q_stricmp( checkName, s_serveroptions.playerNameBuffers[n] ) == 0 ) { - return qtrue; - } - } - - return qfalse; -} - - -/* -================= -ServerOptions_Start -================= -*/ -static void ServerOptions_Start( void ) { - int timelimit; - int fraglimit; - int maxclients; - int dedicated; - int friendlyfire; - int flaglimit; - int pure; - int skill; - int n; - char buf[64]; - - - timelimit = atoi( s_serveroptions.timelimit.field.buffer ); - fraglimit = atoi( s_serveroptions.fraglimit.field.buffer ); - flaglimit = atoi( s_serveroptions.flaglimit.field.buffer ); - dedicated = s_serveroptions.dedicated.curvalue; - friendlyfire = s_serveroptions.friendlyfire.curvalue; - pure = s_serveroptions.pure.curvalue; - skill = s_serveroptions.botSkill.curvalue + 1; - - //set maxclients - for( n = 0, maxclients = 0; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue == 2 ) { - continue; - } - if( (s_serveroptions.playerType[n].curvalue == 1) && (s_serveroptions.playerNameBuffers[n][0] == 0) ) { - continue; - } - maxclients++; - } - - switch( s_serveroptions.gametype ) { - case GT_FFA: - default: - trap_Cvar_SetValue( "ui_ffa_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_ffa_timelimit", timelimit ); - break; - - case GT_TOURNAMENT: - trap_Cvar_SetValue( "ui_tourney_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_tourney_timelimit", timelimit ); - break; - - case GT_TEAM: - trap_Cvar_SetValue( "ui_team_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_team_timelimit", timelimit ); - trap_Cvar_SetValue( "ui_team_friendlt", friendlyfire ); - break; - - case GT_CTF: - trap_Cvar_SetValue( "ui_ctf_fraglimit", fraglimit ); - trap_Cvar_SetValue( "ui_ctf_timelimit", timelimit ); - trap_Cvar_SetValue( "ui_ctf_friendlt", friendlyfire ); - break; - } - - trap_Cvar_SetValue( "sv_maxclients", Com_Clamp( 0, 12, maxclients ) ); - trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, dedicated ) ); - trap_Cvar_SetValue ("timelimit", Com_Clamp( 0, timelimit, timelimit ) ); - trap_Cvar_SetValue ("fraglimit", Com_Clamp( 0, fraglimit, fraglimit ) ); - trap_Cvar_SetValue ("capturelimit", Com_Clamp( 0, flaglimit, flaglimit ) ); - trap_Cvar_SetValue( "g_friendlyfire", friendlyfire ); - trap_Cvar_SetValue( "sv_pure", pure ); - trap_Cvar_Set("sv_hostname", s_serveroptions.hostname.field.buffer ); - - trap_Cvar_SetValue( "sv_punkbuster", s_serveroptions.punkbuster.curvalue ); - - // the wait commands will allow the dedicated to take effect - trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", s_startserver.maplist[s_startserver.currentmap] ) ); - - // add bots - trap_Cmd_ExecuteText( EXEC_APPEND, "wait 3\n" ); - for( n = 1; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue != 1 ) { - continue; - } - if( s_serveroptions.playerNameBuffers[n][0] == 0 ) { - continue; - } - if( s_serveroptions.playerNameBuffers[n][0] == '-' ) { - continue; - } - if( s_serveroptions.gametype >= GT_TEAM ) { - Com_sprintf( buf, sizeof(buf), "addbot %s %i %s\n", s_serveroptions.playerNameBuffers[n], skill, - playerTeam_list[s_serveroptions.playerTeam[n].curvalue] ); - } - else { - Com_sprintf( buf, sizeof(buf), "addbot %s %i\n", s_serveroptions.playerNameBuffers[n], skill ); - } - trap_Cmd_ExecuteText( EXEC_APPEND, buf ); - } - - // set player's team - if( dedicated == 0 && s_serveroptions.gametype >= GT_TEAM ) { - trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait 5; team %s\n", playerTeam_list[s_serveroptions.playerTeam[0].curvalue] ) ); - } -} - - -/* -================= -ServerOptions_InitPlayerItems -================= -*/ -static void ServerOptions_InitPlayerItems( void ) { - int n; - int v; - - // init types - if( s_serveroptions.multiplayer ) { - v = 0; // open - } - else { - v = 1; // bot - } - - for( n = 0; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerType[n].curvalue = v; - } - - if( s_serveroptions.multiplayer && (s_serveroptions.gametype < GT_TEAM) ) { - for( n = 8; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerType[n].curvalue = 2; - } - } - - // if not a dedicated server, first slot is reserved for the human on the server - if( s_serveroptions.dedicated.curvalue == 0 ) { - // human - s_serveroptions.playerType[0].generic.flags |= QMF_INACTIVE; - s_serveroptions.playerType[0].curvalue = 0; - trap_Cvar_VariableStringBuffer( "name", s_serveroptions.playerNameBuffers[0], sizeof(s_serveroptions.playerNameBuffers[0]) ); - Q_CleanStr( s_serveroptions.playerNameBuffers[0] ); - } - - // init teams - if( s_serveroptions.gametype >= GT_TEAM ) { - for( n = 0; n < (PLAYER_SLOTS / 2); n++ ) { - s_serveroptions.playerTeam[n].curvalue = 0; - } - for( ; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerTeam[n].curvalue = 1; - } - } - else { - for( n = 0; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - } -} - - -/* -================= -ServerOptions_SetPlayerItems -================= -*/ -static void ServerOptions_SetPlayerItems( void ) { - int start; - int n; - - // types -// for( n = 0; n < PLAYER_SLOTS; n++ ) { -// if( (!s_serveroptions.multiplayer) && (n > 0) && (s_serveroptions.playerType[n].curvalue == 0) ) { -// s_serveroptions.playerType[n].curvalue = 1; -// } -// } - - // names - if( s_serveroptions.dedicated.curvalue == 0 ) { - s_serveroptions.player0.string = "Human"; - s_serveroptions.playerName[0].generic.flags &= ~QMF_HIDDEN; - - start = 1; - } - else { - s_serveroptions.player0.string = "Open"; - start = 0; - } - for( n = start; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue == 1 ) { - s_serveroptions.playerName[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); - } - else { - s_serveroptions.playerName[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - } - - // teams - if( s_serveroptions.gametype < GT_TEAM ) { - return; - } - for( n = start; n < PLAYER_SLOTS; n++ ) { - if( s_serveroptions.playerType[n].curvalue == 2 ) { - s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); - } - else { - s_serveroptions.playerTeam[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); - } - } -} - - -/* -================= -ServerOptions_Event -================= -*/ -static void ServerOptions_Event( void* ptr, int event ) { - switch( ((menucommon_s*)ptr)->id ) { - - //if( event != QM_ACTIVATED && event != QM_LOSTFOCUS) { - // return; - //} - case ID_PLAYER_TYPE: - if( event != QM_ACTIVATED ) { - break; - } - ServerOptions_SetPlayerItems(); - break; - - case ID_MAXCLIENTS: - case ID_DEDICATED: - ServerOptions_SetPlayerItems(); - break; - case ID_GO: - if( event != QM_ACTIVATED ) { - break; - } - ServerOptions_Start(); - break; - - case ID_STARTSERVERNEXT: - if( event != QM_ACTIVATED ) { - break; - } - break; - case ID_BACK: - if( event != QM_ACTIVATED ) { - break; - } - UI_PopMenu(); - break; - } -} - - -static void ServerOptions_PlayerNameEvent( void* ptr, int event ) { - int n; - - if( event != QM_ACTIVATED ) { - return; - } - n = ((menutext_s*)ptr)->generic.id; - s_serveroptions.newBotIndex = n; - UI_BotSelectMenu( s_serveroptions.playerNameBuffers[n] ); -} - - -/* -================= -ServerOptions_StatusBar -================= -*/ -static void ServerOptions_StatusBar( void* ptr ) { - switch( ((menucommon_s*)ptr)->id ) { - default: - UI_DrawString( 320, 440, "0 = NO LIMIT", UI_CENTER|UI_SMALLFONT, colorWhite ); - break; - } -} - - -/* -=============== -ServerOptions_LevelshotDraw -=============== -*/ -static void ServerOptions_LevelshotDraw( void *self ) { - menubitmap_s *b; - int x; - int y; - - // strange place for this, but it works - if( s_serveroptions.newBot ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[s_serveroptions.newBotIndex], s_serveroptions.newBotName, 16 ); - s_serveroptions.newBot = qfalse; - } - - b = (menubitmap_s *)self; - - Bitmap_Draw( b ); - - x = b->generic.x; - y = b->generic.y + b->height; - UI_FillRect( x, y, b->width, 40, colorBlack ); - - x += b->width / 2; - y += 4; - UI_DrawString( x, y, s_serveroptions.mapnamebuffer, UI_CENTER|UI_SMALLFONT, color_orange ); - - y += SMALLCHAR_HEIGHT; - UI_DrawString( x, y, gametype_items[gametype_remap2[s_serveroptions.gametype]], UI_CENTER|UI_SMALLFONT, color_orange ); -} - - -static void ServerOptions_InitBotNames( void ) { - int count; - int n; - const char *arenaInfo; - const char *botInfo; - char *p; - char *bot; - char bots[MAX_INFO_STRING]; - - if( s_serveroptions.gametype >= GT_TEAM ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[1], "grunt", 16 ); - Q_strncpyz( s_serveroptions.playerNameBuffers[2], "major", 16 ); - if( s_serveroptions.gametype == GT_TEAM ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[3], "visor", 16 ); - } - else { - s_serveroptions.playerType[3].curvalue = 2; - } - s_serveroptions.playerType[4].curvalue = 2; - s_serveroptions.playerType[5].curvalue = 2; - - Q_strncpyz( s_serveroptions.playerNameBuffers[6], "sarge", 16 ); - Q_strncpyz( s_serveroptions.playerNameBuffers[7], "grunt", 16 ); - Q_strncpyz( s_serveroptions.playerNameBuffers[8], "major", 16 ); - if( s_serveroptions.gametype == GT_TEAM ) { - Q_strncpyz( s_serveroptions.playerNameBuffers[9], "visor", 16 ); - } - else { - s_serveroptions.playerType[9].curvalue = 2; - } - s_serveroptions.playerType[10].curvalue = 2; - s_serveroptions.playerType[11].curvalue = 2; - - return; - } - - count = 1; // skip the first slot, reserved for a human - - // get info for this map - arenaInfo = UI_GetArenaInfoByMap( s_serveroptions.mapnamebuffer ); - - // get the bot info - we'll seed with them if any are listed - Q_strncpyz( bots, Info_ValueForKey( arenaInfo, "bots" ), sizeof(bots) ); - p = &bots[0]; - while( *p && count < PLAYER_SLOTS ) { - //skip spaces - while( *p && *p == ' ' ) { - p++; - } - if( !p ) { - break; - } - - // mark start of bot name - bot = p; - - // skip until space of null - while( *p && *p != ' ' ) { - p++; - } - if( *p ) { - *p++ = 0; - } - - botInfo = UI_GetBotInfoByName( bot ); - bot = Info_ValueForKey( botInfo, "name" ); - - Q_strncpyz( s_serveroptions.playerNameBuffers[count], bot, sizeof(s_serveroptions.playerNameBuffers[count]) ); - count++; - } - - // set the rest of the bot slots to "---" - for( n = count; n < PLAYER_SLOTS; n++ ) { - strcpy( s_serveroptions.playerNameBuffers[n], "--------" ); - } - - // pad up to #8 as open slots - for( ;count < 8; count++ ) { - s_serveroptions.playerType[count].curvalue = 0; - } - - // close off the rest by default - for( ;count < PLAYER_SLOTS; count++ ) { - if( s_serveroptions.playerType[count].curvalue == 1 ) { - s_serveroptions.playerType[count].curvalue = 2; - } - } -} - - -/* -================= -ServerOptions_SetMenuItems -================= -*/ -static void ServerOptions_SetMenuItems( void ) { - static char picname[64]; - - switch( s_serveroptions.gametype ) { - case GT_FFA: - default: - Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_fraglimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_timelimit" ) ) ); - break; - - case GT_TOURNAMENT: - Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_fraglimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_timelimit" ) ) ); - break; - - case GT_TEAM: - Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_fraglimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_timelimit" ) ) ); - s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_team_friendly" ) ); - break; - - case GT_CTF: - Com_sprintf( s_serveroptions.flaglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 100, trap_Cvar_VariableValue( "ui_ctf_capturelimit" ) ) ); - Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ctf_timelimit" ) ) ); - s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_ctf_friendly" ) ); - break; - } - - Q_strncpyz( s_serveroptions.hostname.field.buffer, UI_Cvar_VariableString( "sv_hostname" ), sizeof( s_serveroptions.hostname.field.buffer ) ); - s_serveroptions.pure.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_pure" ) ); - - // set the map pic - Com_sprintf( picname, 64, "levelshots/%s", s_startserver.maplist[s_startserver.currentmap] ); - s_serveroptions.mappic.generic.name = picname; - - // set the map name - strcpy( s_serveroptions.mapnamebuffer, s_startserver.mapname.string ); - Q_strupr( s_serveroptions.mapnamebuffer ); - - // get the player selections initialized - ServerOptions_InitPlayerItems(); - ServerOptions_SetPlayerItems(); - - // seed bot names - ServerOptions_InitBotNames(); - ServerOptions_SetPlayerItems(); -} - -/* -================= -PlayerName_Draw -================= -*/ -static void PlayerName_Draw( void *item ) { - menutext_s *s; - float *color; - int x, y; - int style; - qboolean focus; - - s = (menutext_s *)item; - - x = s->generic.x; - y = s->generic.y; - - style = UI_SMALLFONT; - focus = (s->generic.parent->cursor == s->generic.menuPosition); - - if ( s->generic.flags & QMF_GRAYED ) - color = text_color_disabled; - else if ( focus ) - { - color = text_color_highlight; - style |= UI_PULSE; - } - else if ( s->generic.flags & QMF_BLINK ) - { - color = text_color_highlight; - style |= UI_BLINK; - } - else - color = text_color_normal; - - if ( focus ) - { - // draw cursor - UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); - UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); - } - - UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); - UI_DrawString( x + SMALLCHAR_WIDTH, y, s->string, style|UI_LEFT, color ); -} - - -/* -================= -ServerOptions_MenuInit -================= -*/ -#define OPTIONS_X 456 - -static void ServerOptions_MenuInit( qboolean multiplayer ) { - int y; - int n; - - memset( &s_serveroptions, 0 ,sizeof(serveroptions_t) ); - s_serveroptions.multiplayer = multiplayer; - s_serveroptions.gametype = (int)Com_Clamp( 0, 5, trap_Cvar_VariableValue( "g_gameType" ) ); - s_serveroptions.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_punkbuster" ) ); - - ServerOptions_Cache(); - - s_serveroptions.menu.wrapAround = qtrue; - s_serveroptions.menu.fullscreen = qtrue; - - s_serveroptions.banner.generic.type = MTYPE_BTEXT; - s_serveroptions.banner.generic.x = 320; - s_serveroptions.banner.generic.y = 16; - s_serveroptions.banner.string = "GAME SERVER"; - s_serveroptions.banner.color = color_white; - s_serveroptions.banner.style = UI_CENTER; - - s_serveroptions.mappic.generic.type = MTYPE_BITMAP; - s_serveroptions.mappic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - s_serveroptions.mappic.generic.x = 352; - s_serveroptions.mappic.generic.y = 80; - s_serveroptions.mappic.width = 160; - s_serveroptions.mappic.height = 120; - s_serveroptions.mappic.errorpic = GAMESERVER_UNKNOWNMAP; - s_serveroptions.mappic.generic.ownerdraw = ServerOptions_LevelshotDraw; - - s_serveroptions.picframe.generic.type = MTYPE_BITMAP; - s_serveroptions.picframe.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE|QMF_HIGHLIGHT; - s_serveroptions.picframe.generic.x = 352 - 38; - s_serveroptions.picframe.generic.y = 80 - 40; - s_serveroptions.picframe.width = 320; - s_serveroptions.picframe.height = 320; - s_serveroptions.picframe.focuspic = GAMESERVER_SELECT; - - y = 272; - if( s_serveroptions.gametype != GT_CTF ) { - s_serveroptions.fraglimit.generic.type = MTYPE_FIELD; - s_serveroptions.fraglimit.generic.name = "Frag Limit:"; - s_serveroptions.fraglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.fraglimit.generic.x = OPTIONS_X; - s_serveroptions.fraglimit.generic.y = y; - s_serveroptions.fraglimit.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.fraglimit.field.widthInChars = 3; - s_serveroptions.fraglimit.field.maxchars = 3; - } - else { - s_serveroptions.flaglimit.generic.type = MTYPE_FIELD; - s_serveroptions.flaglimit.generic.name = "Capture Limit:"; - s_serveroptions.flaglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.flaglimit.generic.x = OPTIONS_X; - s_serveroptions.flaglimit.generic.y = y; - s_serveroptions.flaglimit.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.flaglimit.field.widthInChars = 3; - s_serveroptions.flaglimit.field.maxchars = 3; - } - - y += BIGCHAR_HEIGHT+2; - s_serveroptions.timelimit.generic.type = MTYPE_FIELD; - s_serveroptions.timelimit.generic.name = "Time Limit:"; - s_serveroptions.timelimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.timelimit.generic.x = OPTIONS_X; - s_serveroptions.timelimit.generic.y = y; - s_serveroptions.timelimit.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.timelimit.field.widthInChars = 3; - s_serveroptions.timelimit.field.maxchars = 3; - - if( s_serveroptions.gametype >= GT_TEAM ) { - y += BIGCHAR_HEIGHT+2; - s_serveroptions.friendlyfire.generic.type = MTYPE_RADIOBUTTON; - s_serveroptions.friendlyfire.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.friendlyfire.generic.x = OPTIONS_X; - s_serveroptions.friendlyfire.generic.y = y; - s_serveroptions.friendlyfire.generic.name = "Friendly Fire:"; - } - - y += BIGCHAR_HEIGHT+2; - s_serveroptions.pure.generic.type = MTYPE_RADIOBUTTON; - s_serveroptions.pure.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.pure.generic.x = OPTIONS_X; - s_serveroptions.pure.generic.y = y; - s_serveroptions.pure.generic.name = "Pure Server:"; - - if( s_serveroptions.multiplayer ) { - y += BIGCHAR_HEIGHT+2; - s_serveroptions.dedicated.generic.type = MTYPE_SPINCONTROL; - s_serveroptions.dedicated.generic.id = ID_DEDICATED; - s_serveroptions.dedicated.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.dedicated.generic.callback = ServerOptions_Event; - s_serveroptions.dedicated.generic.x = OPTIONS_X; - s_serveroptions.dedicated.generic.y = y; - s_serveroptions.dedicated.generic.name = "Dedicated:"; - s_serveroptions.dedicated.itemnames = dedicated_list; - } - - if( s_serveroptions.multiplayer ) { - y += BIGCHAR_HEIGHT+2; - s_serveroptions.hostname.generic.type = MTYPE_FIELD; - s_serveroptions.hostname.generic.name = "Hostname:"; - s_serveroptions.hostname.generic.flags = QMF_SMALLFONT; - s_serveroptions.hostname.generic.x = OPTIONS_X; - s_serveroptions.hostname.generic.y = y; - s_serveroptions.hostname.field.widthInChars = 18; - s_serveroptions.hostname.field.maxchars = 64; - } - - y += BIGCHAR_HEIGHT+2; - s_serveroptions.punkbuster.generic.type = MTYPE_SPINCONTROL; - s_serveroptions.punkbuster.generic.name = "Punkbuster:"; - s_serveroptions.punkbuster.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.punkbuster.generic.id = 0; - s_serveroptions.punkbuster.generic.x = OPTIONS_X; - s_serveroptions.punkbuster.generic.y = y; - s_serveroptions.punkbuster.itemnames = punkbuster_items; - - y = 80; - s_serveroptions.botSkill.generic.type = MTYPE_SPINCONTROL; - s_serveroptions.botSkill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_serveroptions.botSkill.generic.name = "Bot Skill: "; - s_serveroptions.botSkill.generic.x = 32 + (strlen(s_serveroptions.botSkill.generic.name) + 2 ) * SMALLCHAR_WIDTH; - s_serveroptions.botSkill.generic.y = y; - s_serveroptions.botSkill.itemnames = botSkill_list; - s_serveroptions.botSkill.curvalue = 1; - - y += ( 2 * SMALLCHAR_HEIGHT ); - s_serveroptions.player0.generic.type = MTYPE_TEXT; - s_serveroptions.player0.generic.flags = QMF_SMALLFONT; - s_serveroptions.player0.generic.x = 32 + SMALLCHAR_WIDTH; - s_serveroptions.player0.generic.y = y; - s_serveroptions.player0.color = color_orange; - s_serveroptions.player0.style = UI_LEFT|UI_SMALLFONT; - - for( n = 0; n < PLAYER_SLOTS; n++ ) { - s_serveroptions.playerType[n].generic.type = MTYPE_SPINCONTROL; - s_serveroptions.playerType[n].generic.flags = QMF_SMALLFONT; - s_serveroptions.playerType[n].generic.id = ID_PLAYER_TYPE; - s_serveroptions.playerType[n].generic.callback = ServerOptions_Event; - s_serveroptions.playerType[n].generic.x = 32; - s_serveroptions.playerType[n].generic.y = y; - s_serveroptions.playerType[n].itemnames = playerType_list; - - s_serveroptions.playerName[n].generic.type = MTYPE_TEXT; - s_serveroptions.playerName[n].generic.flags = QMF_SMALLFONT; - s_serveroptions.playerName[n].generic.x = 96; - s_serveroptions.playerName[n].generic.y = y; - s_serveroptions.playerName[n].generic.callback = ServerOptions_PlayerNameEvent; - s_serveroptions.playerName[n].generic.id = n; - s_serveroptions.playerName[n].generic.ownerdraw = PlayerName_Draw; - s_serveroptions.playerName[n].color = color_orange; - s_serveroptions.playerName[n].style = UI_SMALLFONT; - s_serveroptions.playerName[n].string = s_serveroptions.playerNameBuffers[n]; - s_serveroptions.playerName[n].generic.top = s_serveroptions.playerName[n].generic.y; - s_serveroptions.playerName[n].generic.bottom = s_serveroptions.playerName[n].generic.y + SMALLCHAR_HEIGHT; - s_serveroptions.playerName[n].generic.left = s_serveroptions.playerName[n].generic.x - SMALLCHAR_HEIGHT/ 2; - s_serveroptions.playerName[n].generic.right = s_serveroptions.playerName[n].generic.x + 16 * SMALLCHAR_WIDTH; - - s_serveroptions.playerTeam[n].generic.type = MTYPE_SPINCONTROL; - s_serveroptions.playerTeam[n].generic.flags = QMF_SMALLFONT; - s_serveroptions.playerTeam[n].generic.x = 240; - s_serveroptions.playerTeam[n].generic.y = y; - s_serveroptions.playerTeam[n].itemnames = playerTeam_list; - - y += ( SMALLCHAR_HEIGHT + 4 ); - } - - s_serveroptions.back.generic.type = MTYPE_BITMAP; - s_serveroptions.back.generic.name = GAMESERVER_BACK0; - s_serveroptions.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_serveroptions.back.generic.callback = ServerOptions_Event; - s_serveroptions.back.generic.id = ID_BACK; - s_serveroptions.back.generic.x = 0; - s_serveroptions.back.generic.y = 480-64; - s_serveroptions.back.width = 128; - s_serveroptions.back.height = 64; - s_serveroptions.back.focuspic = GAMESERVER_BACK1; - - s_serveroptions.next.generic.type = MTYPE_BITMAP; - s_serveroptions.next.generic.name = GAMESERVER_NEXT0; - s_serveroptions.next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE|QMF_GRAYED|QMF_HIDDEN; - s_serveroptions.next.generic.callback = ServerOptions_Event; - s_serveroptions.next.generic.id = ID_STARTSERVERNEXT; - s_serveroptions.next.generic.x = 640; - s_serveroptions.next.generic.y = 480-64-72; - s_serveroptions.next.generic.statusbar = ServerOptions_StatusBar; - s_serveroptions.next.width = 128; - s_serveroptions.next.height = 64; - s_serveroptions.next.focuspic = GAMESERVER_NEXT1; - - s_serveroptions.go.generic.type = MTYPE_BITMAP; - s_serveroptions.go.generic.name = GAMESERVER_FIGHT0; - s_serveroptions.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_serveroptions.go.generic.callback = ServerOptions_Event; - s_serveroptions.go.generic.id = ID_GO; - s_serveroptions.go.generic.x = 640; - s_serveroptions.go.generic.y = 480-64; - s_serveroptions.go.width = 128; - s_serveroptions.go.height = 64; - s_serveroptions.go.focuspic = GAMESERVER_FIGHT1; - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.banner ); - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.mappic ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.picframe ); - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.botSkill ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.player0 ); - for( n = 0; n < PLAYER_SLOTS; n++ ) { - if( n != 0 ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerType[n] ); - } - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerName[n] ); - if( s_serveroptions.gametype >= GT_TEAM ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerTeam[n] ); - } - } - - if( s_serveroptions.gametype != GT_CTF ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.fraglimit ); - } - else { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.flaglimit ); - } - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.timelimit ); - if( s_serveroptions.gametype >= GT_TEAM ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.friendlyfire ); - } - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.pure ); - if( s_serveroptions.multiplayer ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.dedicated ); - } - if( s_serveroptions.multiplayer ) { - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.hostname ); - } - - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.back ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.next ); - Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.go ); - - Menu_AddItem( &s_serveroptions.menu, (void*) &s_serveroptions.punkbuster ); - - ServerOptions_SetMenuItems(); -} - -/* -================= -ServerOptions_Cache -================= -*/ -void ServerOptions_Cache( void ) { - trap_R_RegisterShaderNoMip( GAMESERVER_BACK0 ); - trap_R_RegisterShaderNoMip( GAMESERVER_BACK1 ); - trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT0 ); - trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT1 ); - trap_R_RegisterShaderNoMip( GAMESERVER_SELECT ); - trap_R_RegisterShaderNoMip( GAMESERVER_UNKNOWNMAP ); -} - - -/* -================= -UI_ServerOptionsMenu -================= -*/ -static void UI_ServerOptionsMenu( qboolean multiplayer ) { - ServerOptions_MenuInit( multiplayer ); - UI_PushMenu( &s_serveroptions.menu ); -} - - - -/* -============================================================================= - -BOT SELECT MENU ***** - -============================================================================= -*/ - - -#define BOTSELECT_BACK0 "menu/art/back_0" -#define BOTSELECT_BACK1 "menu/art/back_1" -#define BOTSELECT_ACCEPT0 "menu/art/accept_0" -#define BOTSELECT_ACCEPT1 "menu/art/accept_1" -#define BOTSELECT_SELECT "menu/art/opponents_select" -#define BOTSELECT_SELECTED "menu/art/opponents_selected" -#define BOTSELECT_ARROWS "menu/art/gs_arrows_0" -#define BOTSELECT_ARROWSL "menu/art/gs_arrows_l" -#define BOTSELECT_ARROWSR "menu/art/gs_arrows_r" - -#define PLAYERGRID_COLS 4 -#define PLAYERGRID_ROWS 4 -#define MAX_MODELSPERPAGE (PLAYERGRID_ROWS * PLAYERGRID_COLS) - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - - menubitmap_s pics[MAX_MODELSPERPAGE]; - menubitmap_s picbuttons[MAX_MODELSPERPAGE]; - menutext_s picnames[MAX_MODELSPERPAGE]; - - menubitmap_s arrows; - menubitmap_s left; - menubitmap_s right; - - menubitmap_s go; - menubitmap_s back; - - int numBots; - int modelpage; - int numpages; - int selectedmodel; - int sortedBotNums[MAX_BOTS]; - char boticons[MAX_MODELSPERPAGE][MAX_QPATH]; - char botnames[MAX_MODELSPERPAGE][16]; -} botSelectInfo_t; - -static botSelectInfo_t botSelectInfo; - - -/* -================= -UI_BotSelectMenu_SortCompare -================= -*/ -static int QDECL UI_BotSelectMenu_SortCompare( const void *arg1, const void *arg2 ) { - int num1, num2; - const char *info1, *info2; - const char *name1, *name2; - - num1 = *(int *)arg1; - num2 = *(int *)arg2; - - info1 = UI_GetBotInfoByNumber( num1 ); - info2 = UI_GetBotInfoByNumber( num2 ); - - name1 = Info_ValueForKey( info1, "name" ); - name2 = Info_ValueForKey( info2, "name" ); - - return Q_stricmp( name1, name2 ); -} - - -/* -================= -UI_BotSelectMenu_BuildList -================= -*/ -static void UI_BotSelectMenu_BuildList( void ) { - int n; - - botSelectInfo.modelpage = 0; - botSelectInfo.numBots = UI_GetNumBots(); - botSelectInfo.numpages = botSelectInfo.numBots / MAX_MODELSPERPAGE; - if( botSelectInfo.numBots % MAX_MODELSPERPAGE ) { - botSelectInfo.numpages++; - } - - // initialize the array - for( n = 0; n < botSelectInfo.numBots; n++ ) { - botSelectInfo.sortedBotNums[n] = n; - } - - // now sort it - qsort( botSelectInfo.sortedBotNums, botSelectInfo.numBots, sizeof(botSelectInfo.sortedBotNums[0]), UI_BotSelectMenu_SortCompare ); -} - - -/* -================= -ServerPlayerIcon -================= -*/ -static void ServerPlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) { - char *skin; - char model[MAX_QPATH]; - - Q_strncpyz( model, modelAndSkin, sizeof(model)); - skin = Q_strrchr( model, '/' ); - if ( skin ) { - *skin++ = '\0'; - } - else { - skin = "default"; - } - - Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin ); - - if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) { - Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model ); - } -} - - -/* -================= -UI_BotSelectMenu_UpdateGrid -================= -*/ -static void UI_BotSelectMenu_UpdateGrid( void ) { - const char *info; - int i; - int j; - - j = botSelectInfo.modelpage * MAX_MODELSPERPAGE; - for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++, j++) { - if( j < botSelectInfo.numBots ) { - info = UI_GetBotInfoByNumber( botSelectInfo.sortedBotNums[j] ); - ServerPlayerIcon( Info_ValueForKey( info, "model" ), botSelectInfo.boticons[i], MAX_QPATH ); - Q_strncpyz( botSelectInfo.botnames[i], Info_ValueForKey( info, "name" ), 16 ); - Q_CleanStr( botSelectInfo.botnames[i] ); - botSelectInfo.pics[i].generic.name = botSelectInfo.boticons[i]; - if( BotAlreadySelected( botSelectInfo.botnames[i] ) ) { - botSelectInfo.picnames[i].color = color_red; - } - else { - botSelectInfo.picnames[i].color = color_orange; - } - botSelectInfo.picbuttons[i].generic.flags &= ~QMF_INACTIVE; - } - else { - // dead slot - botSelectInfo.pics[i].generic.name = NULL; - botSelectInfo.picbuttons[i].generic.flags |= QMF_INACTIVE; - botSelectInfo.botnames[i][0] = 0; - } - - botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; - botSelectInfo.pics[i].shader = 0; - botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; - } - - // set selected model - i = botSelectInfo.selectedmodel % MAX_MODELSPERPAGE; - botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; - botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; - - if( botSelectInfo.numpages > 1 ) { - if( botSelectInfo.modelpage > 0 ) { - botSelectInfo.left.generic.flags &= ~QMF_INACTIVE; - } - else { - botSelectInfo.left.generic.flags |= QMF_INACTIVE; - } - - if( botSelectInfo.modelpage < (botSelectInfo.numpages - 1) ) { - botSelectInfo.right.generic.flags &= ~QMF_INACTIVE; - } - else { - botSelectInfo.right.generic.flags |= QMF_INACTIVE; - } - } - else { - // hide left/right markers - botSelectInfo.left.generic.flags |= QMF_INACTIVE; - botSelectInfo.right.generic.flags |= QMF_INACTIVE; - } -} - - -/* -================= -UI_BotSelectMenu_Default -================= -*/ -static void UI_BotSelectMenu_Default( char *bot ) { - const char *botInfo; - const char *test; - int n; - int i; - - for( n = 0; n < botSelectInfo.numBots; n++ ) { - botInfo = UI_GetBotInfoByNumber( n ); - test = Info_ValueForKey( botInfo, "name" ); - if( Q_stricmp( bot, test ) == 0 ) { - break; - } - } - if( n == botSelectInfo.numBots ) { - botSelectInfo.selectedmodel = 0; - return; - } - - for( i = 0; i < botSelectInfo.numBots; i++ ) { - if( botSelectInfo.sortedBotNums[i] == n ) { - break; - } - } - if( i == botSelectInfo.numBots ) { - botSelectInfo.selectedmodel = 0; - return; - } - - botSelectInfo.selectedmodel = i; -} - - -/* -================= -UI_BotSelectMenu_LeftEvent -================= -*/ -static void UI_BotSelectMenu_LeftEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - if( botSelectInfo.modelpage > 0 ) { - botSelectInfo.modelpage--; - botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; - UI_BotSelectMenu_UpdateGrid(); - } -} - - -/* -================= -UI_BotSelectMenu_RightEvent -================= -*/ -static void UI_BotSelectMenu_RightEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - if( botSelectInfo.modelpage < botSelectInfo.numpages - 1 ) { - botSelectInfo.modelpage++; - botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; - UI_BotSelectMenu_UpdateGrid(); - } -} - - -/* -================= -UI_BotSelectMenu_BotEvent -================= -*/ -static void UI_BotSelectMenu_BotEvent( void* ptr, int event ) { - int i; - - if( event != QM_ACTIVATED ) { - return; - } - - for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++ ) { - botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; - botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; - } - - // set selected - i = ((menucommon_s*)ptr)->id; - botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; - botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; - botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE + i; -} - - -/* -================= -UI_BotSelectMenu_BackEvent -================= -*/ -static void UI_BotSelectMenu_BackEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - UI_PopMenu(); -} - - -/* -================= -UI_BotSelectMenu_SelectEvent -================= -*/ -static void UI_BotSelectMenu_SelectEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - UI_PopMenu(); - - s_serveroptions.newBot = qtrue; - Q_strncpyz( s_serveroptions.newBotName, botSelectInfo.botnames[botSelectInfo.selectedmodel % MAX_MODELSPERPAGE], 16 ); -} - - -/* -================= -UI_BotSelectMenu_Cache -================= -*/ -void UI_BotSelectMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( BOTSELECT_BACK0 ); - trap_R_RegisterShaderNoMip( BOTSELECT_BACK1 ); - trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT0 ); - trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT1 ); - trap_R_RegisterShaderNoMip( BOTSELECT_SELECT ); - trap_R_RegisterShaderNoMip( BOTSELECT_SELECTED ); - trap_R_RegisterShaderNoMip( BOTSELECT_ARROWS ); - trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSL ); - trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSR ); -} - - -static void UI_BotSelectMenu_Init( char *bot ) { - int i, j, k; - int x, y; - - memset( &botSelectInfo, 0 ,sizeof(botSelectInfo) ); - botSelectInfo.menu.wrapAround = qtrue; - botSelectInfo.menu.fullscreen = qtrue; - - UI_BotSelectMenu_Cache(); - - botSelectInfo.banner.generic.type = MTYPE_BTEXT; - botSelectInfo.banner.generic.x = 320; - botSelectInfo.banner.generic.y = 16; - botSelectInfo.banner.string = "SELECT BOT"; - botSelectInfo.banner.color = color_white; - botSelectInfo.banner.style = UI_CENTER; - - y = 80; - for( i = 0, k = 0; i < PLAYERGRID_ROWS; i++) { - x = 180; - for( j = 0; j < PLAYERGRID_COLS; j++, k++ ) { - botSelectInfo.pics[k].generic.type = MTYPE_BITMAP; - botSelectInfo.pics[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; - botSelectInfo.pics[k].generic.x = x; - botSelectInfo.pics[k].generic.y = y; - botSelectInfo.pics[k].generic.name = botSelectInfo.boticons[k]; - botSelectInfo.pics[k].width = 64; - botSelectInfo.pics[k].height = 64; - botSelectInfo.pics[k].focuspic = BOTSELECT_SELECTED; - botSelectInfo.pics[k].focuscolor = colorRed; - - botSelectInfo.picbuttons[k].generic.type = MTYPE_BITMAP; - botSelectInfo.picbuttons[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_NODEFAULTINIT|QMF_PULSEIFFOCUS; - botSelectInfo.picbuttons[k].generic.callback = UI_BotSelectMenu_BotEvent; - botSelectInfo.picbuttons[k].generic.id = k; - botSelectInfo.picbuttons[k].generic.x = x - 16; - botSelectInfo.picbuttons[k].generic.y = y - 16; - botSelectInfo.picbuttons[k].generic.left = x; - botSelectInfo.picbuttons[k].generic.top = y; - botSelectInfo.picbuttons[k].generic.right = x + 64; - botSelectInfo.picbuttons[k].generic.bottom = y + 64; - botSelectInfo.picbuttons[k].width = 128; - botSelectInfo.picbuttons[k].height = 128; - botSelectInfo.picbuttons[k].focuspic = BOTSELECT_SELECT; - botSelectInfo.picbuttons[k].focuscolor = colorRed; - - botSelectInfo.picnames[k].generic.type = MTYPE_TEXT; - botSelectInfo.picnames[k].generic.flags = QMF_SMALLFONT; - botSelectInfo.picnames[k].generic.x = x + 32; - botSelectInfo.picnames[k].generic.y = y + 64; - botSelectInfo.picnames[k].string = botSelectInfo.botnames[k]; - botSelectInfo.picnames[k].color = color_orange; - botSelectInfo.picnames[k].style = UI_CENTER|UI_SMALLFONT; - - x += (64 + 6); - } - y += (64 + SMALLCHAR_HEIGHT + 6); - } - - botSelectInfo.arrows.generic.type = MTYPE_BITMAP; - botSelectInfo.arrows.generic.name = BOTSELECT_ARROWS; - botSelectInfo.arrows.generic.flags = QMF_INACTIVE; - botSelectInfo.arrows.generic.x = 260; - botSelectInfo.arrows.generic.y = 440; - botSelectInfo.arrows.width = 128; - botSelectInfo.arrows.height = 32; - - botSelectInfo.left.generic.type = MTYPE_BITMAP; - botSelectInfo.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.left.generic.callback = UI_BotSelectMenu_LeftEvent; - botSelectInfo.left.generic.x = 260; - botSelectInfo.left.generic.y = 440; - botSelectInfo.left.width = 64; - botSelectInfo.left.height = 32; - botSelectInfo.left.focuspic = BOTSELECT_ARROWSL; - - botSelectInfo.right.generic.type = MTYPE_BITMAP; - botSelectInfo.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.right.generic.callback = UI_BotSelectMenu_RightEvent; - botSelectInfo.right.generic.x = 321; - botSelectInfo.right.generic.y = 440; - botSelectInfo.right.width = 64; - botSelectInfo.right.height = 32; - botSelectInfo.right.focuspic = BOTSELECT_ARROWSR; - - botSelectInfo.back.generic.type = MTYPE_BITMAP; - botSelectInfo.back.generic.name = BOTSELECT_BACK0; - botSelectInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.back.generic.callback = UI_BotSelectMenu_BackEvent; - botSelectInfo.back.generic.x = 0; - botSelectInfo.back.generic.y = 480-64; - botSelectInfo.back.width = 128; - botSelectInfo.back.height = 64; - botSelectInfo.back.focuspic = BOTSELECT_BACK1; - - botSelectInfo.go.generic.type = MTYPE_BITMAP; - botSelectInfo.go.generic.name = BOTSELECT_ACCEPT0; - botSelectInfo.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - botSelectInfo.go.generic.callback = UI_BotSelectMenu_SelectEvent; - botSelectInfo.go.generic.x = 640; - botSelectInfo.go.generic.y = 480-64; - botSelectInfo.go.width = 128; - botSelectInfo.go.height = 64; - botSelectInfo.go.focuspic = BOTSELECT_ACCEPT1; - - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.banner ); - for( i = 0; i < MAX_MODELSPERPAGE; i++ ) { - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.pics[i] ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picbuttons[i] ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picnames[i] ); - } - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.arrows ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.left ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.right ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.back ); - Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.go ); - - UI_BotSelectMenu_BuildList(); - UI_BotSelectMenu_Default( bot ); - botSelectInfo.modelpage = botSelectInfo.selectedmodel / MAX_MODELSPERPAGE; - UI_BotSelectMenu_UpdateGrid(); -} - - -/* -================= -UI_BotSelectMenu -================= -*/ -void UI_BotSelectMenu( char *bot ) { - UI_BotSelectMenu_Init( bot ); - UI_PushMenu( &botSelectInfo.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +============================================================================= + +START SERVER MENU ***** + +============================================================================= +*/ + + +#include "ui_local.h" + + +#define GAMESERVER_BACK0 "menu/art/back_0" +#define GAMESERVER_BACK1 "menu/art/back_1" +#define GAMESERVER_NEXT0 "menu/art/next_0" +#define GAMESERVER_NEXT1 "menu/art/next_1" +#define GAMESERVER_FRAMEL "menu/art/frame2_l" +#define GAMESERVER_FRAMER "menu/art/frame1_r" +#define GAMESERVER_SELECT "menu/art/maps_select" +#define GAMESERVER_SELECTED "menu/art/maps_selected" +#define GAMESERVER_FIGHT0 "menu/art/fight_0" +#define GAMESERVER_FIGHT1 "menu/art/fight_1" +#define GAMESERVER_UNKNOWNMAP "menu/art/unknownmap" +#define GAMESERVER_ARROWS "menu/art/gs_arrows_0" +#define GAMESERVER_ARROWSL "menu/art/gs_arrows_l" +#define GAMESERVER_ARROWSR "menu/art/gs_arrows_r" + +#define MAX_MAPROWS 2 +#define MAX_MAPCOLS 2 +#define MAX_MAPSPERPAGE 4 + +#define MAX_SERVERSTEXT 8192 + +#define MAX_SERVERMAPS 64 +#define MAX_NAMELENGTH 16 + +#define ID_GAMETYPE 10 +#define ID_PICTURES 11 // 12, 13, 14 +#define ID_PREVPAGE 15 +#define ID_NEXTPAGE 16 +#define ID_STARTSERVERBACK 17 +#define ID_STARTSERVERNEXT 18 + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menulist_s gametype; + menubitmap_s mappics[MAX_MAPSPERPAGE]; + menubitmap_s mapbuttons[MAX_MAPSPERPAGE]; + menubitmap_s arrows; + menubitmap_s prevpage; + menubitmap_s nextpage; + menubitmap_s back; + menubitmap_s next; + + menutext_s mapname; + menubitmap_s item_null; + + qboolean multiplayer; + int currentmap; + int nummaps; + int page; + int maxpages; + char maplist[MAX_SERVERMAPS][MAX_NAMELENGTH]; + int mapGamebits[MAX_SERVERMAPS]; +} startserver_t; + +static startserver_t s_startserver; + +static const char *gametype_items[] = { + "Free For All", + "Team Deathmatch", + "Tournament", + "Capture the Flag", + 0 +}; + +static int gametype_remap[] = {GT_FFA, GT_TEAM, GT_TOURNAMENT, GT_CTF}; +static int gametype_remap2[] = {0, 2, 0, 1, 3}; + +// use ui_servers2.c definition +extern const char* punkbuster_items[]; + +static void UI_ServerOptionsMenu( qboolean multiplayer ); + + +/* +================= +GametypeBits +================= +*/ +static int GametypeBits( char *string ) { + int bits; + char *p; + char *token; + + bits = 0; + p = string; + while( 1 ) { + token = COM_ParseExt( &p, qfalse ); + if( token[0] == 0 ) { + break; + } + + if( Q_stricmp( token, "ffa" ) == 0 ) { + bits |= 1 << GT_FFA; + continue; + } + + if( Q_stricmp( token, "tourney" ) == 0 ) { + bits |= 1 << GT_TOURNAMENT; + continue; + } + + if( Q_stricmp( token, "single" ) == 0 ) { + bits |= 1 << GT_SINGLE_PLAYER; + continue; + } + + if( Q_stricmp( token, "team" ) == 0 ) { + bits |= 1 << GT_TEAM; + continue; + } + + if( Q_stricmp( token, "ctf" ) == 0 ) { + bits |= 1 << GT_CTF; + continue; + } + } + + return bits; +} + + +/* +================= +StartServer_Update +================= +*/ +static void StartServer_Update( void ) { + int i; + int top; + static char picname[MAX_MAPSPERPAGE][64]; + + top = s_startserver.page*MAX_MAPSPERPAGE; + + for (i=0; i= s_startserver.nummaps) + break; + + Com_sprintf( picname[i], sizeof(picname[i]), "levelshots/%s", s_startserver.maplist[top+i] ); + + s_startserver.mappics[i].generic.flags &= ~QMF_HIGHLIGHT; + s_startserver.mappics[i].generic.name = picname[i]; + s_startserver.mappics[i].shader = 0; + + // reset + s_startserver.mapbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; + s_startserver.mapbuttons[i].generic.flags &= ~QMF_INACTIVE; + } + + for (; i=0 && i < MAX_MAPSPERPAGE ) + { + s_startserver.mappics[i].generic.flags |= QMF_HIGHLIGHT; + s_startserver.mapbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; + } + + // set the map name + strcpy( s_startserver.mapname.string, s_startserver.maplist[s_startserver.currentmap] ); + } + + Q_strupr( s_startserver.mapname.string ); +} + + +/* +================= +StartServer_MapEvent +================= +*/ +static void StartServer_MapEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED) { + return; + } + + s_startserver.currentmap = (s_startserver.page*MAX_MAPSPERPAGE) + (((menucommon_s*)ptr)->id - ID_PICTURES); + StartServer_Update(); +} + + +/* +================= +StartServer_GametypeEvent +================= +*/ +static void StartServer_GametypeEvent( void* ptr, int event ) { + int i; + int count; + int gamebits; + int matchbits; + const char *info; + + if( event != QM_ACTIVATED) { + return; + } + + count = UI_GetNumArenas(); + s_startserver.nummaps = 0; + matchbits = 1 << gametype_remap[s_startserver.gametype.curvalue]; + if( gametype_remap[s_startserver.gametype.curvalue] == GT_FFA ) { + matchbits |= ( 1 << GT_SINGLE_PLAYER ); + } + for( i = 0; i < count; i++ ) { + info = UI_GetArenaInfoByNumber( i ); + + gamebits = GametypeBits( Info_ValueForKey( info, "type") ); + if( !( gamebits & matchbits ) ) { + continue; + } + + Q_strncpyz( s_startserver.maplist[s_startserver.nummaps], Info_ValueForKey( info, "map"), MAX_NAMELENGTH ); + Q_strupr( s_startserver.maplist[s_startserver.nummaps] ); + s_startserver.mapGamebits[s_startserver.nummaps] = gamebits; + s_startserver.nummaps++; + } + s_startserver.maxpages = (s_startserver.nummaps + MAX_MAPSPERPAGE-1)/MAX_MAPSPERPAGE; + s_startserver.page = 0; + s_startserver.currentmap = 0; + + StartServer_Update(); +} + + +/* +================= +StartServer_MenuEvent +================= +*/ +static void StartServer_MenuEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_PREVPAGE: + if( s_startserver.page > 0 ) { + s_startserver.page--; + StartServer_Update(); + } + break; + + case ID_NEXTPAGE: + if( s_startserver.page < s_startserver.maxpages - 1 ) { + s_startserver.page++; + StartServer_Update(); + } + break; + + case ID_STARTSERVERNEXT: + trap_Cvar_SetValue( "g_gameType", gametype_remap[s_startserver.gametype.curvalue] ); + UI_ServerOptionsMenu( s_startserver.multiplayer ); + break; + + case ID_STARTSERVERBACK: + UI_PopMenu(); + break; + } +} + + +/* +=============== +StartServer_LevelshotDraw +=============== +*/ +static void StartServer_LevelshotDraw( void *self ) { + menubitmap_s *b; + int x; + int y; + int w; + int h; + int n; + + b = (menubitmap_s *)self; + + if( !b->generic.name ) { + return; + } + + if( b->generic.name && !b->shader ) { + b->shader = trap_R_RegisterShaderNoMip( b->generic.name ); + if( !b->shader && b->errorpic ) { + b->shader = trap_R_RegisterShaderNoMip( b->errorpic ); + } + } + + if( b->focuspic && !b->focusshader ) { + b->focusshader = trap_R_RegisterShaderNoMip( b->focuspic ); + } + + x = b->generic.x; + y = b->generic.y; + w = b->width; + h = b->height; + if( b->shader ) { + UI_DrawHandlePic( x, y, w, h, b->shader ); + } + + x = b->generic.x; + y = b->generic.y + b->height; + UI_FillRect( x, y, b->width, 28, colorBlack ); + + x += b->width / 2; + y += 4; + n = s_startserver.page * MAX_MAPSPERPAGE + b->generic.id - ID_PICTURES; + UI_DrawString( x, y, s_startserver.maplist[n], UI_CENTER|UI_SMALLFONT, color_orange ); + + x = b->generic.x; + y = b->generic.y; + w = b->width; + h = b->height + 28; + if( b->generic.flags & QMF_HIGHLIGHT ) { + UI_DrawHandlePic( x, y, w, h, b->focusshader ); + } +} + + +/* +================= +StartServer_MenuInit +================= +*/ +static void StartServer_MenuInit( void ) { + int i; + int x; + int y; + static char mapnamebuffer[64]; + + // zero set all our globals + memset( &s_startserver, 0 ,sizeof(startserver_t) ); + + StartServer_Cache(); + + s_startserver.menu.wrapAround = qtrue; + s_startserver.menu.fullscreen = qtrue; + + s_startserver.banner.generic.type = MTYPE_BTEXT; + s_startserver.banner.generic.x = 320; + s_startserver.banner.generic.y = 16; + s_startserver.banner.string = "GAME SERVER"; + s_startserver.banner.color = color_white; + s_startserver.banner.style = UI_CENTER; + + s_startserver.framel.generic.type = MTYPE_BITMAP; + s_startserver.framel.generic.name = GAMESERVER_FRAMEL; + s_startserver.framel.generic.flags = QMF_INACTIVE; + s_startserver.framel.generic.x = 0; + s_startserver.framel.generic.y = 78; + s_startserver.framel.width = 256; + s_startserver.framel.height = 329; + + s_startserver.framer.generic.type = MTYPE_BITMAP; + s_startserver.framer.generic.name = GAMESERVER_FRAMER; + s_startserver.framer.generic.flags = QMF_INACTIVE; + s_startserver.framer.generic.x = 376; + s_startserver.framer.generic.y = 76; + s_startserver.framer.width = 256; + s_startserver.framer.height = 334; + + s_startserver.gametype.generic.type = MTYPE_SPINCONTROL; + s_startserver.gametype.generic.name = "Game Type:"; + s_startserver.gametype.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_startserver.gametype.generic.callback = StartServer_GametypeEvent; + s_startserver.gametype.generic.id = ID_GAMETYPE; + s_startserver.gametype.generic.x = 320 - 24; + s_startserver.gametype.generic.y = 368; + s_startserver.gametype.itemnames = gametype_items; + + for (i=0; i= GT_TEAM) && + (s_serveroptions.playerTeam[n].curvalue != s_serveroptions.playerTeam[s_serveroptions.newBotIndex].curvalue ) ) { + continue; + } + if( Q_stricmp( checkName, s_serveroptions.playerNameBuffers[n] ) == 0 ) { + return qtrue; + } + } + + return qfalse; +} + + +/* +================= +ServerOptions_Start +================= +*/ +static void ServerOptions_Start( void ) { + int timelimit; + int fraglimit; + int maxclients; + int dedicated; + int friendlyfire; + int flaglimit; + int pure; + int skill; + int n; + char buf[64]; + + + timelimit = atoi( s_serveroptions.timelimit.field.buffer ); + fraglimit = atoi( s_serveroptions.fraglimit.field.buffer ); + flaglimit = atoi( s_serveroptions.flaglimit.field.buffer ); + dedicated = s_serveroptions.dedicated.curvalue; + friendlyfire = s_serveroptions.friendlyfire.curvalue; + pure = s_serveroptions.pure.curvalue; + skill = s_serveroptions.botSkill.curvalue + 1; + + //set maxclients + for( n = 0, maxclients = 0; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue == 2 ) { + continue; + } + if( (s_serveroptions.playerType[n].curvalue == 1) && (s_serveroptions.playerNameBuffers[n][0] == 0) ) { + continue; + } + maxclients++; + } + + switch( s_serveroptions.gametype ) { + case GT_FFA: + default: + trap_Cvar_SetValue( "ui_ffa_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_ffa_timelimit", timelimit ); + break; + + case GT_TOURNAMENT: + trap_Cvar_SetValue( "ui_tourney_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_tourney_timelimit", timelimit ); + break; + + case GT_TEAM: + trap_Cvar_SetValue( "ui_team_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_team_timelimit", timelimit ); + trap_Cvar_SetValue( "ui_team_friendlt", friendlyfire ); + break; + + case GT_CTF: + trap_Cvar_SetValue( "ui_ctf_fraglimit", fraglimit ); + trap_Cvar_SetValue( "ui_ctf_timelimit", timelimit ); + trap_Cvar_SetValue( "ui_ctf_friendlt", friendlyfire ); + break; + } + + trap_Cvar_SetValue( "sv_maxclients", Com_Clamp( 0, 12, maxclients ) ); + trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, dedicated ) ); + trap_Cvar_SetValue ("timelimit", Com_Clamp( 0, timelimit, timelimit ) ); + trap_Cvar_SetValue ("fraglimit", Com_Clamp( 0, fraglimit, fraglimit ) ); + trap_Cvar_SetValue ("capturelimit", Com_Clamp( 0, flaglimit, flaglimit ) ); + trap_Cvar_SetValue( "g_friendlyfire", friendlyfire ); + trap_Cvar_SetValue( "sv_pure", pure ); + trap_Cvar_Set("sv_hostname", s_serveroptions.hostname.field.buffer ); + + trap_Cvar_SetValue( "sv_punkbuster", s_serveroptions.punkbuster.curvalue ); + + // the wait commands will allow the dedicated to take effect + trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", s_startserver.maplist[s_startserver.currentmap] ) ); + + // add bots + trap_Cmd_ExecuteText( EXEC_APPEND, "wait 3\n" ); + for( n = 1; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue != 1 ) { + continue; + } + if( s_serveroptions.playerNameBuffers[n][0] == 0 ) { + continue; + } + if( s_serveroptions.playerNameBuffers[n][0] == '-' ) { + continue; + } + if( s_serveroptions.gametype >= GT_TEAM ) { + Com_sprintf( buf, sizeof(buf), "addbot %s %i %s\n", s_serveroptions.playerNameBuffers[n], skill, + playerTeam_list[s_serveroptions.playerTeam[n].curvalue] ); + } + else { + Com_sprintf( buf, sizeof(buf), "addbot %s %i\n", s_serveroptions.playerNameBuffers[n], skill ); + } + trap_Cmd_ExecuteText( EXEC_APPEND, buf ); + } + + // set player's team + if( dedicated == 0 && s_serveroptions.gametype >= GT_TEAM ) { + trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait 5; team %s\n", playerTeam_list[s_serveroptions.playerTeam[0].curvalue] ) ); + } +} + + +/* +================= +ServerOptions_InitPlayerItems +================= +*/ +static void ServerOptions_InitPlayerItems( void ) { + int n; + int v; + + // init types + if( s_serveroptions.multiplayer ) { + v = 0; // open + } + else { + v = 1; // bot + } + + for( n = 0; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerType[n].curvalue = v; + } + + if( s_serveroptions.multiplayer && (s_serveroptions.gametype < GT_TEAM) ) { + for( n = 8; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerType[n].curvalue = 2; + } + } + + // if not a dedicated server, first slot is reserved for the human on the server + if( s_serveroptions.dedicated.curvalue == 0 ) { + // human + s_serveroptions.playerType[0].generic.flags |= QMF_INACTIVE; + s_serveroptions.playerType[0].curvalue = 0; + trap_Cvar_VariableStringBuffer( "name", s_serveroptions.playerNameBuffers[0], sizeof(s_serveroptions.playerNameBuffers[0]) ); + Q_CleanStr( s_serveroptions.playerNameBuffers[0] ); + } + + // init teams + if( s_serveroptions.gametype >= GT_TEAM ) { + for( n = 0; n < (PLAYER_SLOTS / 2); n++ ) { + s_serveroptions.playerTeam[n].curvalue = 0; + } + for( ; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerTeam[n].curvalue = 1; + } + } + else { + for( n = 0; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + } +} + + +/* +================= +ServerOptions_SetPlayerItems +================= +*/ +static void ServerOptions_SetPlayerItems( void ) { + int start; + int n; + + // types +// for( n = 0; n < PLAYER_SLOTS; n++ ) { +// if( (!s_serveroptions.multiplayer) && (n > 0) && (s_serveroptions.playerType[n].curvalue == 0) ) { +// s_serveroptions.playerType[n].curvalue = 1; +// } +// } + + // names + if( s_serveroptions.dedicated.curvalue == 0 ) { + s_serveroptions.player0.string = "Human"; + s_serveroptions.playerName[0].generic.flags &= ~QMF_HIDDEN; + + start = 1; + } + else { + s_serveroptions.player0.string = "Open"; + start = 0; + } + for( n = start; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue == 1 ) { + s_serveroptions.playerName[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); + } + else { + s_serveroptions.playerName[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + } + + // teams + if( s_serveroptions.gametype < GT_TEAM ) { + return; + } + for( n = start; n < PLAYER_SLOTS; n++ ) { + if( s_serveroptions.playerType[n].curvalue == 2 ) { + s_serveroptions.playerTeam[n].generic.flags |= (QMF_INACTIVE|QMF_HIDDEN); + } + else { + s_serveroptions.playerTeam[n].generic.flags &= ~(QMF_INACTIVE|QMF_HIDDEN); + } + } +} + + +/* +================= +ServerOptions_Event +================= +*/ +static void ServerOptions_Event( void* ptr, int event ) { + switch( ((menucommon_s*)ptr)->id ) { + + //if( event != QM_ACTIVATED && event != QM_LOSTFOCUS) { + // return; + //} + case ID_PLAYER_TYPE: + if( event != QM_ACTIVATED ) { + break; + } + ServerOptions_SetPlayerItems(); + break; + + case ID_MAXCLIENTS: + case ID_DEDICATED: + ServerOptions_SetPlayerItems(); + break; + case ID_GO: + if( event != QM_ACTIVATED ) { + break; + } + ServerOptions_Start(); + break; + + case ID_STARTSERVERNEXT: + if( event != QM_ACTIVATED ) { + break; + } + break; + case ID_BACK: + if( event != QM_ACTIVATED ) { + break; + } + UI_PopMenu(); + break; + } +} + + +static void ServerOptions_PlayerNameEvent( void* ptr, int event ) { + int n; + + if( event != QM_ACTIVATED ) { + return; + } + n = ((menutext_s*)ptr)->generic.id; + s_serveroptions.newBotIndex = n; + UI_BotSelectMenu( s_serveroptions.playerNameBuffers[n] ); +} + + +/* +================= +ServerOptions_StatusBar +================= +*/ +static void ServerOptions_StatusBar( void* ptr ) { + switch( ((menucommon_s*)ptr)->id ) { + default: + UI_DrawString( 320, 440, "0 = NO LIMIT", UI_CENTER|UI_SMALLFONT, colorWhite ); + break; + } +} + + +/* +=============== +ServerOptions_LevelshotDraw +=============== +*/ +static void ServerOptions_LevelshotDraw( void *self ) { + menubitmap_s *b; + int x; + int y; + + // strange place for this, but it works + if( s_serveroptions.newBot ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[s_serveroptions.newBotIndex], s_serveroptions.newBotName, 16 ); + s_serveroptions.newBot = qfalse; + } + + b = (menubitmap_s *)self; + + Bitmap_Draw( b ); + + x = b->generic.x; + y = b->generic.y + b->height; + UI_FillRect( x, y, b->width, 40, colorBlack ); + + x += b->width / 2; + y += 4; + UI_DrawString( x, y, s_serveroptions.mapnamebuffer, UI_CENTER|UI_SMALLFONT, color_orange ); + + y += SMALLCHAR_HEIGHT; + UI_DrawString( x, y, gametype_items[gametype_remap2[s_serveroptions.gametype]], UI_CENTER|UI_SMALLFONT, color_orange ); +} + + +static void ServerOptions_InitBotNames( void ) { + int count; + int n; + const char *arenaInfo; + const char *botInfo; + char *p; + char *bot; + char bots[MAX_INFO_STRING]; + + if( s_serveroptions.gametype >= GT_TEAM ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[1], "grunt", 16 ); + Q_strncpyz( s_serveroptions.playerNameBuffers[2], "major", 16 ); + if( s_serveroptions.gametype == GT_TEAM ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[3], "visor", 16 ); + } + else { + s_serveroptions.playerType[3].curvalue = 2; + } + s_serveroptions.playerType[4].curvalue = 2; + s_serveroptions.playerType[5].curvalue = 2; + + Q_strncpyz( s_serveroptions.playerNameBuffers[6], "sarge", 16 ); + Q_strncpyz( s_serveroptions.playerNameBuffers[7], "grunt", 16 ); + Q_strncpyz( s_serveroptions.playerNameBuffers[8], "major", 16 ); + if( s_serveroptions.gametype == GT_TEAM ) { + Q_strncpyz( s_serveroptions.playerNameBuffers[9], "visor", 16 ); + } + else { + s_serveroptions.playerType[9].curvalue = 2; + } + s_serveroptions.playerType[10].curvalue = 2; + s_serveroptions.playerType[11].curvalue = 2; + + return; + } + + count = 1; // skip the first slot, reserved for a human + + // get info for this map + arenaInfo = UI_GetArenaInfoByMap( s_serveroptions.mapnamebuffer ); + + // get the bot info - we'll seed with them if any are listed + Q_strncpyz( bots, Info_ValueForKey( arenaInfo, "bots" ), sizeof(bots) ); + p = &bots[0]; + while( *p && count < PLAYER_SLOTS ) { + //skip spaces + while( *p && *p == ' ' ) { + p++; + } + if( !p ) { + break; + } + + // mark start of bot name + bot = p; + + // skip until space of null + while( *p && *p != ' ' ) { + p++; + } + if( *p ) { + *p++ = 0; + } + + botInfo = UI_GetBotInfoByName( bot ); + bot = Info_ValueForKey( botInfo, "name" ); + + Q_strncpyz( s_serveroptions.playerNameBuffers[count], bot, sizeof(s_serveroptions.playerNameBuffers[count]) ); + count++; + } + + // set the rest of the bot slots to "---" + for( n = count; n < PLAYER_SLOTS; n++ ) { + strcpy( s_serveroptions.playerNameBuffers[n], "--------" ); + } + + // pad up to #8 as open slots + for( ;count < 8; count++ ) { + s_serveroptions.playerType[count].curvalue = 0; + } + + // close off the rest by default + for( ;count < PLAYER_SLOTS; count++ ) { + if( s_serveroptions.playerType[count].curvalue == 1 ) { + s_serveroptions.playerType[count].curvalue = 2; + } + } +} + + +/* +================= +ServerOptions_SetMenuItems +================= +*/ +static void ServerOptions_SetMenuItems( void ) { + static char picname[64]; + + switch( s_serveroptions.gametype ) { + case GT_FFA: + default: + Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_fraglimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ffa_timelimit" ) ) ); + break; + + case GT_TOURNAMENT: + Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_fraglimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_tourney_timelimit" ) ) ); + break; + + case GT_TEAM: + Com_sprintf( s_serveroptions.fraglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_fraglimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_team_timelimit" ) ) ); + s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_team_friendly" ) ); + break; + + case GT_CTF: + Com_sprintf( s_serveroptions.flaglimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 100, trap_Cvar_VariableValue( "ui_ctf_capturelimit" ) ) ); + Com_sprintf( s_serveroptions.timelimit.field.buffer, 4, "%i", (int)Com_Clamp( 0, 999, trap_Cvar_VariableValue( "ui_ctf_timelimit" ) ) ); + s_serveroptions.friendlyfire.curvalue = (int)Com_Clamp( 0, 1, trap_Cvar_VariableValue( "ui_ctf_friendly" ) ); + break; + } + + Q_strncpyz( s_serveroptions.hostname.field.buffer, UI_Cvar_VariableString( "sv_hostname" ), sizeof( s_serveroptions.hostname.field.buffer ) ); + s_serveroptions.pure.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_pure" ) ); + + // set the map pic + Com_sprintf( picname, 64, "levelshots/%s", s_startserver.maplist[s_startserver.currentmap] ); + s_serveroptions.mappic.generic.name = picname; + + // set the map name + strcpy( s_serveroptions.mapnamebuffer, s_startserver.mapname.string ); + Q_strupr( s_serveroptions.mapnamebuffer ); + + // get the player selections initialized + ServerOptions_InitPlayerItems(); + ServerOptions_SetPlayerItems(); + + // seed bot names + ServerOptions_InitBotNames(); + ServerOptions_SetPlayerItems(); +} + +/* +================= +PlayerName_Draw +================= +*/ +static void PlayerName_Draw( void *item ) { + menutext_s *s; + float *color; + int x, y; + int style; + qboolean focus; + + s = (menutext_s *)item; + + x = s->generic.x; + y = s->generic.y; + + style = UI_SMALLFONT; + focus = (s->generic.parent->cursor == s->generic.menuPosition); + + if ( s->generic.flags & QMF_GRAYED ) + color = text_color_disabled; + else if ( focus ) + { + color = text_color_highlight; + style |= UI_PULSE; + } + else if ( s->generic.flags & QMF_BLINK ) + { + color = text_color_highlight; + style |= UI_BLINK; + } + else + color = text_color_normal; + + if ( focus ) + { + // draw cursor + UI_FillRect( s->generic.left, s->generic.top, s->generic.right-s->generic.left+1, s->generic.bottom-s->generic.top+1, listbar_color ); + UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, color); + } + + UI_DrawString( x - SMALLCHAR_WIDTH, y, s->generic.name, style|UI_RIGHT, color ); + UI_DrawString( x + SMALLCHAR_WIDTH, y, s->string, style|UI_LEFT, color ); +} + + +/* +================= +ServerOptions_MenuInit +================= +*/ +#define OPTIONS_X 456 + +static void ServerOptions_MenuInit( qboolean multiplayer ) { + int y; + int n; + + memset( &s_serveroptions, 0 ,sizeof(serveroptions_t) ); + s_serveroptions.multiplayer = multiplayer; + s_serveroptions.gametype = (int)Com_Clamp( 0, 5, trap_Cvar_VariableValue( "g_gameType" ) ); + s_serveroptions.punkbuster.curvalue = Com_Clamp( 0, 1, trap_Cvar_VariableValue( "sv_punkbuster" ) ); + + ServerOptions_Cache(); + + s_serveroptions.menu.wrapAround = qtrue; + s_serveroptions.menu.fullscreen = qtrue; + + s_serveroptions.banner.generic.type = MTYPE_BTEXT; + s_serveroptions.banner.generic.x = 320; + s_serveroptions.banner.generic.y = 16; + s_serveroptions.banner.string = "GAME SERVER"; + s_serveroptions.banner.color = color_white; + s_serveroptions.banner.style = UI_CENTER; + + s_serveroptions.mappic.generic.type = MTYPE_BITMAP; + s_serveroptions.mappic.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + s_serveroptions.mappic.generic.x = 352; + s_serveroptions.mappic.generic.y = 80; + s_serveroptions.mappic.width = 160; + s_serveroptions.mappic.height = 120; + s_serveroptions.mappic.errorpic = GAMESERVER_UNKNOWNMAP; + s_serveroptions.mappic.generic.ownerdraw = ServerOptions_LevelshotDraw; + + s_serveroptions.picframe.generic.type = MTYPE_BITMAP; + s_serveroptions.picframe.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE|QMF_HIGHLIGHT; + s_serveroptions.picframe.generic.x = 352 - 38; + s_serveroptions.picframe.generic.y = 80 - 40; + s_serveroptions.picframe.width = 320; + s_serveroptions.picframe.height = 320; + s_serveroptions.picframe.focuspic = GAMESERVER_SELECT; + + y = 272; + if( s_serveroptions.gametype != GT_CTF ) { + s_serveroptions.fraglimit.generic.type = MTYPE_FIELD; + s_serveroptions.fraglimit.generic.name = "Frag Limit:"; + s_serveroptions.fraglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.fraglimit.generic.x = OPTIONS_X; + s_serveroptions.fraglimit.generic.y = y; + s_serveroptions.fraglimit.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.fraglimit.field.widthInChars = 3; + s_serveroptions.fraglimit.field.maxchars = 3; + } + else { + s_serveroptions.flaglimit.generic.type = MTYPE_FIELD; + s_serveroptions.flaglimit.generic.name = "Capture Limit:"; + s_serveroptions.flaglimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.flaglimit.generic.x = OPTIONS_X; + s_serveroptions.flaglimit.generic.y = y; + s_serveroptions.flaglimit.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.flaglimit.field.widthInChars = 3; + s_serveroptions.flaglimit.field.maxchars = 3; + } + + y += BIGCHAR_HEIGHT+2; + s_serveroptions.timelimit.generic.type = MTYPE_FIELD; + s_serveroptions.timelimit.generic.name = "Time Limit:"; + s_serveroptions.timelimit.generic.flags = QMF_NUMBERSONLY|QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.timelimit.generic.x = OPTIONS_X; + s_serveroptions.timelimit.generic.y = y; + s_serveroptions.timelimit.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.timelimit.field.widthInChars = 3; + s_serveroptions.timelimit.field.maxchars = 3; + + if( s_serveroptions.gametype >= GT_TEAM ) { + y += BIGCHAR_HEIGHT+2; + s_serveroptions.friendlyfire.generic.type = MTYPE_RADIOBUTTON; + s_serveroptions.friendlyfire.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.friendlyfire.generic.x = OPTIONS_X; + s_serveroptions.friendlyfire.generic.y = y; + s_serveroptions.friendlyfire.generic.name = "Friendly Fire:"; + } + + y += BIGCHAR_HEIGHT+2; + s_serveroptions.pure.generic.type = MTYPE_RADIOBUTTON; + s_serveroptions.pure.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.pure.generic.x = OPTIONS_X; + s_serveroptions.pure.generic.y = y; + s_serveroptions.pure.generic.name = "Pure Server:"; + + if( s_serveroptions.multiplayer ) { + y += BIGCHAR_HEIGHT+2; + s_serveroptions.dedicated.generic.type = MTYPE_SPINCONTROL; + s_serveroptions.dedicated.generic.id = ID_DEDICATED; + s_serveroptions.dedicated.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.dedicated.generic.callback = ServerOptions_Event; + s_serveroptions.dedicated.generic.x = OPTIONS_X; + s_serveroptions.dedicated.generic.y = y; + s_serveroptions.dedicated.generic.name = "Dedicated:"; + s_serveroptions.dedicated.itemnames = dedicated_list; + } + + if( s_serveroptions.multiplayer ) { + y += BIGCHAR_HEIGHT+2; + s_serveroptions.hostname.generic.type = MTYPE_FIELD; + s_serveroptions.hostname.generic.name = "Hostname:"; + s_serveroptions.hostname.generic.flags = QMF_SMALLFONT; + s_serveroptions.hostname.generic.x = OPTIONS_X; + s_serveroptions.hostname.generic.y = y; + s_serveroptions.hostname.field.widthInChars = 18; + s_serveroptions.hostname.field.maxchars = 64; + } + + y += BIGCHAR_HEIGHT+2; + s_serveroptions.punkbuster.generic.type = MTYPE_SPINCONTROL; + s_serveroptions.punkbuster.generic.name = "Punkbuster:"; + s_serveroptions.punkbuster.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.punkbuster.generic.id = 0; + s_serveroptions.punkbuster.generic.x = OPTIONS_X; + s_serveroptions.punkbuster.generic.y = y; + s_serveroptions.punkbuster.itemnames = punkbuster_items; + + y = 80; + s_serveroptions.botSkill.generic.type = MTYPE_SPINCONTROL; + s_serveroptions.botSkill.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_serveroptions.botSkill.generic.name = "Bot Skill: "; + s_serveroptions.botSkill.generic.x = 32 + (strlen(s_serveroptions.botSkill.generic.name) + 2 ) * SMALLCHAR_WIDTH; + s_serveroptions.botSkill.generic.y = y; + s_serveroptions.botSkill.itemnames = botSkill_list; + s_serveroptions.botSkill.curvalue = 1; + + y += ( 2 * SMALLCHAR_HEIGHT ); + s_serveroptions.player0.generic.type = MTYPE_TEXT; + s_serveroptions.player0.generic.flags = QMF_SMALLFONT; + s_serveroptions.player0.generic.x = 32 + SMALLCHAR_WIDTH; + s_serveroptions.player0.generic.y = y; + s_serveroptions.player0.color = color_orange; + s_serveroptions.player0.style = UI_LEFT|UI_SMALLFONT; + + for( n = 0; n < PLAYER_SLOTS; n++ ) { + s_serveroptions.playerType[n].generic.type = MTYPE_SPINCONTROL; + s_serveroptions.playerType[n].generic.flags = QMF_SMALLFONT; + s_serveroptions.playerType[n].generic.id = ID_PLAYER_TYPE; + s_serveroptions.playerType[n].generic.callback = ServerOptions_Event; + s_serveroptions.playerType[n].generic.x = 32; + s_serveroptions.playerType[n].generic.y = y; + s_serveroptions.playerType[n].itemnames = playerType_list; + + s_serveroptions.playerName[n].generic.type = MTYPE_TEXT; + s_serveroptions.playerName[n].generic.flags = QMF_SMALLFONT; + s_serveroptions.playerName[n].generic.x = 96; + s_serveroptions.playerName[n].generic.y = y; + s_serveroptions.playerName[n].generic.callback = ServerOptions_PlayerNameEvent; + s_serveroptions.playerName[n].generic.id = n; + s_serveroptions.playerName[n].generic.ownerdraw = PlayerName_Draw; + s_serveroptions.playerName[n].color = color_orange; + s_serveroptions.playerName[n].style = UI_SMALLFONT; + s_serveroptions.playerName[n].string = s_serveroptions.playerNameBuffers[n]; + s_serveroptions.playerName[n].generic.top = s_serveroptions.playerName[n].generic.y; + s_serveroptions.playerName[n].generic.bottom = s_serveroptions.playerName[n].generic.y + SMALLCHAR_HEIGHT; + s_serveroptions.playerName[n].generic.left = s_serveroptions.playerName[n].generic.x - SMALLCHAR_HEIGHT/ 2; + s_serveroptions.playerName[n].generic.right = s_serveroptions.playerName[n].generic.x + 16 * SMALLCHAR_WIDTH; + + s_serveroptions.playerTeam[n].generic.type = MTYPE_SPINCONTROL; + s_serveroptions.playerTeam[n].generic.flags = QMF_SMALLFONT; + s_serveroptions.playerTeam[n].generic.x = 240; + s_serveroptions.playerTeam[n].generic.y = y; + s_serveroptions.playerTeam[n].itemnames = playerTeam_list; + + y += ( SMALLCHAR_HEIGHT + 4 ); + } + + s_serveroptions.back.generic.type = MTYPE_BITMAP; + s_serveroptions.back.generic.name = GAMESERVER_BACK0; + s_serveroptions.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_serveroptions.back.generic.callback = ServerOptions_Event; + s_serveroptions.back.generic.id = ID_BACK; + s_serveroptions.back.generic.x = 0; + s_serveroptions.back.generic.y = 480-64; + s_serveroptions.back.width = 128; + s_serveroptions.back.height = 64; + s_serveroptions.back.focuspic = GAMESERVER_BACK1; + + s_serveroptions.next.generic.type = MTYPE_BITMAP; + s_serveroptions.next.generic.name = GAMESERVER_NEXT0; + s_serveroptions.next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_INACTIVE|QMF_GRAYED|QMF_HIDDEN; + s_serveroptions.next.generic.callback = ServerOptions_Event; + s_serveroptions.next.generic.id = ID_STARTSERVERNEXT; + s_serveroptions.next.generic.x = 640; + s_serveroptions.next.generic.y = 480-64-72; + s_serveroptions.next.generic.statusbar = ServerOptions_StatusBar; + s_serveroptions.next.width = 128; + s_serveroptions.next.height = 64; + s_serveroptions.next.focuspic = GAMESERVER_NEXT1; + + s_serveroptions.go.generic.type = MTYPE_BITMAP; + s_serveroptions.go.generic.name = GAMESERVER_FIGHT0; + s_serveroptions.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_serveroptions.go.generic.callback = ServerOptions_Event; + s_serveroptions.go.generic.id = ID_GO; + s_serveroptions.go.generic.x = 640; + s_serveroptions.go.generic.y = 480-64; + s_serveroptions.go.width = 128; + s_serveroptions.go.height = 64; + s_serveroptions.go.focuspic = GAMESERVER_FIGHT1; + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.banner ); + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.mappic ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.picframe ); + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.botSkill ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.player0 ); + for( n = 0; n < PLAYER_SLOTS; n++ ) { + if( n != 0 ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerType[n] ); + } + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerName[n] ); + if( s_serveroptions.gametype >= GT_TEAM ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.playerTeam[n] ); + } + } + + if( s_serveroptions.gametype != GT_CTF ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.fraglimit ); + } + else { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.flaglimit ); + } + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.timelimit ); + if( s_serveroptions.gametype >= GT_TEAM ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.friendlyfire ); + } + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.pure ); + if( s_serveroptions.multiplayer ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.dedicated ); + } + if( s_serveroptions.multiplayer ) { + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.hostname ); + } + + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.back ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.next ); + Menu_AddItem( &s_serveroptions.menu, &s_serveroptions.go ); + + Menu_AddItem( &s_serveroptions.menu, (void*) &s_serveroptions.punkbuster ); + + ServerOptions_SetMenuItems(); +} + +/* +================= +ServerOptions_Cache +================= +*/ +void ServerOptions_Cache( void ) { + trap_R_RegisterShaderNoMip( GAMESERVER_BACK0 ); + trap_R_RegisterShaderNoMip( GAMESERVER_BACK1 ); + trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT0 ); + trap_R_RegisterShaderNoMip( GAMESERVER_FIGHT1 ); + trap_R_RegisterShaderNoMip( GAMESERVER_SELECT ); + trap_R_RegisterShaderNoMip( GAMESERVER_UNKNOWNMAP ); +} + + +/* +================= +UI_ServerOptionsMenu +================= +*/ +static void UI_ServerOptionsMenu( qboolean multiplayer ) { + ServerOptions_MenuInit( multiplayer ); + UI_PushMenu( &s_serveroptions.menu ); +} + + + +/* +============================================================================= + +BOT SELECT MENU ***** + +============================================================================= +*/ + + +#define BOTSELECT_BACK0 "menu/art/back_0" +#define BOTSELECT_BACK1 "menu/art/back_1" +#define BOTSELECT_ACCEPT0 "menu/art/accept_0" +#define BOTSELECT_ACCEPT1 "menu/art/accept_1" +#define BOTSELECT_SELECT "menu/art/opponents_select" +#define BOTSELECT_SELECTED "menu/art/opponents_selected" +#define BOTSELECT_ARROWS "menu/art/gs_arrows_0" +#define BOTSELECT_ARROWSL "menu/art/gs_arrows_l" +#define BOTSELECT_ARROWSR "menu/art/gs_arrows_r" + +#define PLAYERGRID_COLS 4 +#define PLAYERGRID_ROWS 4 +#define MAX_MODELSPERPAGE (PLAYERGRID_ROWS * PLAYERGRID_COLS) + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + + menubitmap_s pics[MAX_MODELSPERPAGE]; + menubitmap_s picbuttons[MAX_MODELSPERPAGE]; + menutext_s picnames[MAX_MODELSPERPAGE]; + + menubitmap_s arrows; + menubitmap_s left; + menubitmap_s right; + + menubitmap_s go; + menubitmap_s back; + + int numBots; + int modelpage; + int numpages; + int selectedmodel; + int sortedBotNums[MAX_BOTS]; + char boticons[MAX_MODELSPERPAGE][MAX_QPATH]; + char botnames[MAX_MODELSPERPAGE][16]; +} botSelectInfo_t; + +static botSelectInfo_t botSelectInfo; + + +/* +================= +UI_BotSelectMenu_SortCompare +================= +*/ +static int QDECL UI_BotSelectMenu_SortCompare( const void *arg1, const void *arg2 ) { + int num1, num2; + const char *info1, *info2; + const char *name1, *name2; + + num1 = *(int *)arg1; + num2 = *(int *)arg2; + + info1 = UI_GetBotInfoByNumber( num1 ); + info2 = UI_GetBotInfoByNumber( num2 ); + + name1 = Info_ValueForKey( info1, "name" ); + name2 = Info_ValueForKey( info2, "name" ); + + return Q_stricmp( name1, name2 ); +} + + +/* +================= +UI_BotSelectMenu_BuildList +================= +*/ +static void UI_BotSelectMenu_BuildList( void ) { + int n; + + botSelectInfo.modelpage = 0; + botSelectInfo.numBots = UI_GetNumBots(); + botSelectInfo.numpages = botSelectInfo.numBots / MAX_MODELSPERPAGE; + if( botSelectInfo.numBots % MAX_MODELSPERPAGE ) { + botSelectInfo.numpages++; + } + + // initialize the array + for( n = 0; n < botSelectInfo.numBots; n++ ) { + botSelectInfo.sortedBotNums[n] = n; + } + + // now sort it + qsort( botSelectInfo.sortedBotNums, botSelectInfo.numBots, sizeof(botSelectInfo.sortedBotNums[0]), UI_BotSelectMenu_SortCompare ); +} + + +/* +================= +ServerPlayerIcon +================= +*/ +static void ServerPlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) { + char *skin; + char model[MAX_QPATH]; + + Q_strncpyz( model, modelAndSkin, sizeof(model)); + skin = Q_strrchr( model, '/' ); + if ( skin ) { + *skin++ = '\0'; + } + else { + skin = "default"; + } + + Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin ); + + if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) { + Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model ); + } +} + + +/* +================= +UI_BotSelectMenu_UpdateGrid +================= +*/ +static void UI_BotSelectMenu_UpdateGrid( void ) { + const char *info; + int i; + int j; + + j = botSelectInfo.modelpage * MAX_MODELSPERPAGE; + for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++, j++) { + if( j < botSelectInfo.numBots ) { + info = UI_GetBotInfoByNumber( botSelectInfo.sortedBotNums[j] ); + ServerPlayerIcon( Info_ValueForKey( info, "model" ), botSelectInfo.boticons[i], MAX_QPATH ); + Q_strncpyz( botSelectInfo.botnames[i], Info_ValueForKey( info, "name" ), 16 ); + Q_CleanStr( botSelectInfo.botnames[i] ); + botSelectInfo.pics[i].generic.name = botSelectInfo.boticons[i]; + if( BotAlreadySelected( botSelectInfo.botnames[i] ) ) { + botSelectInfo.picnames[i].color = color_red; + } + else { + botSelectInfo.picnames[i].color = color_orange; + } + botSelectInfo.picbuttons[i].generic.flags &= ~QMF_INACTIVE; + } + else { + // dead slot + botSelectInfo.pics[i].generic.name = NULL; + botSelectInfo.picbuttons[i].generic.flags |= QMF_INACTIVE; + botSelectInfo.botnames[i][0] = 0; + } + + botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; + botSelectInfo.pics[i].shader = 0; + botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; + } + + // set selected model + i = botSelectInfo.selectedmodel % MAX_MODELSPERPAGE; + botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; + botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; + + if( botSelectInfo.numpages > 1 ) { + if( botSelectInfo.modelpage > 0 ) { + botSelectInfo.left.generic.flags &= ~QMF_INACTIVE; + } + else { + botSelectInfo.left.generic.flags |= QMF_INACTIVE; + } + + if( botSelectInfo.modelpage < (botSelectInfo.numpages - 1) ) { + botSelectInfo.right.generic.flags &= ~QMF_INACTIVE; + } + else { + botSelectInfo.right.generic.flags |= QMF_INACTIVE; + } + } + else { + // hide left/right markers + botSelectInfo.left.generic.flags |= QMF_INACTIVE; + botSelectInfo.right.generic.flags |= QMF_INACTIVE; + } +} + + +/* +================= +UI_BotSelectMenu_Default +================= +*/ +static void UI_BotSelectMenu_Default( char *bot ) { + const char *botInfo; + const char *test; + int n; + int i; + + for( n = 0; n < botSelectInfo.numBots; n++ ) { + botInfo = UI_GetBotInfoByNumber( n ); + test = Info_ValueForKey( botInfo, "name" ); + if( Q_stricmp( bot, test ) == 0 ) { + break; + } + } + if( n == botSelectInfo.numBots ) { + botSelectInfo.selectedmodel = 0; + return; + } + + for( i = 0; i < botSelectInfo.numBots; i++ ) { + if( botSelectInfo.sortedBotNums[i] == n ) { + break; + } + } + if( i == botSelectInfo.numBots ) { + botSelectInfo.selectedmodel = 0; + return; + } + + botSelectInfo.selectedmodel = i; +} + + +/* +================= +UI_BotSelectMenu_LeftEvent +================= +*/ +static void UI_BotSelectMenu_LeftEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + if( botSelectInfo.modelpage > 0 ) { + botSelectInfo.modelpage--; + botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; + UI_BotSelectMenu_UpdateGrid(); + } +} + + +/* +================= +UI_BotSelectMenu_RightEvent +================= +*/ +static void UI_BotSelectMenu_RightEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + if( botSelectInfo.modelpage < botSelectInfo.numpages - 1 ) { + botSelectInfo.modelpage++; + botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE; + UI_BotSelectMenu_UpdateGrid(); + } +} + + +/* +================= +UI_BotSelectMenu_BotEvent +================= +*/ +static void UI_BotSelectMenu_BotEvent( void* ptr, int event ) { + int i; + + if( event != QM_ACTIVATED ) { + return; + } + + for( i = 0; i < (PLAYERGRID_ROWS * PLAYERGRID_COLS); i++ ) { + botSelectInfo.pics[i].generic.flags &= ~QMF_HIGHLIGHT; + botSelectInfo.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS; + } + + // set selected + i = ((menucommon_s*)ptr)->id; + botSelectInfo.pics[i].generic.flags |= QMF_HIGHLIGHT; + botSelectInfo.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS; + botSelectInfo.selectedmodel = botSelectInfo.modelpage * MAX_MODELSPERPAGE + i; +} + + +/* +================= +UI_BotSelectMenu_BackEvent +================= +*/ +static void UI_BotSelectMenu_BackEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + UI_PopMenu(); +} + + +/* +================= +UI_BotSelectMenu_SelectEvent +================= +*/ +static void UI_BotSelectMenu_SelectEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + UI_PopMenu(); + + s_serveroptions.newBot = qtrue; + Q_strncpyz( s_serveroptions.newBotName, botSelectInfo.botnames[botSelectInfo.selectedmodel % MAX_MODELSPERPAGE], 16 ); +} + + +/* +================= +UI_BotSelectMenu_Cache +================= +*/ +void UI_BotSelectMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( BOTSELECT_BACK0 ); + trap_R_RegisterShaderNoMip( BOTSELECT_BACK1 ); + trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT0 ); + trap_R_RegisterShaderNoMip( BOTSELECT_ACCEPT1 ); + trap_R_RegisterShaderNoMip( BOTSELECT_SELECT ); + trap_R_RegisterShaderNoMip( BOTSELECT_SELECTED ); + trap_R_RegisterShaderNoMip( BOTSELECT_ARROWS ); + trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSL ); + trap_R_RegisterShaderNoMip( BOTSELECT_ARROWSR ); +} + + +static void UI_BotSelectMenu_Init( char *bot ) { + int i, j, k; + int x, y; + + memset( &botSelectInfo, 0 ,sizeof(botSelectInfo) ); + botSelectInfo.menu.wrapAround = qtrue; + botSelectInfo.menu.fullscreen = qtrue; + + UI_BotSelectMenu_Cache(); + + botSelectInfo.banner.generic.type = MTYPE_BTEXT; + botSelectInfo.banner.generic.x = 320; + botSelectInfo.banner.generic.y = 16; + botSelectInfo.banner.string = "SELECT BOT"; + botSelectInfo.banner.color = color_white; + botSelectInfo.banner.style = UI_CENTER; + + y = 80; + for( i = 0, k = 0; i < PLAYERGRID_ROWS; i++) { + x = 180; + for( j = 0; j < PLAYERGRID_COLS; j++, k++ ) { + botSelectInfo.pics[k].generic.type = MTYPE_BITMAP; + botSelectInfo.pics[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; + botSelectInfo.pics[k].generic.x = x; + botSelectInfo.pics[k].generic.y = y; + botSelectInfo.pics[k].generic.name = botSelectInfo.boticons[k]; + botSelectInfo.pics[k].width = 64; + botSelectInfo.pics[k].height = 64; + botSelectInfo.pics[k].focuspic = BOTSELECT_SELECTED; + botSelectInfo.pics[k].focuscolor = colorRed; + + botSelectInfo.picbuttons[k].generic.type = MTYPE_BITMAP; + botSelectInfo.picbuttons[k].generic.flags = QMF_LEFT_JUSTIFY|QMF_NODEFAULTINIT|QMF_PULSEIFFOCUS; + botSelectInfo.picbuttons[k].generic.callback = UI_BotSelectMenu_BotEvent; + botSelectInfo.picbuttons[k].generic.id = k; + botSelectInfo.picbuttons[k].generic.x = x - 16; + botSelectInfo.picbuttons[k].generic.y = y - 16; + botSelectInfo.picbuttons[k].generic.left = x; + botSelectInfo.picbuttons[k].generic.top = y; + botSelectInfo.picbuttons[k].generic.right = x + 64; + botSelectInfo.picbuttons[k].generic.bottom = y + 64; + botSelectInfo.picbuttons[k].width = 128; + botSelectInfo.picbuttons[k].height = 128; + botSelectInfo.picbuttons[k].focuspic = BOTSELECT_SELECT; + botSelectInfo.picbuttons[k].focuscolor = colorRed; + + botSelectInfo.picnames[k].generic.type = MTYPE_TEXT; + botSelectInfo.picnames[k].generic.flags = QMF_SMALLFONT; + botSelectInfo.picnames[k].generic.x = x + 32; + botSelectInfo.picnames[k].generic.y = y + 64; + botSelectInfo.picnames[k].string = botSelectInfo.botnames[k]; + botSelectInfo.picnames[k].color = color_orange; + botSelectInfo.picnames[k].style = UI_CENTER|UI_SMALLFONT; + + x += (64 + 6); + } + y += (64 + SMALLCHAR_HEIGHT + 6); + } + + botSelectInfo.arrows.generic.type = MTYPE_BITMAP; + botSelectInfo.arrows.generic.name = BOTSELECT_ARROWS; + botSelectInfo.arrows.generic.flags = QMF_INACTIVE; + botSelectInfo.arrows.generic.x = 260; + botSelectInfo.arrows.generic.y = 440; + botSelectInfo.arrows.width = 128; + botSelectInfo.arrows.height = 32; + + botSelectInfo.left.generic.type = MTYPE_BITMAP; + botSelectInfo.left.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.left.generic.callback = UI_BotSelectMenu_LeftEvent; + botSelectInfo.left.generic.x = 260; + botSelectInfo.left.generic.y = 440; + botSelectInfo.left.width = 64; + botSelectInfo.left.height = 32; + botSelectInfo.left.focuspic = BOTSELECT_ARROWSL; + + botSelectInfo.right.generic.type = MTYPE_BITMAP; + botSelectInfo.right.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.right.generic.callback = UI_BotSelectMenu_RightEvent; + botSelectInfo.right.generic.x = 321; + botSelectInfo.right.generic.y = 440; + botSelectInfo.right.width = 64; + botSelectInfo.right.height = 32; + botSelectInfo.right.focuspic = BOTSELECT_ARROWSR; + + botSelectInfo.back.generic.type = MTYPE_BITMAP; + botSelectInfo.back.generic.name = BOTSELECT_BACK0; + botSelectInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.back.generic.callback = UI_BotSelectMenu_BackEvent; + botSelectInfo.back.generic.x = 0; + botSelectInfo.back.generic.y = 480-64; + botSelectInfo.back.width = 128; + botSelectInfo.back.height = 64; + botSelectInfo.back.focuspic = BOTSELECT_BACK1; + + botSelectInfo.go.generic.type = MTYPE_BITMAP; + botSelectInfo.go.generic.name = BOTSELECT_ACCEPT0; + botSelectInfo.go.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + botSelectInfo.go.generic.callback = UI_BotSelectMenu_SelectEvent; + botSelectInfo.go.generic.x = 640; + botSelectInfo.go.generic.y = 480-64; + botSelectInfo.go.width = 128; + botSelectInfo.go.height = 64; + botSelectInfo.go.focuspic = BOTSELECT_ACCEPT1; + + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.banner ); + for( i = 0; i < MAX_MODELSPERPAGE; i++ ) { + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.pics[i] ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picbuttons[i] ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.picnames[i] ); + } + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.arrows ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.left ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.right ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.back ); + Menu_AddItem( &botSelectInfo.menu, &botSelectInfo.go ); + + UI_BotSelectMenu_BuildList(); + UI_BotSelectMenu_Default( bot ); + botSelectInfo.modelpage = botSelectInfo.selectedmodel / MAX_MODELSPERPAGE; + UI_BotSelectMenu_UpdateGrid(); +} + + +/* +================= +UI_BotSelectMenu +================= +*/ +void UI_BotSelectMenu( char *bot ) { + UI_BotSelectMenu_Init( bot ); + UI_PushMenu( &botSelectInfo.menu ); +} diff --git a/code/q3_ui/ui_team.c b/code/q3_ui/ui_team.c index 1ea1bd1..230f075 100755 --- a/code/q3_ui/ui_team.c +++ b/code/q3_ui/ui_team.c @@ -1,210 +1,210 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -// -// ui_team.c -// - -#include "ui_local.h" - - -#define TEAMMAIN_FRAME "menu/art/cut_frame" - -#define ID_JOINRED 100 -#define ID_JOINBLUE 101 -#define ID_JOINGAME 102 -#define ID_SPECTATE 103 - - -typedef struct -{ - menuframework_s menu; - menubitmap_s frame; - menutext_s joinred; - menutext_s joinblue; - menutext_s joingame; - menutext_s spectate; -} teammain_t; - -static teammain_t s_teammain; - -// bk001204 - unused -//static menuframework_s s_teammain_menu; -//static menuaction_s s_teammain_orders; -//static menuaction_s s_teammain_voice; -//static menuaction_s s_teammain_joinred; -//static menuaction_s s_teammain_joinblue; -//static menuaction_s s_teammain_joingame; -//static menuaction_s s_teammain_spectate; - - -/* -=============== -TeamMain_MenuEvent -=============== -*/ -static void TeamMain_MenuEvent( void* ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_JOINRED: - trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team red\n" ); - UI_ForceMenuOff(); - break; - - case ID_JOINBLUE: - trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team blue\n" ); - UI_ForceMenuOff(); - break; - - case ID_JOINGAME: - trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team free\n" ); - UI_ForceMenuOff(); - break; - - case ID_SPECTATE: - trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team spectator\n" ); - UI_ForceMenuOff(); - break; - } -} - - -/* -=============== -TeamMain_MenuInit -=============== -*/ -void TeamMain_MenuInit( void ) { - int y; - int gametype; - char info[MAX_INFO_STRING]; - - memset( &s_teammain, 0, sizeof(s_teammain) ); - - TeamMain_Cache(); - - s_teammain.menu.wrapAround = qtrue; - s_teammain.menu.fullscreen = qfalse; - - s_teammain.frame.generic.type = MTYPE_BITMAP; - s_teammain.frame.generic.flags = QMF_INACTIVE; - s_teammain.frame.generic.name = TEAMMAIN_FRAME; - s_teammain.frame.generic.x = 142; - s_teammain.frame.generic.y = 118; - s_teammain.frame.width = 359; - s_teammain.frame.height = 256; - - y = 194; - - s_teammain.joinred.generic.type = MTYPE_PTEXT; - s_teammain.joinred.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_teammain.joinred.generic.id = ID_JOINRED; - s_teammain.joinred.generic.callback = TeamMain_MenuEvent; - s_teammain.joinred.generic.x = 320; - s_teammain.joinred.generic.y = y; - s_teammain.joinred.string = "JOIN RED"; - s_teammain.joinred.style = UI_CENTER|UI_SMALLFONT; - s_teammain.joinred.color = colorRed; - y += 20; - - s_teammain.joinblue.generic.type = MTYPE_PTEXT; - s_teammain.joinblue.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_teammain.joinblue.generic.id = ID_JOINBLUE; - s_teammain.joinblue.generic.callback = TeamMain_MenuEvent; - s_teammain.joinblue.generic.x = 320; - s_teammain.joinblue.generic.y = y; - s_teammain.joinblue.string = "JOIN BLUE"; - s_teammain.joinblue.style = UI_CENTER|UI_SMALLFONT; - s_teammain.joinblue.color = colorRed; - y += 20; - - s_teammain.joingame.generic.type = MTYPE_PTEXT; - s_teammain.joingame.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_teammain.joingame.generic.id = ID_JOINGAME; - s_teammain.joingame.generic.callback = TeamMain_MenuEvent; - s_teammain.joingame.generic.x = 320; - s_teammain.joingame.generic.y = y; - s_teammain.joingame.string = "JOIN GAME"; - s_teammain.joingame.style = UI_CENTER|UI_SMALLFONT; - s_teammain.joingame.color = colorRed; - y += 20; - - s_teammain.spectate.generic.type = MTYPE_PTEXT; - s_teammain.spectate.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_teammain.spectate.generic.id = ID_SPECTATE; - s_teammain.spectate.generic.callback = TeamMain_MenuEvent; - s_teammain.spectate.generic.x = 320; - s_teammain.spectate.generic.y = y; - s_teammain.spectate.string = "SPECTATE"; - s_teammain.spectate.style = UI_CENTER|UI_SMALLFONT; - s_teammain.spectate.color = colorRed; - y += 20; - - trap_GetConfigString(CS_SERVERINFO, info, MAX_INFO_STRING); - gametype = atoi( Info_ValueForKey( info,"g_gametype" ) ); - - // set initial states - switch( gametype ) { - case GT_SINGLE_PLAYER: - case GT_FFA: - case GT_TOURNAMENT: - s_teammain.joinred.generic.flags |= QMF_GRAYED; - s_teammain.joinblue.generic.flags |= QMF_GRAYED; - break; - - default: - case GT_TEAM: - case GT_CTF: - s_teammain.joingame.generic.flags |= QMF_GRAYED; - break; - } - - Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.frame ); - Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.joinred ); - Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.joinblue ); - Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.joingame ); - Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.spectate ); -} - - -/* -=============== -TeamMain_Cache -=============== -*/ -void TeamMain_Cache( void ) { - trap_R_RegisterShaderNoMip( TEAMMAIN_FRAME ); -} - - -/* -=============== -UI_TeamMainMenu -=============== -*/ -void UI_TeamMainMenu( void ) { - TeamMain_MenuInit(); - UI_PushMenu ( &s_teammain.menu ); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +// +// ui_team.c +// + +#include "ui_local.h" + + +#define TEAMMAIN_FRAME "menu/art/cut_frame" + +#define ID_JOINRED 100 +#define ID_JOINBLUE 101 +#define ID_JOINGAME 102 +#define ID_SPECTATE 103 + + +typedef struct +{ + menuframework_s menu; + menubitmap_s frame; + menutext_s joinred; + menutext_s joinblue; + menutext_s joingame; + menutext_s spectate; +} teammain_t; + +static teammain_t s_teammain; + +// bk001204 - unused +//static menuframework_s s_teammain_menu; +//static menuaction_s s_teammain_orders; +//static menuaction_s s_teammain_voice; +//static menuaction_s s_teammain_joinred; +//static menuaction_s s_teammain_joinblue; +//static menuaction_s s_teammain_joingame; +//static menuaction_s s_teammain_spectate; + + +/* +=============== +TeamMain_MenuEvent +=============== +*/ +static void TeamMain_MenuEvent( void* ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_JOINRED: + trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team red\n" ); + UI_ForceMenuOff(); + break; + + case ID_JOINBLUE: + trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team blue\n" ); + UI_ForceMenuOff(); + break; + + case ID_JOINGAME: + trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team free\n" ); + UI_ForceMenuOff(); + break; + + case ID_SPECTATE: + trap_Cmd_ExecuteText( EXEC_APPEND, "cmd team spectator\n" ); + UI_ForceMenuOff(); + break; + } +} + + +/* +=============== +TeamMain_MenuInit +=============== +*/ +void TeamMain_MenuInit( void ) { + int y; + int gametype; + char info[MAX_INFO_STRING]; + + memset( &s_teammain, 0, sizeof(s_teammain) ); + + TeamMain_Cache(); + + s_teammain.menu.wrapAround = qtrue; + s_teammain.menu.fullscreen = qfalse; + + s_teammain.frame.generic.type = MTYPE_BITMAP; + s_teammain.frame.generic.flags = QMF_INACTIVE; + s_teammain.frame.generic.name = TEAMMAIN_FRAME; + s_teammain.frame.generic.x = 142; + s_teammain.frame.generic.y = 118; + s_teammain.frame.width = 359; + s_teammain.frame.height = 256; + + y = 194; + + s_teammain.joinred.generic.type = MTYPE_PTEXT; + s_teammain.joinred.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_teammain.joinred.generic.id = ID_JOINRED; + s_teammain.joinred.generic.callback = TeamMain_MenuEvent; + s_teammain.joinred.generic.x = 320; + s_teammain.joinred.generic.y = y; + s_teammain.joinred.string = "JOIN RED"; + s_teammain.joinred.style = UI_CENTER|UI_SMALLFONT; + s_teammain.joinred.color = colorRed; + y += 20; + + s_teammain.joinblue.generic.type = MTYPE_PTEXT; + s_teammain.joinblue.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_teammain.joinblue.generic.id = ID_JOINBLUE; + s_teammain.joinblue.generic.callback = TeamMain_MenuEvent; + s_teammain.joinblue.generic.x = 320; + s_teammain.joinblue.generic.y = y; + s_teammain.joinblue.string = "JOIN BLUE"; + s_teammain.joinblue.style = UI_CENTER|UI_SMALLFONT; + s_teammain.joinblue.color = colorRed; + y += 20; + + s_teammain.joingame.generic.type = MTYPE_PTEXT; + s_teammain.joingame.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_teammain.joingame.generic.id = ID_JOINGAME; + s_teammain.joingame.generic.callback = TeamMain_MenuEvent; + s_teammain.joingame.generic.x = 320; + s_teammain.joingame.generic.y = y; + s_teammain.joingame.string = "JOIN GAME"; + s_teammain.joingame.style = UI_CENTER|UI_SMALLFONT; + s_teammain.joingame.color = colorRed; + y += 20; + + s_teammain.spectate.generic.type = MTYPE_PTEXT; + s_teammain.spectate.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_teammain.spectate.generic.id = ID_SPECTATE; + s_teammain.spectate.generic.callback = TeamMain_MenuEvent; + s_teammain.spectate.generic.x = 320; + s_teammain.spectate.generic.y = y; + s_teammain.spectate.string = "SPECTATE"; + s_teammain.spectate.style = UI_CENTER|UI_SMALLFONT; + s_teammain.spectate.color = colorRed; + y += 20; + + trap_GetConfigString(CS_SERVERINFO, info, MAX_INFO_STRING); + gametype = atoi( Info_ValueForKey( info,"g_gametype" ) ); + + // set initial states + switch( gametype ) { + case GT_SINGLE_PLAYER: + case GT_FFA: + case GT_TOURNAMENT: + s_teammain.joinred.generic.flags |= QMF_GRAYED; + s_teammain.joinblue.generic.flags |= QMF_GRAYED; + break; + + default: + case GT_TEAM: + case GT_CTF: + s_teammain.joingame.generic.flags |= QMF_GRAYED; + break; + } + + Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.frame ); + Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.joinred ); + Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.joinblue ); + Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.joingame ); + Menu_AddItem( &s_teammain.menu, (void*) &s_teammain.spectate ); +} + + +/* +=============== +TeamMain_Cache +=============== +*/ +void TeamMain_Cache( void ) { + trap_R_RegisterShaderNoMip( TEAMMAIN_FRAME ); +} + + +/* +=============== +UI_TeamMainMenu +=============== +*/ +void UI_TeamMainMenu( void ) { + TeamMain_MenuInit(); + UI_PushMenu ( &s_teammain.menu ); +} diff --git a/code/q3_ui/ui_teamorders.c b/code/q3_ui/ui_teamorders.c index 3187402..0529397 100755 --- a/code/q3_ui/ui_teamorders.c +++ b/code/q3_ui/ui_teamorders.c @@ -1,449 +1,449 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -/* -======================================================================= - -TEAM ORDERS MENU - -======================================================================= -*/ - - -#include "ui_local.h" - - -#define ART_FRAME "menu/art/addbotframe" -#define ART_BACK0 "menu/art/back_0" -#define ART_BACK1 "menu/art/back_1" - -#define ID_LIST_BOTS 10 -#define ID_LIST_CTF_ORDERS 11 -#define ID_LIST_TEAM_ORDERS 12 - - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s frame; - - menulist_s list; - - menubitmap_s back; - - int gametype; - int numBots; - int selectedBot; - char *bots[9]; - char botNames[9][16]; -} teamOrdersMenuInfo_t; - -static teamOrdersMenuInfo_t teamOrdersMenuInfo; - -#define NUM_CTF_ORDERS 7 -static const char *ctfOrders[] = { - "I Am the Leader", - "Defend the Base", - "Follow Me", - "Get Enemy Flag", - "Camp Here", - "Report", - "I Relinquish Command", - NULL -}; -static const char *ctfMessages[] = { - "i am the leader", - "%s defend the base", - "%s follow me", - "%s get enemy flag", - "%s camp here", - "%s report", - "i stop being the leader", - NULL -}; - -#define NUM_TEAM_ORDERS 6 -static const char *teamOrders[] = { - "I Am the Leader", - "Follow Me", - "Roam", - "Camp Here", - "Report", - "I Relinquish Command", - NULL -}; -static const char *teamMessages[] = { - "i am the leader", - "%s follow me", - "%s roam", - "%s camp here", - "%s report", - "i stop being the leader", - NULL -}; - - -/* -=============== -UI_TeamOrdersMenu_BackEvent -=============== -*/ -static void UI_TeamOrdersMenu_BackEvent( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - UI_PopMenu(); -} - - -/* -=============== -UI_TeamOrdersMenu_SetList -=============== -*/ -static void UI_TeamOrdersMenu_SetList( int id ) { - switch( id ) { - default: - case ID_LIST_BOTS: - teamOrdersMenuInfo.list.generic.id = id; - teamOrdersMenuInfo.list.numitems = teamOrdersMenuInfo.numBots; - teamOrdersMenuInfo.list.itemnames = (const char **)teamOrdersMenuInfo.bots; - break; - - case ID_LIST_CTF_ORDERS: - teamOrdersMenuInfo.list.generic.id = id; - teamOrdersMenuInfo.list.numitems = NUM_CTF_ORDERS; - teamOrdersMenuInfo.list.itemnames = ctfOrders; - break; - - case ID_LIST_TEAM_ORDERS: - teamOrdersMenuInfo.list.generic.id = id; - teamOrdersMenuInfo.list.numitems = NUM_TEAM_ORDERS; - teamOrdersMenuInfo.list.itemnames = teamOrders; - break; - } - - teamOrdersMenuInfo.list.generic.bottom = teamOrdersMenuInfo.list.generic.top + teamOrdersMenuInfo.list.numitems * PROP_HEIGHT; -} - - -/* -================= -UI_TeamOrdersMenu_Key -================= -*/ -sfxHandle_t UI_TeamOrdersMenu_Key( int key ) { - menulist_s *l; - int x; - int y; - int index; - - l = (menulist_s *)Menu_ItemAtCursor( &teamOrdersMenuInfo.menu ); - if( l != &teamOrdersMenuInfo.list ) { - return Menu_DefaultKey( &teamOrdersMenuInfo.menu, key ); - } - - switch( key ) { - case K_MOUSE1: - x = l->generic.left; - y = l->generic.top; - if( UI_CursorInRect( x, y, l->generic.right - x, l->generic.bottom - y ) ) { - index = (uis.cursory - y) / PROP_HEIGHT; - l->oldvalue = l->curvalue; - l->curvalue = index; - - if( l->generic.callback ) { - l->generic.callback( l, QM_ACTIVATED ); - return menu_move_sound; - } - } - return menu_null_sound; - - case K_KP_UPARROW: - case K_UPARROW: - l->oldvalue = l->curvalue; - - if( l->curvalue == 0 ) { - l->curvalue = l->numitems - 1; - } - else { - l->curvalue--; - } - return menu_move_sound; - - case K_KP_DOWNARROW: - case K_DOWNARROW: - l->oldvalue = l->curvalue; - - if( l->curvalue == l->numitems - 1 ) { - l->curvalue = 0;; - } - else { - l->curvalue++; - } - return menu_move_sound; - } - - return Menu_DefaultKey( &teamOrdersMenuInfo.menu, key ); -} - - -/* -================= -UI_TeamOrdersMenu_ListDraw -================= -*/ -static void UI_TeamOrdersMenu_ListDraw( void *self ) { - menulist_s *l; - int x; - int y; - int i; - float *color; - qboolean hasfocus; - int style; - - l = (menulist_s *)self; - - hasfocus = (l->generic.parent->cursor == l->generic.menuPosition); - - x = 320;//l->generic.x; - y = l->generic.y; - for( i = 0; i < l->numitems; i++ ) { - style = UI_LEFT|UI_SMALLFONT|UI_CENTER; - if( i == l->curvalue ) { - color = color_yellow; - if( hasfocus ) { - style |= UI_PULSE; - } - } - else { - color = color_orange; - } - - UI_DrawProportionalString( x, y, l->itemnames[i], style, color ); - y += PROP_HEIGHT; - } -} - - -/* -=============== -UI_TeamOrdersMenu_ListEvent -=============== -*/ -static void UI_TeamOrdersMenu_ListEvent( void *ptr, int event ) { - int id; - int selection; - char message[256]; - - if (event != QM_ACTIVATED) - return; - - id = ((menulist_s *)ptr)->generic.id; - selection = ((menulist_s *)ptr)->curvalue; - - if( id == ID_LIST_BOTS ) { - teamOrdersMenuInfo.selectedBot = selection; - if( teamOrdersMenuInfo.gametype == GT_CTF ) { - UI_TeamOrdersMenu_SetList( ID_LIST_CTF_ORDERS ); - } - else { - UI_TeamOrdersMenu_SetList( ID_LIST_TEAM_ORDERS ); - } - return; - } - - if( id == ID_LIST_CTF_ORDERS ) { - Com_sprintf( message, sizeof(message), ctfMessages[selection], teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.selectedBot] ); - } - else { - Com_sprintf( message, sizeof(message), teamMessages[selection], teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.selectedBot] ); - } - - trap_Cmd_ExecuteText( EXEC_APPEND, va( "say_team \"%s\"\n", message ) ); - UI_PopMenu(); -} - - -/* -=============== -UI_TeamOrdersMenu_BuildBotList -=============== -*/ -static void UI_TeamOrdersMenu_BuildBotList( void ) { - uiClientState_t cs; - int numPlayers; - int isBot; - int n; - char playerTeam; - char botTeam; - char info[MAX_INFO_STRING]; - - for( n = 0; n < 9; n++ ) { - teamOrdersMenuInfo.bots[n] = teamOrdersMenuInfo.botNames[n]; - } - - trap_GetClientState( &cs ); - - Q_strncpyz( teamOrdersMenuInfo.botNames[0], "Everyone", 16 ); - teamOrdersMenuInfo.numBots = 1; - - trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); - numPlayers = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); - teamOrdersMenuInfo.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) ); - - for( n = 0; n < numPlayers && teamOrdersMenuInfo.numBots < 9; n++ ) { - trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); - - playerTeam = TEAM_SPECTATOR; // bk001204 = possible uninit use - - if( n == cs.clientNum ) { - playerTeam = *Info_ValueForKey( info, "t" ); - continue; - } - - isBot = atoi( Info_ValueForKey( info, "skill" ) ); - if( !isBot ) { - continue; - } - - botTeam = *Info_ValueForKey( info, "t" ); - if( botTeam != playerTeam ) { - continue; - } - - Q_strncpyz( teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots], Info_ValueForKey( info, "n" ), 16 ); - Q_CleanStr( teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots] ); - teamOrdersMenuInfo.numBots++; - } -} - - -/* -=============== -UI_TeamOrdersMenu_Init -=============== -*/ -static void UI_TeamOrdersMenu_Init( void ) { - UI_TeamOrdersMenu_Cache(); - - memset( &teamOrdersMenuInfo, 0, sizeof(teamOrdersMenuInfo) ); - teamOrdersMenuInfo.menu.fullscreen = qfalse; - teamOrdersMenuInfo.menu.key = UI_TeamOrdersMenu_Key; - - UI_TeamOrdersMenu_BuildBotList(); - - teamOrdersMenuInfo.banner.generic.type = MTYPE_BTEXT; - teamOrdersMenuInfo.banner.generic.x = 320; - teamOrdersMenuInfo.banner.generic.y = 16; - teamOrdersMenuInfo.banner.string = "TEAM ORDERS"; - teamOrdersMenuInfo.banner.color = color_white; - teamOrdersMenuInfo.banner.style = UI_CENTER; - - teamOrdersMenuInfo.frame.generic.type = MTYPE_BITMAP; - teamOrdersMenuInfo.frame.generic.flags = QMF_INACTIVE; - teamOrdersMenuInfo.frame.generic.name = ART_FRAME; - teamOrdersMenuInfo.frame.generic.x = 320-233; - teamOrdersMenuInfo.frame.generic.y = 240-166; - teamOrdersMenuInfo.frame.width = 466; - teamOrdersMenuInfo.frame.height = 332; - - teamOrdersMenuInfo.list.generic.type = MTYPE_SCROLLLIST; - teamOrdersMenuInfo.list.generic.flags = QMF_PULSEIFFOCUS; - teamOrdersMenuInfo.list.generic.ownerdraw = UI_TeamOrdersMenu_ListDraw; - teamOrdersMenuInfo.list.generic.callback = UI_TeamOrdersMenu_ListEvent; - teamOrdersMenuInfo.list.generic.x = 320-64; - teamOrdersMenuInfo.list.generic.y = 120; - - teamOrdersMenuInfo.back.generic.type = MTYPE_BITMAP; - teamOrdersMenuInfo.back.generic.name = ART_BACK0; - teamOrdersMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - teamOrdersMenuInfo.back.generic.callback = UI_TeamOrdersMenu_BackEvent; - teamOrdersMenuInfo.back.generic.x = 0; - teamOrdersMenuInfo.back.generic.y = 480-64; - teamOrdersMenuInfo.back.width = 128; - teamOrdersMenuInfo.back.height = 64; - teamOrdersMenuInfo.back.focuspic = ART_BACK1; - - Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.banner ); - Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.frame ); - Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.list ); - Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.back ); - - teamOrdersMenuInfo.list.generic.left = 220; - teamOrdersMenuInfo.list.generic.top = teamOrdersMenuInfo.list.generic.y; - teamOrdersMenuInfo.list.generic.right = 420; - UI_TeamOrdersMenu_SetList( ID_LIST_BOTS ); -} - - -/* -================= -UI_TeamOrdersMenu_Cache -================= -*/ -void UI_TeamOrdersMenu_Cache( void ) { - trap_R_RegisterShaderNoMip( ART_FRAME ); - trap_R_RegisterShaderNoMip( ART_BACK0 ); - trap_R_RegisterShaderNoMip( ART_BACK1 ); -} - - -/* -=============== -UI_TeamOrdersMenu -=============== -*/ -void UI_TeamOrdersMenu( void ) { - UI_TeamOrdersMenu_Init(); - UI_PushMenu( &teamOrdersMenuInfo.menu ); -} - - -/* -=============== -UI_TeamOrdersMenu_f -=============== -*/ -void UI_TeamOrdersMenu_f( void ) { - uiClientState_t cs; - char info[MAX_INFO_STRING]; - int team; - - // make sure it's a team game - trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); - teamOrdersMenuInfo.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) ); - if( teamOrdersMenuInfo.gametype < GT_TEAM ) { - return; - } - - // not available to spectators - trap_GetClientState( &cs ); - trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); - team = atoi( Info_ValueForKey( info, "t" ) ); - if( team == TEAM_SPECTATOR ) { - return; - } - - UI_TeamOrdersMenu(); -} +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +/* +======================================================================= + +TEAM ORDERS MENU + +======================================================================= +*/ + + +#include "ui_local.h" + + +#define ART_FRAME "menu/art/addbotframe" +#define ART_BACK0 "menu/art/back_0" +#define ART_BACK1 "menu/art/back_1" + +#define ID_LIST_BOTS 10 +#define ID_LIST_CTF_ORDERS 11 +#define ID_LIST_TEAM_ORDERS 12 + + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s frame; + + menulist_s list; + + menubitmap_s back; + + int gametype; + int numBots; + int selectedBot; + char *bots[9]; + char botNames[9][16]; +} teamOrdersMenuInfo_t; + +static teamOrdersMenuInfo_t teamOrdersMenuInfo; + +#define NUM_CTF_ORDERS 7 +static const char *ctfOrders[] = { + "I Am the Leader", + "Defend the Base", + "Follow Me", + "Get Enemy Flag", + "Camp Here", + "Report", + "I Relinquish Command", + NULL +}; +static const char *ctfMessages[] = { + "i am the leader", + "%s defend the base", + "%s follow me", + "%s get enemy flag", + "%s camp here", + "%s report", + "i stop being the leader", + NULL +}; + +#define NUM_TEAM_ORDERS 6 +static const char *teamOrders[] = { + "I Am the Leader", + "Follow Me", + "Roam", + "Camp Here", + "Report", + "I Relinquish Command", + NULL +}; +static const char *teamMessages[] = { + "i am the leader", + "%s follow me", + "%s roam", + "%s camp here", + "%s report", + "i stop being the leader", + NULL +}; + + +/* +=============== +UI_TeamOrdersMenu_BackEvent +=============== +*/ +static void UI_TeamOrdersMenu_BackEvent( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + UI_PopMenu(); +} + + +/* +=============== +UI_TeamOrdersMenu_SetList +=============== +*/ +static void UI_TeamOrdersMenu_SetList( int id ) { + switch( id ) { + default: + case ID_LIST_BOTS: + teamOrdersMenuInfo.list.generic.id = id; + teamOrdersMenuInfo.list.numitems = teamOrdersMenuInfo.numBots; + teamOrdersMenuInfo.list.itemnames = (const char **)teamOrdersMenuInfo.bots; + break; + + case ID_LIST_CTF_ORDERS: + teamOrdersMenuInfo.list.generic.id = id; + teamOrdersMenuInfo.list.numitems = NUM_CTF_ORDERS; + teamOrdersMenuInfo.list.itemnames = ctfOrders; + break; + + case ID_LIST_TEAM_ORDERS: + teamOrdersMenuInfo.list.generic.id = id; + teamOrdersMenuInfo.list.numitems = NUM_TEAM_ORDERS; + teamOrdersMenuInfo.list.itemnames = teamOrders; + break; + } + + teamOrdersMenuInfo.list.generic.bottom = teamOrdersMenuInfo.list.generic.top + teamOrdersMenuInfo.list.numitems * PROP_HEIGHT; +} + + +/* +================= +UI_TeamOrdersMenu_Key +================= +*/ +sfxHandle_t UI_TeamOrdersMenu_Key( int key ) { + menulist_s *l; + int x; + int y; + int index; + + l = (menulist_s *)Menu_ItemAtCursor( &teamOrdersMenuInfo.menu ); + if( l != &teamOrdersMenuInfo.list ) { + return Menu_DefaultKey( &teamOrdersMenuInfo.menu, key ); + } + + switch( key ) { + case K_MOUSE1: + x = l->generic.left; + y = l->generic.top; + if( UI_CursorInRect( x, y, l->generic.right - x, l->generic.bottom - y ) ) { + index = (uis.cursory - y) / PROP_HEIGHT; + l->oldvalue = l->curvalue; + l->curvalue = index; + + if( l->generic.callback ) { + l->generic.callback( l, QM_ACTIVATED ); + return menu_move_sound; + } + } + return menu_null_sound; + + case K_KP_UPARROW: + case K_UPARROW: + l->oldvalue = l->curvalue; + + if( l->curvalue == 0 ) { + l->curvalue = l->numitems - 1; + } + else { + l->curvalue--; + } + return menu_move_sound; + + case K_KP_DOWNARROW: + case K_DOWNARROW: + l->oldvalue = l->curvalue; + + if( l->curvalue == l->numitems - 1 ) { + l->curvalue = 0;; + } + else { + l->curvalue++; + } + return menu_move_sound; + } + + return Menu_DefaultKey( &teamOrdersMenuInfo.menu, key ); +} + + +/* +================= +UI_TeamOrdersMenu_ListDraw +================= +*/ +static void UI_TeamOrdersMenu_ListDraw( void *self ) { + menulist_s *l; + int x; + int y; + int i; + float *color; + qboolean hasfocus; + int style; + + l = (menulist_s *)self; + + hasfocus = (l->generic.parent->cursor == l->generic.menuPosition); + + x = 320;//l->generic.x; + y = l->generic.y; + for( i = 0; i < l->numitems; i++ ) { + style = UI_LEFT|UI_SMALLFONT|UI_CENTER; + if( i == l->curvalue ) { + color = color_yellow; + if( hasfocus ) { + style |= UI_PULSE; + } + } + else { + color = color_orange; + } + + UI_DrawProportionalString( x, y, l->itemnames[i], style, color ); + y += PROP_HEIGHT; + } +} + + +/* +=============== +UI_TeamOrdersMenu_ListEvent +=============== +*/ +static void UI_TeamOrdersMenu_ListEvent( void *ptr, int event ) { + int id; + int selection; + char message[256]; + + if (event != QM_ACTIVATED) + return; + + id = ((menulist_s *)ptr)->generic.id; + selection = ((menulist_s *)ptr)->curvalue; + + if( id == ID_LIST_BOTS ) { + teamOrdersMenuInfo.selectedBot = selection; + if( teamOrdersMenuInfo.gametype == GT_CTF ) { + UI_TeamOrdersMenu_SetList( ID_LIST_CTF_ORDERS ); + } + else { + UI_TeamOrdersMenu_SetList( ID_LIST_TEAM_ORDERS ); + } + return; + } + + if( id == ID_LIST_CTF_ORDERS ) { + Com_sprintf( message, sizeof(message), ctfMessages[selection], teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.selectedBot] ); + } + else { + Com_sprintf( message, sizeof(message), teamMessages[selection], teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.selectedBot] ); + } + + trap_Cmd_ExecuteText( EXEC_APPEND, va( "say_team \"%s\"\n", message ) ); + UI_PopMenu(); +} + + +/* +=============== +UI_TeamOrdersMenu_BuildBotList +=============== +*/ +static void UI_TeamOrdersMenu_BuildBotList( void ) { + uiClientState_t cs; + int numPlayers; + int isBot; + int n; + char playerTeam; + char botTeam; + char info[MAX_INFO_STRING]; + + for( n = 0; n < 9; n++ ) { + teamOrdersMenuInfo.bots[n] = teamOrdersMenuInfo.botNames[n]; + } + + trap_GetClientState( &cs ); + + Q_strncpyz( teamOrdersMenuInfo.botNames[0], "Everyone", 16 ); + teamOrdersMenuInfo.numBots = 1; + + trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); + numPlayers = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); + teamOrdersMenuInfo.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) ); + + for( n = 0; n < numPlayers && teamOrdersMenuInfo.numBots < 9; n++ ) { + trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); + + playerTeam = TEAM_SPECTATOR; // bk001204 = possible uninit use + + if( n == cs.clientNum ) { + playerTeam = *Info_ValueForKey( info, "t" ); + continue; + } + + isBot = atoi( Info_ValueForKey( info, "skill" ) ); + if( !isBot ) { + continue; + } + + botTeam = *Info_ValueForKey( info, "t" ); + if( botTeam != playerTeam ) { + continue; + } + + Q_strncpyz( teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots], Info_ValueForKey( info, "n" ), 16 ); + Q_CleanStr( teamOrdersMenuInfo.botNames[teamOrdersMenuInfo.numBots] ); + teamOrdersMenuInfo.numBots++; + } +} + + +/* +=============== +UI_TeamOrdersMenu_Init +=============== +*/ +static void UI_TeamOrdersMenu_Init( void ) { + UI_TeamOrdersMenu_Cache(); + + memset( &teamOrdersMenuInfo, 0, sizeof(teamOrdersMenuInfo) ); + teamOrdersMenuInfo.menu.fullscreen = qfalse; + teamOrdersMenuInfo.menu.key = UI_TeamOrdersMenu_Key; + + UI_TeamOrdersMenu_BuildBotList(); + + teamOrdersMenuInfo.banner.generic.type = MTYPE_BTEXT; + teamOrdersMenuInfo.banner.generic.x = 320; + teamOrdersMenuInfo.banner.generic.y = 16; + teamOrdersMenuInfo.banner.string = "TEAM ORDERS"; + teamOrdersMenuInfo.banner.color = color_white; + teamOrdersMenuInfo.banner.style = UI_CENTER; + + teamOrdersMenuInfo.frame.generic.type = MTYPE_BITMAP; + teamOrdersMenuInfo.frame.generic.flags = QMF_INACTIVE; + teamOrdersMenuInfo.frame.generic.name = ART_FRAME; + teamOrdersMenuInfo.frame.generic.x = 320-233; + teamOrdersMenuInfo.frame.generic.y = 240-166; + teamOrdersMenuInfo.frame.width = 466; + teamOrdersMenuInfo.frame.height = 332; + + teamOrdersMenuInfo.list.generic.type = MTYPE_SCROLLLIST; + teamOrdersMenuInfo.list.generic.flags = QMF_PULSEIFFOCUS; + teamOrdersMenuInfo.list.generic.ownerdraw = UI_TeamOrdersMenu_ListDraw; + teamOrdersMenuInfo.list.generic.callback = UI_TeamOrdersMenu_ListEvent; + teamOrdersMenuInfo.list.generic.x = 320-64; + teamOrdersMenuInfo.list.generic.y = 120; + + teamOrdersMenuInfo.back.generic.type = MTYPE_BITMAP; + teamOrdersMenuInfo.back.generic.name = ART_BACK0; + teamOrdersMenuInfo.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + teamOrdersMenuInfo.back.generic.callback = UI_TeamOrdersMenu_BackEvent; + teamOrdersMenuInfo.back.generic.x = 0; + teamOrdersMenuInfo.back.generic.y = 480-64; + teamOrdersMenuInfo.back.width = 128; + teamOrdersMenuInfo.back.height = 64; + teamOrdersMenuInfo.back.focuspic = ART_BACK1; + + Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.banner ); + Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.frame ); + Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.list ); + Menu_AddItem( &teamOrdersMenuInfo.menu, &teamOrdersMenuInfo.back ); + + teamOrdersMenuInfo.list.generic.left = 220; + teamOrdersMenuInfo.list.generic.top = teamOrdersMenuInfo.list.generic.y; + teamOrdersMenuInfo.list.generic.right = 420; + UI_TeamOrdersMenu_SetList( ID_LIST_BOTS ); +} + + +/* +================= +UI_TeamOrdersMenu_Cache +================= +*/ +void UI_TeamOrdersMenu_Cache( void ) { + trap_R_RegisterShaderNoMip( ART_FRAME ); + trap_R_RegisterShaderNoMip( ART_BACK0 ); + trap_R_RegisterShaderNoMip( ART_BACK1 ); +} + + +/* +=============== +UI_TeamOrdersMenu +=============== +*/ +void UI_TeamOrdersMenu( void ) { + UI_TeamOrdersMenu_Init(); + UI_PushMenu( &teamOrdersMenuInfo.menu ); +} + + +/* +=============== +UI_TeamOrdersMenu_f +=============== +*/ +void UI_TeamOrdersMenu_f( void ) { + uiClientState_t cs; + char info[MAX_INFO_STRING]; + int team; + + // make sure it's a team game + trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ); + teamOrdersMenuInfo.gametype = atoi( Info_ValueForKey( info, "g_gametype" ) ); + if( teamOrdersMenuInfo.gametype < GT_TEAM ) { + return; + } + + // not available to spectators + trap_GetClientState( &cs ); + trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING ); + team = atoi( Info_ValueForKey( info, "t" ) ); + if( team == TEAM_SPECTATOR ) { + return; + } + + UI_TeamOrdersMenu(); +} diff --git a/code/q3_ui/ui_video.c b/code/q3_ui/ui_video.c index 8784245..a7f16f4 100755 --- a/code/q3_ui/ui_video.c +++ b/code/q3_ui/ui_video.c @@ -1,1070 +1,1070 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code is free software; you can redistribute it -and/or modify it under the terms of the GNU General Public License as -published by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -Quake III Arena source code is distributed in the hope that it will be -useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// -#include "ui_local.h" - -void GraphicsOptions_MenuInit( void ); - -/* -======================================================================= - -DRIVER INFORMATION MENU - -======================================================================= -*/ - - -#define DRIVERINFO_FRAMEL "menu/art/frame2_l" -#define DRIVERINFO_FRAMER "menu/art/frame1_r" -#define DRIVERINFO_BACK0 "menu/art/back_0" -#define DRIVERINFO_BACK1 "menu/art/back_1" - -static char* driverinfo_artlist[] = -{ - DRIVERINFO_FRAMEL, - DRIVERINFO_FRAMER, - DRIVERINFO_BACK0, - DRIVERINFO_BACK1, - NULL, -}; - -#define ID_DRIVERINFOBACK 100 - -typedef struct -{ - menuframework_s menu; - menutext_s banner; - menubitmap_s back; - menubitmap_s framel; - menubitmap_s framer; - char stringbuff[1024]; - char* strings[64]; - int numstrings; -} driverinfo_t; - -static driverinfo_t s_driverinfo; - -/* -================= -DriverInfo_Event -================= -*/ -static void DriverInfo_Event( void* ptr, int event ) -{ - if (event != QM_ACTIVATED) - return; - - switch (((menucommon_s*)ptr)->id) - { - case ID_DRIVERINFOBACK: - UI_PopMenu(); - break; - } -} - -/* -================= -DriverInfo_MenuDraw -================= -*/ -static void DriverInfo_MenuDraw( void ) -{ - int i; - int y; - - Menu_Draw( &s_driverinfo.menu ); - - UI_DrawString( 320, 80, "VENDOR", UI_CENTER|UI_SMALLFONT, color_red ); - UI_DrawString( 320, 152, "PIXELFORMAT", UI_CENTER|UI_SMALLFONT, color_red ); - UI_DrawString( 320, 192, "EXTENSIONS", UI_CENTER|UI_SMALLFONT, color_red ); - - UI_DrawString( 320, 80+16, uis.glconfig.vendor_string, UI_CENTER|UI_SMALLFONT, text_color_normal ); - UI_DrawString( 320, 96+16, uis.glconfig.version_string, UI_CENTER|UI_SMALLFONT, text_color_normal ); - UI_DrawString( 320, 112+16, uis.glconfig.renderer_string, UI_CENTER|UI_SMALLFONT, text_color_normal ); - UI_DrawString( 320, 152+16, va ("color(%d-bits) Z(%d-bits) stencil(%d-bits)", uis.glconfig.colorBits, uis.glconfig.depthBits, uis.glconfig.stencilBits), UI_CENTER|UI_SMALLFONT, text_color_normal ); - - // double column - y = 192+16; - for (i=0; i 32) { - s_driverinfo.strings[i][len-1] = '>'; - s_driverinfo.strings[i][len] = '\0'; - } - } - - Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.banner ); - Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.framel ); - Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.framer ); - Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.back ); - - UI_PushMenu( &s_driverinfo.menu ); -} - -/* -======================================================================= - -GRAPHICS OPTIONS MENU - -======================================================================= -*/ - -#define GRAPHICSOPTIONS_FRAMEL "menu/art/frame2_l" -#define GRAPHICSOPTIONS_FRAMER "menu/art/frame1_r" -#define GRAPHICSOPTIONS_BACK0 "menu/art/back_0" -#define GRAPHICSOPTIONS_BACK1 "menu/art/back_1" -#define GRAPHICSOPTIONS_ACCEPT0 "menu/art/accept_0" -#define GRAPHICSOPTIONS_ACCEPT1 "menu/art/accept_1" - -static const char *s_drivers[] = -{ - OPENGL_DRIVER_NAME, - _3DFX_DRIVER_NAME, - 0 -}; - -#define ID_BACK2 101 -#define ID_FULLSCREEN 102 -#define ID_LIST 103 -#define ID_MODE 104 -#define ID_DRIVERINFO 105 -#define ID_GRAPHICS 106 -#define ID_DISPLAY 107 -#define ID_SOUND 108 -#define ID_NETWORK 109 - -typedef struct { - menuframework_s menu; - - menutext_s banner; - menubitmap_s framel; - menubitmap_s framer; - - menutext_s graphics; - menutext_s display; - menutext_s sound; - menutext_s network; - - menulist_s list; - menulist_s mode; - menulist_s driver; - menuslider_s tq; - menulist_s fs; - menulist_s lighting; - menulist_s allow_extensions; - menulist_s texturebits; - menulist_s colordepth; - menulist_s geometry; - menulist_s filter; - menutext_s driverinfo; - - menubitmap_s apply; - menubitmap_s back; -} graphicsoptions_t; - -typedef struct -{ - int mode; - qboolean fullscreen; - int tq; - int lighting; - int colordepth; - int texturebits; - int geometry; - int filter; - int driver; - qboolean extensions; -} InitialVideoOptions_s; - -static InitialVideoOptions_s s_ivo; -static graphicsoptions_t s_graphicsoptions; - -static InitialVideoOptions_s s_ivo_templates[] = -{ - { - 4, qtrue, 2, 0, 2, 2, 1, 1, 0, qtrue // JDC: this was tq 3 - }, - { - 3, qtrue, 2, 0, 0, 0, 1, 0, 0, qtrue - }, - { - 2, qtrue, 1, 0, 1, 0, 0, 0, 0, qtrue - }, - { - 2, qtrue, 1, 1, 1, 0, 0, 0, 0, qtrue - }, - { - 3, qtrue, 1, 0, 0, 0, 1, 0, 0, qtrue - } -}; - -#define NUM_IVO_TEMPLATES ( sizeof( s_ivo_templates ) / sizeof( s_ivo_templates[0] ) ) - -/* -================= -GraphicsOptions_GetInitialVideo -================= -*/ -static void GraphicsOptions_GetInitialVideo( void ) -{ - s_ivo.colordepth = s_graphicsoptions.colordepth.curvalue; - s_ivo.driver = s_graphicsoptions.driver.curvalue; - s_ivo.mode = s_graphicsoptions.mode.curvalue; - s_ivo.fullscreen = s_graphicsoptions.fs.curvalue; - s_ivo.extensions = s_graphicsoptions.allow_extensions.curvalue; - s_ivo.tq = s_graphicsoptions.tq.curvalue; - s_ivo.lighting = s_graphicsoptions.lighting.curvalue; - s_ivo.geometry = s_graphicsoptions.geometry.curvalue; - s_ivo.filter = s_graphicsoptions.filter.curvalue; - s_ivo.texturebits = s_graphicsoptions.texturebits.curvalue; -} - -/* -================= -GraphicsOptions_CheckConfig -================= -*/ -static void GraphicsOptions_CheckConfig( void ) -{ - int i; - - for ( i = 0; i < NUM_IVO_TEMPLATES; i++ ) - { - if ( s_ivo_templates[i].colordepth != s_graphicsoptions.colordepth.curvalue ) - continue; - if ( s_ivo_templates[i].driver != s_graphicsoptions.driver.curvalue ) - continue; - if ( s_ivo_templates[i].mode != s_graphicsoptions.mode.curvalue ) - continue; - if ( s_ivo_templates[i].fullscreen != s_graphicsoptions.fs.curvalue ) - continue; - if ( s_ivo_templates[i].tq != s_graphicsoptions.tq.curvalue ) - continue; - if ( s_ivo_templates[i].lighting != s_graphicsoptions.lighting.curvalue ) - continue; - if ( s_ivo_templates[i].geometry != s_graphicsoptions.geometry.curvalue ) - continue; - if ( s_ivo_templates[i].filter != s_graphicsoptions.filter.curvalue ) - continue; -// if ( s_ivo_templates[i].texturebits != s_graphicsoptions.texturebits.curvalue ) -// continue; - s_graphicsoptions.list.curvalue = i; - return; - } - s_graphicsoptions.list.curvalue = 4; -} - -/* -================= -GraphicsOptions_UpdateMenuItems -================= -*/ -static void GraphicsOptions_UpdateMenuItems( void ) -{ - if ( s_graphicsoptions.driver.curvalue == 1 ) - { - s_graphicsoptions.fs.curvalue = 1; - s_graphicsoptions.fs.generic.flags |= QMF_GRAYED; - s_graphicsoptions.colordepth.curvalue = 1; - } - else - { - s_graphicsoptions.fs.generic.flags &= ~QMF_GRAYED; - } - - if ( s_graphicsoptions.fs.curvalue == 0 || s_graphicsoptions.driver.curvalue == 1 ) - { - s_graphicsoptions.colordepth.curvalue = 0; - s_graphicsoptions.colordepth.generic.flags |= QMF_GRAYED; - } - else - { - s_graphicsoptions.colordepth.generic.flags &= ~QMF_GRAYED; - } - - if ( s_graphicsoptions.allow_extensions.curvalue == 0 ) - { - if ( s_graphicsoptions.texturebits.curvalue == 0 ) - { - s_graphicsoptions.texturebits.curvalue = 1; - } - } - - s_graphicsoptions.apply.generic.flags |= QMF_HIDDEN|QMF_INACTIVE; - - if ( s_ivo.mode != s_graphicsoptions.mode.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.fullscreen != s_graphicsoptions.fs.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.extensions != s_graphicsoptions.allow_extensions.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.tq != s_graphicsoptions.tq.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.lighting != s_graphicsoptions.lighting.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.colordepth != s_graphicsoptions.colordepth.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.driver != s_graphicsoptions.driver.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.texturebits != s_graphicsoptions.texturebits.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.geometry != s_graphicsoptions.geometry.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - if ( s_ivo.filter != s_graphicsoptions.filter.curvalue ) - { - s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); - } - - GraphicsOptions_CheckConfig(); -} - -/* -================= -GraphicsOptions_ApplyChanges -================= -*/ -static void GraphicsOptions_ApplyChanges( void *unused, int notification ) -{ - if (notification != QM_ACTIVATED) - return; - - switch ( s_graphicsoptions.texturebits.curvalue ) - { - case 0: - trap_Cvar_SetValue( "r_texturebits", 0 ); - break; - case 1: - trap_Cvar_SetValue( "r_texturebits", 16 ); - break; - case 2: - trap_Cvar_SetValue( "r_texturebits", 32 ); - break; - } - trap_Cvar_SetValue( "r_picmip", 3 - s_graphicsoptions.tq.curvalue ); - trap_Cvar_SetValue( "r_allowExtensions", s_graphicsoptions.allow_extensions.curvalue ); - trap_Cvar_SetValue( "r_mode", s_graphicsoptions.mode.curvalue ); - trap_Cvar_SetValue( "r_fullscreen", s_graphicsoptions.fs.curvalue ); - trap_Cvar_Set( "r_glDriver", ( char * ) s_drivers[s_graphicsoptions.driver.curvalue] ); - switch ( s_graphicsoptions.colordepth.curvalue ) - { - case 0: - trap_Cvar_SetValue( "r_colorbits", 0 ); - trap_Cvar_SetValue( "r_depthbits", 0 ); - trap_Cvar_SetValue( "r_stencilbits", 0 ); - break; - case 1: - trap_Cvar_SetValue( "r_colorbits", 16 ); - trap_Cvar_SetValue( "r_depthbits", 16 ); - trap_Cvar_SetValue( "r_stencilbits", 0 ); - break; - case 2: - trap_Cvar_SetValue( "r_colorbits", 32 ); - trap_Cvar_SetValue( "r_depthbits", 24 ); - break; - } - trap_Cvar_SetValue( "r_vertexLight", s_graphicsoptions.lighting.curvalue ); - - if ( s_graphicsoptions.geometry.curvalue == 2 ) - { - trap_Cvar_SetValue( "r_lodBias", 0 ); - trap_Cvar_SetValue( "r_subdivisions", 4 ); - } - else if ( s_graphicsoptions.geometry.curvalue == 1 ) - { - trap_Cvar_SetValue( "r_lodBias", 1 ); - trap_Cvar_SetValue( "r_subdivisions", 12 ); - } - else - { - trap_Cvar_SetValue( "r_lodBias", 1 ); - trap_Cvar_SetValue( "r_subdivisions", 20 ); - } - - if ( s_graphicsoptions.filter.curvalue ) - { - trap_Cvar_Set( "r_textureMode", "GL_LINEAR_MIPMAP_LINEAR" ); - } - else - { - trap_Cvar_Set( "r_textureMode", "GL_LINEAR_MIPMAP_NEAREST" ); - } - - trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); -} - -/* -================= -GraphicsOptions_Event -================= -*/ -static void GraphicsOptions_Event( void* ptr, int event ) { - InitialVideoOptions_s *ivo; - - if( event != QM_ACTIVATED ) { - return; - } - - switch( ((menucommon_s*)ptr)->id ) { - case ID_MODE: - // clamp 3dfx video modes - if ( s_graphicsoptions.driver.curvalue == 1 ) - { - if ( s_graphicsoptions.mode.curvalue < 2 ) - s_graphicsoptions.mode.curvalue = 2; - else if ( s_graphicsoptions.mode.curvalue > 6 ) - s_graphicsoptions.mode.curvalue = 6; - } - break; - - case ID_LIST: - ivo = &s_ivo_templates[s_graphicsoptions.list.curvalue]; - - s_graphicsoptions.mode.curvalue = ivo->mode; - s_graphicsoptions.tq.curvalue = ivo->tq; - s_graphicsoptions.lighting.curvalue = ivo->lighting; - s_graphicsoptions.colordepth.curvalue = ivo->colordepth; - s_graphicsoptions.texturebits.curvalue = ivo->texturebits; - s_graphicsoptions.geometry.curvalue = ivo->geometry; - s_graphicsoptions.filter.curvalue = ivo->filter; - s_graphicsoptions.fs.curvalue = ivo->fullscreen; - break; - - case ID_DRIVERINFO: - UI_DriverInfo_Menu(); - break; - - case ID_BACK2: - UI_PopMenu(); - break; - - case ID_GRAPHICS: - break; - - case ID_DISPLAY: - UI_PopMenu(); - UI_DisplayOptionsMenu(); - break; - - case ID_SOUND: - UI_PopMenu(); - UI_SoundOptionsMenu(); - break; - - case ID_NETWORK: - UI_PopMenu(); - UI_NetworkOptionsMenu(); - break; - } -} - - -/* -================ -GraphicsOptions_TQEvent -================ -*/ -static void GraphicsOptions_TQEvent( void *ptr, int event ) { - if( event != QM_ACTIVATED ) { - return; - } - s_graphicsoptions.tq.curvalue = (int)(s_graphicsoptions.tq.curvalue + 0.5); -} - - -/* -================ -GraphicsOptions_MenuDraw -================ -*/ -void GraphicsOptions_MenuDraw (void) -{ -//APSFIX - rework this - GraphicsOptions_UpdateMenuItems(); - - Menu_Draw( &s_graphicsoptions.menu ); -} - -/* -================= -GraphicsOptions_SetMenuItems -================= -*/ -static void GraphicsOptions_SetMenuItems( void ) -{ - s_graphicsoptions.mode.curvalue = trap_Cvar_VariableValue( "r_mode" ); - if ( s_graphicsoptions.mode.curvalue < 0 ) - { - s_graphicsoptions.mode.curvalue = 3; - } - s_graphicsoptions.fs.curvalue = trap_Cvar_VariableValue("r_fullscreen"); - s_graphicsoptions.allow_extensions.curvalue = trap_Cvar_VariableValue("r_allowExtensions"); - s_graphicsoptions.tq.curvalue = 3-trap_Cvar_VariableValue( "r_picmip"); - if ( s_graphicsoptions.tq.curvalue < 0 ) - { - s_graphicsoptions.tq.curvalue = 0; - } - else if ( s_graphicsoptions.tq.curvalue > 3 ) - { - s_graphicsoptions.tq.curvalue = 3; - } - - s_graphicsoptions.lighting.curvalue = trap_Cvar_VariableValue( "r_vertexLight" ) != 0; - switch ( ( int ) trap_Cvar_VariableValue( "r_texturebits" ) ) - { - default: - case 0: - s_graphicsoptions.texturebits.curvalue = 0; - break; - case 16: - s_graphicsoptions.texturebits.curvalue = 1; - break; - case 32: - s_graphicsoptions.texturebits.curvalue = 2; - break; - } - - if ( !Q_stricmp( UI_Cvar_VariableString( "r_textureMode" ), "GL_LINEAR_MIPMAP_NEAREST" ) ) - { - s_graphicsoptions.filter.curvalue = 0; - } - else - { - s_graphicsoptions.filter.curvalue = 1; - } - - if ( trap_Cvar_VariableValue( "r_lodBias" ) > 0 ) - { - if ( trap_Cvar_VariableValue( "r_subdivisions" ) >= 20 ) - { - s_graphicsoptions.geometry.curvalue = 0; - } - else - { - s_graphicsoptions.geometry.curvalue = 1; - } - } - else - { - s_graphicsoptions.geometry.curvalue = 2; - } - - switch ( ( int ) trap_Cvar_VariableValue( "r_colorbits" ) ) - { - default: - case 0: - s_graphicsoptions.colordepth.curvalue = 0; - break; - case 16: - s_graphicsoptions.colordepth.curvalue = 1; - break; - case 32: - s_graphicsoptions.colordepth.curvalue = 2; - break; - } - - if ( s_graphicsoptions.fs.curvalue == 0 ) - { - s_graphicsoptions.colordepth.curvalue = 0; - } - if ( s_graphicsoptions.driver.curvalue == 1 ) - { - s_graphicsoptions.colordepth.curvalue = 1; - } -} - -/* -================ -GraphicsOptions_MenuInit -================ -*/ -void GraphicsOptions_MenuInit( void ) -{ - static const char *s_driver_names[] = - { - "Default", - "Voodoo", - 0 - }; - - static const char *tq_names[] = - { - "Default", - "16 bit", - "32 bit", - 0 - }; - - static const char *s_graphics_options_names[] = - { - "High Quality", - "Normal", - "Fast", - "Fastest", - "Custom", - 0 - }; - - static const char *lighting_names[] = - { - "Lightmap", - "Vertex", - 0 - }; - - static const char *colordepth_names[] = - { - "Default", - "16 bit", - "32 bit", - 0 - }; - - static const char *resolutions[] = - { - "320x240", - "400x300", - "512x384", - "640x480", - "800x600", - "960x720", - "1024x768", - "1152x864", - "1280x1024", - "1600x1200", - "2048x1536", - "856x480 wide screen", - 0 - }; - static const char *filter_names[] = - { - "Bilinear", - "Trilinear", - 0 - }; - static const char *quality_names[] = - { - "Low", - "Medium", - "High", - 0 - }; - static const char *enabled_names[] = - { - "Off", - "On", - 0 - }; - - int y; - - // zero set all our globals - memset( &s_graphicsoptions, 0 ,sizeof(graphicsoptions_t) ); - - GraphicsOptions_Cache(); - - s_graphicsoptions.menu.wrapAround = qtrue; - s_graphicsoptions.menu.fullscreen = qtrue; - s_graphicsoptions.menu.draw = GraphicsOptions_MenuDraw; - - s_graphicsoptions.banner.generic.type = MTYPE_BTEXT; - s_graphicsoptions.banner.generic.x = 320; - s_graphicsoptions.banner.generic.y = 16; - s_graphicsoptions.banner.string = "SYSTEM SETUP"; - s_graphicsoptions.banner.color = color_white; - s_graphicsoptions.banner.style = UI_CENTER; - - s_graphicsoptions.framel.generic.type = MTYPE_BITMAP; - s_graphicsoptions.framel.generic.name = GRAPHICSOPTIONS_FRAMEL; - s_graphicsoptions.framel.generic.flags = QMF_INACTIVE; - s_graphicsoptions.framel.generic.x = 0; - s_graphicsoptions.framel.generic.y = 78; - s_graphicsoptions.framel.width = 256; - s_graphicsoptions.framel.height = 329; - - s_graphicsoptions.framer.generic.type = MTYPE_BITMAP; - s_graphicsoptions.framer.generic.name = GRAPHICSOPTIONS_FRAMER; - s_graphicsoptions.framer.generic.flags = QMF_INACTIVE; - s_graphicsoptions.framer.generic.x = 376; - s_graphicsoptions.framer.generic.y = 76; - s_graphicsoptions.framer.width = 256; - s_graphicsoptions.framer.height = 334; - - s_graphicsoptions.graphics.generic.type = MTYPE_PTEXT; - s_graphicsoptions.graphics.generic.flags = QMF_RIGHT_JUSTIFY; - s_graphicsoptions.graphics.generic.id = ID_GRAPHICS; - s_graphicsoptions.graphics.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.graphics.generic.x = 216; - s_graphicsoptions.graphics.generic.y = 240 - 2 * PROP_HEIGHT; - s_graphicsoptions.graphics.string = "GRAPHICS"; - s_graphicsoptions.graphics.style = UI_RIGHT; - s_graphicsoptions.graphics.color = color_red; - - s_graphicsoptions.display.generic.type = MTYPE_PTEXT; - s_graphicsoptions.display.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_graphicsoptions.display.generic.id = ID_DISPLAY; - s_graphicsoptions.display.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.display.generic.x = 216; - s_graphicsoptions.display.generic.y = 240 - PROP_HEIGHT; - s_graphicsoptions.display.string = "DISPLAY"; - s_graphicsoptions.display.style = UI_RIGHT; - s_graphicsoptions.display.color = color_red; - - s_graphicsoptions.sound.generic.type = MTYPE_PTEXT; - s_graphicsoptions.sound.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_graphicsoptions.sound.generic.id = ID_SOUND; - s_graphicsoptions.sound.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.sound.generic.x = 216; - s_graphicsoptions.sound.generic.y = 240; - s_graphicsoptions.sound.string = "SOUND"; - s_graphicsoptions.sound.style = UI_RIGHT; - s_graphicsoptions.sound.color = color_red; - - s_graphicsoptions.network.generic.type = MTYPE_PTEXT; - s_graphicsoptions.network.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; - s_graphicsoptions.network.generic.id = ID_NETWORK; - s_graphicsoptions.network.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.network.generic.x = 216; - s_graphicsoptions.network.generic.y = 240 + PROP_HEIGHT; - s_graphicsoptions.network.string = "NETWORK"; - s_graphicsoptions.network.style = UI_RIGHT; - s_graphicsoptions.network.color = color_red; - - y = 240 - 6 * (BIGCHAR_HEIGHT + 2); - s_graphicsoptions.list.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.list.generic.name = "Graphics Settings:"; - s_graphicsoptions.list.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.list.generic.x = 400; - s_graphicsoptions.list.generic.y = y; - s_graphicsoptions.list.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.list.generic.id = ID_LIST; - s_graphicsoptions.list.itemnames = s_graphics_options_names; - y += 2 * ( BIGCHAR_HEIGHT + 2 ); - - s_graphicsoptions.driver.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.driver.generic.name = "GL Driver:"; - s_graphicsoptions.driver.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.driver.generic.x = 400; - s_graphicsoptions.driver.generic.y = y; - s_graphicsoptions.driver.itemnames = s_driver_names; - s_graphicsoptions.driver.curvalue = (uis.glconfig.driverType == GLDRV_VOODOO); - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_allowExtensions" - s_graphicsoptions.allow_extensions.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.allow_extensions.generic.name = "GL Extensions:"; - s_graphicsoptions.allow_extensions.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.allow_extensions.generic.x = 400; - s_graphicsoptions.allow_extensions.generic.y = y; - s_graphicsoptions.allow_extensions.itemnames = enabled_names; - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_mode" - s_graphicsoptions.mode.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.mode.generic.name = "Video Mode:"; - s_graphicsoptions.mode.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.mode.generic.x = 400; - s_graphicsoptions.mode.generic.y = y; - s_graphicsoptions.mode.itemnames = resolutions; - s_graphicsoptions.mode.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.mode.generic.id = ID_MODE; - y += BIGCHAR_HEIGHT+2; - - // references "r_colorbits" - s_graphicsoptions.colordepth.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.colordepth.generic.name = "Color Depth:"; - s_graphicsoptions.colordepth.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.colordepth.generic.x = 400; - s_graphicsoptions.colordepth.generic.y = y; - s_graphicsoptions.colordepth.itemnames = colordepth_names; - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_fullscreen" - s_graphicsoptions.fs.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.fs.generic.name = "Fullscreen:"; - s_graphicsoptions.fs.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.fs.generic.x = 400; - s_graphicsoptions.fs.generic.y = y; - s_graphicsoptions.fs.itemnames = enabled_names; - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_vertexLight" - s_graphicsoptions.lighting.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.lighting.generic.name = "Lighting:"; - s_graphicsoptions.lighting.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.lighting.generic.x = 400; - s_graphicsoptions.lighting.generic.y = y; - s_graphicsoptions.lighting.itemnames = lighting_names; - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_lodBias" & "subdivisions" - s_graphicsoptions.geometry.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.geometry.generic.name = "Geometric Detail:"; - s_graphicsoptions.geometry.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.geometry.generic.x = 400; - s_graphicsoptions.geometry.generic.y = y; - s_graphicsoptions.geometry.itemnames = quality_names; - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_picmip" - s_graphicsoptions.tq.generic.type = MTYPE_SLIDER; - s_graphicsoptions.tq.generic.name = "Texture Detail:"; - s_graphicsoptions.tq.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.tq.generic.x = 400; - s_graphicsoptions.tq.generic.y = y; - s_graphicsoptions.tq.minvalue = 0; - s_graphicsoptions.tq.maxvalue = 3; - s_graphicsoptions.tq.generic.callback = GraphicsOptions_TQEvent; - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_textureBits" - s_graphicsoptions.texturebits.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.texturebits.generic.name = "Texture Quality:"; - s_graphicsoptions.texturebits.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.texturebits.generic.x = 400; - s_graphicsoptions.texturebits.generic.y = y; - s_graphicsoptions.texturebits.itemnames = tq_names; - y += BIGCHAR_HEIGHT+2; - - // references/modifies "r_textureMode" - s_graphicsoptions.filter.generic.type = MTYPE_SPINCONTROL; - s_graphicsoptions.filter.generic.name = "Texture Filter:"; - s_graphicsoptions.filter.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; - s_graphicsoptions.filter.generic.x = 400; - s_graphicsoptions.filter.generic.y = y; - s_graphicsoptions.filter.itemnames = filter_names; - y += 2*BIGCHAR_HEIGHT; - - s_graphicsoptions.driverinfo.generic.type = MTYPE_PTEXT; - s_graphicsoptions.driverinfo.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; - s_graphicsoptions.driverinfo.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.driverinfo.generic.id = ID_DRIVERINFO; - s_graphicsoptions.driverinfo.generic.x = 320; - s_graphicsoptions.driverinfo.generic.y = y; - s_graphicsoptions.driverinfo.string = "Driver Info"; - s_graphicsoptions.driverinfo.style = UI_CENTER|UI_SMALLFONT; - s_graphicsoptions.driverinfo.color = color_red; - y += BIGCHAR_HEIGHT+2; - - s_graphicsoptions.back.generic.type = MTYPE_BITMAP; - s_graphicsoptions.back.generic.name = GRAPHICSOPTIONS_BACK0; - s_graphicsoptions.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; - s_graphicsoptions.back.generic.callback = GraphicsOptions_Event; - s_graphicsoptions.back.generic.id = ID_BACK2; - s_graphicsoptions.back.generic.x = 0; - s_graphicsoptions.back.generic.y = 480-64; - s_graphicsoptions.back.width = 128; - s_graphicsoptions.back.height = 64; - s_graphicsoptions.back.focuspic = GRAPHICSOPTIONS_BACK1; - - s_graphicsoptions.apply.generic.type = MTYPE_BITMAP; - s_graphicsoptions.apply.generic.name = GRAPHICSOPTIONS_ACCEPT0; - s_graphicsoptions.apply.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_HIDDEN|QMF_INACTIVE; - s_graphicsoptions.apply.generic.callback = GraphicsOptions_ApplyChanges; - s_graphicsoptions.apply.generic.x = 640; - s_graphicsoptions.apply.generic.y = 480-64; - s_graphicsoptions.apply.width = 128; - s_graphicsoptions.apply.height = 64; - s_graphicsoptions.apply.focuspic = GRAPHICSOPTIONS_ACCEPT1; - - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.banner ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.framel ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.framer ); - - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.graphics ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.display ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.sound ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.network ); - - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.list ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.driver ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.allow_extensions ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.mode ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.colordepth ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.fs ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.lighting ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.geometry ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.tq ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.texturebits ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.filter ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.driverinfo ); - - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.back ); - Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.apply ); - - GraphicsOptions_SetMenuItems(); - GraphicsOptions_GetInitialVideo(); - - if ( uis.glconfig.driverType == GLDRV_ICD && - uis.glconfig.hardwareType == GLHW_3DFX_2D3D ) - { - s_graphicsoptions.driver.generic.flags |= QMF_HIDDEN|QMF_INACTIVE; - } -} - - -/* -================= -GraphicsOptions_Cache -================= -*/ -void GraphicsOptions_Cache( void ) { - trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_FRAMEL ); - trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_FRAMER ); - trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_BACK0 ); - trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_BACK1 ); - trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_ACCEPT0 ); - trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_ACCEPT1 ); -} - - -/* -================= -UI_GraphicsOptionsMenu -================= -*/ -void UI_GraphicsOptionsMenu( void ) { - GraphicsOptions_MenuInit(); - UI_PushMenu( &s_graphicsoptions.menu ); - Menu_SetCursorToItem( &s_graphicsoptions.menu, &s_graphicsoptions.graphics ); -} - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +Quake III Arena source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// +#include "ui_local.h" + +void GraphicsOptions_MenuInit( void ); + +/* +======================================================================= + +DRIVER INFORMATION MENU + +======================================================================= +*/ + + +#define DRIVERINFO_FRAMEL "menu/art/frame2_l" +#define DRIVERINFO_FRAMER "menu/art/frame1_r" +#define DRIVERINFO_BACK0 "menu/art/back_0" +#define DRIVERINFO_BACK1 "menu/art/back_1" + +static char* driverinfo_artlist[] = +{ + DRIVERINFO_FRAMEL, + DRIVERINFO_FRAMER, + DRIVERINFO_BACK0, + DRIVERINFO_BACK1, + NULL, +}; + +#define ID_DRIVERINFOBACK 100 + +typedef struct +{ + menuframework_s menu; + menutext_s banner; + menubitmap_s back; + menubitmap_s framel; + menubitmap_s framer; + char stringbuff[1024]; + char* strings[64]; + int numstrings; +} driverinfo_t; + +static driverinfo_t s_driverinfo; + +/* +================= +DriverInfo_Event +================= +*/ +static void DriverInfo_Event( void* ptr, int event ) +{ + if (event != QM_ACTIVATED) + return; + + switch (((menucommon_s*)ptr)->id) + { + case ID_DRIVERINFOBACK: + UI_PopMenu(); + break; + } +} + +/* +================= +DriverInfo_MenuDraw +================= +*/ +static void DriverInfo_MenuDraw( void ) +{ + int i; + int y; + + Menu_Draw( &s_driverinfo.menu ); + + UI_DrawString( 320, 80, "VENDOR", UI_CENTER|UI_SMALLFONT, color_red ); + UI_DrawString( 320, 152, "PIXELFORMAT", UI_CENTER|UI_SMALLFONT, color_red ); + UI_DrawString( 320, 192, "EXTENSIONS", UI_CENTER|UI_SMALLFONT, color_red ); + + UI_DrawString( 320, 80+16, uis.glconfig.vendor_string, UI_CENTER|UI_SMALLFONT, text_color_normal ); + UI_DrawString( 320, 96+16, uis.glconfig.version_string, UI_CENTER|UI_SMALLFONT, text_color_normal ); + UI_DrawString( 320, 112+16, uis.glconfig.renderer_string, UI_CENTER|UI_SMALLFONT, text_color_normal ); + UI_DrawString( 320, 152+16, va ("color(%d-bits) Z(%d-bits) stencil(%d-bits)", uis.glconfig.colorBits, uis.glconfig.depthBits, uis.glconfig.stencilBits), UI_CENTER|UI_SMALLFONT, text_color_normal ); + + // double column + y = 192+16; + for (i=0; i 32) { + s_driverinfo.strings[i][len-1] = '>'; + s_driverinfo.strings[i][len] = '\0'; + } + } + + Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.banner ); + Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.framel ); + Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.framer ); + Menu_AddItem( &s_driverinfo.menu, &s_driverinfo.back ); + + UI_PushMenu( &s_driverinfo.menu ); +} + +/* +======================================================================= + +GRAPHICS OPTIONS MENU + +======================================================================= +*/ + +#define GRAPHICSOPTIONS_FRAMEL "menu/art/frame2_l" +#define GRAPHICSOPTIONS_FRAMER "menu/art/frame1_r" +#define GRAPHICSOPTIONS_BACK0 "menu/art/back_0" +#define GRAPHICSOPTIONS_BACK1 "menu/art/back_1" +#define GRAPHICSOPTIONS_ACCEPT0 "menu/art/accept_0" +#define GRAPHICSOPTIONS_ACCEPT1 "menu/art/accept_1" + +static const char *s_drivers[] = +{ + OPENGL_DRIVER_NAME, + _3DFX_DRIVER_NAME, + 0 +}; + +#define ID_BACK2 101 +#define ID_FULLSCREEN 102 +#define ID_LIST 103 +#define ID_MODE 104 +#define ID_DRIVERINFO 105 +#define ID_GRAPHICS 106 +#define ID_DISPLAY 107 +#define ID_SOUND 108 +#define ID_NETWORK 109 + +typedef struct { + menuframework_s menu; + + menutext_s banner; + menubitmap_s framel; + menubitmap_s framer; + + menutext_s graphics; + menutext_s display; + menutext_s sound; + menutext_s network; + + menulist_s list; + menulist_s mode; + menulist_s driver; + menuslider_s tq; + menulist_s fs; + menulist_s lighting; + menulist_s allow_extensions; + menulist_s texturebits; + menulist_s colordepth; + menulist_s geometry; + menulist_s filter; + menutext_s driverinfo; + + menubitmap_s apply; + menubitmap_s back; +} graphicsoptions_t; + +typedef struct +{ + int mode; + qboolean fullscreen; + int tq; + int lighting; + int colordepth; + int texturebits; + int geometry; + int filter; + int driver; + qboolean extensions; +} InitialVideoOptions_s; + +static InitialVideoOptions_s s_ivo; +static graphicsoptions_t s_graphicsoptions; + +static InitialVideoOptions_s s_ivo_templates[] = +{ + { + 4, qtrue, 2, 0, 2, 2, 1, 1, 0, qtrue // JDC: this was tq 3 + }, + { + 3, qtrue, 2, 0, 0, 0, 1, 0, 0, qtrue + }, + { + 2, qtrue, 1, 0, 1, 0, 0, 0, 0, qtrue + }, + { + 2, qtrue, 1, 1, 1, 0, 0, 0, 0, qtrue + }, + { + 3, qtrue, 1, 0, 0, 0, 1, 0, 0, qtrue + } +}; + +#define NUM_IVO_TEMPLATES ( sizeof( s_ivo_templates ) / sizeof( s_ivo_templates[0] ) ) + +/* +================= +GraphicsOptions_GetInitialVideo +================= +*/ +static void GraphicsOptions_GetInitialVideo( void ) +{ + s_ivo.colordepth = s_graphicsoptions.colordepth.curvalue; + s_ivo.driver = s_graphicsoptions.driver.curvalue; + s_ivo.mode = s_graphicsoptions.mode.curvalue; + s_ivo.fullscreen = s_graphicsoptions.fs.curvalue; + s_ivo.extensions = s_graphicsoptions.allow_extensions.curvalue; + s_ivo.tq = s_graphicsoptions.tq.curvalue; + s_ivo.lighting = s_graphicsoptions.lighting.curvalue; + s_ivo.geometry = s_graphicsoptions.geometry.curvalue; + s_ivo.filter = s_graphicsoptions.filter.curvalue; + s_ivo.texturebits = s_graphicsoptions.texturebits.curvalue; +} + +/* +================= +GraphicsOptions_CheckConfig +================= +*/ +static void GraphicsOptions_CheckConfig( void ) +{ + int i; + + for ( i = 0; i < NUM_IVO_TEMPLATES; i++ ) + { + if ( s_ivo_templates[i].colordepth != s_graphicsoptions.colordepth.curvalue ) + continue; + if ( s_ivo_templates[i].driver != s_graphicsoptions.driver.curvalue ) + continue; + if ( s_ivo_templates[i].mode != s_graphicsoptions.mode.curvalue ) + continue; + if ( s_ivo_templates[i].fullscreen != s_graphicsoptions.fs.curvalue ) + continue; + if ( s_ivo_templates[i].tq != s_graphicsoptions.tq.curvalue ) + continue; + if ( s_ivo_templates[i].lighting != s_graphicsoptions.lighting.curvalue ) + continue; + if ( s_ivo_templates[i].geometry != s_graphicsoptions.geometry.curvalue ) + continue; + if ( s_ivo_templates[i].filter != s_graphicsoptions.filter.curvalue ) + continue; +// if ( s_ivo_templates[i].texturebits != s_graphicsoptions.texturebits.curvalue ) +// continue; + s_graphicsoptions.list.curvalue = i; + return; + } + s_graphicsoptions.list.curvalue = 4; +} + +/* +================= +GraphicsOptions_UpdateMenuItems +================= +*/ +static void GraphicsOptions_UpdateMenuItems( void ) +{ + if ( s_graphicsoptions.driver.curvalue == 1 ) + { + s_graphicsoptions.fs.curvalue = 1; + s_graphicsoptions.fs.generic.flags |= QMF_GRAYED; + s_graphicsoptions.colordepth.curvalue = 1; + } + else + { + s_graphicsoptions.fs.generic.flags &= ~QMF_GRAYED; + } + + if ( s_graphicsoptions.fs.curvalue == 0 || s_graphicsoptions.driver.curvalue == 1 ) + { + s_graphicsoptions.colordepth.curvalue = 0; + s_graphicsoptions.colordepth.generic.flags |= QMF_GRAYED; + } + else + { + s_graphicsoptions.colordepth.generic.flags &= ~QMF_GRAYED; + } + + if ( s_graphicsoptions.allow_extensions.curvalue == 0 ) + { + if ( s_graphicsoptions.texturebits.curvalue == 0 ) + { + s_graphicsoptions.texturebits.curvalue = 1; + } + } + + s_graphicsoptions.apply.generic.flags |= QMF_HIDDEN|QMF_INACTIVE; + + if ( s_ivo.mode != s_graphicsoptions.mode.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.fullscreen != s_graphicsoptions.fs.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.extensions != s_graphicsoptions.allow_extensions.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.tq != s_graphicsoptions.tq.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.lighting != s_graphicsoptions.lighting.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.colordepth != s_graphicsoptions.colordepth.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.driver != s_graphicsoptions.driver.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.texturebits != s_graphicsoptions.texturebits.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.geometry != s_graphicsoptions.geometry.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + if ( s_ivo.filter != s_graphicsoptions.filter.curvalue ) + { + s_graphicsoptions.apply.generic.flags &= ~(QMF_HIDDEN|QMF_INACTIVE); + } + + GraphicsOptions_CheckConfig(); +} + +/* +================= +GraphicsOptions_ApplyChanges +================= +*/ +static void GraphicsOptions_ApplyChanges( void *unused, int notification ) +{ + if (notification != QM_ACTIVATED) + return; + + switch ( s_graphicsoptions.texturebits.curvalue ) + { + case 0: + trap_Cvar_SetValue( "r_texturebits", 0 ); + break; + case 1: + trap_Cvar_SetValue( "r_texturebits", 16 ); + break; + case 2: + trap_Cvar_SetValue( "r_texturebits", 32 ); + break; + } + trap_Cvar_SetValue( "r_picmip", 3 - s_graphicsoptions.tq.curvalue ); + trap_Cvar_SetValue( "r_allowExtensions", s_graphicsoptions.allow_extensions.curvalue ); + trap_Cvar_SetValue( "r_mode", s_graphicsoptions.mode.curvalue ); + trap_Cvar_SetValue( "r_fullscreen", s_graphicsoptions.fs.curvalue ); + trap_Cvar_Set( "r_glDriver", ( char * ) s_drivers[s_graphicsoptions.driver.curvalue] ); + switch ( s_graphicsoptions.colordepth.curvalue ) + { + case 0: + trap_Cvar_SetValue( "r_colorbits", 0 ); + trap_Cvar_SetValue( "r_depthbits", 0 ); + trap_Cvar_SetValue( "r_stencilbits", 0 ); + break; + case 1: + trap_Cvar_SetValue( "r_colorbits", 16 ); + trap_Cvar_SetValue( "r_depthbits", 16 ); + trap_Cvar_SetValue( "r_stencilbits", 0 ); + break; + case 2: + trap_Cvar_SetValue( "r_colorbits", 32 ); + trap_Cvar_SetValue( "r_depthbits", 24 ); + break; + } + trap_Cvar_SetValue( "r_vertexLight", s_graphicsoptions.lighting.curvalue ); + + if ( s_graphicsoptions.geometry.curvalue == 2 ) + { + trap_Cvar_SetValue( "r_lodBias", 0 ); + trap_Cvar_SetValue( "r_subdivisions", 4 ); + } + else if ( s_graphicsoptions.geometry.curvalue == 1 ) + { + trap_Cvar_SetValue( "r_lodBias", 1 ); + trap_Cvar_SetValue( "r_subdivisions", 12 ); + } + else + { + trap_Cvar_SetValue( "r_lodBias", 1 ); + trap_Cvar_SetValue( "r_subdivisions", 20 ); + } + + if ( s_graphicsoptions.filter.curvalue ) + { + trap_Cvar_Set( "r_textureMode", "GL_LINEAR_MIPMAP_LINEAR" ); + } + else + { + trap_Cvar_Set( "r_textureMode", "GL_LINEAR_MIPMAP_NEAREST" ); + } + + trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); +} + +/* +================= +GraphicsOptions_Event +================= +*/ +static void GraphicsOptions_Event( void* ptr, int event ) { + InitialVideoOptions_s *ivo; + + if( event != QM_ACTIVATED ) { + return; + } + + switch( ((menucommon_s*)ptr)->id ) { + case ID_MODE: + // clamp 3dfx video modes + if ( s_graphicsoptions.driver.curvalue == 1 ) + { + if ( s_graphicsoptions.mode.curvalue < 2 ) + s_graphicsoptions.mode.curvalue = 2; + else if ( s_graphicsoptions.mode.curvalue > 6 ) + s_graphicsoptions.mode.curvalue = 6; + } + break; + + case ID_LIST: + ivo = &s_ivo_templates[s_graphicsoptions.list.curvalue]; + + s_graphicsoptions.mode.curvalue = ivo->mode; + s_graphicsoptions.tq.curvalue = ivo->tq; + s_graphicsoptions.lighting.curvalue = ivo->lighting; + s_graphicsoptions.colordepth.curvalue = ivo->colordepth; + s_graphicsoptions.texturebits.curvalue = ivo->texturebits; + s_graphicsoptions.geometry.curvalue = ivo->geometry; + s_graphicsoptions.filter.curvalue = ivo->filter; + s_graphicsoptions.fs.curvalue = ivo->fullscreen; + break; + + case ID_DRIVERINFO: + UI_DriverInfo_Menu(); + break; + + case ID_BACK2: + UI_PopMenu(); + break; + + case ID_GRAPHICS: + break; + + case ID_DISPLAY: + UI_PopMenu(); + UI_DisplayOptionsMenu(); + break; + + case ID_SOUND: + UI_PopMenu(); + UI_SoundOptionsMenu(); + break; + + case ID_NETWORK: + UI_PopMenu(); + UI_NetworkOptionsMenu(); + break; + } +} + + +/* +================ +GraphicsOptions_TQEvent +================ +*/ +static void GraphicsOptions_TQEvent( void *ptr, int event ) { + if( event != QM_ACTIVATED ) { + return; + } + s_graphicsoptions.tq.curvalue = (int)(s_graphicsoptions.tq.curvalue + 0.5); +} + + +/* +================ +GraphicsOptions_MenuDraw +================ +*/ +void GraphicsOptions_MenuDraw (void) +{ +//APSFIX - rework this + GraphicsOptions_UpdateMenuItems(); + + Menu_Draw( &s_graphicsoptions.menu ); +} + +/* +================= +GraphicsOptions_SetMenuItems +================= +*/ +static void GraphicsOptions_SetMenuItems( void ) +{ + s_graphicsoptions.mode.curvalue = trap_Cvar_VariableValue( "r_mode" ); + if ( s_graphicsoptions.mode.curvalue < 0 ) + { + s_graphicsoptions.mode.curvalue = 3; + } + s_graphicsoptions.fs.curvalue = trap_Cvar_VariableValue("r_fullscreen"); + s_graphicsoptions.allow_extensions.curvalue = trap_Cvar_VariableValue("r_allowExtensions"); + s_graphicsoptions.tq.curvalue = 3-trap_Cvar_VariableValue( "r_picmip"); + if ( s_graphicsoptions.tq.curvalue < 0 ) + { + s_graphicsoptions.tq.curvalue = 0; + } + else if ( s_graphicsoptions.tq.curvalue > 3 ) + { + s_graphicsoptions.tq.curvalue = 3; + } + + s_graphicsoptions.lighting.curvalue = trap_Cvar_VariableValue( "r_vertexLight" ) != 0; + switch ( ( int ) trap_Cvar_VariableValue( "r_texturebits" ) ) + { + default: + case 0: + s_graphicsoptions.texturebits.curvalue = 0; + break; + case 16: + s_graphicsoptions.texturebits.curvalue = 1; + break; + case 32: + s_graphicsoptions.texturebits.curvalue = 2; + break; + } + + if ( !Q_stricmp( UI_Cvar_VariableString( "r_textureMode" ), "GL_LINEAR_MIPMAP_NEAREST" ) ) + { + s_graphicsoptions.filter.curvalue = 0; + } + else + { + s_graphicsoptions.filter.curvalue = 1; + } + + if ( trap_Cvar_VariableValue( "r_lodBias" ) > 0 ) + { + if ( trap_Cvar_VariableValue( "r_subdivisions" ) >= 20 ) + { + s_graphicsoptions.geometry.curvalue = 0; + } + else + { + s_graphicsoptions.geometry.curvalue = 1; + } + } + else + { + s_graphicsoptions.geometry.curvalue = 2; + } + + switch ( ( int ) trap_Cvar_VariableValue( "r_colorbits" ) ) + { + default: + case 0: + s_graphicsoptions.colordepth.curvalue = 0; + break; + case 16: + s_graphicsoptions.colordepth.curvalue = 1; + break; + case 32: + s_graphicsoptions.colordepth.curvalue = 2; + break; + } + + if ( s_graphicsoptions.fs.curvalue == 0 ) + { + s_graphicsoptions.colordepth.curvalue = 0; + } + if ( s_graphicsoptions.driver.curvalue == 1 ) + { + s_graphicsoptions.colordepth.curvalue = 1; + } +} + +/* +================ +GraphicsOptions_MenuInit +================ +*/ +void GraphicsOptions_MenuInit( void ) +{ + static const char *s_driver_names[] = + { + "Default", + "Voodoo", + 0 + }; + + static const char *tq_names[] = + { + "Default", + "16 bit", + "32 bit", + 0 + }; + + static const char *s_graphics_options_names[] = + { + "High Quality", + "Normal", + "Fast", + "Fastest", + "Custom", + 0 + }; + + static const char *lighting_names[] = + { + "Lightmap", + "Vertex", + 0 + }; + + static const char *colordepth_names[] = + { + "Default", + "16 bit", + "32 bit", + 0 + }; + + static const char *resolutions[] = + { + "320x240", + "400x300", + "512x384", + "640x480", + "800x600", + "960x720", + "1024x768", + "1152x864", + "1280x1024", + "1600x1200", + "2048x1536", + "856x480 wide screen", + 0 + }; + static const char *filter_names[] = + { + "Bilinear", + "Trilinear", + 0 + }; + static const char *quality_names[] = + { + "Low", + "Medium", + "High", + 0 + }; + static const char *enabled_names[] = + { + "Off", + "On", + 0 + }; + + int y; + + // zero set all our globals + memset( &s_graphicsoptions, 0 ,sizeof(graphicsoptions_t) ); + + GraphicsOptions_Cache(); + + s_graphicsoptions.menu.wrapAround = qtrue; + s_graphicsoptions.menu.fullscreen = qtrue; + s_graphicsoptions.menu.draw = GraphicsOptions_MenuDraw; + + s_graphicsoptions.banner.generic.type = MTYPE_BTEXT; + s_graphicsoptions.banner.generic.x = 320; + s_graphicsoptions.banner.generic.y = 16; + s_graphicsoptions.banner.string = "SYSTEM SETUP"; + s_graphicsoptions.banner.color = color_white; + s_graphicsoptions.banner.style = UI_CENTER; + + s_graphicsoptions.framel.generic.type = MTYPE_BITMAP; + s_graphicsoptions.framel.generic.name = GRAPHICSOPTIONS_FRAMEL; + s_graphicsoptions.framel.generic.flags = QMF_INACTIVE; + s_graphicsoptions.framel.generic.x = 0; + s_graphicsoptions.framel.generic.y = 78; + s_graphicsoptions.framel.width = 256; + s_graphicsoptions.framel.height = 329; + + s_graphicsoptions.framer.generic.type = MTYPE_BITMAP; + s_graphicsoptions.framer.generic.name = GRAPHICSOPTIONS_FRAMER; + s_graphicsoptions.framer.generic.flags = QMF_INACTIVE; + s_graphicsoptions.framer.generic.x = 376; + s_graphicsoptions.framer.generic.y = 76; + s_graphicsoptions.framer.width = 256; + s_graphicsoptions.framer.height = 334; + + s_graphicsoptions.graphics.generic.type = MTYPE_PTEXT; + s_graphicsoptions.graphics.generic.flags = QMF_RIGHT_JUSTIFY; + s_graphicsoptions.graphics.generic.id = ID_GRAPHICS; + s_graphicsoptions.graphics.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.graphics.generic.x = 216; + s_graphicsoptions.graphics.generic.y = 240 - 2 * PROP_HEIGHT; + s_graphicsoptions.graphics.string = "GRAPHICS"; + s_graphicsoptions.graphics.style = UI_RIGHT; + s_graphicsoptions.graphics.color = color_red; + + s_graphicsoptions.display.generic.type = MTYPE_PTEXT; + s_graphicsoptions.display.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_graphicsoptions.display.generic.id = ID_DISPLAY; + s_graphicsoptions.display.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.display.generic.x = 216; + s_graphicsoptions.display.generic.y = 240 - PROP_HEIGHT; + s_graphicsoptions.display.string = "DISPLAY"; + s_graphicsoptions.display.style = UI_RIGHT; + s_graphicsoptions.display.color = color_red; + + s_graphicsoptions.sound.generic.type = MTYPE_PTEXT; + s_graphicsoptions.sound.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_graphicsoptions.sound.generic.id = ID_SOUND; + s_graphicsoptions.sound.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.sound.generic.x = 216; + s_graphicsoptions.sound.generic.y = 240; + s_graphicsoptions.sound.string = "SOUND"; + s_graphicsoptions.sound.style = UI_RIGHT; + s_graphicsoptions.sound.color = color_red; + + s_graphicsoptions.network.generic.type = MTYPE_PTEXT; + s_graphicsoptions.network.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; + s_graphicsoptions.network.generic.id = ID_NETWORK; + s_graphicsoptions.network.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.network.generic.x = 216; + s_graphicsoptions.network.generic.y = 240 + PROP_HEIGHT; + s_graphicsoptions.network.string = "NETWORK"; + s_graphicsoptions.network.style = UI_RIGHT; + s_graphicsoptions.network.color = color_red; + + y = 240 - 6 * (BIGCHAR_HEIGHT + 2); + s_graphicsoptions.list.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.list.generic.name = "Graphics Settings:"; + s_graphicsoptions.list.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.list.generic.x = 400; + s_graphicsoptions.list.generic.y = y; + s_graphicsoptions.list.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.list.generic.id = ID_LIST; + s_graphicsoptions.list.itemnames = s_graphics_options_names; + y += 2 * ( BIGCHAR_HEIGHT + 2 ); + + s_graphicsoptions.driver.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.driver.generic.name = "GL Driver:"; + s_graphicsoptions.driver.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.driver.generic.x = 400; + s_graphicsoptions.driver.generic.y = y; + s_graphicsoptions.driver.itemnames = s_driver_names; + s_graphicsoptions.driver.curvalue = (uis.glconfig.driverType == GLDRV_VOODOO); + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_allowExtensions" + s_graphicsoptions.allow_extensions.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.allow_extensions.generic.name = "GL Extensions:"; + s_graphicsoptions.allow_extensions.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.allow_extensions.generic.x = 400; + s_graphicsoptions.allow_extensions.generic.y = y; + s_graphicsoptions.allow_extensions.itemnames = enabled_names; + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_mode" + s_graphicsoptions.mode.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.mode.generic.name = "Video Mode:"; + s_graphicsoptions.mode.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.mode.generic.x = 400; + s_graphicsoptions.mode.generic.y = y; + s_graphicsoptions.mode.itemnames = resolutions; + s_graphicsoptions.mode.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.mode.generic.id = ID_MODE; + y += BIGCHAR_HEIGHT+2; + + // references "r_colorbits" + s_graphicsoptions.colordepth.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.colordepth.generic.name = "Color Depth:"; + s_graphicsoptions.colordepth.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.colordepth.generic.x = 400; + s_graphicsoptions.colordepth.generic.y = y; + s_graphicsoptions.colordepth.itemnames = colordepth_names; + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_fullscreen" + s_graphicsoptions.fs.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.fs.generic.name = "Fullscreen:"; + s_graphicsoptions.fs.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.fs.generic.x = 400; + s_graphicsoptions.fs.generic.y = y; + s_graphicsoptions.fs.itemnames = enabled_names; + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_vertexLight" + s_graphicsoptions.lighting.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.lighting.generic.name = "Lighting:"; + s_graphicsoptions.lighting.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.lighting.generic.x = 400; + s_graphicsoptions.lighting.generic.y = y; + s_graphicsoptions.lighting.itemnames = lighting_names; + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_lodBias" & "subdivisions" + s_graphicsoptions.geometry.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.geometry.generic.name = "Geometric Detail:"; + s_graphicsoptions.geometry.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.geometry.generic.x = 400; + s_graphicsoptions.geometry.generic.y = y; + s_graphicsoptions.geometry.itemnames = quality_names; + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_picmip" + s_graphicsoptions.tq.generic.type = MTYPE_SLIDER; + s_graphicsoptions.tq.generic.name = "Texture Detail:"; + s_graphicsoptions.tq.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.tq.generic.x = 400; + s_graphicsoptions.tq.generic.y = y; + s_graphicsoptions.tq.minvalue = 0; + s_graphicsoptions.tq.maxvalue = 3; + s_graphicsoptions.tq.generic.callback = GraphicsOptions_TQEvent; + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_textureBits" + s_graphicsoptions.texturebits.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.texturebits.generic.name = "Texture Quality:"; + s_graphicsoptions.texturebits.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.texturebits.generic.x = 400; + s_graphicsoptions.texturebits.generic.y = y; + s_graphicsoptions.texturebits.itemnames = tq_names; + y += BIGCHAR_HEIGHT+2; + + // references/modifies "r_textureMode" + s_graphicsoptions.filter.generic.type = MTYPE_SPINCONTROL; + s_graphicsoptions.filter.generic.name = "Texture Filter:"; + s_graphicsoptions.filter.generic.flags = QMF_PULSEIFFOCUS|QMF_SMALLFONT; + s_graphicsoptions.filter.generic.x = 400; + s_graphicsoptions.filter.generic.y = y; + s_graphicsoptions.filter.itemnames = filter_names; + y += 2*BIGCHAR_HEIGHT; + + s_graphicsoptions.driverinfo.generic.type = MTYPE_PTEXT; + s_graphicsoptions.driverinfo.generic.flags = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS; + s_graphicsoptions.driverinfo.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.driverinfo.generic.id = ID_DRIVERINFO; + s_graphicsoptions.driverinfo.generic.x = 320; + s_graphicsoptions.driverinfo.generic.y = y; + s_graphicsoptions.driverinfo.string = "Driver Info"; + s_graphicsoptions.driverinfo.style = UI_CENTER|UI_SMALLFONT; + s_graphicsoptions.driverinfo.color = color_red; + y += BIGCHAR_HEIGHT+2; + + s_graphicsoptions.back.generic.type = MTYPE_BITMAP; + s_graphicsoptions.back.generic.name = GRAPHICSOPTIONS_BACK0; + s_graphicsoptions.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; + s_graphicsoptions.back.generic.callback = GraphicsOptions_Event; + s_graphicsoptions.back.generic.id = ID_BACK2; + s_graphicsoptions.back.generic.x = 0; + s_graphicsoptions.back.generic.y = 480-64; + s_graphicsoptions.back.width = 128; + s_graphicsoptions.back.height = 64; + s_graphicsoptions.back.focuspic = GRAPHICSOPTIONS_BACK1; + + s_graphicsoptions.apply.generic.type = MTYPE_BITMAP; + s_graphicsoptions.apply.generic.name = GRAPHICSOPTIONS_ACCEPT0; + s_graphicsoptions.apply.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_HIDDEN|QMF_INACTIVE; + s_graphicsoptions.apply.generic.callback = GraphicsOptions_ApplyChanges; + s_graphicsoptions.apply.generic.x = 640; + s_graphicsoptions.apply.generic.y = 480-64; + s_graphicsoptions.apply.width = 128; + s_graphicsoptions.apply.height = 64; + s_graphicsoptions.apply.focuspic = GRAPHICSOPTIONS_ACCEPT1; + + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.banner ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.framel ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.framer ); + + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.graphics ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.display ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.sound ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.network ); + + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.list ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.driver ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.allow_extensions ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.mode ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.colordepth ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.fs ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.lighting ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.geometry ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.tq ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.texturebits ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.filter ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.driverinfo ); + + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.back ); + Menu_AddItem( &s_graphicsoptions.menu, ( void * ) &s_graphicsoptions.apply ); + + GraphicsOptions_SetMenuItems(); + GraphicsOptions_GetInitialVideo(); + + if ( uis.glconfig.driverType == GLDRV_ICD && + uis.glconfig.hardwareType == GLHW_3DFX_2D3D ) + { + s_graphicsoptions.driver.generic.flags |= QMF_HIDDEN|QMF_INACTIVE; + } +} + + +/* +================= +GraphicsOptions_Cache +================= +*/ +void GraphicsOptions_Cache( void ) { + trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_FRAMEL ); + trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_FRAMER ); + trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_BACK0 ); + trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_BACK1 ); + trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_ACCEPT0 ); + trap_R_RegisterShaderNoMip( GRAPHICSOPTIONS_ACCEPT1 ); +} + + +/* +================= +UI_GraphicsOptionsMenu +================= +*/ +void UI_GraphicsOptionsMenu( void ) { + GraphicsOptions_MenuInit(); + UI_PushMenu( &s_graphicsoptions.menu ); + Menu_SetCursorToItem( &s_graphicsoptions.menu, &s_graphicsoptions.graphics ); +} + -- cgit v1.2.3