From: terencehill Date: Mon, 6 Jan 2014 01:00:59 +0000 (+0100) Subject: Merge remote-tracking branch 'origin/Mario/quickmenu_merge' into terencehill/quickmen... X-Git-Tag: xonotic-v0.8.2~1987^2~55 X-Git-Url: http://de.git.xonotic.org/?a=commitdiff_plain;h=2755abdfb4cb55785be0e78db99bf2c30c1e297f;hp=-c;p=xonotic%2Fxonotic-data.pk3dir.git Merge remote-tracking branch 'origin/Mario/quickmenu_merge' into terencehill/quickmenu_UPDATE --- 2755abdfb4cb55785be0e78db99bf2c30c1e297f diff --combined defaultXonotic.cfg index 2814738e7,0849d8713..7ddd012fc --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@@ -141,9 -141,6 +141,9 @@@ set rpn_linear_to_sRGB "dup 1.0 2.4 di // q3map_skylight 9.32523632 3 alias skybox_nosRGB_to_sRGB "rpn $3 402.123 $4 div div $rpn_sRGB_to_linear 402.123 $4 div mul /new_skylight: $3 402.123 $4 div div $1 256 div $2 0.017453 mul sin mul add $rpn_sRGB_to_linear $3 402.123 $4 div div $rpn_sRGB_to_linear sub 256 mul $2 0.017453 mul sin div /new_sunlight:" +set cl_orthoview 0 "enable top-down view of the map- meant to be used for radar map images (note: orthoview sets cvars temporarily, requires restart to return them to normal)" +set cl_orthoview_nofog 1 "disable fog while in orthoview-- note, should not be enabled on ALL maps, i.e. oilrig works fine with this disabled" + // these settings determine how much the view is affected by movement/damage cl_smoothviewheight 0.05 // time of the averaging to the viewheight value so that it creates a smooth transition for crouching and such. 0 for instant transition cl_deathfade 0 // fade screen to dark red when dead, value represents how fast the fade is (higher is faster) @@@ -687,6 -684,8 +687,8 @@@ bind F11 disconnec bind F12 screenshot bind F4 ready bind ALT +showaccuracy + alias quickmenu "cl_cmd hud quickmenu" + bind b quickmenu // Gamepad defaults. Tested with Logitech Rumblepad 2, I hope similar ones works as well. bind JOY1 "+crouch" @@@ -1192,9 -1191,32 +1194,9 @@@ set g_showweaponspawns 1 "display sprit // Quake-Joule: 1 qJ = 1 qN * 1 qu // Quake-Pascal: 1 qPa = 1 qN / 1 qu^2 -set g_ballistics_materialconstant 1414213562 -set g_ballistics_mindistance 16 +set g_ballistics_mindistance 2 // enable ballistics starting from 2 qu set g_ballistics_density_player 0.50 // players are 2x as easy to pass as walls set g_ballistics_density_corpse 0.10 // corpses are 10x as easy to pass as walls -// unit: qJ / qu^3 (energy needed per volume unit of solid to push/burn away -// parameter: bullet constant: mass / area in g/qu^2 -// = mass / (pi/4 * caliber^2) -// with caliber in inches, mass in grams: -// = 1.273239544735163 * mass / caliber^2 -// with caliber in inches, mass in grains: -// = 0.082633246453312 * mass / caliber^2 - -// bullet max travel distance inside solid: -// 0.5 * v^2 * bulletconstant / g_ballistics_materialconstant - -// some bullet constants: -// http://hypertextbook.com/facts/2000/ShantayArmstrong.shtml -// second bullet: caliber .45, mass 16.2g, bullet constant 101.859163578813 -// third bullet: caliber .338, mass 16.2g, bullet constant 180.5476053421592 -// fourth bullet: caliber .25, mass 2.3g, bullet constant 46.85521524625399 -// http://en.wikipedia.org/wiki/.50_BMG -// caliber .5, 360 grains, bullet constant 118.9918748927693 -// AK-47: -// caliber .3, 62 grains, bullet constant 56.92512533450383 -// .3 winchester magnum: -// caliber .3, 150 grains, bullet constant 137.7220774221867 set cl_stripcolorcodes 0 "experimental feature (notes: strips ALL color codes from messages!)" diff --combined qcsrc/client/Main.qc index 3206e923c,130a18c31..eecd47856 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@@ -53,7 -53,7 +53,7 @@@ void CSQC_Init(void check_unacceptable_compiler_bugs(); #ifdef WATERMARK - print(sprintf(_("^4CSQC Build information: ^1%s\n"), WATERMARK)); + printf(_("^4CSQC Build information: ^1%s\n"), WATERMARK); #endif float i; @@@ -213,7 -213,7 +213,7 @@@ float SetTeam(entity o, float Team default: if(GetTeam(Team, false) == world) { - print(sprintf(_("trying to switch to unsupported team %d\n"), Team)); + printf(_("trying to switch to unsupported team %d\n"), Team); Team = NUM_SPECTATOR; } break; @@@ -229,7 -229,7 +229,7 @@@ default: if(GetTeam(Team, false) == world) { - print(sprintf(_("trying to switch to unsupported team %d\n"), Team)); + printf(_("trying to switch to unsupported team %d\n"), Team); Team = NUM_SPECTATOR; } break; @@@ -341,6 -341,9 +341,9 @@@ float CSQC_InputEvent(float bInputType if (HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary)) return true; + if (HUD_QuickMenu_InputEvent(bInputType, nPrimary, nSecondary)) + return true; + if (MapVote_InputEvent(bInputType, nPrimary, nSecondary)) return true; @@@ -424,7 -427,7 +427,7 @@@ void Ent_ReadPlayerScore( if(!isNew && n != self.sv_entnum) { //print("A CSQC entity changed its owner!\n"); - print(sprintf("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", num_for_edict(self), self.classname)); + printf("A CSQC entity changed its owner! (edict: %d, classname: %s)\n", num_for_edict(self), self.classname); isNew = true; Ent_Remove(); self.enttype = ENT_CLIENT_SCORES; @@@ -687,7 -690,7 +690,7 @@@ void Ent_ReadSpawnPoint(float is_new) / } } - //print(sprintf("Ent_ReadSpawnPoint(is_new = %d); origin = %s, team = %d, effect = %d\n", is_new, vtos(self.origin), teamnum, self.cnt)); + //printf("Ent_ReadSpawnPoint(is_new = %d); origin = %s, team = %d, effect = %d\n", is_new, vtos(self.origin), teamnum, self.cnt); } void Ent_ReadSpawnEvent(float is_new) @@@ -738,7 -741,7 +741,7 @@@ } } - //print(sprintf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(self.origin), entnum, player_localentnum)); + //printf("Ent_ReadSpawnEvent(is_new = %d); origin = %s, entnum = %d, localentnum = %d\n", is_new, vtos(self.origin), entnum, player_localentnum); } // CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured. @@@ -753,7 -756,7 +756,7 @@@ void CSQC_Ent_Update(float bIsNewEntity t = ReadByte(); if(autocvar_developer_csqcentities) - print(sprintf("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, self, self.entnum, self.enttype, t)); + printf("CSQC_Ent_Update(%d) with self=%i self.entnum=%d self.enttype=%d t=%d\n", bIsNewEntity, self, self.entnum, self.enttype, t); // set up the "time" global for received entities to be correct for interpolation purposes savetime = time; @@@ -774,7 -777,7 +777,7 @@@ if(t != self.enttype || bIsNewEntity) { //print("A CSQC entity changed its type!\n"); - print(sprintf("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(self), self.entnum, self.enttype, t)); + printf("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)\n", num_for_edict(self), self.entnum, self.enttype, t); Ent_Remove(); clearentity(self); bIsNewEntity = 1; @@@ -784,7 -787,7 +787,7 @@@ { if(!bIsNewEntity) { - print(sprintf("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(self), self.entnum, t)); + printf("A CSQC entity appeared out of nowhere! (edict: %d, server: %d, type: %d)\n", num_for_edict(self), self.entnum, t); bIsNewEntity = 1; } } @@@ -868,7 -871,7 +871,7 @@@ void Ent_Remove( void CSQC_Ent_Remove() { if(autocvar_developer_csqcentities) - print(sprintf("CSQC_Ent_Remove() with self=%i self.entnum=%d self.enttype=%d\n", self, self.entnum, self.enttype)); + printf("CSQC_Ent_Remove() with self=%i self.entnum=%d self.enttype=%d\n", self, self.entnum, self.enttype); if(wasfreed(self)) { @@@ -893,7 -896,7 +896,7 @@@ void Gamemode_Init( void CSQC_Parse_StuffCmd(string strMessage) { if(autocvar_developer_csqcentities) - print(sprintf("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage)); + printf("CSQC_Parse_StuffCmd(\"%s\")\n", strMessage); localcmd(strMessage); } @@@ -901,7 -904,7 +904,7 @@@ void CSQC_Parse_Print(string strMessage) { if(autocvar_developer_csqcentities) - print(sprintf("CSQC_Parse_Print(\"%s\")\n", strMessage)); + printf("CSQC_Parse_Print(\"%s\")\n", strMessage); print(ColorTranslateRGB(strMessage)); } @@@ -910,7 -913,7 +913,7 @@@ void CSQC_Parse_CenterPrint(string strMessage) { if(autocvar_developer_csqcentities) - print(sprintf("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage)); + printf("CSQC_Parse_CenterPrint(\"%s\")\n", strMessage); centerprint_hud(strMessage); } @@@ -921,10 -924,8 +924,10 @@@ void Fog_Force( { // TODO somehow thwart prvm_globalset client ... - if(forcefog != "") - localcmd(strcat(notranslate_fogcmd1, forcefog, notranslate_fogcmd2)); + if(autocvar_cl_orthoview && autocvar_cl_orthoview_nofog) + { localcmd("\nr_drawfog 0\n"); } + else if(forcefog != "") + { localcmd(strcat(notranslate_fogcmd1, forcefog, notranslate_fogcmd2)); } } void Gamemode_Init(); @@@ -1201,7 -1202,7 +1204,7 @@@ float CSQC_Parse_TempEntity( nTEID = ReadByte(); if(autocvar_developer_csqcentities) - print(sprintf("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID)); + printf("CSQC_Parse_TempEntity() with nTEID=%d\n", nTEID); // NOTE: Could just do return instead of break... switch(nTEID) @@@ -1218,6 -1219,10 +1221,6 @@@ Net_ReadRace(); bHandled = true; break; - case TE_CSQC_ZCURVEPARTICLES: - Net_ReadZCurveParticles(); - bHandled = true; - break; case TE_CSQC_NEXGUNBEAMPARTICLE: Net_ReadNexgunBeamParticle(); bHandled = true; diff --combined qcsrc/client/View.qc index 41cec30bf,55ea5192e..82454e5a8 --- a/qcsrc/client/View.qc +++ b/qcsrc/client/View.qc @@@ -199,17 -199,6 +199,17 @@@ vector GetCurrentFov(float fov return '1 0 0' * fovx + '0 1 0' * fovy; } +vector GetOrthoviewFOV(vector ov_worldmin, vector ov_worldmax, vector ov_mid, vector ov_org) +{ + float fovx, fovy; + float width = (ov_worldmax_x - ov_worldmin_x); + float height = (ov_worldmax_y - ov_worldmin_y); + float distance_to_middle_of_world = vlen(ov_mid - ov_org); + fovx = atan2(width/2, distance_to_middle_of_world) / M_PI * 360.0; + fovy = atan2(height/2, distance_to_middle_of_world) / M_PI * 360.0; + return '1 0 0' * fovx + '0 1 0' * fovy; +} + // this function must match W_SetupShot! float zoomscript_caught; @@@ -318,15 -307,13 +318,15 @@@ float TrueAimCheck( break; } + vector traceorigin = getplayerorigin(player_localentnum-1) + (eZ * getstati(STAT_VIEWHEIGHT)); + vecs = decompressShotOrigin(getstati(STAT_SHOTORG)); - traceline(view_origin, view_origin + view_forward * MAX_SHOT_DISTANCE, mv, ta); + traceline(traceorigin, traceorigin + view_forward * MAX_SHOT_DISTANCE, mv, ta); trueaimpoint = trace_endpos; - if(vlen(trueaimpoint - view_origin) < g_trueaim_minrange) - trueaimpoint = view_origin + view_forward * g_trueaim_minrange; + if(vlen(trueaimpoint - traceorigin) < g_trueaim_minrange) + trueaimpoint = traceorigin + view_forward * g_trueaim_minrange; if(vecs_x > 0) vecs_y = -vecs_y; @@@ -334,7 -321,7 +334,7 @@@ vecs = '0 0 0'; dv = view_right * vecs_y + view_up * vecs_z; - w_shotorg = view_origin + dv; + w_shotorg = traceorigin + dv; // now move the vecs forward as much as requested if possible tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, ta); // FIXME this MOVE_NORMAL part will misbehave a little in csqc @@@ -492,7 -479,7 +492,7 @@@ void CSQC_UpdateView(float w, float h // event chase camera if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped { - if((spectatee_status >= 0 && (autocvar_cl_eventchase_death && is_dead)) || intermission) + if(((spectatee_status >= 0 && (autocvar_cl_eventchase_death && is_dead)) || intermission) && !autocvar_cl_orthoview) { // make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.) vector current_view_origin = (csqcplayer ? csqcplayer.origin : pmove_org); @@@ -547,7 -534,7 +547,7 @@@ } // do lockview after event chase camera so that it still applies whenever necessary. - if(autocvar_cl_lockview || (!autocvar_hud_cursormode && (autocvar__hud_configure && spectatee_status <= 0 || intermission > 1))) + if(autocvar_cl_lockview || (!autocvar_hud_cursormode && (autocvar__hud_configure && spectatee_status <= 0 || intermission > 1 || HUD_QuickMenu_IsOpened()))) { setproperty(VF_ORIGIN, freeze_org); setproperty(VF_ANGLES, freeze_ang); @@@ -561,60 -548,6 +561,60 @@@ WarpZone_FixView(); //WarpZone_FixPMove(); + vector ov_org = '0 0 0'; + vector ov_mid = '0 0 0'; + vector ov_worldmin = '0 0 0'; + vector ov_worldmax = '0 0 0'; + if(autocvar_cl_orthoview) + { + ov_worldmin = mi_picmin; + ov_worldmax = mi_picmax; + + float ov_width = (ov_worldmax_x - ov_worldmin_x); + float ov_height = (ov_worldmax_y - ov_worldmin_y); + float ov_distance = (max(vid_width, vid_height) * max(ov_width, ov_height)); + + ov_mid = ((ov_worldmax + ov_worldmin) * 0.5); + ov_org = vec3(ov_mid_x, ov_mid_y, (ov_mid_z + ov_distance)); + + float ov_nearest = vlen(ov_org - vec3( + bound(ov_worldmin_x, ov_org_x, ov_worldmax_x), + bound(ov_worldmin_y, ov_org_y, ov_worldmax_y), + bound(ov_worldmin_z, ov_org_z, ov_worldmax_z) + )); + + float ov_furthest = 0; + float dist = 0; + + if((dist = vlen(vec3(ov_worldmin_x, ov_worldmin_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax_x, ov_worldmin_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmin_x, ov_worldmax_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmin_x, ov_worldmin_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax_x, ov_worldmax_y, ov_worldmin_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmin_x, ov_worldmax_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax_x, ov_worldmin_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + if((dist = vlen(vec3(ov_worldmax_x, ov_worldmax_y, ov_worldmax_z) - ov_org)) > ov_furthest) { ov_furthest = dist; } + + cvar_settemp("r_nearclip", ftos(ov_nearest)); + cvar_settemp("r_farclip_base", ftos(ov_furthest)); + cvar_settemp("r_farclip_world", "0"); + cvar_settemp("r_novis", "1"); + cvar_settemp("r_useportalculling", "0"); + cvar_settemp("r_useinfinitefarclip", "0"); + + setproperty(VF_ORIGIN, ov_org); + setproperty(VF_ANGLES, '90 0 0'); + + #if 0 + printf("OrthoView: org = %s, angles = %s, distance = %f, nearest = %f, furthest = %f\n", + vtos(ov_org), + vtos(getpropertyvec(VF_ANGLES)), + ov_distance, + ov_nearest, + ov_furthest); + #endif + } + // Render the Scene view_origin = getpropertyvec(VF_ORIGIN); view_angles = getpropertyvec(VF_ANGLES); @@@ -756,8 -689,7 +756,8 @@@ vid_conheight = autocvar_vid_conheight; vid_pixelheight = autocvar_vid_pixelheight; - setproperty(VF_FOV, GetCurrentFov(fov)); + if(autocvar_cl_orthoview) { setproperty(VF_FOV, GetOrthoviewFOV(ov_worldmin, ov_worldmax, ov_mid, ov_org)); } + else { setproperty(VF_FOV, GetCurrentFov(fov)); } // Camera for demo playback if(camera_active) @@@ -1238,7 -1170,7 +1238,7 @@@ } } - //print(sprintf("crosshair style: %s\n", wcross_style)); + //printf("crosshair style: %s\n", wcross_style); wcross_name = strcat("gfx/crosshair", wcross_style); // MAIN CROSSHAIR COLOR DECISION @@@ -1632,8 -1564,10 +1632,10 @@@ if(autocvar__hud_configure) HUD_Panel_Mouse(); + else if(HUD_QuickMenu_IsOpened()) + HUD_QuickMenu_Mouse(); - if(hud && !intermission) + if(hud && !intermission) { if(hud == HUD_SPIDERBOT) CSQC_SPIDER_HUD(); diff --combined qcsrc/client/autocvars.qh index 43aab6ae4,32641494b..b0fb99679 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@@ -54,8 -54,6 +54,8 @@@ float autocvar_cl_gunalign float autocvar_cl_hidewaypoints; float autocvar_cl_lockview; float autocvar_cl_nogibs; +float autocvar_cl_orthoview; +float autocvar_cl_orthoview_nofog; float autocvar_cl_particlegibs; float autocvar_cl_particles_oldnexbeam; float autocvar_cl_particles_quality; @@@ -297,6 -295,7 +297,7 @@@ float autocvar_hud_panel_powerups_text float autocvar_hud_panel_pressedkeys; float autocvar_hud_panel_pressedkeys_aspect; float autocvar_hud_panel_pressedkeys_attack; + string autocvar_hud_panel_quickmenu_file; float autocvar_hud_panel_racetimer; float autocvar_hud_panel_radar; float autocvar_hud_panel_radar_foreground_alpha; @@@ -341,6 -340,8 +342,8 @@@ float autocvar_hud_panel_weapons_timeou float autocvar_hud_panel_weapons_timeout_fadefgmin; var float autocvar_hud_panel_weapons_timeout_speed_in = 0.25; var float autocvar_hud_panel_weapons_timeout_speed_out = 0.75; + //float autocvar_hud_panel_quickmenu; + float autocvar_hud_panel_quickmenu_align; float autocvar_hud_progressbar_alpha; float autocvar_hud_showbinds; float autocvar_hud_showbinds_limit; diff --combined qcsrc/client/hud.qc index 252142506,90f4df32a..72458cf4b --- a/qcsrc/client/hud.qc +++ b/qcsrc/client/hud.qc @@@ -4095,7 -4095,7 +4095,7 @@@ float centerprint_showing void centerprint_generic(float new_id, string strMessage, float duration, float countdown_num) { - //print(sprintf("centerprint_generic(%d, '%s^7', %d, %d);\n", new_id, strMessage, duration, countdown_num)); + //printf("centerprint_generic(%d, '%s^7', %d, %d);\n", new_id, strMessage, duration, countdown_num); float i, j; if(strMessage == "" && new_id == 0) @@@ -4261,7 -4261,8 +4261,7 @@@ void HUD_CenterPrint (void float a, sz, align, current_msg_pos_y = 0, msg_size; vector pos; string ts; - - n = -1; // if no msg will be displayed, n stays -1 + float all_messages_expired = TRUE; pos = panel_pos; if (autocvar_hud_panel_centerprint_flip) @@@ -4284,20 -4285,16 +4284,20 @@@ continue; } + all_messages_expired = FALSE; // fade the centerprint_hud in/out - if(centerprint_time[j] < 0) - a = bound(0, (time - centerprint_expire_time[j]) / max(0.0001, autocvar_hud_panel_centerprint_fade_in), 1); - else if(centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time) - a = bound(0, (time - (centerprint_expire_time[j] - centerprint_time[j])) / max(0.0001, autocvar_hud_panel_centerprint_fade_in), 1); - else if(centerprint_expire_time[j] > time) + if(centerprint_time[j] < 0) // Expired but forced. Expire time is the fade-in time. + a = (time - centerprint_expire_time[j]) / max(0.0001, autocvar_hud_panel_centerprint_fade_in); + else if(centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time) // Regularily printed. Not fading out yet. + a = (time - (centerprint_expire_time[j] - centerprint_time[j])) / max(0.0001, autocvar_hud_panel_centerprint_fade_in); + else // Expiring soon, so fade it out. a = (centerprint_expire_time[j] - time) / max(0.0001, autocvar_hud_panel_centerprint_fade_out); - else - a = 0; + + if (a <= 0.5/255.0) // Guaranteed invisible - don't show. + continue; + if (a > 1) + a = 1; // set the size from fading in/out before subsequent fading sz = autocvar_hud_panel_centerprint_fade_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_minfontsize); @@@ -4308,7 -4305,6 +4308,7 @@@ a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passone))), 1); // pass one: all messages after the first have half theAlpha a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passtwo))), 1); // pass two: after that, gradually lower theAlpha even more for each message } + a *= panel_fg_alpha; // finally set the size based on the new theAlpha from subsequent fading sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize)); @@@ -4348,8 -4344,7 +4348,8 @@@ { if (align) pos_x = panel_pos_x + (panel_size_x - stringwidth(ts, TRUE, fontsize)) * align; - drawcolorcodedstring(pos + eY * 0.5 * (1 - sz) * fontsize_y, ts, fontsize, a * panel_fg_alpha, DRAWFLAG_NORMAL); + if (a > 0.5/255.0) // Otherwise guaranteed invisible - don't show. This is checked a second time after some multiplications with other factors were done so temporary changes of these cannot cause flicker. + drawcolorcodedstring(pos + eY * 0.5 * (1 - sz) * fontsize_y, ts, fontsize, a, DRAWFLAG_NORMAL); pos_y += fontsize_y; } else @@@ -4386,13 -4381,484 +4386,484 @@@ } } drawfontscale = '1 1 0'; - if (n == -1) + if (all_messages_expired) { centerprint_showing = FALSE; reset_centerprint_messages(); } } + // QuickMenu (#17) + // + // QUICKMENU_MAXLINES must be <= 10 + #define QUICKMENU_MAXLINES 10 + #define QUICKMENU_MAXENTRIES 256 + string QuickMenu_Command[QUICKMENU_MAXLINES]; + string QuickMenu_Description[QUICKMENU_MAXLINES]; + float QuickMenu_CurrentPage; + float QuickMenu_IsLastPage; + var float QuickMenu_Buffer = -1; + float QuickMenu_Buffer_Size; + float QuickMenu_Buffer_Index; + string QuickMenu_CurrentSubMenu; + float QuickMenu_CurrentPage_FirstEntry; + var float QuickMenu_Entries; + void HUD_QuickMenu_load_entry(float i, string s, string s1) + { + //print(sprintf("^xc80 entry %d: %s, %s\n", i, s, s1)); + if (QuickMenu_Description[i]) + strunzone(QuickMenu_Description[i]); + QuickMenu_Description[i] = strzone(s); + if (QuickMenu_Command[i]) + strunzone(QuickMenu_Command[i]); + QuickMenu_Command[i] = strzone(s1); + } + void HUD_QuickMenu_clear_entry(float i) + { + if (QuickMenu_Description[i]) + strunzone(QuickMenu_Description[i]); + QuickMenu_Description[i] = string_null; + if (QuickMenu_Command[i]) + strunzone(QuickMenu_Command[i]); + QuickMenu_Command[i] = string_null; + } + + float HUD_QuickMenu_Buffer_Init() + { + float fh, i; + string s; + fh = fopen(autocvar_hud_panel_quickmenu_file, FILE_READ); + if(fh < 0) + { + print(sprintf(_("Error: Couldn't open file %s!\n"), autocvar_hud_panel_quickmenu_file)); + return false; + } + + QuickMenu_Buffer = buf_create(); + if (QuickMenu_Buffer < 0) + { + fclose(fh); + return false; + } + + i = 0; + while((s = fgets(fh)) && i < QUICKMENU_MAXENTRIES) + { + // first skip invalid entries, so we don't check them anymore + float argc; + argc = tokenize_console(s); + if(argc == 0 || argc > 2) + continue; + + bufstr_set(QuickMenu_Buffer, i, s); + ++i; + } + QuickMenu_Buffer_Size = i; + + if (QuickMenu_Buffer_Size <= 0) + { + buf_del(QuickMenu_Buffer); + QuickMenu_Buffer = -1; + } + fclose(fh); + return true; + } + + void HUD_QuickMenu_Buffer_Close() + { + if (QuickMenu_Buffer >= 0) + { + buf_del(QuickMenu_Buffer); + QuickMenu_Buffer = -1; + QuickMenu_Buffer_Size = 0; + } + } + + void HUD_QuickMenu_Close() + { + if (QuickMenu_CurrentSubMenu) + strunzone(QuickMenu_CurrentSubMenu); + QuickMenu_CurrentSubMenu = string_null; + float i; + for (i = 0; i < QUICKMENU_MAXLINES; ++i) + HUD_QuickMenu_clear_entry(i); + QuickMenu_Entries = 0; + hud_panel_quickmenu = 0; + mouseClicked = 0; + prevMouseClicked = 0; + HUD_QuickMenu_Buffer_Close(); + + if(autocvar_hud_cursormode) + if(!mv_active) + setcursormode(0); + } + + // It assumes submenu open tag is already detected + void HUD_QuickMenu_skip_submenu(string submenu) + { + string s, z_submenu; + z_submenu = strzone(submenu); + for(++QuickMenu_Buffer_Index ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index) + { + s = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index); + float argc; + argc = tokenize_console(s); + if(argc == 2) + continue; + if (argv(0) == "") + continue; + if (argv(0) == z_submenu) // submenu end + break; + HUD_QuickMenu_skip_submenu(argv(0)); + } + strunzone(z_submenu); + } + + float HUD_QuickMenu_IsOpened() + { + return (QuickMenu_Entries > 0); + } + + // new_page 0 means page 0, new_page != 0 means next page + float QuickMenu_Buffer_Index_Prev; + float HUD_QuickMenu_Page(string target_submenu, float new_page) + { + string s, z_submenu; + + if (new_page == 0) + QuickMenu_CurrentPage = 0; + else + ++QuickMenu_CurrentPage; + QuickMenu_CurrentPage_FirstEntry = QuickMenu_CurrentPage * (QUICKMENU_MAXLINES - 2); + + z_submenu = strzone(target_submenu); + if (QuickMenu_CurrentSubMenu) + strunzone(QuickMenu_CurrentSubMenu); + QuickMenu_CurrentSubMenu = strzone(z_submenu); + + QuickMenu_IsLastPage = TRUE; + QuickMenu_Entries = 0; + + QuickMenu_Buffer_Index = 0; + if (z_submenu != "") + { + // skip everything until the submenu open tag is found + for( ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index) + { + s = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index); + if (tokenize_console(s) == 1 && argv(0) == z_submenu) + { + // print(sprintf("^3 beginning of %s\n", z_submenu)); + ++QuickMenu_Buffer_Index; + break; + } + // print(sprintf("^1 skipping %s\n", s)); + } + } + float total = 0; + for( ; QuickMenu_Buffer_Index < QuickMenu_Buffer_Size; ++QuickMenu_Buffer_Index) + { + s = bufstr_get(QuickMenu_Buffer, QuickMenu_Buffer_Index); + float argc; + argc = tokenize_console(s); + + if (z_submenu != "" && z_submenu == argv(0)) + { + // print(sprintf("^3 end of %s\n", z_submenu)); + break; + } + + if (total - QuickMenu_CurrentPage_FirstEntry >= 0) + { + ++QuickMenu_Entries; + if(QuickMenu_Entries == QUICKMENU_MAXLINES - 2) + QuickMenu_Buffer_Index_Prev = QuickMenu_Buffer_Index; + else if(QuickMenu_Entries == QUICKMENU_MAXLINES) + { + HUD_QuickMenu_clear_entry(QUICKMENU_MAXLINES - 1); + QuickMenu_Buffer_Index = QuickMenu_Buffer_Index_Prev; + QuickMenu_IsLastPage = FALSE; + break; + } + } + + // NOTE: entries are loaded starting from 1, not from 0 + if (argc == 1 && argv(0) != "") // submenu + { + if (total - QuickMenu_CurrentPage_FirstEntry >= 0) + HUD_QuickMenu_load_entry(QuickMenu_Entries, argv(0), ""); + HUD_QuickMenu_skip_submenu(argv(0)); + } + else if (total - QuickMenu_CurrentPage_FirstEntry >= 0) + HUD_QuickMenu_load_entry(QuickMenu_Entries, argv(0), argv(1)); + + ++total; + } + strunzone(z_submenu); + if (QuickMenu_Entries == 0) + { + HUD_QuickMenu_Close(); + return 0; + } + return 1; + } + + void HUD_QuickMenu_Open() + { + if(!HUD_QuickMenu_Buffer_Init()) return; + + hud_panel_quickmenu = 1; + if(autocvar_hud_cursormode) + setcursormode(1); + hudShiftState = 0; + + HUD_QuickMenu_Page("", 0); + } + + float HUD_QuickMenu_ActionForNumber(float num) + { + if (!QuickMenu_IsLastPage) + { + if (num < 0 || num >= QUICKMENU_MAXLINES) + return 0; + if (num == QUICKMENU_MAXLINES - 1) + return 0; + if (num == 0) + { + HUD_QuickMenu_Page(QuickMenu_CurrentSubMenu, +1); + return 0; + } + } else if (num <= 0 || num > QuickMenu_Entries) + return 0; + + if (QuickMenu_Command[num] != "") + { + localcmd(strcat("\n", QuickMenu_Command[num], "\n")); + return 1; + } + if (QuickMenu_Description[num] != "") + HUD_QuickMenu_Page(QuickMenu_Description[num], 0); + return 0; + } + + float HUD_QuickMenu_InputEvent(float bInputType, float nPrimary, float nSecondary) + { + // we only care for keyboard events + if(bInputType == 2) + return false; + + if(!HUD_QuickMenu_IsOpened() || autocvar__hud_configure || mv_active) + return false; + + if(bInputType == 3) + { + mousepos_x = nPrimary; + mousepos_y = nSecondary; + return true; + } + + // allow console bind to work + string con_keys; + float keys; + con_keys = findkeysforcommand("toggleconsole", 0); + keys = tokenize(con_keys); // findkeysforcommand returns data for this + + float hit_con_bind = 0, i; + for (i = 0; i < keys; ++i) + { + if(nPrimary == stof(argv(i))) + hit_con_bind = 1; + } + + if(bInputType == 0) { + if(nPrimary == K_ALT) hudShiftState |= S_ALT; + if(nPrimary == K_CTRL) hudShiftState |= S_CTRL; + if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT; + } + else if(bInputType == 1) { + if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT); + if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL); + if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT); + } + + if(nPrimary == K_ESCAPE) + { + if (bInputType == 1) + return true; + HUD_QuickMenu_Close(); + } + else if(nPrimary >= '0' && nPrimary <= '9') + { + if (bInputType == 1) + return true; + HUD_QuickMenu_ActionForNumber(stof(chr2str(nPrimary))); + } + if(nPrimary == K_MOUSE1) + { + if(bInputType == 0) // key pressed + mouseClicked |= S_MOUSE1; + else if(bInputType == 1) // key released + mouseClicked -= (mouseClicked & S_MOUSE1); + } + else if(nPrimary == K_MOUSE2) + { + if(bInputType == 0) // key pressed + mouseClicked |= S_MOUSE2; + else if(bInputType == 1) // key released + mouseClicked -= (mouseClicked & S_MOUSE2); + } + else if(hit_con_bind) + return false; + + return true; + } + void HUD_QuickMenu_Mouse() + { + if(mv_active) return; + + if(!mouseClicked) + if(prevMouseClicked & S_MOUSE2) + { + HUD_QuickMenu_Close(); + return; + } + + if(!autocvar_hud_cursormode) + { + mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed; + + mousepos_x = bound(0, mousepos_x, vid_conwidth); + mousepos_y = bound(0, mousepos_y, vid_conheight); + } + + HUD_Panel_UpdateCvars() + + if(panel_bg_padding) + { + panel_pos += '1 1 0' * panel_bg_padding; + panel_size -= '2 2 0' * panel_bg_padding; + } + + float first_entry_pos, entries_height; + vector fontsize; + fontsize = '1 1 0' * (panel_size_y / QUICKMENU_MAXLINES); + first_entry_pos = panel_pos_y + ((QUICKMENU_MAXLINES - QuickMenu_Entries) * fontsize_y) / 2; + entries_height = panel_size_y - ((QUICKMENU_MAXLINES - QuickMenu_Entries) * fontsize_y); + + if (mousepos_x >= panel_pos_x && mousepos_y >= first_entry_pos && mousepos_x <= panel_pos_x + panel_size_x && mousepos_y <= first_entry_pos + entries_height) + { + float entry_num; + entry_num = floor((mousepos_y - first_entry_pos) / fontsize_y); + if (QuickMenu_IsLastPage || entry_num != QUICKMENU_MAXLINES - 2) + { + panel_pos_y = first_entry_pos + entry_num * fontsize_y; + vector color; + if(mouseClicked & S_MOUSE1) + color = '0.5 1 0.5'; + else if(hudShiftState & S_CTRL) + color = '1 1 0.3'; + else + color = '1 1 1'; + drawfill(panel_pos, eX * panel_size_x + eY * fontsize_y, color, .2, DRAWFLAG_NORMAL); + + if(!mouseClicked && (prevMouseClicked & S_MOUSE1)) + { + float f; + if (entry_num < QUICKMENU_MAXLINES - 1) + f = HUD_QuickMenu_ActionForNumber(entry_num + 1); + else + f = HUD_QuickMenu_ActionForNumber(0); + if(f && !(hudShiftState & S_CTRL)) + HUD_QuickMenu_Close(); + } + } + } + + const vector cursorsize = '32 32 0'; + drawpic(mousepos, strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursorsize, '1 1 1', 0.8, DRAWFLAG_NORMAL); + + prevMouseClicked = mouseClicked; + } + void HUD_QuickMenu_DrawEntry(vector pos, string s, vector fontsize) + { + string entry; + float offset; + entry = textShortenToWidth(s, panel_size_x, fontsize, stringwidth_colors); + if (autocvar_hud_panel_quickmenu_align > 0) + { + offset = (panel_size_x - stringwidth_colors(entry, fontsize)) * min(autocvar_hud_panel_quickmenu_align, 1); + drawcolorcodedstring(pos + eX * offset, entry, fontsize, panel_fg_alpha, DRAWFLAG_ADDITIVE); + } + else + drawcolorcodedstring(pos, entry, fontsize, panel_fg_alpha, DRAWFLAG_ADDITIVE); + } + void HUD_QuickMenu(void) + { + if(!autocvar__hud_configure) + { + if (hud_configure_prev && hud_configure_prev != -1) + HUD_QuickMenu_Close(); + + if(!hud_draw_maximized) return; + if(mv_active) return; + //if(!autocvar_hud_panel_quickmenu) return; // autocvar exists only for conformity with other panels + if(!hud_panel_quickmenu) return; + } + else + { + if(!HUD_QuickMenu_IsOpened()) + { + QuickMenu_Entries = 1; + HUD_QuickMenu_load_entry(QuickMenu_Entries, sprintf(_("Submenu%d"), QuickMenu_Entries), ""); + ++QuickMenu_Entries; + HUD_QuickMenu_load_entry(QuickMenu_Entries, sprintf(_("Submenu%d"), QuickMenu_Entries), ""); + ++QuickMenu_Entries; + // although real command doesn't matter here, it must not be empty + // otherwise the entry is displayed like a submenu + for (; QuickMenu_Entries < QUICKMENU_MAXLINES - 1; ++QuickMenu_Entries) + HUD_QuickMenu_load_entry(QuickMenu_Entries, sprintf(_("Command%d"), QuickMenu_Entries), "-"); + ++QuickMenu_Entries; + HUD_QuickMenu_clear_entry(QuickMenu_Entries); + QuickMenu_IsLastPage = FALSE; + } + } + + HUD_Panel_UpdateCvars(); + HUD_Panel_ApplyFadeAlpha(); + + HUD_Panel_DrawBg(1); + + if(panel_bg_padding) + { + panel_pos += '1 1 0' * panel_bg_padding; + panel_size -= '2 2 0' * panel_bg_padding; + } + + float i; + vector fontsize; + string color; + fontsize = '1 1 0' * (panel_size_y / QUICKMENU_MAXLINES); + + if (!QuickMenu_IsLastPage) + { + color = "^5"; + HUD_QuickMenu_DrawEntry(panel_pos + eY * (panel_size_y - fontsize_y), sprintf("%d: %s%s", 0, color, _("Continue...")), fontsize); + } + else + panel_pos_y += ((QUICKMENU_MAXLINES - QuickMenu_Entries) * fontsize_y) / 2; + + for (i = 1; i <= QuickMenu_Entries; ++i) { + if (QuickMenu_Description[i] == "") + break; + if (QuickMenu_Command[i] == "") + color = "^4"; + else + color = "^3"; + HUD_QuickMenu_DrawEntry(panel_pos, sprintf("%d: %s%s", i, color, QuickMenu_Description[i]), fontsize); + panel_pos_y += fontsize_y; + } + } + /* ================== Main HUD system @@@ -4572,6 -5038,8 +5043,8 @@@ void HUD_Main (void (panel = HUD_PANEL(RADAR)).panel_draw(); if(autocvar__con_chat_maximized) (panel = HUD_PANEL(CHAT)).panel_draw(); + if(hud_panel_quickmenu) + (panel = HUD_PANEL(QUICKMENU)).panel_draw(); if(autocvar__hud_configure) { diff --combined qcsrc/client/hud.qh index c2432b97c,711929066..c86eb91b8 --- a/qcsrc/client/hud.qh +++ b/qcsrc/client/hud.qh @@@ -9,6 -9,7 +9,7 @@@ string hud_panelorder_prev float hud_draw_maximized; float hud_panel_radar_maximized; + float hud_panel_quickmenu; vector mousepos; vector panel_click_distance; // mouse cursor distance from the top left corner of the panel (saved only upon a click) @@@ -98,6 -99,8 +99,8 @@@ var string panel_bg_padding_str float current_player; + float mv_active; + #define HUD_PANELS \ HUD_PANEL(WEAPONS , HUD_Weapons , weapons) \ @@@ -116,7 -119,8 +119,8 @@@ HUD_PANEL(ENGINEINFO , HUD_EngineInfo , engineinfo) \ HUD_PANEL(INFOMESSAGES , HUD_InfoMessages , infomessages) \ HUD_PANEL(PHYSICS , HUD_Physics , physics) \ - HUD_PANEL(CENTERPRINT , HUD_CenterPrint , centerprint) + HUD_PANEL(CENTERPRINT , HUD_CenterPrint , centerprint) \ + HUD_PANEL(QUICKMENU , HUD_QuickMenu , quickmenu) #define HUD_PANEL(NAME,draw_func,name) \ float HUD_PANEL_##NAME; \ @@@ -344,7 -348,7 +348,7 @@@ if(panel.update_time <= time) { strunzone(panel.current_panel_bg); \ if(panel_bg == "")\ {\ - /*print(sprintf("^xf08 %s panel: panel_bg is empty\n", panel.panel_name));*/\ + /*printf("^xf08 %s panel: panel_bg is empty\n", panel.panel_name);*/\ panel_bg = "0";\ }\ panel.current_panel_bg = strzone(panel_bg); \ @@@ -361,7 -365,7 +365,7 @@@ panel_bg = panel.current_panel_bg; \ if(panel.current_panel_bg == "")\ {\ - /*print(sprintf("^xf08 %s panel: panel.current_panel_bg is empty\n", panel.panel_name));*/\ + /*printf("^xf08 %s panel: panel.current_panel_bg is empty\n", panel.panel_name);*/\ panel_bg = "0";\ }\ panel_bg_alpha = panel.current_panel_bg_alpha; \ diff --combined qcsrc/client/hud_config.qc index d36145484,9ceec5de0..92e33653c --- a/qcsrc/client/hud_config.qc +++ b/qcsrc/client/hud_config.qc @@@ -188,16 -188,19 +188,19 @@@ void HUD_Panel_ExportCfg(string cfgname HUD_Write_PanelCvar_q("_fade_subsequent_minfontsize"); HUD_Write_PanelCvar_q("_fade_minfontsize"); break; + case HUD_PANEL_QUICKMENU: + HUD_Write_PanelCvar_q("_align"); + break; } HUD_Write("\n"); } HUD_Write("menu_sync\n"); // force the menu to reread the cvars, so that the dialogs are updated - print(sprintf(_("^2Successfully exported to %s! (Note: It's saved in data/data/)\n"), filename)); + printf(_("^2Successfully exported to %s! (Note: It's saved in data/data/)\n"), filename); fclose(fh); } else - print(sprintf(_("^1Couldn't write to %s\n"), filename)); + printf(_("^1Couldn't write to %s\n"), filename); } void HUD_Configure_Exit_Force() diff --combined qcsrc/client/scoreboard.qc index 8a7d3fd49,055e3b5cc..0d2cd934e --- a/qcsrc/client/scoreboard.qc +++ b/qcsrc/client/scoreboard.qc @@@ -410,7 -410,7 +410,7 @@@ void Cmd_HUD_SetFields(float argc else { if (!nocomplain) - print(sprintf("^1Error:^7 Unknown score field: '%s'\n", str)); + printf("^1Error:^7 Unknown score field: '%s'\n", str); continue; } :found @@@ -481,7 -481,7 +481,7 @@@ hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], FALSE, hud_fontsize); hud_field[hud_num_fields] = ps_secondary; ++hud_num_fields; - print(sprintf("fixed missing field '%s'\n", scores_label[ps_secondary])); + printf("fixed missing field '%s'\n", scores_label[ps_secondary]); } if(!have_primary) { @@@ -490,7 -490,7 +490,7 @@@ hud_size[hud_num_fields] = stringwidth(hud_title[hud_num_fields], FALSE, hud_fontsize); hud_field[hud_num_fields] = ps_primary; ++hud_num_fields; - print(sprintf("fixed missing field '%s'\n", scores_label[ps_primary])); + printf("fixed missing field '%s'\n", scores_label[ps_primary]); } } @@@ -952,6 -952,8 +952,8 @@@ vector HUD_Scoreboard_MakeTable(vector float HUD_WouldDrawScoreboard() { if (autocvar__hud_configure) return 0; + else if (HUD_QuickMenu_IsOpened()) + return 0; else if (scoreboard_showscores) return 1; else if (intermission == 1) diff --combined qcsrc/common/util.qh index e4ce02309,21897346b..dc3cf6f8c --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@@ -281,7 -281,6 +281,6 @@@ float get_model_parameters_bone_aimweig float get_model_parameters_fixbone; string get_model_parameters_desc; float get_model_parameters(string mod, float skn); // call with string_null to clear; skin -1 means mod is the filename of the txt file and is to be split - vector vec2(vector v); #ifndef MENUQC @@@ -367,12 -366,6 +366,12 @@@ void FindConnectedComponent(entity e, . // expand multiple arguments into one argument by stripping parenthesis #define XPD(...) __VA_ARGS__ +// Some common varargs functions. Lowercase as they match C. +#define printf(...) print(sprintf(__VA_ARGS__)) +#define dprintf(...) dprint(sprintf(__VA_ARGS__)) +#define fprintf(file, ...) fputs(file, sprintf(__VA_ARGS__)) +#define bprintf(...) bprint(sprintf(__VA_ARGS__)) + #ifndef MENUQC void backtrace(string msg); #endif