diff --git a/Misc/fitzquake080.txt b/Misc/fitzquake080.txt index 025f250b..ef160b52 100644 --- a/Misc/fitzquake080.txt +++ b/Misc/fitzquake080.txt @@ -1,7 +1,7 @@ ================================================================================ -Fitzquake version 0.80, May 26, 2005 +Fitzquake version 0.80, May 26, 2005 Filename : fitzquake080.exe Author : John Fitzgibbons @@ -9,18 +9,18 @@ Email Address : johnfitz@u.washington.edu Author's Homepage : http://www.celephais.net/ Fitzquake Homepage : http://www.celephais.net/fitzquake -Fitzquake is a modified glquake based on the source code released by id -Software. My primary focus is fixing a lot of the rendering bugs which made -glquake inferior to the software renderer. My secondary focus is adding +Fitzquake is a modified glquake based on the source code released by id +Software. My primary focus is fixing a lot of the rendering bugs which made +glquake inferior to the software renderer. My secondary focus is adding conveniences for mappers and general users. I am also slowly adding support for -new modding or mapping features such as skyboxes, fog, and colored light. +new modding or mapping features such as skyboxes, fog, and colored light. -While I have made extensive changes to the code, I pretty much use the same -OpenGL features that the original glquake uses. Therefore, if you can run -glquake, you can probably run Fitzquake. +While I have made extensive changes to the code, I pretty much use the same +OpenGL features that the original glquake uses. Therefore, if you can run +glquake, you can probably run Fitzquake. I am not finished working on this project, so bug reports and feature requests -are welcome. +are welcome. Acknowlegements -------------------------------------------------------------------------------- @@ -30,8 +30,8 @@ LordHavoc (code and assistance) Bengt Jardrup (feedback, assistance, testing) additional thanks to: Aardappel, SmallPileOfGibs, FrikaC, Vondur, Topaz, Tomaz, -Tonik, Radix, EvilTypeGuy, NightBringer, MH, Maddes, Fett, Craig Wills, Heffo, -Riot, Gleeb, people in #flipcode, and others for their tutorials, code, testing, +Tonik, Radix, EvilTypeGuy, NightBringer, MH, Maddes, Fett, Craig Wills, Heffo, +Riot, Gleeb, people in #flipcode, and others for their tutorials, code, testing, and assistance. Copyright / Permissions @@ -40,19 +40,19 @@ Copyright / Permissions Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others -This program 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 +This program 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. -This program 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 +This program 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 -this program; if not, write to the Free Software Foundation, Inc., 59 Temple +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. History @@ -113,27 +113,27 @@ changes in 0.80 - fixed bug where imagelist and r_speeds2 would report the same megabyte counts in both 16bpp and 32bpp mode, even though texture bpp should match (and does match) framebuffer bpp. The numbers are now different and accurate for each bit depth. - removed cvars "vid_config_x," "vid_config_y," "vid_wait," "vid_nopageflip," "_vid_wait_override," "_vid_default_mode," "_vid_default_mode_win," and "vid_stretch_by_2," none of which glquake ever used. - removed cvar "vid_mode" and commands "vid_describemode" and "vid_nummodes," because of the new video mode handling. - + cvars: - gl_texture_anisotropy. Controls the amount of anisotropy in texture filtering. If 1 or less than 1, texture filtering is normal (isotropic.) If greater than 1, increasing degrees of anisotropic filtering are used, up to the hardware maximum. Set value to 2 for 2x anisotropic, 4 for 4x, etc. Default 1. - host_timescale. Scales the passage of time on client and server. Set to 0 or 1 for normal speed, less than 1 for slow motion, and greater than 1 for fast-forward. If greater than 0, overrides host_framerate. Default 0. - + - max_edicts. Sets the maximum number of entites on both the client and server. Default 1024. Acceptable values range from 256 to 8192. Set to 600 to mimic standard quake. Changes won't take effect until the next time a map is loaded. Note: if a client connects to a server, and the client's maximum is lower than the server's, the client will probably crash if it ever sees an entnum higher than its local max_edicts. Warning: you may need to increase -heapsize if you want a high max_edicts value. - + - r_drawworld. If 1, draw world as usual. If 0, don't draw the world. Default 1. (compare r_drawentities) - + - r_showbboxes. If 1, draw a wireframe bounding box around each entity. Note that these are the server-side per-edict physics bounding boxes, not the client-side per-model rendering bboxes. If 0, disable this feature. Default 0. - + - r_showtris. If 1, draw wireframe outlines for every triangle in the scene. Like in Quake 3, the lines will be visible even through solid geometry. If 2, draw the outlines only on visible surfaces (like r_showtris 2 in Medal of Honor.) If 0, disable wireframe overlay. Default 0. - + - vid_bpp. Sets the color depth of the screen in fullscreen mode. Windowed mode ignores this setting. Can be 16 or 32. Default 16. (Changes won't take effect until the next call to vid_restart.) - + - vid_fullscreen. If 1, fitzquake will run fullscreen. If 0, fitzquake will run in a window. Default 1. (Changes won't take effect until the next call to vid_restart.) - + - vid_height. Sets the vertical screen/window resolution. Default 480. In windowed mode, cannot be less than 200. (Changes won't take effect until the next call to vid_restart.) - + - vid_refreshrate. Sets the refresh rate of the screen in fullscreen mode. Windowed mode ignores this setting. Possible values include 60, 70, 72, 75, 85, etc. Default 60. (Changes won't take effect until the next call to vid_restart.) - vid_width. Sets the horizontal screen/window resolution. Default 640. In windowed mode, cannot be less than 320. (Changes won't take effect until the next call to vid_restart.) @@ -145,7 +145,7 @@ commands: - "cycle [ [ ...]]" to cycle a cvar through a list of values.. Note: this command will get stuck on a list that contains the same value more than once, such as "cycle blah 1 2 1 3". If you're doing anything that complex you can just use aliases. - vid_restart. Tries to set a video mode that matches the values of vid_width, vid_height, vid_fullscreen, and, if vid_fullscreen is 1, vid_bpp and vid_refreshrate. - + - vid_test. Like vid_restart, except that after switching to the new mode pops up a confirmation dialogue. This is useful if you are not sure what modes your monitor can handle, so you don't get stuck with a blank screen. The dialogue has a time limit so that if you don't press a key within 5 seconds, it will revert to the previous mode. changes in 0.75 @@ -182,13 +182,13 @@ changes in 0.75 - removed cvar gl_ztrick. The depth buffer is now cleared every frame. - removed cvar gl_keeptjunctions. Extra verts created by qbsp to eliminate tjunctions are now always kept. - removed "sliding on monsters' heads" fix, becuase I decided I don't like the idea of changing gameplay, even if the original behaviour is clearly a bug. Since this bug can be fixed in quakec also, I feel safer leaving it as it was. - + cvars: - gl_overbright. default 1. This variable controls overbright lighting on the world polygons. (For lighting on models, use gl_overbright_models.) If 1, overbright will be enabled and lighting will resemble software Quake. If 0, overbright will be disabled and lighting will resemble GLQuake. - + - r_oldskyleaf. default 0. If 0, surfaces inside sky leaves will be skipped by the renderer. If 1, they will be drawn whenever they are in your PVS, just like any other surface. - + - r_oldwater. default 1. If 1, use the old GLQuake method of subdividing the water surface to enable a warping animation. If 0, use the new render-to-texture method. Note: in general, r_oldwater 0 looks better and runs slower. So experiment to see if the performance hit is acceptable to you. - r_skyalpha. default 1. Sets the alpha of the front sky layer. Note that if sky alpha is less than 1.0, the sky will be drawn in two passes even if you have multitexture. @@ -239,33 +239,33 @@ Changes in 0.70 - removed support for GL_EXT_shared_texture_palette (special 8-bit texture format) - removed VCR code. command line switches "-record" and "-playback" no longer supported. - removed support for command line switch "-gamma" -- just use the gamma cvar, or idgamma or something. - + cvars: - r_stereo. default 0. If nonzero, the scene will be rendered once in red, and again in cyan, with the two views shifted slightly. If you have 3D glasses you can appreciate this (assumes that the left eye is red and the right eye is cyan.) The value of r_stereo sets the eye separation. If your glasses have red on the right eye, use a negative value to flip the views. - + - r_stereodepth. default 128. Sets the distance at which the two views will converge when stereo rendering is active. - + - scr_conwdith. default 0. Sets the virtual console width, where smaller numbers means larger text. Values larger than window width, or smaller than 320, will be clamped to that range, and all values will be rounded to a multiple of 8. If 0, the window width will be used. Note that values that divide evenly into the window width will make the text look nicest. - + - scr_menuscale. default 1. Sets the scale factor for menus and other centered overlays. If 1, images will be drawn at 1:1 scale. If 2, images will be double size. Menus will never be drawn smaller than 1:1, and never larger than the size of the window. Note that integer values will make the text look nicest. - + - scr_sbarscale. default 1. Sets the scale factor for the statusbar. If 1, images will be drawn at 1:1 scale. If 2, images will be double size. The statusbar will never be drawn smaller than 1:1, and never larger than the width of the window. Note that integer values will make the text look nicest. - + - host_maxfps. default 72. sets the maximum frames per second fitzquake will render (also the maximum number of server frames per second.) Clamped to the range 10 - 1000. Set to 72 to mimic standard quake. - + - r_quadparticles. default 1. If 1, particles are drawn as GL_QUADS instead of GL_TRIANGLES. Quads use 4 verts instead of 3, but the fillrate cost is 1/2 that of triangles. Depending on your card, either one may be faster. This cvar has no effect on the appearance of particles. - + - r_speeds. default 0. Values of 1 and 2 will give you increasing amounts of information. When you see two numbers separated by a slash, the first number is polys, and the second number is passes. - + commands: - gl_info. Displays opengl info which was previously displayed during initialization: vendor, renderer, version, and extensions - + - imagelist. Displays a list of loaded textures, and their dimentions. - + - gl_texturemode. Now accepts a number (1 through 6) as well as the name (gl_nearest, etc.) - + - gl_describetexturemodes. Lists all texturemodes. Changes in 0.65 @@ -293,7 +293,7 @@ Changes in 0.65 - optional 2x overbrightening on models. (see cvar "gl_overbright_models") - optional quake2-style noclip. (see cvar "sv_altnoclip") - new icon - + cvars: - con_logcenterprint: If 1, centerprint messages will be logged to the console in sp/coop. If 2, they will also be logged in deathmatch. Default 1. @@ -306,7 +306,7 @@ cvars: - r_flatlightstyles: If 1, styled lights (torch flicker, etc.) will be displayed as a steady light. If 2, the peak intensity will be used instead of the average intensity. Default 0. - - sv_altnoclip: If 1, enable the alternative noclip movement which resembles quake2 and is not constrained to the horizontal plane. Set to 0 to retain quake's original noclip behavior. Default 1. + - sv_altnoclip: If 1, enable the alternative noclip movement which resembles quake2 and is not constrained to the horizontal plane. Set to 0 to retain quake's original noclip behavior. Default 1. Changes in 0.60 --------------- @@ -358,7 +358,7 @@ Changes in 0.60 - carets indicate that you are scrolled back, like in quakeworld/quake2 - left arrow, right arrow, pgup, pgdn keys now auto-repeat - quadrupled the length of the console history - - commands: + - commands: - "game " to load a mod. - "reset " to reset a cvar to default. Note that this is the engine default, not the default.cfg value - resetall. resets all cvars. diff --git a/QC/boss.qc b/QC/boss.qc index f4e1d974..2425e8ee 100644 --- a/QC/boss.qc +++ b/QC/boss.qc @@ -117,7 +117,7 @@ void() boss_missile7 =[ $attack7, boss_missile8 ] {boss_face();}; void() boss_missile8 =[ $attack8, boss_missile9 ] {boss_face();}; void() boss_missile9 =[ $attack9, boss_missile10 ] {boss_missile(0, '100 100 200');}; void() boss_missile10 =[ $attack10, boss_missile11 ] {boss_face();}; -void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_missile(1, '100 100 200');}; +void() boss_missile11 =[ $attack11, boss_missile12 ] {boss_face();}; void() boss_missile12 =[ $attack12, boss_missile13 ] {boss_face();}; void() boss_missile13 =[ $attack13, boss_missile14 ] {boss_face();}; void() boss_missile14 =[ $attack14, boss_missile15 ] {boss_face();}; @@ -202,11 +202,11 @@ void(float r, vector p) boss_missile = // VR: Predicted direction attack. if (r == 0) { - vel = 700 + random() * 200; + vel = 450 + random() * 150; } else { - vel = 300 + random() * 200; + vel = 100 + random() * 150; } offang = vectoangles (self.enemy.origin - self.origin); diff --git a/QC/buttons.qc b/QC/buttons.qc index 2c560186..95e7d8da 100644 --- a/QC/buttons.qc +++ b/QC/buttons.qc @@ -1,5 +1,18 @@ // button and multiple button +void(entity e) VRButtonPressHaptic = +{ + if (cvar("vr_body_interactions") == 0) + { + haptic(e.touchinghand, 0.0, 0.3, 75, 1.0); + } + else + { + haptic(0, 0.0, 0.3, 75, 1.0); + haptic(1, 0.0, 0.3, 75, 1.0); + } +} + void() button_wait; void() button_return; @@ -20,8 +33,17 @@ void() button_done = void() button_return = { + local vector porg; + + porg_x = self.absmin_x + ((self.absmax_x - self.absmin_x) / 2); + porg_y = self.absmin_y + ((self.absmax_y - self.absmin_y) / 2); + porg_z = self.absmin_z + ((self.absmax_z - self.absmin_z) / 2); + particle2 (porg, '0 0 0', 5 /* sparks preset */, 64); + self.state = STATE_DOWN; + SUB_CalcMove (self.pos1, self.speed, button_done); + self.frame = 0; // use normal textures if (self.health) self.takedamage = DAMAGE_YES; // can be shot again @@ -35,11 +57,19 @@ void() button_blocked = void() button_fire = { + local vector porg; + if (self.state == STATE_UP || self.state == STATE_TOP) { return; } + + porg_x = self.absmin_x + ((self.absmax_x - self.absmin_x) / 2); + porg_y = self.absmin_y + ((self.absmax_y - self.absmin_y) / 2); + porg_z = self.absmin_z + ((self.absmax_z - self.absmin_z) / 2); + particle2 (porg, '0 0 0', 5 /* sparks preset */, 64); + sound (self, CHAN_VOICE, self.noise, 1, ATTN_NORM); self.state = STATE_UP; @@ -60,6 +90,8 @@ void() button_touch = return; } + VRButtonPressHaptic(other); + self.enemy = other; button_fire (); }; diff --git a/QC/combat.qc b/QC/combat.qc index 37b2a749..f021f688 100644 --- a/QC/combat.qc +++ b/QC/combat.qc @@ -27,7 +27,7 @@ float(entity targ, entity inflictor) CanDamage = return TRUE; return FALSE; } - + traceline(inflictor.origin, targ.origin, TRUE, self); if (trace_fraction == 1) return TRUE; @@ -59,7 +59,7 @@ void(entity targ, entity attacker) Killed = oself = self; self = targ; - + if (self.health < -99) self.health = -99; // don't let sbar look bad if a player @@ -80,16 +80,17 @@ void(entity targ, entity attacker) Killed = } ClientObituary(self, attacker); - + self.takedamage = DAMAGE_NO; self.touch = SUB_Null; monster_death_use(); self.th_die (); - + self = oself; }; +void(vector org, float damage) SpawnBloodSplash; /* ============ @@ -125,7 +126,7 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= targ.armortype = 0; // lost all armor targ.items = targ.items - (targ.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)); } - + targ.armorvalue = targ.armorvalue - save; take = ceil(damage-save); @@ -163,14 +164,23 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= // team play damage avoidance // if ( (teamplay == 1) && (targ.team > 0)&&(targ.team == attacker.team) ) if ( (teamplay == 1) && (targ.team > 0) && (targ.team == attacker.team) - && (targ != attacker) + && (targ != attacker) && (attacker.classname == "player") && (inflictor.classname != "door") ) // because squishing a teammate is still possible return; - + + if (targ.classname == "player") + { + SpawnBloodSplash(targ.origin, take / 2.0); + SpawnBloodSplash(targ.handpos, take / 2.0); + SpawnBloodSplash(targ.offhandpos, take / 2.0); + haptic(0, 0.0, 0.5, 30, 1.0); + haptic(1, 0.0, 0.5, 30, 1.0); + } + // do the damage targ.health = targ.health - take; - + if (targ.health <= 0) { Killed (targ, attacker); @@ -186,7 +196,7 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= // get mad unless of the same class (except for soldiers) if (self != attacker && attacker != self.enemy) { - if ( (self.classname != attacker.classname) + if ( (self.classname != attacker.classname) || (self.classname == "monster_army" ) ) { if (self.enemy.classname == "player") @@ -202,7 +212,7 @@ void(entity targ, entity inflictor, entity attacker, float damage) T_Damage= self.th_pain (attacker, take); // nightmare mode monsters don't go into pain frames often if (skill == 3) - self.pain_finished = time + 5; + self.pain_finished = time + 5; } self = oldself; @@ -220,7 +230,7 @@ void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDam local vector org; head = findradius(inflictor.origin, damage+40); - + while (head) { if (head != ignore) @@ -238,7 +248,7 @@ void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDam { if (CanDamage (head, inflictor)) { // shambler takes half damage from all explosions - if (head.classname == "monster_shambler") + if (head.classname == "monster_shambler") T_Damage (head, inflictor, attacker, points*0.5); else T_Damage (head, inflictor, attacker, points); @@ -259,9 +269,9 @@ void(entity attacker, float damage) T_BeamDamage = { local float points; local entity head; - + head = findradius(attacker.origin, damage+40); - + while (head) { if (head.takedamage) @@ -276,7 +286,7 @@ void(entity attacker, float damage) T_BeamDamage = { if (CanDamage (head, attacker)) { - if (head.classname == "monster_shambler") + if (head.classname == "monster_shambler") T_Damage (head, attacker, attacker, points*0.5); else T_Damage (head, attacker, attacker, points); diff --git a/QC/defs.qc b/QC/defs.qc index 6b8b9b00..78d35f4f 100644 --- a/QC/defs.qc +++ b/QC/defs.qc @@ -218,6 +218,8 @@ void end_sys_globals; // flag for structure dumping .vector offhandrot; .vector offhandvel; .float offhandvelmag; +.float touchinghand; +.vector muzzlepos; //================================================ void end_sys_fields; // flag for structure dumping @@ -684,6 +686,10 @@ void(entity e) setspawnparms = #78; // set parm1... to the // values at level start // for coop respawn +void(vector o, vector d, float preset, float count) particle2 = #79;// start a particle2 effect +float(float base, float exp) pow = #80; // power function +void(float hand, float delay, float duration, float frequency, float amplitude) haptic = #81; // VR haptics function + //============================================================================ // diff --git a/QC/items.qc b/QC/items.qc index 88a16e82..5d4945ef 100644 --- a/QC/items.qc +++ b/QC/items.qc @@ -2,6 +2,18 @@ void() W_SetCurrentAmmo; /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD BE .8 .3 .4 IN COLOR */ +void(entity e) VRItemPickupHaptic = +{ + if (cvar("vr_body_interactions") == 0) + { + haptic(e.touchinghand, 0.0, 0.3, 75, 1.0); + } + else + { + haptic(0, 0.0, 0.3, 75, 1.0); + haptic(1, 0.0, 0.3, 75, 1.0); + } +} void() SUB_regen = { @@ -173,6 +185,8 @@ void() health_touch = return; } + VRItemPickupHaptic(other); + sprint(other, "You receive "); s = ftos(self.healamount); sprint(other, s); @@ -280,6 +294,8 @@ void() armor_touch = self.nextthink = time + 20; self.think = SUB_regen; + VRItemPickupHaptic(other); + sprint(other, "You got armor\n"); // armor touch sound sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM); @@ -471,6 +487,8 @@ void() weapon_touch = else objerror ("weapon_touch: unknown classname"); + VRItemPickupHaptic(other); + sprint (other, "You got the "); sprint (other, self.netname); sprint (other, "\n"); @@ -668,6 +686,8 @@ local float best; bound_other_ammo (); + VRItemPickupHaptic(other); + sprint (other, "You got the "); sprint (other, self.netname); sprint (other, "\n"); @@ -911,6 +931,8 @@ local float best; if (other.items & self.items) return; + VRItemPickupHaptic(other); + sprint (other, "You got the "); sprint (other, self.netname); sprint (other,"\n"); @@ -1121,6 +1143,8 @@ local float best; if (other.health <= 0) return; + VRItemPickupHaptic(other); + sprint (other, "You got the "); sprint (other, self.netname); sprint (other,"\n"); @@ -1191,7 +1215,7 @@ void() item_artifact_invulnerability = setmodel (self, "progs/invulner.mdl"); self.netname = "Pentagram of Protection"; self.items = IT_INVULNERABILITY; - setsize (self, '-16 -16 -24', '16 16 32'); + setsize (self, '-8 -8 -24', '8 8 32'); StartItem (); }; @@ -1210,7 +1234,7 @@ void() item_artifact_envirosuit = setmodel (self, "progs/suit.mdl"); self.netname = "Biosuit"; self.items = IT_SUIT; - setsize (self, '-16 -16 -24', '16 16 32'); + setsize (self, '-8 -8 -24', '8 8 32'); StartItem (); }; @@ -1231,7 +1255,7 @@ void() item_artifact_invisibility = setmodel (self, "progs/invisibl.mdl"); self.netname = "Ring of Shadows"; self.items = IT_INVISIBILITY; - setsize (self, '-16 -16 -24', '16 16 32'); + setsize (self, '-8 -8 -24', '8 8 32'); StartItem (); }; @@ -1252,7 +1276,7 @@ void() item_artifact_super_damage = setmodel (self, "progs/quaddama.mdl"); self.netname = "Quad Damage"; self.items = IT_QUAD; - setsize (self, '-16 -16 -24', '16 16 32'); + setsize (self, '-8 -8 -24', '8 8 32'); StartItem (); }; @@ -1278,6 +1302,8 @@ void() BackpackTouch = if (other.health <= 0) return; + VRItemPickupHaptic(other); + acount = 0; sprint (other, "You get "); diff --git a/QC/misc.qc b/QC/misc.qc index ca01ba1c..d91f941f 100644 --- a/QC/misc.qc +++ b/QC/misc.qc @@ -219,7 +219,8 @@ void() barrel_explode = // did say self.owner T_RadiusDamage (self, self, 160, world); sound (self, CHAN_VOICE, "weapons/r_exp3.wav", 1, ATTN_NORM); - particle (self.origin, '0 0 0', 75, 255); + + particle2 (self.origin, '0 0 0', 2 /* explosion preset */, 1); self.origin_z = self.origin_z + 32; BecomeExplosion (); diff --git a/QC/pak3.pak b/QC/pak3.pak index 218b5b0b..4c7abf8b 100644 Binary files a/QC/pak3.pak and b/QC/pak3.pak differ diff --git a/QC/player.qc b/QC/player.qc index 6a3d8426..43a1bfcd 100644 --- a/QC/player.qc +++ b/QC/player.qc @@ -180,7 +180,7 @@ void() player_nail1 =[$nailatt1, player_nail2 ] if (self.weaponframe == 9) self.weaponframe = 1; SuperDamageSound(); - W_FireSpikes (3); + W_FireSpikes (2.35); self.attack_finished = time + 0.2; }; void() player_nail2 =[$nailatt2, player_nail1 ] @@ -193,7 +193,7 @@ void() player_nail2 =[$nailatt2, player_nail1 ] if (self.weaponframe == 9) self.weaponframe = 1; SuperDamageSound(); - W_FireSpikes (-3); + W_FireSpikes (-2.35); self.attack_finished = time + 0.2; }; @@ -483,6 +483,8 @@ void(string gibname, float dm) ThrowGib = new.nextthink = time + 10 + random()*10; new.frame = 0; new.flags = 0; + + particle2 (self.origin, new.velocity, 1 /* blood preset */, 40); }; void(string gibname, float dm) ThrowHead = @@ -499,6 +501,8 @@ void(string gibname, float dm) ThrowHead = self.origin_z = self.origin_z - 24; self.flags = self.flags - (self.flags & FL_ONGROUND); self.avelocity = crandom() * '0 600 0'; + + particle2 (self.origin, self.velocity, 1 /* blood preset */, 40); }; diff --git a/QC/progdefs.h b/QC/progdefs.h index 072b27ff..39285901 100644 --- a/QC/progdefs.h +++ b/QC/progdefs.h @@ -148,6 +148,8 @@ typedef struct vec3_t offhandrot; vec3_t offhandvel; float offhandvelmag; + float touchinghand; + vec3_t muzzlepos; } entvars_t; -#define PROGHEADER_CRC 37768 +#define PROGHEADER_CRC 52248 diff --git a/QC/progs.dat b/QC/progs.dat index ff63a2ef..c63cb10e 100644 Binary files a/QC/progs.dat and b/QC/progs.dat differ diff --git a/QC/weapons.qc b/QC/weapons.qc index 6bad4124..24d3ed2d 100644 --- a/QC/weapons.qc +++ b/QC/weapons.qc @@ -4,6 +4,7 @@ void (entity targ, entity inflictor, entity attacker, float damage) T_Damage; void () player_run; void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage; void(vector org, vector vel, float damage) SpawnBlood; +void(vector org, float damage) SpawnBloodSplash; void() SuperDamageSound; void() PainSound; @@ -55,20 +56,84 @@ vector() vrProjectileVelocity = return VEC_ORIGIN; }; +float() VRMeleeDmgQuadMult = +{ + if (self.super_damage_finished > time) + { + return 2.75; + } + + return 1; +} + +float(float velmag) VRMeleeStrengthMult = +{ + local float strength; + strength = velmag - cvar("vr_melee_threshold"); + + if (strength > 1.0) + { + strength = pow(strength, 1.5); + } + + return strength; +} + + float(float v) VRMeleeDmg = { - return (v * self.handvelmag) * cvar("vr_melee_dmg_multiplier"); + return (v * VRMeleeStrengthMult(self.handvelmag)) * cvar("vr_melee_dmg_multiplier") * VRMeleeDmgQuadMult(); } float(float v) VRMeleeOffHandDmg = { - return (v * self.offhandvelmag) * cvar("vr_melee_dmg_multiplier"); + return (v * VRMeleeStrengthMult(self.offhandvelmag)) * cvar("vr_melee_dmg_multiplier") * VRMeleeDmgQuadMult(); } - float(float v) VRMeleeRange = { - return v * cvar("vr_melee_range_multiplier"); + local float mult; + + if (self.super_damage_finished > time) + { + mult = 1.25; + } + else + { + mult = 1; + } + + return v * cvar("vr_melee_range_multiplier") * mult; +} + +void(float hand, float velmag) VRMeleeHaptic = +{ + local float power, amplitude, duration; + power = VRMeleeStrengthMult(velmag); + + amplitude = power / 10.0; + if (amplitude > 1.0) { amplitude = 1.0; } + else if (amplitude < 0.45) { amplitude = 0.45; } + + duration = 0.35 + power / 18.0; + if (duration < 0.35) { duration = 0.35; } + else if (duration > 0.9) { duration = 0.9; } + + haptic(hand, 0.0, duration, 75.0, amplitude); +} + +void(float duration, float frequency, float amplitude) VRGunHaptic = +{ + haptic(1, 0.0, duration, frequency, amplitude); +} + +void(vector org) BroadcastGunshotEffect = +{ + WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte (MSG_BROADCAST, TE_GUNSHOT); + WriteCoord (MSG_BROADCAST, org_x); + WriteCoord (MSG_BROADCAST, org_y); + WriteCoord (MSG_BROADCAST, org_z); } /* @@ -82,17 +147,12 @@ void() W_FireAxe = local vector org; local float xdmg; local string s; - local float playedsound; - - xdmg = VRMeleeDmg(0.73); - // s = ftos(xdmg); - // sprint (self, "DMG: "); - // sprint (self, s); - // sprint (self, "\n"); + xdmg = VRMeleeDmg(0.95); makevectors (self.v_angle); source = self.handpos + '0 0 0'; + // TODO VR: improve this collision detection traceline (source - v_forward*24, source + v_forward * VRMeleeRange(28), FALSE, self); if (trace_fraction == 1.0) return; @@ -102,13 +162,14 @@ void() W_FireAxe = if (trace_ent.takedamage) { trace_ent.axhitme = 1; - SpawnBlood (org, '0 0 0', xdmg); + SpawnBloodSplash (org, xdmg); T_Damage (trace_ent, self, self, xdmg); if (self.melee_hit_sound_played == FALSE) { + VRMeleeHaptic(1, self.handvelmag); sound (self, CHAN_WEAPON, "fisthit.wav", 1.0, ATTN_NORM); - playedsound = TRUE; + self.melee_hit_sound_played = TRUE; } } else @@ -116,20 +177,12 @@ void() W_FireAxe = // hit wall if (self.melee_hit_sound_played == FALSE) { + VRMeleeHaptic(1, self.handvelmag); sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); - playedsound = TRUE; + self.melee_hit_sound_played = TRUE; } - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_GUNSHOT); - WriteCoord (MSG_BROADCAST, org_x); - WriteCoord (MSG_BROADCAST, org_y); - WriteCoord (MSG_BROADCAST, org_z); - } - - if (playedsound) - { - self.melee_hit_sound_played = TRUE; + BroadcastGunshotEffect(org); } }; @@ -147,14 +200,8 @@ void() W_GunMelee = local vector org; local float xdmg; local string s; - local float playedsound; - xdmg = VRMeleeDmg(0.43); - - // s = ftos(xdmg); - // sprint (self, "DMG: "); - // sprint (self, s); - // sprint (self, "\n"); + xdmg = VRMeleeDmg(0.5); makevectors (self.v_angle); source = self.handpos + '0 0 0'; @@ -167,13 +214,14 @@ void() W_GunMelee = if (trace_ent.takedamage) { trace_ent.axhitme = 1; - SpawnBlood (org, '0 0 0', xdmg); + SpawnBloodSplash (org, xdmg); T_Damage (trace_ent, self, self, xdmg); if (self.melee_hit_sound_played == FALSE) { + VRMeleeHaptic(1, self.handvelmag); sound (self, CHAN_WEAPON, "fisthit.wav", 1.0, ATTN_NORM); - playedsound = TRUE; + self.melee_hit_sound_played = TRUE; } } else @@ -181,20 +229,12 @@ void() W_GunMelee = // hit wall if (self.melee_hit_sound_played == FALSE) { + VRMeleeHaptic(1, self.handvelmag); sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); - playedsound = TRUE; + self.melee_hit_sound_played = TRUE; } - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_GUNSHOT); - WriteCoord (MSG_BROADCAST, org_x); - WriteCoord (MSG_BROADCAST, org_y); - WriteCoord (MSG_BROADCAST, org_z); - } - - if (playedsound) - { - self.melee_hit_sound_played = TRUE; + BroadcastGunshotEffect(org); } }; @@ -215,16 +255,11 @@ void() W_FistMelee = local string s; local float playedsound; - xdmg = VRMeleeOffHandDmg(0.53); - - // s = ftos(xdmg); - // sprint (self, "OFFHANDDMG: "); - // sprint (self, s); - // sprint (self, "\n"); + xdmg = VRMeleeOffHandDmg(0.75); makevectors (self.v_angle); source = self.offhandpos + '0 0 0'; - traceline (source - v_forward*24, source + v_forward * VRMeleeRange(24), FALSE, self); + traceline (source - v_forward*24, source + v_forward * VRMeleeRange(26), FALSE, self); if (trace_fraction == 1.0) return; @@ -238,8 +273,9 @@ void() W_FistMelee = if (trace_ent.takedamage) { + VRMeleeHaptic(0, self.offhandvelmag); trace_ent.axhitme = 1; - SpawnBlood (org, '0 0 0', xdmg); + SpawnBloodSplash (org, xdmg); T_Damage (trace_ent, self, self, xdmg); } else @@ -247,16 +283,13 @@ void() W_FistMelee = // hit wall if (self.offhand_melee_hit_sound_played == FALSE) { + VRMeleeHaptic(0, self.offhandvelmag); PainSound(); - SpawnBlood(org, '0 0 0', xdmg); + SpawnBloodSplash (org, xdmg); playedsound = TRUE; } - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_GUNSHOT); - WriteCoord (MSG_BROADCAST, org_x); - WriteCoord (MSG_BROADCAST, org_y); - WriteCoord (MSG_BROADCAST, org_z); + BroadcastGunshotEffect(org); } if (playedsound) @@ -321,9 +354,28 @@ SpawnBlood */ void(vector org, vector vel, float damage) SpawnBlood = { - particle (org, vel*0.1, 73, damage*2); + particle2 (org, vel * 0.2, 1 /* blood preset */, damage); }; +/* +================ +SpawnBloodSplash +================ +*/ +void(vector org, float damage) SpawnBloodSplash = +{ + local vector pvel; + + pvel_x = crandom() * 240; + pvel_y = crandom() * 240; + pvel_z = random() * 120 + 100; + + SpawnBlood(org, pvel, damage); +}; + + + + /* ================ spawn_touchblood @@ -334,7 +386,7 @@ void(float damage) spawn_touchblood = local vector vel; vel = wall_velocity () * 0.2; - SpawnBlood (self.origin + vel*0.01, vel, damage); + SpawnBlood (self.origin + vel * 0.01, vel, damage); }; @@ -345,7 +397,7 @@ SpawnChunk */ void(vector org, vector vel) SpawnChunk = { - particle (org, vel*0.02, 0, 10); + particle (org, vel * 0.02, 0, 10); }; /* @@ -419,11 +471,7 @@ void(float damage, vector dir) TraceAttack = } else { - WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); - WriteByte (MSG_BROADCAST, TE_GUNSHOT); - WriteCoord (MSG_BROADCAST, org_x); - WriteCoord (MSG_BROADCAST, org_y); - WriteCoord (MSG_BROADCAST, org_z); + BroadcastGunshotEffect(org); } }; @@ -508,6 +556,10 @@ void() W_FireShotgun = self.currentammo = self.ammo_shells = self.ammo_shells - 1; dir = aim (self, 100000); FireBullets (6, dir, '0.01 0.01 0'); + + VRGunHaptic(0.25, 70, 0.75); + + particle2 (self.muzzlepos, '0 0 0', 6 /* gun smoke preset */, 1); }; @@ -533,6 +585,11 @@ void() W_FireSuperShotgun = self.currentammo = self.ammo_shells = self.ammo_shells - 2; dir = aim (self, 100000); FireBullets (14, dir, '0.035 0.025 0'); + + VRGunHaptic(0.55, 75, 1.0); + + particle2 (self.muzzlepos - '0 2 0', '0 0 0', 6 /* gun smoke preset */, 1); + particle2 (self.muzzlepos + '0 2 0', '0 0 0', 6 /* gun smoke preset */, 1); }; @@ -640,6 +697,10 @@ void() W_FireRocket = setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, self.handpos + '0 0 0'); //setorigin (missile, self.handpos + v_forward*8 + '0 0 16'); + + VRGunHaptic(0.5, 75, 1.0); + + particle2 (self.muzzlepos, '0 0 0', 6 /* gun smoke preset */, 3); }; /* @@ -672,7 +733,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = traceline (p1, p2, FALSE, self); if (trace_ent.takedamage) { - particle (trace_endpos, '0 0 100', 225, damage*4); + SpawnBloodSplash (trace_endpos, damage*5); T_Damage (trace_ent, from, from, damage); if (self.classname == "player") { @@ -685,7 +746,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = traceline (p1 + f, p2 + f, FALSE, self); if (trace_ent != e1 && trace_ent.takedamage) { - particle (trace_endpos, '0 0 100', 225, damage*4); + SpawnBloodSplash (trace_endpos, damage*5); T_Damage (trace_ent, from, from, damage); } e2 = trace_ent; @@ -693,7 +754,7 @@ void(vector p1, vector p2, entity from, float damage) LightningDamage = traceline (p1 - f, p2 - f, FALSE, self); if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage) { - particle (trace_endpos, '0 0 100', 225, damage*4); + SpawnBloodSplash (trace_endpos, damage*5); T_Damage (trace_ent, from, from, damage); } }; @@ -734,7 +795,13 @@ void() W_FireLightning = org = self.handpos + '0 0 0'; traceline (org, org + v_forward*600, TRUE, self); + particle2 (trace_endpos, '0 0 0', 3 /* lightning preset */, 60); + particle2 (trace_endpos, '0 0 0', 4 /* smoke preset */, 1); + particle2 (trace_endpos, '0 0 0', 5 /* sparks preset */, 12); LightningDamage (self.handpos, trace_endpos + v_forward*4, self, 30); + + VRGunHaptic(0.4, 175, 1.0); + particle2 (self.muzzlepos, '0 0 0', 6 /* gun smoke preset */, 1); }; @@ -834,6 +901,9 @@ void() W_FireGrenade = setmodel (missile, "progs/grenade.mdl"); setsize (missile, '0 0 0', '0 0 0'); setorigin (missile, self.handpos); + + VRGunHaptic(0.4, 75, 1.0); + particle2 (self.muzzlepos, '0 0 0', 6 /* gun smoke preset */, 2); }; @@ -888,6 +958,9 @@ void() W_FireSuperSpikes = newmis.velocity = newmis.velocity + vrProjectileVelocity(); self.punchangle_x = -2; + + VRGunHaptic(0.05, 150, 1.0); + particle2 (self.muzzlepos, '0 0 0', 6 /* gun smoke preset */, 1); }; void(float ox) W_FireSpikes = @@ -920,6 +993,9 @@ void(float ox) W_FireSpikes = newmis.velocity = newmis.velocity + vrProjectileVelocity(); self.punchangle_x = -2; + + VRGunHaptic(0.05, 150, 1.0); + particle2 (self.muzzlepos + v_right*ox, '0 0 0', 6 /* gun smoke preset */, 1); }; @@ -1522,6 +1598,8 @@ void() W_WeaponFrame = if (self.weapon == IT_LIGHTNING) { org = self.handpos + '0 0 0'; + + makevectors(self.v_angle); traceline (org, org + v_forward*600, TRUE, self); WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); diff --git a/Quake/bgmusic.cpp b/Quake/bgmusic.cpp index 09b837fe..93661920 100644 --- a/Quake/bgmusic.cpp +++ b/Quake/bgmusic.cpp @@ -31,7 +31,7 @@ bool bgmloop; cvar_t bgm_extmusic = {"bgm_extmusic", "1", CVAR_ARCHIVE}; -static qboolean no_extmusic = false; +static bool no_extmusic = false; static float old_volume = -1.0f; enum bgm_player_t @@ -132,7 +132,7 @@ static void BGM_Stop_f() BGM_Stop(); } -qboolean BGM_Init() +bool BGM_Init() { music_handler_t* handlers = nullptr; int i; @@ -292,7 +292,7 @@ void BGM_Play(const char* filename) Con_Printf("Couldn't handle music file %s\n", filename); } -void BGM_PlayCDtrack(byte track, qboolean looping) +void BGM_PlayCDtrack(byte track, bool looping) { /* instead of searching by the order of music_handlers, do so by * the order of searchpath priority: the file from the searchpath @@ -406,7 +406,7 @@ void BGM_Resume() static void BGM_UpdateStream() { - qboolean did_rewind = false; + bool did_rewind = false; int res; /* Number of bytes read. */ int bufferSamples; int fileSamples; diff --git a/Quake/bgmusic.hpp b/Quake/bgmusic.hpp index 512ec4a6..1a4c634d 100644 --- a/Quake/bgmusic.hpp +++ b/Quake/bgmusic.hpp @@ -28,7 +28,7 @@ extern bool bgmloop; extern cvar_t bgm_extmusic; -qboolean BGM_Init(void); +bool BGM_Init(void); void BGM_Shutdown(void); void BGM_Play(const char* filename); @@ -37,6 +37,6 @@ void BGM_Update(void); void BGM_Pause(void); void BGM_Resume(void); -void BGM_PlayCDtrack(byte track, qboolean looping); +void BGM_PlayCDtrack(byte track, bool looping); #endif /* _BGMUSIC_H_ */ diff --git a/Quake/bspfile.hpp b/Quake/bspfile.hpp index 51f5ab15..d17255be 100644 --- a/Quake/bspfile.hpp +++ b/Quake/bspfile.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/cd_null.cpp b/Quake/cd_null.cpp index 5655a462..d95a3390 100644 --- a/Quake/cd_null.cpp +++ b/Quake/cd_null.cpp @@ -20,7 +20,7 @@ #include "quakedef.hpp" -int CDAudio_Play(byte track, qboolean looping) +int CDAudio_Play(byte track, bool looping) { (void)track; (void)looping; diff --git a/Quake/cd_sdl.cpp b/Quake/cd_sdl.cpp index 7bbb1da8..b5b0e34c 100644 --- a/Quake/cd_sdl.cpp +++ b/Quake/cd_sdl.cpp @@ -43,18 +43,18 @@ #include "quakedef.hpp" -static qboolean cdValid = false; -static qboolean playing = false; -static qboolean wasPlaying = false; -static qboolean enabled = true; -static qboolean playLooping = false; +static bool cdValid = false; +static bool playing = false; +static bool wasPlaying = false; +static bool enabled = true; +static bool playLooping = false; static byte remap[100]; static byte playTrack; static double endOfTrack = -1.0, pausetime = -1.0; static SDL_CD* cd_handle; static int cd_dev = -1; static float old_cdvolume; -static qboolean hw_vol_works = true; +static bool hw_vol_works = true; static void CDAudio_Eject(void) @@ -81,7 +81,7 @@ static int CDAudio_GetAudioDiskInfo(void) return 0; } -int CDAudio_Play(byte track, qboolean looping) +int CDAudio_Play(byte track, bool looping) { int len_m, len_s, len_f; @@ -358,7 +358,7 @@ static void CD_f(void) Con_Printf("cd: unknown command \"%s\"\n", command); } -static qboolean CD_GetVolume(void* unused) +static bool CD_GetVolume(void* unused) { (void)unused; @@ -367,7 +367,7 @@ static qboolean CD_GetVolume(void* unused) return false; } -static qboolean CD_SetVolume(void* unused) +static bool CD_SetVolume(void* unused) { (void)unused; @@ -376,7 +376,7 @@ static qboolean CD_SetVolume(void* unused) return false; } -static qboolean CDAudio_SetVolume(float value) +static bool CDAudio_SetVolume(float value) { if(!cd_handle || !enabled) return false; diff --git a/Quake/cdaudio.hpp b/Quake/cdaudio.hpp index 7acfaae9..4ef26dc3 100644 --- a/Quake/cdaudio.hpp +++ b/Quake/cdaudio.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __CDAUDIO_H int CDAudio_Init(void); -int CDAudio_Play(byte track, qboolean looping); +int CDAudio_Play(byte track, bool looping); /* returns 0 for success, -1 for failure. */ void CDAudio_Stop(void); void CDAudio_Pause(void); diff --git a/Quake/cfgfile.cpp b/Quake/cfgfile.cpp index f18cb519..ae2a0a21 100644 --- a/Quake/cfgfile.cpp +++ b/Quake/cfgfile.cpp @@ -175,7 +175,7 @@ int CFG_OpenConfig(const char* cfg_name) { FILE* f; long length; - qboolean pak; + bool pak; CFG_CloseConfig(); diff --git a/Quake/chase.cpp b/Quake/chase.cpp index 41601af3..6c4f2c26 100644 --- a/Quake/chase.cpp +++ b/Quake/chase.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/cl_demo.cpp b/Quake/cl_demo.cpp index 28f5317a..ac31fa42 100644 --- a/Quake/cl_demo.cpp +++ b/Quake/cl_demo.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -413,7 +414,7 @@ void CL_PlayDemo_f() int i; int c; - qboolean neg; + bool neg; if(cmd_source != src_command) { diff --git a/Quake/cl_input.cpp b/Quake/cl_input.cpp index a00a785d..eeb5f4c9 100644 --- a/Quake/cl_input.cpp +++ b/Quake/cl_input.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -558,6 +559,9 @@ void CL_SendMove(const usercmd_t* cmd) writeVec(cmd->offhandvel); MSG_WriteFloat(&buf, cmd->offhandvelmag); + // muzzlepos + writeVec(cmd->muzzlepos); + MSG_WriteShort(&buf, cmd->forwardmove); MSG_WriteShort(&buf, cmd->sidemove); MSG_WriteShort(&buf, cmd->upmove); diff --git a/Quake/cl_main.cpp b/Quake/cl_main.cpp index dc62a0af..ff448a78 100644 --- a/Quake/cl_main.cpp +++ b/Quake/cl_main.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -631,23 +632,23 @@ void CL_RelinkEntities() if(ent->model->flags & EF_GIB) { - R_RocketTrail(oldorg, ent->origin, 2); + R_RocketTrail(oldorg, ent->origin, 2 /* blood */); } else if(ent->model->flags & EF_ZOMGIB) { - R_RocketTrail(oldorg, ent->origin, 4); + R_RocketTrail(oldorg, ent->origin, 4 /* slight blood */); } else if(ent->model->flags & EF_TRACER) { - R_RocketTrail(oldorg, ent->origin, 3); + R_RocketTrail(oldorg, ent->origin, 3) /* tracer */; } else if(ent->model->flags & EF_TRACER2) { - R_RocketTrail(oldorg, ent->origin, 5); + R_RocketTrail(oldorg, ent->origin, 5 /* tracer */); } else if(ent->model->flags & EF_ROCKET) { - R_RocketTrail(oldorg, ent->origin, 0); + R_RocketTrail(oldorg, ent->origin, 0 /* rocket trail */); dl = CL_AllocDlight(i); VectorCopy(ent->origin, dl->origin); dl->radius = 200; @@ -655,11 +656,11 @@ void CL_RelinkEntities() } else if(ent->model->flags & EF_GRENADE) { - R_RocketTrail(oldorg, ent->origin, 1); + R_RocketTrail(oldorg, ent->origin, 1 /* smoke */); } else if(ent->model->flags & EF_TRACER3) { - R_RocketTrail(oldorg, ent->origin, 6); + R_RocketTrail(oldorg, ent->origin, 6 /* voor trail */); } ent->forcelink = false; diff --git a/Quake/cl_parse.cpp b/Quake/cl_parse.cpp index 09b48023..7b7d95f2 100644 --- a/Quake/cl_parse.cpp +++ b/Quake/cl_parse.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -73,16 +74,16 @@ const char* svc_strings[] = { // framenum, alpha, using flags "svc_spawnstaticsound2", // 44 // [coord3] [short] samp [byte] vol //[byte] aten - "", // 44 - "", // 45 + "svc_particle2", // 45 "", // 46 "", // 47 "", // 48 "", // 49 + "", // 50 // johnfitz }; -qboolean warn_about_nehahra_protocol; // johnfitz +bool warn_about_nehahra_protocol; // johnfitz extern vec3_t v_punchangles[2]; // johnfitz @@ -477,7 +478,7 @@ void CL_ParseUpdate(int bits) int i; qmodel_t* model; int modnum; - qboolean forcelink; + bool forcelink; entity_t* ent; int num; int skin; @@ -1386,6 +1387,7 @@ void CL_ParseServerMessage() break; case svc_particle: R_ParseParticleEffect(); break; + case svc_particle2: R_ParseParticle2Effect(); break; case svc_spawnbaseline: i = MSG_ReadShort(); diff --git a/Quake/cl_tent.cpp b/Quake/cl_tent.cpp index 293ca1e0..206ce92f 100644 --- a/Quake/cl_tent.cpp +++ b/Quake/cl_tent.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -59,23 +60,21 @@ CL_ParseBeam */ void CL_ParseBeam(qmodel_t* m) { - int ent; - vec3_t start; - - vec3_t end; - beam_t* b; - int i; - - ent = MSG_ReadShort(); + const int ent = MSG_ReadShort(); + vec3_t start; start[0] = MSG_ReadCoord(cl.protocolflags); start[1] = MSG_ReadCoord(cl.protocolflags); start[2] = MSG_ReadCoord(cl.protocolflags); + vec3_t end; end[0] = MSG_ReadCoord(cl.protocolflags); end[1] = MSG_ReadCoord(cl.protocolflags); end[2] = MSG_ReadCoord(cl.protocolflags); + beam_t* b; + int i; + // override any beam with the same entity for(i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++) { @@ -136,7 +135,7 @@ void CL_ParseTEnt() pos[0] = MSG_ReadCoord(cl.protocolflags); pos[1] = MSG_ReadCoord(cl.protocolflags); pos[2] = MSG_ReadCoord(cl.protocolflags); - R_RunParticleEffect(pos, vec3_origin, 20, 30); + R_RunParticleEffect_BulletPuff(pos, vec3_origin, 20, 30); S_StartSound(-1, 0, cl_sfx_wizhit, pos, 1, 1); break; @@ -144,7 +143,7 @@ void CL_ParseTEnt() pos[0] = MSG_ReadCoord(cl.protocolflags); pos[1] = MSG_ReadCoord(cl.protocolflags); pos[2] = MSG_ReadCoord(cl.protocolflags); - R_RunParticleEffect(pos, vec3_origin, 226, 20); + R_RunParticleEffect_BulletPuff(pos, vec3_origin, 226, 20); S_StartSound(-1, 0, cl_sfx_knighthit, pos, 1, 1); break; @@ -152,7 +151,7 @@ void CL_ParseTEnt() pos[0] = MSG_ReadCoord(cl.protocolflags); pos[1] = MSG_ReadCoord(cl.protocolflags); pos[2] = MSG_ReadCoord(cl.protocolflags); - R_RunParticleEffect(pos, vec3_origin, 0, 10); + R_RunParticleEffect_BulletPuff(pos, vec3_origin, 0, 10); if(rand() % 5) { S_StartSound(-1, 0, cl_sfx_tink1, pos, 1, 1); @@ -178,7 +177,7 @@ void CL_ParseTEnt() pos[0] = MSG_ReadCoord(cl.protocolflags); pos[1] = MSG_ReadCoord(cl.protocolflags); pos[2] = MSG_ReadCoord(cl.protocolflags); - R_RunParticleEffect(pos, vec3_origin, 0, 20); + R_RunParticleEffect_BulletPuff(pos, vec3_origin, 0, 20); if(rand() % 5) { @@ -206,7 +205,7 @@ void CL_ParseTEnt() pos[0] = MSG_ReadCoord(cl.protocolflags); pos[1] = MSG_ReadCoord(cl.protocolflags); pos[2] = MSG_ReadCoord(cl.protocolflags); - R_RunParticleEffect(pos, vec3_origin, 0, 20); + R_RunParticleEffect_BulletPuff(pos, vec3_origin, 0, 10); break; case TE_EXPLOSION: // rocket explosion @@ -226,7 +225,7 @@ void CL_ParseTEnt() pos[0] = MSG_ReadCoord(cl.protocolflags); pos[1] = MSG_ReadCoord(cl.protocolflags); pos[2] = MSG_ReadCoord(cl.protocolflags); - R_BlobExplosion(pos); + R_ParticleExplosion(pos); S_StartSound(-1, 0, cl_sfx_r_exp3, pos, 1, 1); break; @@ -315,26 +314,13 @@ CL_UpdateTEnts */ void CL_UpdateTEnts() { - int i; - - int j; // johnfitz -- use j instead of using i twice, so we don't corrupt - // memory - beam_t* b; - vec3_t dist; - - vec3_t org; - float d; - entity_t* ent; - float yaw; - - float pitch; - float forward; - num_temp_entities = 0; srand((int)(cl.time * 1000)); // johnfitz -- freeze beams when paused // update lightning + int i; + beam_t* b; for(i = 0, b = cl_beams; i < MAX_BEAMS; i++, b++) { if(!b->model || b->endtime < cl.time) @@ -375,8 +361,12 @@ void CL_UpdateTEnts() } // calculate pitch and yaw + vec3_t dist; VectorSubtract(b->end, b->start, dist); + float pitch; + float yaw; + if(dist[1] == 0 && dist[0] == 0) { yaw = 0; @@ -397,7 +387,7 @@ void CL_UpdateTEnts() yaw += 360; } - forward = sqrt(dist[0] * dist[0] + dist[1] * dist[1]); + const float forward = sqrt(dist[0] * dist[0] + dist[1] * dist[1]); pitch = (int)(atan2(dist[2], forward) * 180 / M_PI); if(pitch < 0) { @@ -406,11 +396,13 @@ void CL_UpdateTEnts() } // add new entities for the lightning + vec3_t org; VectorCopy(b->start, org); - d = VectorNormalize(dist); + float d = VectorNormalize(dist); while(d > 0) { - ent = CL_NewTempEntity(); + + entity_t* ent = CL_NewTempEntity(); if(!ent) { return; @@ -423,7 +415,7 @@ void CL_UpdateTEnts() // johnfitz -- use j instead of using i twice, so we don't corrupt // memory - for(j = 0; j < 3; j++) + for(int j = 0; j < 3; j++) { org[j] += dist[j] * 30; } diff --git a/Quake/client.hpp b/Quake/client.hpp index fde75763..a66858c6 100644 --- a/Quake/client.hpp +++ b/Quake/client.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -117,15 +118,15 @@ typedef struct // demo recording info must be here, because record is started before // entering a map (and clearing client_state_t) - qboolean demorecording; - qboolean demoplayback; + bool demorecording; + bool demoplayback; // did the user pause demo playback? (separate from cl.paused because we // don't want a svc_setpause inside the demo to actually pause demo // playback). - qboolean demopaused; + bool demopaused; - qboolean timedemo; + bool timedemo; int forcetrack; // -1 = use normal cd track FILE* demofile; int td_lastframe; // to meter out one message a frame @@ -186,16 +187,16 @@ struct client_state_t // pitch drifting vars float idealpitch; float pitchvel; - qboolean nodrift; + bool nodrift; float driftmove; double laststop; float viewheight; float crouch; // local amount for smoothing stepups - qboolean paused; // send over by server - qboolean onground; - qboolean inwater; + bool paused; // send over by server + bool onground; + bool inwater; int intermission; // don't change view angle, full screen, etc int completed_time; // latched at intermission start diff --git a/Quake/cmd.cpp b/Quake/cmd.cpp index 908bc683..cc978447 100644 --- a/Quake/cmd.cpp +++ b/Quake/cmd.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -39,7 +40,7 @@ typedef struct cmdalias_s cmdalias_t* cmd_alias; -qboolean cmd_wait; +bool cmd_wait; //============================================================================= diff --git a/Quake/cmd.hpp b/Quake/cmd.hpp index 2837254e..d4d1b845 100644 --- a/Quake/cmd.hpp +++ b/Quake/cmd.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/common.cpp b/Quake/common.cpp index c7cd217e..5dc21eb6 100644 --- a/Quake/common.cpp +++ b/Quake/common.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -38,9 +39,9 @@ cvar_t cmdline = { "cmdline", "", CVAR_ROM /*|CVAR_SERVERINFO*/}; /* sending cmdline upon CCREQ_RULE_INFO is evil */ -static qboolean com_modified; // set true if using non-id files +static bool com_modified; // set true if using non-id files -qboolean fitzmode; +bool fitzmode; static void COM_Path_f(); @@ -60,7 +61,7 @@ char** com_argv; #define CMDLINE_LENGTH 256 /* johnfitz -- mirrored in cmd.c */ char com_cmdline[CMDLINE_LENGTH]; -qboolean standard_quake = true, rogue, hipnotic; +bool standard_quake = true, rogue, hipnotic; // this graphic needs to be in the pak file to use registered features static unsigned short pop[] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, @@ -655,7 +656,7 @@ float Q_atof(const char* str) ============================================================================ */ -qboolean host_bigendian; +bool host_bigendian; short (*BigShort)(short l); short (*LittleShort)(short l); @@ -892,7 +893,7 @@ void MSG_WriteAngle16(sizebuf_t* sb, float f, unsigned int flags) // reading functions // int msg_readcount; -qboolean msg_badread; +bool msg_badread; void MSG_BeginReading() { @@ -2025,7 +2026,7 @@ COM_FileExists Returns whether the file is found in the quake filesystem. =========== */ -qboolean COM_FileExists(const char* filename, unsigned int* path_id) +bool COM_FileExists(const char* filename, unsigned int* path_id) { int ret = COM_FindFile(filename, nullptr, nullptr, path_id); return (ret == -1) ? false : true; @@ -2371,7 +2372,7 @@ static void COM_AddGameDirectory(const char* base, const char* dir) pack_t* qspak; char pakfile[MAX_OSPATH]; - qboolean been_here = false; + bool been_here = false; q_strlcpy(com_gamedir, va("%s/%s", base, dir), sizeof(com_gamedir)); @@ -2404,7 +2405,7 @@ static void COM_AddGameDirectory(const char* base, const char* dir) } else { - qboolean old = com_modified; + bool old = com_modified; if(been_here) { base = host_parms->userdir; diff --git a/Quake/common.hpp b/Quake/common.hpp index cb1005f3..c6bdad00 100644 --- a/Quake/common.hpp +++ b/Quake/common.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -48,8 +49,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef struct sizebuf_s { - qboolean allowoverflow; // if false, do a Sys_Error - qboolean overflowed; // set to true if the buffer size failed + bool allowoverflow; // if false, do a Sys_Error + bool overflowed; // set to true if the buffer size failed byte* data; int maxsize; int cursize; @@ -82,7 +83,7 @@ void InsertLinkAfter(link_t* l, link_t* after); //============================================================================ -extern qboolean host_bigendian; +extern bool host_bigendian; extern short (*BigShort)(short l); extern short (*LittleShort)(short l); @@ -104,7 +105,7 @@ void MSG_WriteAngle(sizebuf_t* sb, float f, unsigned int flags); void MSG_WriteAngle16(sizebuf_t* sb, float f, unsigned int flags); // johnfitz extern int msg_readcount; -extern qboolean msg_badread; // set if a read goes beyond end of message +extern bool msg_badread; // set if a read goes beyond end of message void MSG_BeginReading(void); int MSG_ReadChar(void); @@ -156,7 +157,7 @@ extern int q_vsnprintf(char* str, size_t size, const char* format, va_list args) //============================================================================ extern char com_token[1024]; -extern qboolean com_eof; +extern bool com_eof; const char* COM_Parse(const char* data); @@ -232,7 +233,7 @@ extern int file_from_pak; // global indicating that file came from a pak void COM_WriteFile(const char* filename, const void* data, int len); int COM_OpenFile(const char* filename, int* handle, unsigned int* path_id); int COM_FOpenFile(const char* filename, FILE** file, unsigned int* path_id); -qboolean COM_FileExists(const char* filename, unsigned int* path_id); +bool COM_FileExists(const char* filename, unsigned int* path_id); void COM_CloseFile(int h); // these procedures open a file using COM_FindFile and loads it into a proper @@ -282,7 +283,7 @@ const char* COM_ParseStringNewline(const char* buffer); typedef struct _fshandle_t { FILE* file; - qboolean pak; /* is the file read from a pak */ + bool pak; /* is the file read from a pak */ long start; /* file or data start position */ long length; /* file or data size */ long pos; /* current position relative to start */ @@ -301,8 +302,8 @@ long FS_filelength(fshandle_t* fh); extern struct cvar_s registered; -extern qboolean standard_quake, rogue, hipnotic; -extern qboolean fitzmode; +extern bool standard_quake, rogue, hipnotic; +extern bool fitzmode; /* if true, run in fitzquake mode disabling custom quakespasm hacks */ #endif /* _Q_COMMON_H */ diff --git a/Quake/console.cpp b/Quake/console.cpp index f0eafdbf..c8f211cb 100644 --- a/Quake/console.cpp +++ b/Quake/console.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -42,7 +43,7 @@ float con_cursorspeed = 4; int con_buffersize; // johnfitz -- user can now override default -qboolean con_forcedup; // because no entities to refresh +bool con_forcedup; // because no entities to refresh int con_totallines; // total lines in console scrollback int con_backscroll; // lines up from bottom to display @@ -61,9 +62,9 @@ float con_times[NUM_CON_TIMES]; // realtime time the line was generated int con_vislines; -qboolean con_debuglog = false; +bool con_debuglog = false; -qboolean con_initialized; +bool con_initialized; /* @@ -433,7 +434,7 @@ static void Con_Print(const char* txt) int l; static int cr; int mask; - qboolean boundary; + bool boundary; // con_backscroll = 0; //johnfitz -- better console scrolling @@ -555,7 +556,7 @@ void Con_Printf(const char* fmt, ...) { va_list argptr; char msg[MAXPRINTMSG]; - static qboolean inupdate; + static bool inupdate; va_start(argptr, fmt); q_vsnprintf(msg, sizeof(msg), fmt, argptr); @@ -814,7 +815,7 @@ typedef struct tab_s tab_t* tablist; // defs from elsewhere -extern qboolean keydown[256]; +extern bool keydown[256]; typedef struct cmd_function_s { struct cmd_function_s* next; @@ -842,7 +843,7 @@ tablist is a doubly-linked loop, alphabetized by name // bash_partial is the string that can be expanded, // aka Linux Bash shell. -- S.A. static char bash_partial[80]; -static qboolean bash_singlematch; +static bool bash_singlematch; void AddToTabList(const char* name, const char* type) { @@ -1366,7 +1367,7 @@ The typing input line at the bottom should only be drawn if typing is allowed ================ */ -void Con_DrawConsole(int lines, qboolean drawinput) +void Con_DrawConsole(int lines, bool drawinput) { int i; diff --git a/Quake/console.hpp b/Quake/console.hpp index b8cbd089..56f58f1d 100644 --- a/Quake/console.hpp +++ b/Quake/console.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -28,8 +29,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // extern int con_totallines; extern int con_backscroll; -extern qboolean con_forcedup; // because no entities to refresh -extern qboolean con_initialized; +extern bool con_forcedup; // because no entities to refresh +extern bool con_initialized; extern byte* con_chars; extern char con_lastcenterstring[]; // johnfitz @@ -38,7 +39,7 @@ void Con_DrawCharacter(int cx, int line, int num); void Con_CheckResize(void); void Con_Init(void); -void Con_DrawConsole(int lines, qboolean drawinput); +void Con_DrawConsole(int lines, bool drawinput); void Con_Printf(const char* fmt, ...) FUNC_PRINTF(1, 2); void Con_DWarning(const char* fmt, ...) FUNC_PRINTF(1, 2); // ericw void Con_Warning(const char* fmt, ...) FUNC_PRINTF(1, 2); // johnfitz diff --git a/Quake/cvar.cpp b/Quake/cvar.cpp index 0247be99..4c1f605a 100644 --- a/Quake/cvar.cpp +++ b/Quake/cvar.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -602,7 +603,7 @@ Adds a freestanding variable to the variable list. void Cvar_RegisterVariable(cvar_t* variable) { char value[512]; - qboolean set_rom; + bool set_rom; cvar_t* cursor; cvar_t* prev; // johnfitz -- sorted list insert @@ -692,7 +693,7 @@ Cvar_Command Handles variable inspection and changing from the console ============ */ -qboolean Cvar_Command() +bool Cvar_Command() { cvar_t* v; diff --git a/Quake/cvar.hpp b/Quake/cvar.hpp index 4ca50d70..8ac3a0f9 100644 --- a/Quake/cvar.hpp +++ b/Quake/cvar.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -121,7 +122,7 @@ float Cvar_VariableValue(const char* var_name); const char* Cvar_VariableString(const char* var_name); // returns an empty string if not defined -qboolean Cvar_Command(void); +bool Cvar_Command(void); // called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known // command. Returns true if the command was a variable reference that // was handled. (print or change) diff --git a/Quake/debug_menu.cpp b/Quake/debug_menu.cpp index ddab6983..0d7a4c40 100644 --- a/Quake/debug_menu.cpp +++ b/Quake/debug_menu.cpp @@ -43,6 +43,7 @@ static void Debug_MenuPrintOptionValue(int cx, int cy, DebugMenuOpt option) case DebugMenuOpt::e_Noclip: break; case DebugMenuOpt::e_Fly: break; case DebugMenuOpt::e_HostTimescale: printAsStr(host_timescale); break; + case DebugMenuOpt::e_Impulse255: break; default: assert(false); break; } } @@ -80,6 +81,7 @@ static void M_Debug_KeyOption(int key, DebugMenuOpt option) case DebugMenuOpt::e_HostTimescale: adjustF(host_timescale, 0.05f, 0.1f, 5.f); break; + case DebugMenuOpt::e_Impulse255: doCheat("impulse 255"); break; default: assert(false); break; } } @@ -150,7 +152,7 @@ void M_Debug_Draw() static const auto adjustedLabels = quake::util::makeAdjustedMenuLabels("Show BBoxes", "Impulse 9", - "Impuse 11", "God", "Noclip", "Fly", "Timescale"); + "Impuse 11", "God", "Noclip", "Fly", "Timescale", "Impulse 255"); static_assert(adjustedLabels.size() == (int)DebugMenuOpt::k_Max); diff --git a/Quake/debug_menu.hpp b/Quake/debug_menu.hpp index 9b4c0364..2675f70e 100644 --- a/Quake/debug_menu.hpp +++ b/Quake/debug_menu.hpp @@ -9,6 +9,7 @@ enum class DebugMenuOpt e_Noclip, e_Fly, e_HostTimescale, + e_Impulse255, k_Max }; diff --git a/Quake/draw.hpp b/Quake/draw.hpp index 220cc962..571f6827 100644 --- a/Quake/draw.hpp +++ b/Quake/draw.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/gl_draw.cpp b/Quake/gl_draw.cpp index 51f04a21..3b01b6c8 100644 --- a/Quake/gl_draw.cpp +++ b/Quake/gl_draw.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -134,7 +135,7 @@ int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; byte scrap_texels[MAX_SCRAPS] [BLOCK_WIDTH * BLOCK_HEIGHT]; // johnfitz -- removed *4 after BLOCK_HEIGHT -qboolean scrap_dirty; +bool scrap_dirty; gltexture_t* scrap_textures[MAX_SCRAPS]; // johnfitz diff --git a/Quake/gl_fog.cpp b/Quake/gl_fog.cpp index 8c7f2dcc..514266fc 100644 --- a/Quake/gl_fog.cpp +++ b/Quake/gl_fog.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/gl_mesh.cpp b/Quake/gl_mesh.cpp index a98fa652..3b416c3a 100644 --- a/Quake/gl_mesh.cpp +++ b/Quake/gl_mesh.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -35,7 +36,7 @@ ALIAS MODEL DISPLAY LIST GENERATION qmodel_t* aliasmodel; aliashdr_t* paliashdr; -int used[8192]; // qboolean +int used[8192]; // bool // the command list holds counts and s/t values that are valid for // every frame diff --git a/Quake/gl_model.cpp b/Quake/gl_model.cpp index 4946589c..d68d5771 100644 --- a/Quake/gl_model.cpp +++ b/Quake/gl_model.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -32,7 +33,7 @@ char loadname[32]; // for hunk tags void Mod_LoadSpriteModel(qmodel_t* mod, void* buffer); void Mod_LoadBrushModel(qmodel_t* mod, void* buffer); void Mod_LoadAliasModel(qmodel_t* mod, void* buffer); -qmodel_t* Mod_LoadModel(qmodel_t* mod, qboolean crash); +qmodel_t* Mod_LoadModel(qmodel_t* mod, bool crash); cvar_t external_ents = {"external_ents", "1", CVAR_ARCHIVE}; @@ -343,7 +344,7 @@ Mod_LoadModel Loads a model into the cache ================== */ -qmodel_t* Mod_LoadModel(qmodel_t* mod, qboolean crash) +qmodel_t* Mod_LoadModel(qmodel_t* mod, bool crash) { byte* buf; byte stackbuf[1024]; // avoid dirtying the cache heap @@ -420,7 +421,7 @@ Mod_ForName Loads in a model for the given name ================== */ -qmodel_t* Mod_ForName(const char* name, qboolean crash) +qmodel_t* Mod_ForName(const char* name, bool crash) { qmodel_t* mod; @@ -445,7 +446,7 @@ byte* mod_base; Mod_CheckFullbrights -- johnfitz ================= */ -qboolean Mod_CheckFullbrights(byte* pixels, int count) +bool Mod_CheckFullbrights(byte* pixels, int count) { int i; for(i = 0; i < count; i++) @@ -1400,7 +1401,7 @@ void Mod_CalcSurfaceBounds(msurface_t* s) Mod_LoadFaces ================= */ -void Mod_LoadFaces(lump_t* l, qboolean bsp2) +void Mod_LoadFaces(lump_t* l, bool bsp2) { dsface_t* ins; dlface_t* inl; @@ -2040,7 +2041,7 @@ void Mod_LoadLeafs(lump_t* l, int bsp2) Mod_LoadClipnodes ================= */ -void Mod_LoadClipnodes(lump_t* l, qboolean bsp2) +void Mod_LoadClipnodes(lump_t* l, bool bsp2) { dsclipnode_t* ins; dlclipnode_t* inl; @@ -3067,7 +3068,7 @@ void Mod_CalcAliasBounds(aliashdr_t* a) loadmodel->ymaxs[2] = loadmodel->maxs[2]; } -static qboolean nameInList(const char* list, const char* name) +static bool nameInList(const char* list, const char* name) { const char* s; char tmp[MAX_QPATH]; diff --git a/Quake/gl_model.hpp b/Quake/gl_model.hpp index cfaf566c..06fda1d2 100644 --- a/Quake/gl_model.hpp +++ b/Quake/gl_model.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -91,7 +92,7 @@ typedef struct texture_s struct gltexture_s* gltexture; // johnfitz -- pointer to gltexture struct gltexture_s* fullbright; // johnfitz -- fullbright mask texture struct gltexture_s* warpimage; // johnfitz -- for water animation - qboolean update_warp; // johnfitz -- update warp this frame + bool update_warp; // johnfitz -- update warp this frame struct msurface_s* texturechains[2]; // for texture chains int anim_total; // total tenths in sequence ( 0 = no) int anim_min, anim_max; // time for this frame min <=time< max @@ -143,7 +144,7 @@ typedef struct glpoly_s typedef struct msurface_s { int visframe; // should be drawn when node is crossed - qboolean culled; // johnfitz -- for frustum culling + bool culled; // johnfitz -- for frustum culling float mins[3]; // johnfitz -- for frustum culling float maxs[3]; // johnfitz -- for frustum culling @@ -173,7 +174,7 @@ typedef struct msurface_s int lightmaptexturenum; byte styles[MAXLIGHTMAPS]; int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap - qboolean cached_dlight; // true if dynamic light in cache + bool cached_dlight; // true if dynamic light in cache byte* samples; // [numstyles*surfsize] } msurface_t; @@ -427,7 +428,7 @@ typedef struct qmodel_s char name[MAX_QPATH]; unsigned int path_id; // path id of the game directory // that this model came from - qboolean needload; // bmodels and sprites don't cache normally + bool needload; // bmodels and sprites don't cache normally modtype_t type; int numframes; @@ -447,7 +448,7 @@ typedef struct qmodel_s // // solid volume for clipping // - qboolean clipbox; + bool clipbox; vec3_t clipmins, clipmaxs; // @@ -497,7 +498,7 @@ typedef struct qmodel_s byte* lightdata; char* entities; - qboolean viswarn; // for Mod_DecompressVis() + bool viswarn; // for Mod_DecompressVis() int bspversion; @@ -523,7 +524,7 @@ typedef struct qmodel_s void Mod_Init(void); void Mod_ClearAll(void); void Mod_ResetAll(void); // for gamedir changes (Host_Game_f) -qmodel_t* Mod_ForName(const char* name, qboolean crash); +qmodel_t* Mod_ForName(const char* name, bool crash); void* Mod_Extradata(qmodel_t* mod); // handles caching void Mod_TouchModel(const char* name); diff --git a/Quake/gl_refrag.cpp b/Quake/gl_refrag.cpp index e2c40769..b2ecc376 100644 --- a/Quake/gl_refrag.cpp +++ b/Quake/gl_refrag.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/gl_rlight.cpp b/Quake/gl_rlight.cpp index 1f5dc063..d4bbbc68 100644 --- a/Quake/gl_rlight.cpp +++ b/Quake/gl_rlight.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/gl_rmain.cpp b/Quake/gl_rmain.cpp index a08f8278..8241973e 100644 --- a/Quake/gl_rmain.cpp +++ b/Quake/gl_rmain.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.hpp" #include "vr.hpp" -qboolean r_cache_thrash; // compatability +bool r_cache_thrash; // compatability vec3_t modelorg, r_entorigin; entity_t* currententity; @@ -35,7 +36,7 @@ int r_framecount; // used for dlight push checking mplane_t frustum[4]; // johnfitz -- rendering statistics -int rs_brushpolys, rs_aliaspolys, rs_skypolys, rs_particles, rs_fogpolys; +int rs_brushpolys, rs_aliaspolys, rs_skypolys, rs_fogpolys; int rs_dynamiclightmaps, rs_brushpasses, rs_aliaspasses, rs_skypasses; float rs_megatexels; @@ -119,7 +120,7 @@ cvar_t r_slimealpha = {"r_slimealpha", "0", CVAR_NONE}; float map_wateralpha, map_lavaalpha, map_telealpha, map_slimealpha; -qboolean r_drawflat_cheatsafe, r_fullbright_cheatsafe, r_lightmap_cheatsafe, +bool r_drawflat_cheatsafe, r_fullbright_cheatsafe, r_lightmap_cheatsafe, r_drawworld_cheatsafe; // johnfitz cvar_t r_scale = {"r_scale", "1", CVAR_ARCHIVE}; @@ -296,7 +297,7 @@ R_CullBox -- johnfitz -- replaced with new function from lordhavoc Returns true if the box is completely outside the frustum ================= */ -qboolean R_CullBox(vec3_t emins, vec3_t emaxs) +bool R_CullBox(vec3_t emins, vec3_t emaxs) { int i; mplane_t* p; @@ -379,7 +380,7 @@ qboolean R_CullBox(vec3_t emins, vec3_t emaxs) R_CullModelForEntity -- johnfitz -- uses correct bounds based on rotation =============== */ -qboolean R_CullModelForEntity(entity_t* e) +bool R_CullModelForEntity(entity_t* e) { vec3_t mins; @@ -738,7 +739,7 @@ void R_SetupView() R_DrawEntitiesOnList ============= */ -void R_DrawEntitiesOnList(qboolean alphapass) // johnfitz -- added parameter +void R_DrawEntitiesOnList(bool alphapass) // johnfitz -- added parameter { if(!r_drawentities.value) { @@ -938,8 +939,6 @@ R_ShowTris -- johnfitz */ void R_ShowTris() { - extern cvar_t r_particles; - if(r_showtris.value < 1 || r_showtris.value > 2 || cl.maxclients > 1) { return; @@ -1002,6 +1001,7 @@ void R_ShowTris() doViewmodel(&cl.offhand_viewent); } + extern cvar_t r_particles; if(r_particles.value) { R_DrawParticles_ShowTris(); @@ -1255,7 +1255,7 @@ void R_RenderView() time1 = Sys_DoubleTime(); // johnfitz -- rendering statistics - rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_particles = + rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_fogpolys = rs_megatexels = rs_dynamiclightmaps = rs_aliaspasses = rs_skypasses = rs_brushpasses = 0; } diff --git a/Quake/gl_rmisc.cpp b/Quake/gl_rmisc.cpp index cc531a80..9a3e6a77 100644 --- a/Quake/gl_rmisc.cpp +++ b/Quake/gl_rmisc.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -532,7 +533,7 @@ void D_FlushCaches() static GLuint gl_programs[16]; static int gl_num_programs; -static qboolean GL_CheckShader(GLuint shader) +static bool GL_CheckShader(GLuint shader) { GLint status; GL_GetShaderivFunc(shader, GL_COMPILE_STATUS, &status); @@ -551,7 +552,7 @@ static qboolean GL_CheckShader(GLuint shader) return true; } -static qboolean GL_CheckProgram(GLuint program) +static bool GL_CheckProgram(GLuint program) { GLint status; GL_GetProgramivFunc(program, GL_LINK_STATUS, &status); diff --git a/Quake/gl_screen.cpp b/Quake/gl_screen.cpp index 57170e72..2ef00f60 100644 --- a/Quake/gl_screen.cpp +++ b/Quake/gl_screen.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -102,7 +103,7 @@ cvar_t gl_triplebuffer = {"gl_triplebuffer", "1", CVAR_ARCHIVE}; extern cvar_t crosshair; -qboolean scr_initialized; // ready to draw +bool scr_initialized; // ready to draw qpic_t* scr_ram; qpic_t* scr_net; @@ -113,8 +114,8 @@ int clearnotify; vrect_t scr_vrect; -qboolean scr_disabled_for_loading; -qboolean scr_drawloading; +bool scr_disabled_for_loading; +bool scr_drawloading; float scr_disabled_time; int scr_tileclear_updates = 0; // johnfitz @@ -911,7 +912,7 @@ void SCR_ScreenShot_f() int i; int quality; - qboolean ok; + bool ok; Q_strncpy(ext, "png", sizeof(ext)); @@ -1056,7 +1057,7 @@ void SCR_EndLoadingPlaque() //============================================================================= const char* scr_notifystring; -qboolean scr_drawdialog; +bool scr_drawdialog; void SCR_DrawNotifyString() { diff --git a/Quake/gl_sky.cpp b/Quake/gl_sky.cpp index 108c224d..87d4d6ce 100644 --- a/Quake/gl_sky.cpp +++ b/Quake/gl_sky.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -165,7 +166,7 @@ void Sky_LoadSkyBox(const char* name) int height; char filename[MAX_OSPATH]; byte* data; - qboolean nonefound = true; + bool nonefound = true; if(strcmp(skybox_name, name) == 0) { @@ -505,9 +506,9 @@ void Sky_ClipPoly(int nump, vec3_t vecs, int stage) { float* norm; float* v; - qboolean front; + bool front; - qboolean back; + bool back; float d; float e; diff --git a/Quake/gl_texmgr.cpp b/Quake/gl_texmgr.cpp index 9adff14e..289418cb 100644 --- a/Quake/gl_texmgr.cpp +++ b/Quake/gl_texmgr.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -393,7 +394,7 @@ static void GL_DeleteTexture(gltexture_t* texture); // ericw -- workaround for preventing TexMgr_FreeTexture during // TexMgr_ReloadImages -static qboolean in_reload_images; +static bool in_reload_images; /* ================ @@ -843,7 +844,7 @@ TexMgr_ResampleTexture -- bilinear resample ================ */ static unsigned* TexMgr_ResampleTexture( - unsigned* in, int inwidth, int inheight, qboolean alpha) + unsigned* in, int inwidth, int inheight, bool alpha) { byte* nwpx; @@ -1356,9 +1357,9 @@ TexMgr_LoadImage8 -- handles 8bit source data, then passes it to LoadImage32 static void TexMgr_LoadImage8(gltexture_t* glt, byte* data) { extern cvar_t gl_fullbrights; - qboolean padw = false; + bool padw = false; - qboolean padh = false; + bool padh = false; byte padbyte; unsigned int* usepal; int i; @@ -1774,7 +1775,7 @@ void TexMgr_ReloadNobrightImages() static GLuint currenttexture[3] = {GL_UNUSED_TEXTURE, GL_UNUSED_TEXTURE, GL_UNUSED_TEXTURE}; // to avoid unnecessary texture sets static GLenum currenttarget = GL_TEXTURE0_ARB; -qboolean mtexenabled = false; +bool mtexenabled = false; /* ================ diff --git a/Quake/gl_texmgr.hpp b/Quake/gl_texmgr.hpp index 283231fb..b96c353a 100644 --- a/Quake/gl_texmgr.hpp +++ b/Quake/gl_texmgr.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/gl_vidsdl.cpp b/Quake/gl_vidsdl.cpp index 86b96353..815f931d 100644 --- a/Quake/gl_vidsdl.cpp +++ b/Quake/gl_vidsdl.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -74,7 +75,7 @@ static char* gl_extensions_nice; static vmode_t modelist[MAX_MODE_LIST]; static int nummodes; -static qboolean vid_initialized = false; +static bool vid_initialized = false; #if defined(USE_SDL2) static SDL_Window* draw_context; @@ -83,8 +84,8 @@ static SDL_GLContext gl_context; static SDL_Surface* draw_context; #endif -static qboolean vid_locked = false; // johnfitz -static qboolean vid_changed = false; +static bool vid_locked = false; // johnfitz +static bool vid_changed = false; static void VID_Menu_Init(); // johnfitz static void VID_Menu_f(); // johnfitz @@ -97,20 +98,20 @@ static void GL_SetupState(); // johnfitz viddef_t vid; // global video state modestate_t modestate = MS_UNINIT; -qboolean scr_skipupdate; +bool scr_skipupdate; -qboolean gl_mtexable = false; -qboolean gl_texture_env_combine = false; // johnfitz -qboolean gl_texture_env_add = false; // johnfitz -qboolean gl_swap_control = false; // johnfitz -qboolean gl_anisotropy_able = false; // johnfitz +bool gl_mtexable = false; +bool gl_texture_env_combine = false; // johnfitz +bool gl_texture_env_add = false; // johnfitz +bool gl_swap_control = false; // johnfitz +bool gl_anisotropy_able = false; // johnfitz float gl_max_anisotropy; // johnfitz -qboolean gl_texture_NPOT = false; // ericw -qboolean gl_vbo_able = false; // ericw -qboolean gl_glsl_able = false; // ericw +bool gl_texture_NPOT = false; // ericw +bool gl_vbo_able = false; // ericw +bool gl_glsl_able = false; // ericw GLint gl_max_texture_units = 0; // ericw -qboolean gl_glsl_gamma_able = false; // ericw -qboolean gl_glsl_alias_able = false; // ericw +bool gl_glsl_gamma_able = false; // ericw +bool gl_glsl_alias_able = false; // ericw int gl_stencilbits; PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = nullptr; // johnfitz @@ -189,7 +190,7 @@ static unsigned short vid_sysgamma_green[256]; static unsigned short vid_sysgamma_blue[256]; #endif -static qboolean gammaworks = false; // whether hw-gamma works +static bool gammaworks = false; // whether hw-gamma works static int fsaa; /* @@ -453,7 +454,7 @@ VID_GetFullscreen returns true if we are in regular fullscreen or "desktop fullscren" ==================== */ -static qboolean VID_GetFullscreen() +static bool VID_GetFullscreen() { #if defined(USE_SDL2) return (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN) != 0; @@ -469,7 +470,7 @@ VID_GetDesktopFullscreen returns true if we are specifically in "desktop fullscreen" mode ==================== */ -static qboolean VID_GetDesktopFullscreen() +static bool VID_GetDesktopFullscreen() { #if defined(USE_SDL2) return (SDL_GetWindowFlags(draw_context) & SDL_WINDOW_FULLSCREEN_DESKTOP) == @@ -484,7 +485,7 @@ static qboolean VID_GetDesktopFullscreen() VID_GetVSync ==================== */ -static qboolean VID_GetVSync() +static bool VID_GetVSync() { #if defined(USE_SDL2) return SDL_GL_GetSwapInterval() == 1; @@ -517,7 +518,7 @@ void* VID_GetWindow() VID_HasMouseOrInputFocus ==================== */ -qboolean VID_HasMouseOrInputFocus() +bool VID_HasMouseOrInputFocus() { #if defined(USE_SDL2) return (SDL_GetWindowFlags(draw_context) & @@ -532,7 +533,7 @@ qboolean VID_HasMouseOrInputFocus() VID_IsMinimized ==================== */ -qboolean VID_IsMinimized() +bool VID_IsMinimized() { #if defined(USE_SDL2) return !(SDL_GetWindowFlags(draw_context) & SDL_WINDOW_SHOWN); @@ -585,8 +586,8 @@ static SDL_DisplayMode* VID_SDL2_GetDisplayMode( VID_ValidMode ================ */ -static qboolean VID_ValidMode( - int width, int height, int refreshrate, int bpp, qboolean fullscreen) +static bool VID_ValidMode( + int width, int height, int refreshrate, int bpp, bool fullscreen) { // ignore width / height / bpp if vid_desktopfullscreen is enabled if(fullscreen && vid_desktopfullscreen.value) @@ -635,8 +636,8 @@ static qboolean VID_ValidMode( VID_SetMode ================ */ -static qboolean VID_SetMode( - int width, int height, int refreshrate, int bpp, qboolean fullscreen) +static bool VID_SetMode( + int width, int height, int refreshrate, int bpp, bool fullscreen) { int temp; Uint32 flags; @@ -886,7 +887,7 @@ static void VID_Restart() int refreshrate; int bpp; - qboolean fullscreen; + bool fullscreen; if(vid_locked || !vid_changed) { @@ -1122,7 +1123,7 @@ static void GL_Info_f() GL_CheckExtensions =============== */ -static qboolean GL_ParseExtensionList(const char* list, const char* name) +static bool GL_ParseExtensionList(const char* list, const char* name) { const char* start; const char* where; @@ -1849,7 +1850,7 @@ void VID_Init() int display_refreshrate; int display_bpp; - qboolean fullscreen; + bool fullscreen; const char* read_vars[] = {"vid_fullscreen", "vid_width", "vid_height", "vid_refreshrate", "vid_bpp", "vid_vsync", "vid_fsaa", "vid_desktopfullscreen", "vid_borderless"}; @@ -2047,8 +2048,8 @@ void VID_Toggle() // TODO: Clear out the dead code, reinstate the fast path using // SDL_SetWindowFullscreen inside VID_SetMode, check window size to fix // WinXP issue. This will keep all the mode changing code in one place. - static qboolean vid_toggle_works = false; - qboolean toggleWorked; + static bool vid_toggle_works = false; + bool toggleWorked; #if defined(USE_SDL2) Uint32 flags = 0; #endif diff --git a/Quake/gl_warp.cpp b/Quake/gl_warp.cpp index 541a222a..6e061a67 100644 --- a/Quake/gl_warp.cpp +++ b/Quake/gl_warp.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/glquake.hpp b/Quake/glquake.hpp index eb300853..2dfa96f1 100644 --- a/Quake/glquake.hpp +++ b/Quake/glquake.hpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __GLQUAKE_H #define __GLQUAKE_H +#include + void GL_BeginRendering(int* x, int* y, int* width, int* height); void GL_EndRendering(void); void GL_Set2D(void); @@ -81,36 +84,10 @@ typedef struct } drawsurf_t; -enum ptype_t -{ - pt_static, - pt_grav, - pt_slowgrav, - pt_fire, - pt_explode, - pt_explode2, - pt_blob, - pt_blob2 -}; - -// !!! if this is changed, it must be changed in d_ifacea.h too !!! -struct particle_t -{ - // driver-usable fields - vec3_t org; - float color; - // drivers never touch the following fields - struct particle_t* next; - vec3_t vel; - float ramp; - float die; - ptype_t type; -}; - //==================================================== -extern qboolean r_cache_thrash; // compatability +extern bool r_cache_thrash; // compatability extern vec3_t modelorg, r_entorigin; extern entity_t* currententity; extern int r_visframecount; // ??? what difs? @@ -167,8 +144,8 @@ extern float load_subdivide_size; // johnfitz -- remember what subdivide_size extern int gl_stencilbits; // Multitexture -extern qboolean mtexenabled; -extern qboolean gl_mtexable; +extern bool mtexenabled; +extern bool gl_mtexable; extern PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc; extern PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc; extern PFNGLCLIENTACTIVETEXTUREARBPROC GL_ClientActiveTextureFunc; @@ -178,7 +155,7 @@ extern GLint gl_max_texture_units; // ericw #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF extern float gl_max_anisotropy; -extern qboolean gl_anisotropy_able; +extern bool gl_anisotropy_able; // ericw -- VBO extern PFNGLBINDBUFFERARBPROC GL_BindBufferFunc; @@ -186,7 +163,7 @@ extern PFNGLBUFFERDATAARBPROC GL_BufferDataFunc; extern PFNGLBUFFERSUBDATAARBPROC GL_BufferSubDataFunc; extern PFNGLDELETEBUFFERSARBPROC GL_DeleteBuffersFunc; extern PFNGLGENBUFFERSARBPROC GL_GenBuffersFunc; -extern qboolean gl_vbo_able; +extern bool gl_vbo_able; // ericw // ericw -- GLSL @@ -251,13 +228,13 @@ extern QS_PFNGLUNIFORM1IPROC GL_Uniform1iFunc; extern QS_PFNGLUNIFORM1FPROC GL_Uniform1fFunc; extern QS_PFNGLUNIFORM3FPROC GL_Uniform3fFunc; extern QS_PFNGLUNIFORM4FPROC GL_Uniform4fFunc; -extern qboolean gl_glsl_able; -extern qboolean gl_glsl_gamma_able; -extern qboolean gl_glsl_alias_able; +extern bool gl_glsl_able; +extern bool gl_glsl_gamma_able; +extern bool gl_glsl_alias_able; // ericw -- // ericw -- NPOT texture support -extern qboolean gl_texture_NPOT; +extern bool gl_texture_NPOT; // johnfitz -- polygon offset #define OFFSET_BMODEL 1 @@ -280,11 +257,11 @@ void GL_PolygonOffset(int); #define GL_SOURCE1_RGB_EXT 0x8581 #define GL_SOURCE0_ALPHA_EXT 0x8588 #define GL_SOURCE1_ALPHA_EXT 0x8589 -extern qboolean gl_texture_env_combine; -extern qboolean gl_texture_env_add; // for GL_EXT_texture_env_add +extern bool gl_texture_env_combine; +extern bool gl_texture_env_add; // for GL_EXT_texture_env_add // johnfitz -- rendering statistics -extern int rs_brushpolys, rs_aliaspolys, rs_skypolys, rs_particles, rs_fogpolys; +extern int rs_brushpolys, rs_aliaspolys, rs_skypolys, rs_fogpolys; extern int rs_dynamiclightmaps, rs_brushpasses, rs_aliaspasses, rs_skypasses; extern float rs_megatexels; @@ -334,7 +311,7 @@ struct lightmap_s { gltexture_t* texture; glpoly_t* polys; - qboolean modified; + bool modified; glRect_t rectchange; // the lightmap texture data needs to be kept in @@ -346,7 +323,7 @@ extern int lightmap_count; // allocated lightmaps extern int gl_warpimagesize; // johnfitz -- for water warp -extern qboolean r_drawflat_cheatsafe, r_fullbright_cheatsafe, +extern bool r_drawflat_cheatsafe, r_fullbright_cheatsafe, r_lightmap_cheatsafe, r_drawworld_cheatsafe; // johnfitz typedef struct glsl_attrib_binding_s @@ -378,9 +355,9 @@ struct dlight_t; void R_AnimateLight(void); void R_MarkSurfaces(void); void R_CullSurfaces(void); -qboolean R_CullBox(vec3_t emins, vec3_t emaxs); +bool R_CullBox(vec3_t emins, vec3_t emaxs); void R_StoreEfrags(efrag_t** ppefrag); -qboolean R_CullModelForEntity(entity_t* e); +bool R_CullModelForEntity(entity_t* e); void R_RotateForEntity(vec3_t origin, vec3_t angles); void R_MarkLights(dlight_t* light, int num, mnode_t* node); diff --git a/Quake/host.cpp b/Quake/host.cpp index bc723aa2..d0d35bf2 100644 --- a/Quake/host.cpp +++ b/Quake/host.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -40,7 +41,7 @@ Memory is cleared / released when a server or client begins, not when they end. quakeparms_t* host_parms; -qboolean host_initialized; // true if into command execution +bool host_initialized; // true if into command execution double host_frametime; double realtime; // without any filtering or bounding @@ -172,7 +173,7 @@ void Host_Error(const char* error, ...) { va_list argptr; char string[1024]; - static qboolean inerror = false; + static bool inerror = false; if(inerror) { @@ -460,7 +461,7 @@ Called when the player is getting totally kicked off the host if (crash = true), don't bother sending signofs ===================== */ -void SV_DropClient(qboolean crash) +void SV_DropClient(bool crash) { int saveSelf; int i; @@ -524,7 +525,7 @@ Host_ShutdownServer This only happens at the end of a game, not between levels ================== */ -void Host_ShutdownServer(qboolean crash) +void Host_ShutdownServer(bool crash) { int i; int count; @@ -639,7 +640,7 @@ Host_FilterTime Returns false if the time is too short to run a frame =================== */ -qboolean Host_FilterTime(float time) +bool Host_FilterTime(float time) { float maxfps; // johnfitz @@ -1049,7 +1050,7 @@ to run quit through here before the final handoff to the sys code. */ void Host_Shutdown() { - static qboolean isdown = false; + static bool isdown = false; if(isdown) { diff --git a/Quake/host_cmd.cpp b/Quake/host_cmd.cpp index 14730ffd..2a9e5834 100644 --- a/Quake/host_cmd.cpp +++ b/Quake/host_cmd.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -626,7 +627,7 @@ void Host_Notarget_f() // johnfitz } -qboolean noclip_anglehack; +bool noclip_anglehack; /* ================== @@ -1466,7 +1467,7 @@ void Host_Name_f() MSG_WriteString(&sv.reliable_datagram, host_client->name); } -void Host_Say(qboolean teamonly) +void Host_Say(bool teamonly) { int j; client_t* client; @@ -1475,8 +1476,8 @@ void Host_Say(qboolean teamonly) char text[MAXCMDLINE]; char* p2; - qboolean quoted; - qboolean fromServer = false; + bool quoted; + bool fromServer = false; if(cmd_source == src_command) { @@ -1582,7 +1583,7 @@ void Host_Tell_f() char text[MAXCMDLINE]; char* p2; - qboolean quoted; + bool quoted; if(cmd_source == src_command) { @@ -1968,7 +1969,7 @@ void Host_Kick_f() const char* message = nullptr; client_t* save; int i; - qboolean byNumber = false; + bool byNumber = false; if(cmd_source == src_command) { diff --git a/Quake/image.cpp b/Quake/image.cpp index 4ccc637d..fcbce7d9 100644 --- a/Quake/image.cpp +++ b/Quake/image.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -162,8 +163,8 @@ TODO: support BGRA and BGR formats (since opengl can return them, and we don't have to swap) ============ */ -qboolean Image_WriteTGA(const char* name, byte* data, int width, int height, - int bpp, qboolean upsidedown) +bool Image_WriteTGA(const char* name, byte* data, int width, int height, + int bpp, bool upsidedown) { int handle; @@ -233,7 +234,7 @@ byte* Image_LoadTGA(FILE* fin, int* width, int* height) int column; byte* targa_rgba; int realrow; // johnfitz -- fix for upside-down targas - qboolean upside_down; // johnfitz -- fix for upside-down targas + bool upside_down; // johnfitz -- fix for upside-down targas stdio_buffer_t* buf; targa_header.id_length = fgetc(fin); @@ -616,8 +617,8 @@ Image_WriteJPG -- writes using stb_image_write returns true if successful ============ */ -qboolean Image_WriteJPG(const char* name, byte* data, int width, int height, - int bpp, int quality, qboolean upsidedown) +bool Image_WriteJPG(const char* name, byte* data, int width, int height, + int bpp, int quality, bool upsidedown) { unsigned error; char pathname[MAX_OSPATH]; @@ -658,8 +659,8 @@ qboolean Image_WriteJPG(const char* name, byte* data, int width, int height, return (error != 0); } -qboolean Image_WritePNG(const char* name, byte* data, int width, int height, - int bpp, qboolean upsidedown) +bool Image_WritePNG(const char* name, byte* data, int width, int height, + int bpp, bool upsidedown) { unsigned error; char pathname[MAX_OSPATH]; diff --git a/Quake/image.hpp b/Quake/image.hpp index 4820c89e..69d679aa 100644 --- a/Quake/image.hpp +++ b/Quake/image.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -30,11 +31,11 @@ byte* Image_LoadTGA(FILE* f, int* width, int* height); byte* Image_LoadPCX(FILE* f, int* width, int* height); byte* Image_LoadImage(const char* name, int* width, int* height); -qboolean Image_WriteTGA(const char* name, byte* data, int width, int height, - int bpp, qboolean upsidedown); -qboolean Image_WritePNG(const char* name, byte* data, int width, int height, - int bpp, qboolean upsidedown); -qboolean Image_WriteJPG(const char* name, byte* data, int width, int height, - int bpp, int quality, qboolean upsidedown); +bool Image_WriteTGA(const char* name, byte* data, int width, int height, + int bpp, bool upsidedown); +bool Image_WritePNG(const char* name, byte* data, int width, int height, + int bpp, bool upsidedown); +bool Image_WriteJPG(const char* name, byte* data, int width, int height, + int bpp, int quality, bool upsidedown); #endif /* GL_IMAGE_H */ diff --git a/Quake/in_sdl.cpp b/Quake/in_sdl.cpp index 0f3e2cbd..ea140a12 100644 --- a/Quake/in_sdl.cpp +++ b/Quake/in_sdl.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -32,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "SDL.h" #endif -static qboolean textmode; +static bool textmode; static cvar_t in_debugkeys = {"in_debugkeys", "0", CVAR_NONE}; @@ -64,7 +65,7 @@ static SDL_JoystickID joy_active_instaceid = -1; static SDL_GameController* joy_active_controller = nullptr; #endif -static qboolean no_mouse = false; +static bool no_mouse = false; static int buttonremap[] = {K_MOUSE1, K_MOUSE3, /* right button */ K_MOUSE2, /* middle button */ @@ -256,7 +257,7 @@ void IN_Activate() total_dy = 0; } -void IN_Deactivate(qboolean free_cursor) +void IN_Deactivate(bool free_cursor) { if(no_mouse) { @@ -441,7 +442,7 @@ typedef struct joyaxis_s typedef struct joy_buttonstate_s { - qboolean buttondown[SDL_CONTROLLER_BUTTON_MAX]; + bool buttondown[SDL_CONTROLLER_BUTTON_MAX]; } joybuttonstate_t; typedef struct axisstate_s @@ -593,7 +594,7 @@ Adapted from DarkPlaces by lordhavoc ================ */ static void IN_JoyKeyEvent( - qboolean wasdown, qboolean isdown, int key, double* timer) + bool wasdown, bool isdown, int key, double* timer) { // we can't use `realtime` for key repeats because it is not monotomic const double currenttime = Sys_DoubleTime(); @@ -654,9 +655,9 @@ void IN_Commands() // emit key events for controller buttons for(i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) { - qboolean newstate = SDL_GameControllerGetButton( + bool newstate = SDL_GameControllerGetButton( joy_active_controller, (SDL_GameControllerButton)i); - qboolean oldstate = joy_buttonstate.buttondown[i]; + bool oldstate = joy_buttonstate.buttondown[i]; joy_buttonstate.buttondown[i] = newstate; @@ -879,7 +880,7 @@ void IN_ClearStates() void IN_UpdateInputMode() { - qboolean want_textmode = Key_TextEntry(); + bool want_textmode = Key_TextEntry(); if(textmode != want_textmode) { textmode = want_textmode; @@ -1134,7 +1135,7 @@ void IN_SendKeyEvents() { SDL_Event event; int key; - qboolean down; + bool down; while(SDL_PollEvent(&event)) { diff --git a/Quake/input.hpp b/Quake/input.hpp index 5d875915..9f88e82d 100644 --- a/Quake/input.hpp +++ b/Quake/input.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -51,6 +52,6 @@ void IN_ClearStates(void); void IN_Activate(); // called when the app becomes inactive -void IN_Deactivate(qboolean free_cursor); +void IN_Deactivate(bool free_cursor); #endif /* _QUAKE_INPUT_H */ diff --git a/Quake/keys.cpp b/Quake/keys.cpp index e1842105..4fcdf1bd 100644 --- a/Quake/keys.cpp +++ b/Quake/keys.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -41,9 +42,9 @@ int history_line = 0; keydest_t key_dest; char* keybindings[MAX_KEYS]; -qboolean consolekeys[MAX_KEYS]; // if true, can't be rebound while in console -qboolean menubound[MAX_KEYS]; // if true, can't be rebound while in menu -qboolean keydown[MAX_KEYS]; +bool consolekeys[MAX_KEYS]; // if true, can't be rebound while in console +bool menubound[MAX_KEYS]; // if true, can't be rebound while in menu +bool keydown[MAX_KEYS]; typedef struct { @@ -451,7 +452,7 @@ void Char_Console(int key) if(key_linepos < MAXCMDLINE - 1) { - qboolean endpos = !workline[key_linepos]; + bool endpos = !workline[key_linepos]; key_tabpartial[0] = 0; // johnfitz // if inserting, move the text to the right @@ -479,7 +480,7 @@ void Char_Console(int key) //============================================================================ -qboolean chat_team = false; +bool chat_team = false; static char chat_buffer[MAXCMDLINE]; static int chat_bufferlen = 0; @@ -940,7 +941,7 @@ void Key_Init() static struct { - qboolean active; + bool active; int lastkey; int lastchar; } key_inputgrab = {false, -1, -1}; @@ -1000,7 +1001,7 @@ Called by the system between frames for both key up and key down events Should NOT be called during an interrupt! =================== */ -void Key_Event(int key, qboolean down) +void Key_Event(int key, bool down) { char* kb; char cmd[1024]; @@ -1174,7 +1175,7 @@ void Char_Event(int key) { break; } - /* fallthrough */ + [[fallthrough]]; case key_console: Char_Console(key); break; default: break; } @@ -1185,7 +1186,7 @@ void Char_Event(int key) Key_TextEntry =================== */ -qboolean Key_TextEntry() +bool Key_TextEntry() { if(key_inputgrab.active) { @@ -1201,7 +1202,7 @@ qboolean Key_TextEntry() { return false; } - /* fallthrough */ + [[fallthrough]]; case key_console: return true; default: return false; } @@ -1232,7 +1233,7 @@ Key_UpdateForDest */ void Key_UpdateForDest() { - static qboolean forced = false; + static bool forced = false; if(cls.state == ca_dedicated) { @@ -1257,7 +1258,7 @@ void Key_UpdateForDest() key_dest = key_console; break; } - /* fallthrough */ + [[fallthrough]]; default: forced = false; break; } } diff --git a/Quake/keys.hpp b/Quake/keys.hpp index 0eb7ddf9..03967f87 100644 --- a/Quake/keys.hpp +++ b/Quake/keys.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -177,7 +178,7 @@ extern int key_linepos; extern int key_insert; extern double key_blinktime; -extern qboolean chat_team; +extern bool chat_team; void Key_Init(void); void Key_ClearStates(void); @@ -187,9 +188,9 @@ void Key_BeginInputGrab(void); void Key_EndInputGrab(void); void Key_GetGrabbedInput(int* lastkey, int* lastchar); -void Key_Event(int key, qboolean down); +void Key_Event(int key, bool down); void Char_Event(int key); -qboolean Key_TextEntry(void); +bool Key_TextEntry(void); void Key_SetBinding(int keynum, const char* binding); const char* Key_KeynumToString(int keynum); diff --git a/Quake/lodepng.cpp b/Quake/lodepng.cpp index 263f0813..b24db090 100644 --- a/Quake/lodepng.cpp +++ b/Quake/lodepng.cpp @@ -1931,7 +1931,7 @@ static unsigned encodeLZ77(uivector* out, Hash* hash, const unsigned char* in, /*search for the longest string*/ prev_offset = 0; - for(;;) + while(true) { if(chainlength++ >= maxchainlength) break; current_offset = @@ -3026,7 +3026,7 @@ const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk) unsigned char* lodepng_chunk_find( unsigned char* chunk, const unsigned char* end, const char type[5]) { - for(;;) + while(true) { if(chunk + 12 >= end) return 0; if(lodepng_chunk_type_equals(chunk, type)) return chunk; @@ -3037,7 +3037,7 @@ unsigned char* lodepng_chunk_find( const unsigned char* lodepng_chunk_find_const( const unsigned char* chunk, const unsigned char* end, const char type[5]) { - for(;;) + while(true) { if(chunk + 12 >= end) return 0; if(lodepng_chunk_type_equals(chunk, type)) return chunk; diff --git a/Quake/main_sdl.cpp b/Quake/main_sdl.cpp index 99006576..5d198919 100644 --- a/Quake/main_sdl.cpp +++ b/Quake/main_sdl.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/mathlib.cpp b/Quake/mathlib.cpp index 6a1673ab..67213675 100644 --- a/Quake/mathlib.cpp +++ b/Quake/mathlib.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/mathlib.hpp b/Quake/mathlib.hpp index bf152128..1185d00e 100644 --- a/Quake/mathlib.hpp +++ b/Quake/mathlib.hpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/menu.cpp b/Quake/menu.cpp index 25196896..13dc3c92 100644 --- a/Quake/menu.cpp +++ b/Quake/menu.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -1066,8 +1067,6 @@ void M_Net_Key(int k) enum { - // TODO VR: - // OPT_CUSTOMIZE = 0, OPT_CONSOLE = 0, OPT_DEFAULTS, OPT_SCALE, @@ -1121,9 +1120,6 @@ void M_Menu_Options_f() void M_AdjustSliders(int dir) { - // TODO VR: - // int curr_alwaysrun; - int target_alwaysrun; float f; @@ -1237,21 +1233,6 @@ void M_AdjustSliders(int dir) break; case OPT_ALWAYRUN: // always run - // TODO VR: - /*if(cl_alwaysrun.value) - { - curr_alwaysrun = ALWAYSRUN_QUAKESPASM; - } - else */ - /*if(cl_forwardspeed.value > 200) - { - curr_alwaysrun = ALWAYSRUN_VANILLA; - } - else - { - curr_alwaysrun = ALWAYSRUN_OFF; - }*/ - target_alwaysrun = (ALWAYSRUN_ITEMS + (int)cl_alwaysrun.value + dir) % ALWAYSRUN_ITEMS; @@ -1260,10 +1241,6 @@ void M_AdjustSliders(int dir) { Cvar_SetValue("cl_alwaysrun", 1); } - // TODO VR: - // else if(target_alwaysrun == ALWAYSRUN_QUAKESPASM) - // { - // } else // ALWAYSRUN_OFF { Cvar_SetValue("cl_alwaysrun", 0); @@ -1347,9 +1324,6 @@ void M_Options_Draw() M_DrawPic((320 - p->width) / 2, 4, p); // Draw the items in the order of the enum defined above: - // TODO VR: - // OPT_CUSTOMIZE: - // M_Print(16, 32, " Controls"); // OPT_CONSOLE: M_Print(16, 32 + 8 * OPT_CONSOLE, " Goto console"); // OPT_DEFAULTS: @@ -1461,8 +1435,6 @@ void M_Options_Key(int k) m_entersound = true; switch(options_cursor) { - // TODO VR: - // case OPT_CUSTOMIZE: M_Menu_Keys_f(); break; case OPT_CONSOLE: m_state = m_none; Con_ToggleConsole_f(); @@ -1921,9 +1893,9 @@ void M_Quit_Draw() // johnfitz -- modified for new quit message M_DrawTextBox(160 - 4 * (boxlen + 2), 76, boxlen, 4); // now do the text - M_Print(160 - 4 * strlen(msg1), 88, msg1); - M_Print(160 - 4 * (sizeof(msg2) - 1), 96, msg2); - M_PrintWhite(160 - 4 * (sizeof(msg3) - 1), 104, msg3); + M_Print(260 - 4 * strlen(msg1), 88, msg1); + M_Print(260 - 4 * (sizeof(msg2) - 1), 96, msg2); + M_PrintWhite(260 - 4 * (sizeof(msg3) - 1), 104, msg3); } //============================================================================= diff --git a/Quake/menu.hpp b/Quake/menu.hpp index a0b20f41..36e229c2 100644 --- a/Quake/menu.hpp +++ b/Quake/menu.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/net.hpp b/Quake/net.hpp index ec619047..c02da086 100644 --- a/Quake/net.hpp +++ b/Quake/net.hpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2009-2010 Ozkan Sezer Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -58,7 +59,7 @@ struct qsocket_s* NET_Connect(const char* host); double NET_QSocketGetTime(const struct qsocket_s* sock); const char* NET_QSocketGetAddressString(const struct qsocket_s* sock); -qboolean NET_CanSendMessage(struct qsocket_s* sock); +bool NET_CanSendMessage(struct qsocket_s* sock); // Returns true or false if the given qsocket can currently accept a // message to be transmitted. @@ -92,9 +93,9 @@ void NET_Poll(void); // Server list related globals: -extern qboolean slistInProgress; -extern qboolean slistSilent; -extern qboolean slistLocal; +extern bool slistInProgress; +extern bool slistSilent; +extern bool slistLocal; extern int hostCacheCount; @@ -106,8 +107,8 @@ const char* NET_SlistPrintServerName(int n); /* FIXME: driver related, but public: */ -extern qboolean ipxAvailable; -extern qboolean tcpipAvailable; +extern bool ipxAvailable; +extern bool tcpipAvailable; extern char my_ipx_address[NET_NAMELEN]; extern char my_tcpip_address[NET_NAMELEN]; diff --git a/Quake/net_bsd.cpp b/Quake/net_bsd.cpp index e84b725c..ae24db77 100644 --- a/Quake/net_bsd.cpp +++ b/Quake/net_bsd.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/net_defs.hpp b/Quake/net_defs.hpp index 041e391c..a52c82cf 100644 --- a/Quake/net_defs.hpp +++ b/Quake/net_defs.hpp @@ -134,9 +134,9 @@ typedef struct qsocket_s double lastMessageTime; double lastSendTime; - qboolean disconnected; - qboolean canSend; - qboolean sendNext; + bool disconnected; + bool canSend; + bool sendNext; int driver; int landriver; @@ -166,11 +166,11 @@ extern int net_numsockets; typedef struct { const char* name; - qboolean initialized; + bool initialized; sys_socket_t controlSock; sys_socket_t (*Init)(void); void (*Shutdown)(void); - void (*Listen)(qboolean state); + void (*Listen)(bool state); sys_socket_t (*Open_Socket)(int port); int (*Close_Socket)(sys_socket_t socketid); int (*Connect)(sys_socket_t socketid, struct qsockaddr* addr); @@ -197,17 +197,17 @@ extern const int net_numlandrivers; typedef struct { const char* name; - qboolean initialized; + bool initialized; int (*Init)(void); - void (*Listen)(qboolean state); - void (*SearchForHosts)(qboolean xmit); + void (*Listen)(bool state); + void (*SearchForHosts)(bool xmit); qsocket_t* (*Connect)(const char* host); qsocket_t* (*CheckNewConnections)(void); int (*QGetMessage)(qsocket_t* sock); int (*QSendMessage)(qsocket_t* sock, sizebuf_t* data); int (*SendUnreliableMessage)(qsocket_t* sock, sizebuf_t* data); - qboolean (*CanSendMessage)(qsocket_t* sock); - qboolean (*CanSendUnreliableMessage)(qsocket_t* sock); + bool (*CanSendMessage)(qsocket_t* sock); + bool (*CanSendUnreliableMessage)(qsocket_t* sock); void (*Close)(qsocket_t* sock); void (*Shutdown)(void); } net_driver_t; diff --git a/Quake/net_dgrm.cpp b/Quake/net_dgrm.cpp index ba309c88..b4975ae4 100644 --- a/Quake/net_dgrm.cpp +++ b/Quake/net_dgrm.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -259,7 +260,7 @@ static int ReSendMessage(qsocket_t* sock) } -qboolean Datagram_CanSendMessage(qsocket_t* sock) +bool Datagram_CanSendMessage(qsocket_t* sock) { if(sock->sendNext) { @@ -270,7 +271,7 @@ qboolean Datagram_CanSendMessage(qsocket_t* sock) } -qboolean Datagram_CanSendUnreliableMessage(qsocket_t* sock) +bool Datagram_CanSendUnreliableMessage(qsocket_t* sock) { (void)sock; @@ -570,7 +571,7 @@ static const char* Strip_Port(const char* host) } -static qboolean testInProgress = false; +static bool testInProgress = false; static int testPollCount; static int testDriver; static sys_socket_t testSocket; @@ -734,7 +735,7 @@ static void Test_f() } -static qboolean test2InProgress = false; +static bool test2InProgress = false; static int test2Driver; static sys_socket_t test2Socket; @@ -967,7 +968,7 @@ void Datagram_Close(qsocket_t* sock) } -void Datagram_Listen(qboolean state) +void Datagram_Listen(bool state) { int i; @@ -1287,7 +1288,7 @@ qsocket_t* Datagram_CheckNewConnections() } -static void _Datagram_SearchForHosts(qboolean xmit) +static void _Datagram_SearchForHosts(bool xmit) { int ret; int n; @@ -1414,7 +1415,7 @@ static void _Datagram_SearchForHosts(qboolean xmit) } } -void Datagram_SearchForHosts(qboolean xmit) +void Datagram_SearchForHosts(bool xmit) { for(net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) diff --git a/Quake/net_dgrm.hpp b/Quake/net_dgrm.hpp index 932e7431..54a3df71 100644 --- a/Quake/net_dgrm.hpp +++ b/Quake/net_dgrm.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,15 +24,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __NET_DATAGRAM_H int Datagram_Init(void); -void Datagram_Listen(qboolean state); -void Datagram_SearchForHosts(qboolean xmit); +void Datagram_Listen(bool state); +void Datagram_SearchForHosts(bool xmit); qsocket_t* Datagram_Connect(const char* host); qsocket_t* Datagram_CheckNewConnections(void); int Datagram_GetMessage(qsocket_t* sock); int Datagram_SendMessage(qsocket_t* sock, sizebuf_t* data); int Datagram_SendUnreliableMessage(qsocket_t* sock, sizebuf_t* data); -qboolean Datagram_CanSendMessage(qsocket_t* sock); -qboolean Datagram_CanSendUnreliableMessage(qsocket_t* sock); +bool Datagram_CanSendMessage(qsocket_t* sock); +bool Datagram_CanSendUnreliableMessage(qsocket_t* sock); void Datagram_Close(qsocket_t* sock); void Datagram_Shutdown(void); diff --git a/Quake/net_loop.cpp b/Quake/net_loop.cpp index f8222ebf..3d0f3e11 100644 --- a/Quake/net_loop.cpp +++ b/Quake/net_loop.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -26,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "net_defs.hpp" #include "net_loop.hpp" -static qboolean localconnectpending = false; +static bool localconnectpending = false; static qsocket_t* loop_client = nullptr; static qsocket_t* loop_server = nullptr; @@ -45,13 +46,13 @@ void Loop_Shutdown() } -void Loop_Listen(qboolean state) +void Loop_Listen(bool state) { (void)state; } -void Loop_SearchForHosts(qboolean xmit) +void Loop_SearchForHosts(bool xmit) { (void)xmit; @@ -252,7 +253,7 @@ int Loop_SendUnreliableMessage(qsocket_t* sock, sizebuf_t* data) } -qboolean Loop_CanSendMessage(qsocket_t* sock) +bool Loop_CanSendMessage(qsocket_t* sock) { if(!sock->driverdata) { @@ -262,7 +263,7 @@ qboolean Loop_CanSendMessage(qsocket_t* sock) } -qboolean Loop_CanSendUnreliableMessage(qsocket_t* sock) +bool Loop_CanSendUnreliableMessage(qsocket_t* sock) { (void)sock; diff --git a/Quake/net_loop.hpp b/Quake/net_loop.hpp index 0d634832..7b7c35b9 100644 --- a/Quake/net_loop.hpp +++ b/Quake/net_loop.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,15 +25,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // net_loop.h int Loop_Init(void); -void Loop_Listen(qboolean state); -void Loop_SearchForHosts(qboolean xmit); +void Loop_Listen(bool state); +void Loop_SearchForHosts(bool xmit); qsocket_t* Loop_Connect(const char* host); qsocket_t* Loop_CheckNewConnections(void); int Loop_GetMessage(qsocket_t* sock); int Loop_SendMessage(qsocket_t* sock, sizebuf_t* data); int Loop_SendUnreliableMessage(qsocket_t* sock, sizebuf_t* data); -qboolean Loop_CanSendMessage(qsocket_t* sock); -qboolean Loop_CanSendUnreliableMessage(qsocket_t* sock); +bool Loop_CanSendMessage(qsocket_t* sock); +bool Loop_CanSendUnreliableMessage(qsocket_t* sock); void Loop_Close(qsocket_t* sock); void Loop_Shutdown(void); diff --git a/Quake/net_main.cpp b/Quake/net_main.cpp index 9b0f248f..faf9d566 100644 --- a/Quake/net_main.cpp +++ b/Quake/net_main.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -29,8 +30,8 @@ qsocket_t* net_activeSockets = nullptr; qsocket_t* net_freeSockets = nullptr; int net_numsockets = 0; -qboolean ipxAvailable = false; -qboolean tcpipAvailable = false; +bool ipxAvailable = false; +bool tcpipAvailable = false; int net_hostport; int DEFAULTnet_hostport = 26000; @@ -38,11 +39,11 @@ int DEFAULTnet_hostport = 26000; char my_ipx_address[NET_NAMELEN]; char my_tcpip_address[NET_NAMELEN]; -static qboolean listening = false; +static bool listening = false; -qboolean slistInProgress = false; -qboolean slistSilent = false; -qboolean slistLocal = true; +bool slistInProgress = false; +bool slistSilent = false; +bool slistLocal = true; static double slistStartTime; static int slistLastShown; @@ -755,7 +756,7 @@ Returns true or false if the given qsocket can currently accept a message to be transmitted. ================== */ -qboolean NET_CanSendMessage(qsocket_t* sock) +bool NET_CanSendMessage(qsocket_t* sock) { if(!sock) { @@ -778,9 +779,9 @@ int NET_SendToAll(sizebuf_t* data, double blocktime) double start; int i; int count = 0; - qboolean msg_init[MAX_SCOREBOARD]; /* did we write the message to the + bool msg_init[MAX_SCOREBOARD]; /* did we write the message to the client's connection */ - qboolean msg_sent[MAX_SCOREBOARD]; /* did the msg arrive its destination + bool msg_sent[MAX_SCOREBOARD]; /* did the msg arrive its destination (canSend state). */ for(i = 0, host_client = svs.clients; i < svs.maxclients; diff --git a/Quake/net_udp.cpp b/Quake/net_udp.cpp index 48f74d09..c208a792 100644 --- a/Quake/net_udp.cpp +++ b/Quake/net_udp.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -127,7 +128,7 @@ void UDP_Shutdown() //============================================================================= -void UDP_Listen(qboolean state) +void UDP_Listen(bool state) { // enable listening if(state) diff --git a/Quake/net_udp.hpp b/Quake/net_udp.hpp index 798fdced..c37706e6 100644 --- a/Quake/net_udp.hpp +++ b/Quake/net_udp.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. sys_socket_t UDP_Init(void); void UDP_Shutdown(void); -void UDP_Listen(qboolean state); +void UDP_Listen(bool state); sys_socket_t UDP_OpenSocket(int port); int UDP_CloseSocket(sys_socket_t socketid); int UDP_Connect(sys_socket_t socketid, struct qsockaddr* addr); diff --git a/Quake/net_win.cpp b/Quake/net_win.cpp index c86b6ff8..d80a9c78 100644 --- a/Quake/net_win.cpp +++ b/Quake/net_win.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/net_wins.cpp b/Quake/net_wins.cpp index bc8e07db..6fa4fc60 100644 --- a/Quake/net_wins.cpp +++ b/Quake/net_wins.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -209,7 +210,7 @@ void WINS_Shutdown() //============================================================================= -void WINS_Listen(qboolean state) +void WINS_Listen(bool state) { // enable listening if(state) diff --git a/Quake/net_wins.hpp b/Quake/net_wins.hpp index 50fe7dc2..92a46ed1 100644 --- a/Quake/net_wins.hpp +++ b/Quake/net_wins.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. sys_socket_t WINS_Init(void); void WINS_Shutdown(void); -void WINS_Listen(qboolean state); +void WINS_Listen(bool state); sys_socket_t WINS_OpenSocket(int port); int WINS_CloseSocket(sys_socket_t socketid); int WINS_Connect(sys_socket_t socketid, struct qsockaddr* addr); diff --git a/Quake/net_wipx.cpp b/Quake/net_wipx.cpp index 0affde7b..1d236b69 100644 --- a/Quake/net_wipx.cpp +++ b/Quake/net_wipx.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -37,7 +38,7 @@ static sys_socket_t net_controlsocket; static struct sockaddr_ipx broadcastaddr; /* externs from net_wins.c: */ -extern qboolean winsock_initialized; +extern int winsock_initialized; extern WSADATA winsockdata; @@ -134,7 +135,7 @@ void WIPX_Shutdown() //============================================================================= -void WIPX_Listen(qboolean state) +void WIPX_Listen(bool state) { // enable listening if(state) diff --git a/Quake/net_wipx.hpp b/Quake/net_wipx.hpp index 03647bba..18ed1d20 100644 --- a/Quake/net_wipx.hpp +++ b/Quake/net_wipx.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. sys_socket_t WIPX_Init(void); void WIPX_Shutdown(void); -void WIPX_Listen(qboolean state); +void WIPX_Listen(bool state); sys_socket_t WIPX_OpenSocket(int port); int WIPX_CloseSocket(sys_socket_t socketid); int WIPX_Connect(sys_socket_t socketid, struct qsockaddr* addr); diff --git a/Quake/pl_linux.cpp b/Quake/pl_linux.cpp index 4caca9c8..c66e3bb9 100644 --- a/Quake/pl_linux.cpp +++ b/Quake/pl_linux.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/pl_osx.m b/Quake/pl_osx.m index b7004f22..2def67d5 100644 --- a/Quake/pl_osx.m +++ b/Quake/pl_osx.m @@ -3,6 +3,7 @@ Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/pl_win.cpp b/Quake/pl_win.cpp index 411d0e3f..54af53c7 100644 --- a/Quake/pl_win.cpp +++ b/Quake/pl_win.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/platform.hpp b/Quake/platform.hpp index 5d8a5438..b36c1232 100644 --- a/Quake/platform.hpp +++ b/Quake/platform.hpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/pr_cmds.cpp b/Quake/pr_cmds.cpp index d3215d9e..aa853eb5 100644 --- a/Quake/pr_cmds.cpp +++ b/Quake/pr_cmds.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -22,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.hpp" +#include + #define STRINGTEMP_BUFFERS 16 #define STRINGTEMP_LENGTH 1024 static char pr_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH]; @@ -172,8 +175,7 @@ static void PF_setorigin() } -static void SetMinMaxSize( - edict_t* e, float* minvec, float* maxvec, qboolean rotate) +static void SetMinMaxSize(edict_t* e, float* minvec, float* maxvec, bool rotate) { float* angles; vec3_t rmin; @@ -573,35 +575,79 @@ random() */ static void PF_random() { - float num; + const float num = (rand() & 0x7fff) / ((float)0x7fff); + G_FLOAT(OFS_RETURN) = num; +} - num = (rand() & 0x7fff) / ((float)0x7fff); +/* +================= +PF_Pow - G_FLOAT(OFS_RETURN) = num; +power function +================= +*/ +static void PF_pow() +{ + const float base = G_FLOAT(OFS_PARM0); + const float exp = G_FLOAT(OFS_PARM1); + + const float res = std::pow(base, exp); + G_FLOAT(OFS_RETURN) = res; } /* ================= PF_particle -particle(origin, color, count) +particle(origin, dir, color, count) ================= */ static void PF_particle() { - float* org; + float* org = G_VECTOR(OFS_PARM0); + float* dir = G_VECTOR(OFS_PARM1); + const float color = G_FLOAT(OFS_PARM2); + const float count = G_FLOAT(OFS_PARM3); + SV_StartParticle(org, dir, color, count); +} - float* dir; - float color; - float count; +/* +================= +PF_particle2 - org = G_VECTOR(OFS_PARM0); - dir = G_VECTOR(OFS_PARM1); - color = G_FLOAT(OFS_PARM2); - count = G_FLOAT(OFS_PARM3); - SV_StartParticle(org, dir, color, count); +particle2(origin, dir, preset, count) +================= +*/ +static void PF_particle2() +{ + float* org = G_VECTOR(OFS_PARM0); + float* dir = G_VECTOR(OFS_PARM1); + const int preset = G_FLOAT(OFS_PARM2); + const int count = G_FLOAT(OFS_PARM3); + SV_StartParticle2(org, dir, preset, count); } +/* +================= +PF_Haptic + +VR haptics function +================= +*/ +static void PF_haptic() +{ + // {0 = off hand, 1 = main hand} + const int hand = G_FLOAT(OFS_PARM0); + + const float delay = G_FLOAT(OFS_PARM1); + const float duration = G_FLOAT(OFS_PARM2); + const float frequency = G_FLOAT(OFS_PARM3); + const float amplitude = G_FLOAT(OFS_PARM4); + + extern void VR_DoHaptic(const int hand, const float delay, + const float duration, const float frequency, const float amplitude); + VR_DoHaptic(hand, delay, duration, frequency, amplitude); +} /* ================= @@ -1631,25 +1677,18 @@ This was a major timewaster in progs, so it was converted to C */ void PF_changeyaw() { - edict_t* ent; - float ideal; - - float current; - - float move; - - float speed; - - ent = PROG_TO_EDICT(pr_global_struct->self); - current = anglemod(ent->v.angles[1]); - ideal = ent->v.ideal_yaw; - speed = ent->v.yaw_speed; + edict_t* ent = PROG_TO_EDICT(pr_global_struct->self); + float current = anglemod(ent->v.angles[1]); + float ideal = ent->v.ideal_yaw; + float speed = ent->v.yaw_speed; if(current == ideal) { return; } - move = ideal - current; + + float move = ideal - current; + if(ideal > current) { if(move >= 180) @@ -1664,6 +1703,7 @@ void PF_changeyaw() move = move + 360; } } + if(move > 0) { if(move > speed) @@ -1862,19 +1902,15 @@ PF_setspawnparms */ static void PF_setspawnparms() { - edict_t* ent; - int i; - client_t* client; - - ent = G_EDICT(OFS_PARM0); - i = NUM_FOR_EDICT(ent); + edict_t* ent = G_EDICT(OFS_PARM0); + int i = NUM_FOR_EDICT(ent); if(i < 1 || i > svs.maxclients) { PR_RunError("Entity is not a client"); } // copy spawn parms out of the client_t - client = svs.clients + (i - 1); + client_t* client = svs.clients + (i - 1); for(i = 0; i < NUM_SPAWN_PARMS; i++) { @@ -1889,16 +1925,15 @@ PF_changelevel */ static void PF_changelevel() { - const char* s; - // make sure we don't issue two changelevels if(svs.changelevel_issued) { return; } + svs.changelevel_issued = true; - s = G_STRING(OFS_PARM0); + const char* s = G_STRING(OFS_PARM0); Cbuf_AddText(va("changelevel %s\n", s)); } @@ -1907,8 +1942,8 @@ static void PF_Fixme() PR_RunError("unimplemented builtin"); } - -static builtin_t pr_builtin[] = {PF_Fixme, +static builtin_t pr_builtin[] = { + PF_Fixme, PF_makevectors, // void(entity e) makevectors = #1 PF_setorigin, // void(entity e, vector o) setorigin = #2 PF_setmodel, // void(entity e, string m) setmodel = #3 @@ -1964,7 +1999,11 @@ static builtin_t pr_builtin[] = {PF_Fixme, PF_precache_sound, // precache_sound2 is different only for qcc PF_precache_file, - PF_setspawnparms}; + PF_setspawnparms, + PF_particle2, // #79 + PF_pow, // #80 + PF_haptic, // #81 +}; builtin_t* pr_builtins = pr_builtin; -int pr_numbuiltins = sizeof(pr_builtin) / sizeof(pr_builtin[0]); +const int pr_numbuiltins = sizeof(pr_builtin) / sizeof(pr_builtin[0]); diff --git a/Quake/pr_comp.hpp b/Quake/pr_comp.hpp index a3fe8d1a..cf8d4daf 100644 --- a/Quake/pr_comp.hpp +++ b/Quake/pr_comp.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/pr_edict.cpp b/Quake/pr_edict.cpp index 6b667d11..c0129a8c 100644 --- a/Quake/pr_edict.cpp +++ b/Quake/pr_edict.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -35,7 +36,7 @@ static int pr_numknownstrings; static ddef_t* pr_fielddefs; static ddef_t* pr_globaldefs; -qboolean pr_alpha_supported; // johnfitz +bool pr_alpha_supported; // johnfitz dstatement_t* pr_statements; globalvars_t* pr_global_struct; @@ -56,7 +57,7 @@ int type_size[8] = { }; static ddef_t* ED_FieldAtOfs(int ofs); -static qboolean ED_ParseEpair(void* base, ddef_t* key, const char* s); +static bool ED_ParseEpair(void* base, ddef_t* key, const char* s); #define MAX_FIELD_LEN 64 #define GEFV_CACHESIZE 2 @@ -857,7 +858,7 @@ Can parse either fields or globals returns false if error ============= */ -static qboolean ED_ParseEpair(void* base, ddef_t* key, const char* s) +static bool ED_ParseEpair(void* base, ddef_t* key, const char* s) { int i; char string[128]; @@ -954,9 +955,9 @@ const char* ED_ParseEdict(const char* data, edict_t* ent) { ddef_t* key; char keyname[256]; - qboolean anglehack; + bool anglehack; - qboolean init; + bool init; int n; init = false; @@ -1377,16 +1378,12 @@ const char* PR_GetString(int num) { return pr_strings + num; } - if(num < 0 && num >= -pr_numknownstrings) + if(num < 0 && num >= -pr_numknownstrings) { - if(!pr_knownstrings[-1 - num]) - { - Host_Error( - "PR_GetString: attempt to get a non-existant string %d\n", num); return ""; @@ -1394,13 +1391,9 @@ const char* PR_GetString(int num) return pr_knownstrings[-1 - num]; } - else - { - Host_Error("PR_GetString: invalid string offset %d\n", num); - return ""; } } diff --git a/Quake/pr_exec.cpp b/Quake/pr_exec.cpp index d090545b..46624188 100644 --- a/Quake/pr_exec.cpp +++ b/Quake/pr_exec.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -35,7 +36,7 @@ static int pr_depth; static int localstack[LOCALSTACK_SIZE]; static int localstack_used; -qboolean pr_trace; +bool pr_trace; dfunction_t* pr_xfunction; int pr_xstatement; int pr_argc; diff --git a/Quake/progdefs.q1 b/Quake/progdefs.q1 index 072b27ff..39285901 100644 --- a/Quake/progdefs.q1 +++ b/Quake/progdefs.q1 @@ -148,6 +148,8 @@ typedef struct vec3_t offhandrot; vec3_t offhandvel; float offhandvelmag; + float touchinghand; + vec3_t muzzlepos; } entvars_t; -#define PROGHEADER_CRC 37768 +#define PROGHEADER_CRC 52248 diff --git a/Quake/progs.hpp b/Quake/progs.hpp index 176d7621..d4a6cc37 100644 --- a/Quake/progs.hpp +++ b/Quake/progs.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -40,7 +41,7 @@ typedef union eval_s struct edict_t { - qboolean free; + bool free; link_t area; /* linked to a division node or leaf */ int num_leafs; @@ -49,7 +50,7 @@ struct edict_t entity_state_t baseline; unsigned char alpha; /* johnfitz -- hack to support alpha since it's not part of entvars_t */ - qboolean sendinterval; /* johnfitz -- send time until nextthink to client + bool sendinterval; /* johnfitz -- send time until nextthink to client for better lerp timing */ float freetime; /* sv.time when the object was freed */ @@ -123,11 +124,11 @@ extern int type_size[8]; typedef void (*builtin_t)(void); extern builtin_t* pr_builtins; -extern int pr_numbuiltins; +extern const int pr_numbuiltins; extern int pr_argc; -extern qboolean pr_trace; +extern bool pr_trace; extern dfunction_t* pr_xfunction; extern int pr_xstatement; diff --git a/Quake/protocol.hpp b/Quake/protocol.hpp index 688583c3..7b74c1ea 100644 --- a/Quake/protocol.hpp +++ b/Quake/protocol.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -237,6 +238,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define svc_spawnstatic2 \ 43 // support for large modelindex, large framenum, alpha, using flags #define svc_spawnstaticsound2 44 // [coord3] [short] samp [byte] vol [byte] aten +#define svc_particle2 45 // TODO VR: docs // johnfitz // @@ -292,6 +294,7 @@ typedef struct vec3_t offhandrot; vec3_t offhandvel; float offhandvelmag; + vec3_t muzzlepos; // intended velocities float forwardmove; diff --git a/Quake/q_sound.hpp b/Quake/q_sound.hpp index 7c6d0fb0..bc8bc799 100644 --- a/Quake/q_sound.hpp +++ b/Quake/q_sound.hpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -96,7 +97,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t* sfx, vec3_t origin, float fvol, float attenuation); void S_StaticSound(sfx_t* sfx, vec3_t origin, float vol, float attenuation); void S_StopSound(int entnum, int entchannel); -void S_StopAllSounds(qboolean clear); +void S_StopAllSounds(bool clear); void S_ClearBuffer(void); void S_Update(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up); void S_ExtraUpdate(void); @@ -124,7 +125,7 @@ void S_RawSamples( /* Expects data in signed 16 bit, or unsigned 8 bit format. */ /* initializes cycling through a DMA buffer and returns information on it */ -qboolean SNDDMA_Init(dma_t* dma); +bool SNDDMA_Init(dma_t* dma); /* gets the current DMA position */ int SNDDMA_GetDMAPos(void); diff --git a/Quake/q_stdinc.hpp b/Quake/q_stdinc.hpp index 4039d362..cd3a996f 100644 --- a/Quake/q_stdinc.hpp +++ b/Quake/q_stdinc.hpp @@ -32,7 +32,10 @@ #include #include #include + +#define GLM_FORCE_INLINE #include + #ifndef _WIN32 /* others we support without sys/param.h? */ #include #endif @@ -111,13 +114,11 @@ typedef unsigned char byte; #undef true #undef false -/* some structures have qboolean members and the x86 asm code expect - * those members to be 4 bytes long. therefore, qboolean must be 32 + +// TODO VR: seems to work... +/* some structures have bool members and the x86 asm code expect + * those members to be 4 bytes long. therefore, bool must be 32 * bits and it can NOT be binary compatible with the 8 bit C++ bool. */ -typedef int qboolean; -static_assert(0 == false); -static_assert(1 == true); -static_assert(sizeof(qboolean) == 4); /*==========================================================================*/ diff --git a/Quake/quakedef.hpp b/Quake/quakedef.hpp index da7b577d..a6aaf172 100644 --- a/Quake/quakedef.hpp +++ b/Quake/quakedef.hpp @@ -37,7 +37,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define FITZQUAKE_VERSION 0.85 // johnfitz #define QUAKESPASM_VERSION 0.93 -#define QUAKEVR_VERSION "0.0.2" +#define QUAKEVR_VERSION "0.0.3" #define QUAKESPASM_VER_PATCH 2 // helper to print a string like 0.93.2 #ifndef QUAKESPASM_VER_SUFFIX #define QUAKESPASM_VER_SUFFIX // optional version suffix string literal like @@ -278,7 +278,7 @@ typedef struct // command line parms passed to the program, and the amount of memory // available for the program to use -extern qboolean noclip_anglehack; +extern bool noclip_anglehack; // // host @@ -291,7 +291,7 @@ extern cvar_t sys_nostdout; extern cvar_t developer; extern cvar_t max_edicts; // johnfitz -extern qboolean host_initialized; // true if into command execution +extern bool host_initialized; // true if into command execution extern double host_frametime; extern byte* host_colormap; extern int host_framecount; // incremented every frame, never reset @@ -323,7 +323,7 @@ void Host_Callback_Notify(cvar_t* var); /* callback function for CVAR_NOTIFY */ void Host_Frame(float time); void Host_Quit_f(void); void Host_ClientCommands(const char* fmt, ...) FUNC_PRINTF(1, 2); -void Host_ShutdownServer(qboolean crash); +void Host_ShutdownServer(bool crash); void Host_WriteConfiguration(void); void ExtraMaps_Init(void); @@ -336,7 +336,7 @@ extern int current_skill; // skill level for currently loaded level (in case // the user changes the cvar while the level is // running, this reflects the level actually in use) -extern qboolean isDedicated; +extern bool isDedicated; extern int minimum_memory; diff --git a/Quake/r_alias.cpp b/Quake/r_alias.cpp index cbd8312b..c742e48f 100644 --- a/Quake/r_alias.cpp +++ b/Quake/r_alias.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -53,9 +54,9 @@ vec3_t shadevector; float entalpha; // johnfitz -qboolean overbright; // johnfitz +bool overbright; // johnfitz -qboolean shading = +bool shading = true; // johnfitz -- if false, disable vertex shading for various reasons // (fullbright, r_lightmap, showtris, etc) @@ -343,7 +344,7 @@ void GL_DrawAliasFrame(aliashdr_t* paliashdr, lerpdata_t lerpdata) float blend; float iblend; - qboolean lerping; + bool lerping; if(lerpdata.pose1 != lerpdata.pose2) { @@ -729,7 +730,7 @@ void R_DrawAliasModel(entity_t* e, bool horizflip) gltexture_t* fb; lerpdata_t lerpdata; - qboolean alphatest = !!(e->model->flags & MF_HOLEY); + bool alphatest = !!(e->model->flags & MF_HOLEY); // // setup pose/lerp data -- do it first so we don't miss updates due to diff --git a/Quake/r_brush.cpp b/Quake/r_brush.cpp index 6190682b..69afdc90 100644 --- a/Quake/r_brush.cpp +++ b/Quake/r_brush.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/r_part.cpp b/Quake/r_part.cpp index f6fafeb2..02732921 100644 --- a/Quake/r_part.cpp +++ b/Quake/r_part.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -22,31 +23,324 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "quakedef.hpp" +#include "util.hpp" + +#include +#include +#include +#include + +#define GLM_FORCE_INLINE +#include +#include +#include #define MAX_PARTICLES \ - 2048 // default max # of particles at one - // time + 4096 // default max # of particles at one + // time, per texture (TODO VR: should it be per texture?) + #define ABSOLUTE_MIN_PARTICLES \ 512 // no fewer than this no matter what's - // on the command line + // on the command line + +// These "ramps" below are for colors.. + +// Gold/brown/peach +constexpr int ramp1[8] = {111, 112, 107, 105, 103, 101, 99, 97}; + +// Gold/brown +constexpr int ramp2[8] = {111, 110, 109, 108, 107, 106, 104, 102}; + +// Gold/brown/grey +constexpr int ramp3[8] = {109, 107, 6, 5, 4, 3}; + +enum ptype_t : std::uint8_t +{ + pt_static, + pt_fire, + pt_explode, + pt_explode2, + pt_blob, + pt_blob2, + pt_txexplode, + pt_txsmoke, + pt_lightning, + pt_teleport, + pt_rock, + pt_gunsmoke, +}; + +// TODO VR: optimize layout? +struct particle_t +{ + glm::vec3 org; // driver-usable field + glm::vec3 vel; // drivers never touches this field + glm::vec3 acc; // TODO VR: driver? + + float color; // driver-usable field + float ramp; // drivers never touches this field + float die; // drivers never touches this field + float scale; // TODO VR: driver? + float alpha; // TODO VR: use? + float angle; // TODO VR: use? + + ptype_t type; // drivers never touches this field + std::uint8_t param0; // TODO VR: use? +}; + +class ParticleBuffer +{ +private: + particle_t* _particles; + particle_t* _aliveEnd; + particle_t* _end; + std::size_t _maxParticles; + +public: + void initialize(const std::size_t maxParticles) noexcept + { + _maxParticles = maxParticles; + _particles = (particle_t*)Hunk_AllocName( + _maxParticles * sizeof(particle_t), "particles"); + _aliveEnd = _particles; + _end = _particles + _maxParticles; + } + + void cleanup() noexcept + { + _aliveEnd = + std::remove_if(_particles, _aliveEnd, [](const particle_t& p) { + return p.alpha <= 0.f || p.scale <= 0.f || cl.time >= p.die; + }); + } + + [[nodiscard]] QUAKE_FORCEINLINE particle_t& create() noexcept + { + return *_aliveEnd++; + } + + template + QUAKE_FORCEINLINE void forActive(F&& f) noexcept + { + for(auto p = _particles; p != _aliveEnd; ++p) + { + f(*p); + } + } + + [[nodiscard]] QUAKE_FORCEINLINE bool full() const noexcept + { + return _aliveEnd == _end; + } + + void clear() noexcept + { + _aliveEnd = _particles; + } + + [[nodiscard]] QUAKE_FORCEINLINE bool empty() const noexcept + { + return _aliveEnd == _particles; + } +}; + +struct ImageData +{ + byte* data; // Hunk-allocated. + int width; + int height; +}; + +class ParticleTextureManager +{ +public: + using Handle = std::uint8_t; + static constexpr std::size_t maxTextures = 32; + +private: + std::array _textures; + std::array _imageData; + Handle _next = 0; + +public: + [[nodiscard]] Handle put( + gltexture_t* const texture, const ImageData& imageData) noexcept + { + assert(_next < maxTextures); + _textures[_next] = texture; + _imageData[_next] = imageData; + return _next++; + } -int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61}; -int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}; -int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}; + [[nodiscard]] gltexture_t* get(const Handle handle) const noexcept + { + assert(handle < _next); + return _textures[handle]; + } -particle_t *active_particles, *free_particles, *particles; + [[nodiscard]] const ImageData& getImageData( + const Handle handle) const noexcept + { + assert(handle < _next); + return _imageData[handle]; + } -vec3_t r_pright, r_pup, r_ppn; + [[nodiscard]] QUAKE_FORCEINLINE std::size_t numActive() const noexcept + { + return _next; + } +}; int r_numparticles; -gltexture_t *particletexture, *particletexture1, *particletexture2, - *particletexture3, *particletexture4; // johnfitz -float texturescalefactor; // johnfitz -- compensate for apparent size of - // different particle textures +class ParticleManager +{ +public: + using Handle = ParticleTextureManager::Handle; + +private: + ParticleTextureManager _textureMgr; + std::array _buffers; + +public: + [[nodiscard]] Handle createBuffer( + gltexture_t* const texture, const ImageData& imageData) noexcept + { + const Handle h = _textureMgr.put(texture, imageData); + _buffers[h].initialize(r_numparticles); + return h; + } + + [[nodiscard]] gltexture_t* getTexture(const Handle handle) const noexcept + { + return _textureMgr.get(handle); + } + + [[nodiscard]] const ImageData& getImageData( + const Handle handle) const noexcept + { + return _textureMgr.getImageData(handle); + } + + [[nodiscard]] ParticleBuffer& getBuffer( + const ParticleTextureManager::Handle txHandle) noexcept + { + assert(txHandle < _textureMgr.numActive()); + return _buffers[txHandle]; + } + + void clear() noexcept + { + for(std::size_t i = 0; i < _textureMgr.numActive(); ++i) + { + _buffers[i].clear(); + } + } + + void cleanup() noexcept + { + for(std::size_t i = 0; i < _textureMgr.numActive(); ++i) + { + _buffers[i].cleanup(); + } + } + + template + void forActive(F&& f) noexcept + { + for(std::size_t i = 0; i < _textureMgr.numActive(); ++i) + { + _buffers[i].forActive(f); + } + } + + template + void forBuffers(F&& f) noexcept + { + for(std::size_t i = 0; i < _textureMgr.numActive(); ++i) + { + if(!_buffers[i].empty()) + { + f(getTexture(i), getImageData(i), _buffers[i]); + } + } + } +}; + +ParticleManager pMgr; + +std::random_device rd; +std::mt19937 mt(rd()); + +[[nodiscard]] QUAKE_FORCEINLINE static float rnd( + const float min, const float max) noexcept +{ + return std::uniform_real_distribution{min, max}(mt); +} + +[[nodiscard]] QUAKE_FORCEINLINE static int rndi( + const int min, const int max) noexcept +{ + return std::uniform_int_distribution{min, max - 1}(mt); +} + +template +QUAKE_FORCEINLINE void makeNParticlesI( + const ParticleTextureManager::Handle txHandle, const int count, + F&& f) noexcept +{ + auto& pBuffer = pMgr.getBuffer(txHandle); + + for(int i = 0; i < count * r_particle_mult.value; i++) + { + if(pBuffer.full()) + { + return; + } + + f(i, pBuffer.create()); + } +} + + +template +QUAKE_FORCEINLINE void makeNParticles( + const ParticleTextureManager::Handle txHandle, const int count, + F&& f) noexcept +{ + makeNParticlesI(txHandle, count, [&f](const int, particle_t& p) { f(p); }); +} + +QUAKE_FORCEINLINE void setAccGrav(particle_t& p, float mult = 0.5f) noexcept +{ + extern cvar_t sv_gravity; + + p.acc[0] = 0.f; + p.acc[1] = 0.f; + p.acc[2] = -sv_gravity.value * mult; +} -cvar_t r_particles = {"r_particles", "1", CVAR_ARCHIVE}; // johnfitz -cvar_t r_quadparticles = {"r_quadparticles", "1", CVAR_ARCHIVE}; // johnfitz +ParticleTextureManager::Handle ptxCircle; +ParticleTextureManager::Handle ptxSquare; +ParticleTextureManager::Handle ptxBlob; +ParticleTextureManager::Handle ptxExplosion; +ParticleTextureManager::Handle ptxSmoke; +ParticleTextureManager::Handle ptxBlood; +ParticleTextureManager::Handle ptxBloodMist; +ParticleTextureManager::Handle ptxLightning; +ParticleTextureManager::Handle ptxSpark; +ParticleTextureManager::Handle ptxRock; +ParticleTextureManager::Handle ptxGunSmoke; + +cvar_t r_particles = {"r_particles", "1", CVAR_ARCHIVE}; // johnfitz +cvar_t r_particle_mult = {"r_particle_mult", "1", CVAR_ARCHIVE}; + +template +QUAKE_FORCEINLINE void forActiveParticles(F&& f) noexcept +{ + // TODO VR: parallelize with thread pool + pMgr.forActive(std::forward(f)); +} /* =============== @@ -56,38 +350,25 @@ for particles */ int R_ParticleTextureLookup(int x, int y, int sharpness) { - int r; // distance from point x,y to circle origin, squared - int a; // alpha value to return - x -= 16; y -= 16; - r = x * x + y * y; + + // distance from point x,y to circle origin, squared + int r = x * x + y * y; r = r > 255 ? 255 : r; - a = sharpness * (255 - r); + + // alpha value to return + int a = sharpness * (255 - r); a = q_min(a, 255); + return a; } -/* -=============== -R_InitParticleTextures -- johnfitz -- rewritten -=============== -*/ -void R_InitParticleTextures() +static void buildCircleTexture(byte* dst) noexcept { - int x; - - int y; - static byte particle1_data[64 * 64 * 4]; - static byte particle2_data[2 * 2 * 4]; - static byte particle3_data[64 * 64 * 4]; - byte* dst; - - // particle texture 1 -- circle - dst = particle1_data; - for(x = 0; x < 64; x++) + for(int x = 0; x < 64; x++) { - for(y = 0; y < 64; y++) + for(int y = 0; y < 64; y++) { *dst++ = 255; *dst++ = 255; @@ -95,15 +376,13 @@ void R_InitParticleTextures() *dst++ = R_ParticleTextureLookup(x, y, 8); } } - particletexture1 = TexMgr_LoadImage(nullptr, "particle1", 64, 64, SRC_RGBA, - particle1_data, "", (src_offset_t)particle1_data, - TEXPREF_PERSIST | TEXPREF_ALPHA | TEXPREF_LINEAR); +} - // particle texture 2 -- square - dst = particle2_data; - for(x = 0; x < 2; x++) +static void buildSquareTexture(byte* dst) noexcept +{ + for(int x = 0; x < 2; x++) { - for(y = 0; y < 2; y++) + for(int y = 0; y < 2; y++) { *dst++ = 255; *dst++ = 255; @@ -111,15 +390,13 @@ void R_InitParticleTextures() *dst++ = x || y ? 0 : 255; } } - particletexture2 = TexMgr_LoadImage(nullptr, "particle2", 2, 2, SRC_RGBA, - particle2_data, "", (src_offset_t)particle2_data, - TEXPREF_PERSIST | TEXPREF_ALPHA | TEXPREF_NEAREST); +} - // particle texture 3 -- blob - dst = particle3_data; - for(x = 0; x < 64; x++) +static void buildBlobTexture(byte* dst) noexcept +{ + for(int x = 0; x < 64; x++) { - for(y = 0; y < 64; y++) + for(int y = 0; y < 64; y++) { *dst++ = 255; *dst++ = 255; @@ -127,51 +404,87 @@ void R_InitParticleTextures() *dst++ = R_ParticleTextureLookup(x, y, 2); } } - particletexture3 = TexMgr_LoadImage(nullptr, "particle3", 64, 64, SRC_RGBA, - particle3_data, "", (src_offset_t)particle3_data, - TEXPREF_PERSIST | TEXPREF_ALPHA | TEXPREF_LINEAR); +} + +[[nodiscard]] gltexture_t* makeTextureFromDataBuffer( + const char* name, int width, int height, byte* data) noexcept +{ + return TexMgr_LoadImage(nullptr, name, width, height, SRC_RGBA, data, "", + (src_offset_t)data, TEXPREF_PERSIST | TEXPREF_ALPHA | TEXPREF_LINEAR); +} + +[[nodiscard]] ImageData loadImage(const char* filename) +{ + char filenameBuf[128]; + q_snprintf(filenameBuf, sizeof(filenameBuf), filename); + + int width; + int height; + byte* const data = Image_LoadImage(filename, &width, &height); - // set default - particletexture = particletexture1; - texturescalefactor = 1.27; + return {data, width, height}; } +[[nodiscard]] gltexture_t* makeTextureFromImageData( + const char* name, const ImageData& imageData) noexcept +{ + return makeTextureFromDataBuffer( + name, imageData.width, imageData.height, imageData.data); +} + + /* =============== -R_SetParticleTexture_f -- johnfitz +R_InitParticleTextures -- johnfitz -- rewritten =============== */ -static void R_SetParticleTexture_f(cvar_t* var) +void R_InitParticleTextures() { - (void)var; + static byte particle1_data[64 * 64 * 4]; + static byte particle2_data[2 * 2 * 4]; + static byte particle3_data[64 * 64 * 4]; - switch((int)(r_particles.value)) { - case 1: - particletexture = particletexture1; - texturescalefactor = 1.27; - break; - case 2: - particletexture = particletexture2; - texturescalefactor = 1.0; - break; - // case 3: - // particletexture = particletexture3; - // texturescalefactor = 1.5; - // break; + buildCircleTexture(particle1_data); + const ImageData imageData{particle1_data, 64, 64}; + ptxCircle = pMgr.createBuffer( + makeTextureFromImageData("particle1", imageData), imageData); + } + + { + buildSquareTexture(particle2_data); + const ImageData imageData{particle2_data, 64, 64}; + ptxSquare = pMgr.createBuffer( + makeTextureFromImageData("particle2", imageData), imageData); + } + + { + buildBlobTexture(particle3_data); + const ImageData imageData{particle3_data, 64, 64}; + ptxBlob = pMgr.createBuffer( + makeTextureFromImageData("particle3", imageData), imageData); } + + const auto load = [&](ParticleTextureManager::Handle& target, + const char* name) { + const auto imageData = loadImage(name); + target = pMgr.createBuffer( + makeTextureFromImageData(name, imageData), imageData); + }; + + load(ptxExplosion, "textures/particle_explosion"); + load(ptxSmoke, "textures/particle_smoke"); + load(ptxBlood, "textures/particle_blood"); + load(ptxBloodMist, "textures/particle_blood_mist"); + load(ptxLightning, "textures/particle_lightning"); + load(ptxSpark, "textures/particle_spark"); + load(ptxRock, "textures/particle_rock"); + load(ptxGunSmoke, "textures/particle_gun_smoke"); } -/* -=============== -R_InitParticles -=============== -*/ -void R_InitParticles() +static void R_InitRNumParticles() { - int i; - - i = COM_CheckParm("-particles"); + const int i = COM_CheckParm("-particles"); if(i) { @@ -185,14 +498,23 @@ void R_InitParticles() { r_numparticles = MAX_PARTICLES; } +} - particles = (particle_t*)Hunk_AllocName( - r_numparticles * sizeof(particle_t), "particles"); - +static void R_InitParticleCVars() +{ Cvar_RegisterVariable(&r_particles); // johnfitz - Cvar_SetCallback(&r_particles, R_SetParticleTexture_f); - Cvar_RegisterVariable(&r_quadparticles); // johnfitz + Cvar_RegisterVariable(&r_particle_mult); +} +/* +=============== +R_InitParticles +=============== +*/ +void R_InitParticles() +{ + R_InitRNumParticles(); + R_InitParticleCVars(); R_InitParticleTextures(); // johnfitz } @@ -205,33 +527,12 @@ R_EntityParticles extern float r_avertexnormals[NUMVERTEXNORMALS][3]; vec3_t avelocities[NUMVERTEXNORMALS]; float beamlength = 16; -vec3_t avelocity = {23, 7, 3}; -float partstep = 0.01; -float timescale = 0.01; void R_EntityParticles(entity_t* ent) { - int i; - particle_t* p; - float angle; - float sp; - - float sy; - - float cp; - - float cy; - // float sr, cr; - // int count; - vec3_t forward; - float dist; - - dist = 64; - // count = 50; - if(!avelocities[0][0]) { - for(i = 0; i < NUMVERTEXNORMALS; i++) + for(int i = 0; i < NUMVERTEXNORMALS; i++) { avelocities[i][0] = (rand() & 255) * 0.01; avelocities[i][1] = (rand() & 255) * 0.01; @@ -239,41 +540,35 @@ void R_EntityParticles(entity_t* ent) } } - for(i = 0; i < NUMVERTEXNORMALS; i++) + for(int i = 0; i < NUMVERTEXNORMALS; i++) { - angle = cl.time * avelocities[i][0]; - sy = sin(angle); - cy = cos(angle); + float angle = cl.time * avelocities[i][0]; + float sy = sin(angle); + float cy = cos(angle); + angle = cl.time * avelocities[i][1]; - sp = sin(angle); - cp = cos(angle); - angle = cl.time * avelocities[i][2]; - // sr = sin(angle); - // cr = cos(angle); + float sp = sin(angle); + float cp = cos(angle); + vec3_t forward; forward[0] = cp * cy; forward[1] = cp * sy; forward[2] = -sp; - if(!free_particles) - { - return; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = cl.time + 0.01; - p->color = 0x6f; - p->type = pt_explode; - - p->org[0] = ent->origin[0] + r_avertexnormals[i][0] * dist + - forward[0] * beamlength; - p->org[1] = ent->origin[1] + r_avertexnormals[i][1] * dist + - forward[1] * beamlength; - p->org[2] = ent->origin[2] + r_avertexnormals[i][2] * dist + - forward[2] * beamlength; + makeNParticles(ptxCircle, 1, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 0.01; + p.color = 0x6f; + p.type = pt_explode; + p.scale = 1.f; + setAccGrav(p); + + constexpr float dist = 64; + p.org[0] = ent->origin[0] + r_avertexnormals[i][0] * dist + forward[0] * beamlength; + p.org[1] = ent->origin[1] + r_avertexnormals[i][1] * dist + forward[1] * beamlength; + p.org[2] = ent->origin[2] + r_avertexnormals[i][2] * dist + forward[2] * beamlength; + }); } } @@ -284,16 +579,7 @@ R_ClearParticles */ void R_ClearParticles() { - int i; - - free_particles = &particles[0]; - active_particles = nullptr; - - for(i = 0; i < r_numparticles; i++) - { - particles[i].next = &particles[i + 1]; - } - particles[r_numparticles - 1].next = nullptr; + pMgr.clear(); } /* @@ -303,20 +589,15 @@ R_ReadPointFile_f */ void R_ReadPointFile_f() { - FILE* f; - vec3_t org; - int r; - int c; - particle_t* p; - char name[MAX_QPATH]; - if(cls.state != ca_connected) { return; // need an active map. } + char name[MAX_QPATH]; q_snprintf(name, sizeof(name), "maps/%s.pts", cl.mapname); + FILE* f; COM_FOpenFile(name, &f, nullptr); if(!f) { @@ -325,32 +606,32 @@ void R_ReadPointFile_f() } Con_Printf("Reading %s...\n", name); - c = 0; - org[0] = org[1] = org[2] = 0; // silence pesky compiler warnings - for(;;) + + int c = 0; + while(true) { - r = fscanf(f, "%f %f %f\n", &org[0], &org[1], &org[2]); + vec3_t org; + const int r = fscanf(f, "%f %f %f\n", &org[0], &org[1], &org[2]); + if(r != 3) { break; } + c++; - if(!free_particles) - { - Con_Printf("Not enough free particles\n"); - break; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = 99999; - p->color = (-c) & 15; - p->type = pt_static; - VectorCopy(vec3_origin, p->vel); - VectorCopy(org, p->org); + makeNParticles(ptxCircle, 1, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = 99999; + p.color = (-c) & 15; + p.type = pt_static; + p.scale = 1.f; + setAccGrav(p); + + VectorCopy(vec3_origin, p.vel); + VectorCopy(org, p.org); + }); } fclose(f); @@ -367,37 +648,48 @@ Parse an effect out of the server message void R_ParseParticleEffect() { vec3_t org; + for(int i = 0; i < 3; i++) + { + org[i] = MSG_ReadCoord(cl.protocolflags); + } vec3_t dir; - int i; + for(int i = 0; i < 3; i++) + { + dir[i] = MSG_ReadChar() * (1.0 / 16); + } - int count; + const int msgcount = MSG_ReadByte(); + const int color = MSG_ReadByte(); - int msgcount; + R_RunParticleEffect(org, dir, color, msgcount); +} - int color; +/* +=============== +R_ParseParticle2Effect - for(i = 0; i < 3; i++) +Parse an effect out of the server message (preset-based) +=============== +*/ +void R_ParseParticle2Effect() +{ + vec3_t org; + for(int i = 0; i < 3; i++) { org[i] = MSG_ReadCoord(cl.protocolflags); } - for(i = 0; i < 3; i++) + + vec3_t dir; + for(int i = 0; i < 3; i++) { dir[i] = MSG_ReadChar() * (1.0 / 16); } - msgcount = MSG_ReadByte(); - color = MSG_ReadByte(); - if(msgcount == 255) - { - count = 1024; - } - else - { - count = msgcount; - } + const int preset = MSG_ReadByte(); + const int msgcount = MSG_ReadShort(); - R_RunParticleEffect(org, dir, color, count); + R_RunParticle2Effect(org, dir, preset, msgcount); } /* @@ -407,44 +699,92 @@ R_ParticleExplosion */ void R_ParticleExplosion(vec3_t org) { - int i; - - int j; - particle_t* p; - - for(i = 0; i < 1024; i++) - { - if(!free_particles) + makeNParticlesI(ptxCircle, 256, [&](const int i, particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 2; + p.color = ramp1[0]; + p.ramp = rand() & 3; + p.scale = rnd(0.6f, 1.2f); + setAccGrav(p); + p.type = i & 1 ? pt_explode : pt_explode2; + + for(int j = 0; j < 3; j++) { - return; + p.org[j] = org[j] + rnd(-16, 16); + p.vel[j] = rnd(-256, 256); } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = cl.time + 5; - p->color = ramp1[0]; - p->ramp = rand() & 3; - if(i & 1) + }); + + makeNParticlesI(ptxSpark, 64, [&](const int, particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 3; + p.color = ramp1[0]; + p.ramp = rand() & 3; + p.scale = rnd(1.9f, 2.9f) * 0.55f; + setAccGrav(p); + p.type = pt_rock; + p.param0 = rndi(0, 2); // rotation direction + + for(int j = 0; j < 3; j++) { - p->type = pt_explode; - for(j = 0; j < 3; j++) - { - p->org[j] = org[j] + ((rand() % 32) - 16); - p->vel[j] = (rand() % 512) - 256; - } + p.org[j] = org[j] + rnd(-16, 16); + p.vel[j] = rnd(-256, 256); } - else + }); + + makeNParticlesI(ptxRock, 48, [&](const int, particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 3; + p.color = 167 + (rand() & 7); + p.ramp = rand() & 3; + p.scale = rnd(0.9f, 1.9f); + setAccGrav(p); + p.type = pt_rock; + p.param0 = rndi(0, 2); // rotation direction + + for(int j = 0; j < 3; j++) { - p->type = pt_explode2; - for(j = 0; j < 3; j++) - { - p->org[j] = org[j] + ((rand() % 32) - 16); - p->vel[j] = (rand() % 512) - 256; - } + p.org[j] = org[j] + rnd(-16, 16); + p.vel[j] = rnd(-256, 256); } - } + }); + + makeNParticles(ptxExplosion, 3, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 240; + p.die = cl.time + 1.5 * rnd(0.5f, 1.5f); + p.color = ramp1[0]; + p.ramp = rand() & 3; + p.scale = rnd(0.5f, 2.1f) * 2.f; + setAccGrav(p, 0.05f); + p.type = pt_txexplode; + p.param0 = rndi(0, 2); // rotation direction + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + rnd(-11, 11); + p.vel[j] = rnd(-8, 8); + } + }); + + makeNParticles(ptxSmoke, 3, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 225; + p.die = cl.time + 3.5 * (rand() % 5); + p.color = rand() & 7; + p.scale = rnd(1.2f, 1.5f); + p.type = pt_txsmoke; + setAccGrav(p, -0.09f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + ((rand() & 7) - 4); + p.vel[j] = rnd(-24, 24); + } + }); } /* @@ -454,82 +794,250 @@ R_ParticleExplosion2 */ void R_ParticleExplosion2(vec3_t org, int colorStart, int colorLength) { - int i; - - int j; - particle_t* p; int colorMod = 0; - for(i = 0; i < 512; i++) - { - if(!free_particles) - { - return; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = cl.time + 0.3; - p->color = colorStart + (colorMod % colorLength); + makeNParticles(ptxCircle, 512, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 0.3; + p.color = colorStart + (colorMod % colorLength); + p.scale = 1.f; colorMod++; + setAccGrav(p); - p->type = pt_blob; - for(j = 0; j < 3; j++) + p.type = pt_blob; + for(int j = 0; j < 3; j++) { - p->org[j] = org[j] + ((rand() % 32) - 16); - p->vel[j] = (rand() % 512) - 256; + p.org[j] = org[j] + rnd(-16, 16); + p.vel[j] = rnd(-256, 256); } - } + }); } -/* -=============== -R_BlobExplosion -=============== -*/ -void R_BlobExplosion(vec3_t org) +void R_RunParticleEffect_BulletPuff( + vec3_t org, vec3_t dir, int color, int count) { - int i; - - int j; - particle_t* p; - - for(i = 0; i < 1024; i++) - { - if(!free_particles) + const auto debrisCount = count * 0.7f; + const auto dustCount = count * 0.7f; + const auto sparkCount = count * 0.4f; + + makeNParticles(ptxRock, debrisCount, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 0.7 * (rand() % 5); + p.color = (color & ~7) + (rand() & 7); + p.scale = rnd(0.5f, 0.9f); + p.type = pt_rock; + p.param0 = rndi(0, 2); // rotation direction + setAccGrav(p, 0.26f); + + for(int j = 0; j < 3; j++) { - return; + p.org[j] = org[j] + ((rand() & 7) - 4); + p.vel[j] = (dir[j] + 0.3f) * rnd(-75, 75); } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; + }); - p->die = cl.time + 1 + (rand() & 8) * 0.05; + makeNParticles(ptxSmoke, 1, [&](particle_t& p) { + p.alpha = 45; + p.die = cl.time + 1.5 * (rand() % 5); + p.color = rand() & 7; + p.scale = rnd(0.3f, 0.5f); + p.type = pt_txsmoke; + setAccGrav(p, -0.09f); - if(i & 1) + for(int j = 0; j < 3; j++) { - p->type = pt_blob; - p->color = 66 + rand() % 6; - for(j = 0; j < 3; j++) - { - p->org[j] = org[j] + ((rand() % 32) - 16); - p->vel[j] = (rand() % 512) - 256; - } + p.org[j] = org[j] + ((rand() & 4) - 2); + p.vel[j] = rnd(-12, 12); } - else + }); + + makeNParticles(ptxCircle, dustCount, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 1.5 * (rand() % 5); + p.color = (color & ~7) + (rand() & 7); + p.scale = rnd(0.05f, 0.3f); + p.type = pt_static; + setAccGrav(p, 0.08f); + + for(int j = 0; j < 3; j++) { - p->type = pt_blob2; - p->color = 150 + rand() % 6; - for(j = 0; j < 3; j++) - { - p->org[j] = org[j] + ((rand() % 32) - 16); - p->vel[j] = (rand() % 512) - 256; - } + p.org[j] = org[j] + ((rand() & 7) - 4); + p.vel[j] = rnd(-24, 24); } - } + + p.vel[2] += rnd(10, 40); + }); + + makeNParticles(ptxSpark, sparkCount, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 1.6 * (rand() % 5); + p.color = ramp3[0] + (rand() & 7); + p.scale = rnd(1.95f, 2.87f) * 0.35f; + p.type = pt_rock; + p.param0 = rndi(0, 2); // rotation direction + setAccGrav(p, 1.f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + ((rand() & 7) - 4); + p.vel[j] = rnd(-48, 48); + } + + p.vel[2] = rnd(60, 360); + }); +} + +void R_RunParticleEffect_Blood(vec3_t org, vec3_t dir, int count) +{ + constexpr int bloodColors[]{247, 248, 249, 250, 251}; + const auto pickBloodColor = [&] { return bloodColors[rndi(0, 5)]; }; + + makeNParticles(ptxBlood, count * 2, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 100; + p.die = cl.time + 0.7 * (rand() % 3); + p.color = pickBloodColor(); + p.scale = rnd(0.35f, 0.6f) * 6.5f; + p.type = pt_static; + setAccGrav(p, 0.29f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + rnd(-2, 2); + p.vel[j] = (dir[j] + 0.3f) * rnd(-10, 10); + } + + p.vel[2] += rnd(0, 40); + }); + + makeNParticles(ptxCircle, count * 24, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 175; + p.die = cl.time + 0.4 * (rand() % 3); + p.color = pickBloodColor(); + p.scale = rnd(0.12f, 0.2f); + p.type = pt_static; + setAccGrav(p, 0.45f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + rnd(-2, 2); + p.vel[j] = (dir[j] + 0.3f) * rnd(-3, 3); + p.vel[j] *= 13.f; + } + + p.vel[2] += rnd(20, 60); + }); + + makeNParticles(ptxBloodMist, 1, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 38; + p.die = cl.time + 3.2; + p.color = 225; + p.ramp = rand() & 3; + p.scale = rnd(1.1f, 2.4f) * 15.f; + setAccGrav(p, -0.03f); + p.type = pt_txsmoke; + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + rnd(-8, 8); + p.vel[j] = rnd(-4, -4); + } + }); +} + +void R_RunParticleEffect_Lightning(vec3_t org, vec3_t dir, int count) +{ + (void)dir; + + makeNParticles(ptxLightning, count, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 180; + p.die = cl.time + 1.3 * (rand() % 3); + p.color = 254; + p.scale = rnd(0.35f, 0.6f) * 6.2f; + p.type = pt_lightning; + setAccGrav(p, 0.f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + rnd(-3, 3); + p.vel[j] = rnd(-185, 185); + } + }); +} + +void R_RunParticleEffect_Smoke(vec3_t org, vec3_t dir, int count) +{ + (void)dir; + + makeNParticles(ptxSmoke, count, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 125; + p.die = cl.time + 3.5 * (rand() % 5); + p.color = rand() & 7; + p.scale = rnd(1.2f, 1.5f) * 0.8f; + p.type = pt_txsmoke; + setAccGrav(p, -0.09f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + ((rand() & 7) - 4); + p.vel[j] = rnd(-24, 24); + } + }); +} + +void R_RunParticleEffect_Sparks(vec3_t org, vec3_t dir, int count) +{ + (void)dir; + + makeNParticles(ptxSpark, count, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.die = cl.time + 2.6 * (rand() % 5); + p.color = rndi(102, 112); + p.scale = rnd(1.55f, 2.87f) * 0.45f; + p.type = pt_rock; + p.param0 = rndi(0, 2); // rotation direction + setAccGrav(p, 1.f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j] + ((rand() & 7) - 4); + p.vel[j] = rnd(-48, 48); + } + + p.vel[2] = rnd(60, 360); + }); +} + +void R_RunParticleEffect_GunSmoke(vec3_t org, vec3_t dir, int count) +{ + (void)dir; + + makeNParticles(ptxGunSmoke, count, [&](particle_t& p) { + p.angle = 3.14f / 2.f + rnd(-0.2f, 0.2f); + p.alpha = rnd(85, 125); + p.die = cl.time + 6; + p.color = rndi(10, 16); + p.scale = rnd(0.9f, 1.5f) * 0.1f; + p.type = pt_gunsmoke; + setAccGrav(p, -0.09f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = org[j]; + p.vel[j] = rnd(-3, 3); + } + + p.org[2] += 3.f; + }); } /* @@ -539,57 +1047,69 @@ R_RunParticleEffect */ void R_RunParticleEffect(vec3_t org, vec3_t dir, int color, int count) { - int i; - - int j; - particle_t* p; + // TODO VR: add way to change types + R_RunParticleEffect_BulletPuff(org, dir, color, count); +} - for(i = 0; i < count; i++) +/* +=============== +R_RunParticle2Effect +=============== +*/ +void R_RunParticle2Effect(vec3_t org, vec3_t dir, int preset, int count) +{ + enum class Preset : int { - if(!free_particles) + BulletPuff = 0, + Blood = 1, + Explosion = 2, + Lightning = 3, + Smoke = 4, + Sparks = 5, + GunSmoke = 6 + }; + + switch(static_cast(preset)) + { + case Preset::BulletPuff: { - return; + R_RunParticleEffect_BulletPuff(org, dir, 0, count); + break; } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - if(count == 1024) - { // rocket explosion - p->die = cl.time + 5; - p->color = ramp1[0]; - p->ramp = rand() & 3; - if(i & 1) - { - p->type = pt_explode; - for(j = 0; j < 3; j++) - { - p->org[j] = org[j] + ((rand() % 32) - 16); - p->vel[j] = (rand() % 512) - 256; - } - } - else - { - p->type = pt_explode2; - for(j = 0; j < 3; j++) - { - p->org[j] = org[j] + ((rand() % 32) - 16); - p->vel[j] = (rand() % 512) - 256; - } - } + case Preset::Blood: + { + R_RunParticleEffect_Blood(org, dir, count); + break; } - else + case Preset::Explosion: { - p->die = cl.time + 0.1 * (rand() % 5); - p->color = (color & ~7) + (rand() & 7); - p->type = pt_slowgrav; - for(j = 0; j < 3; j++) - { - // TODO VR: bullet puff - p->org[j] = org[j] + ((rand() & 7) - 4); - p->vel[j] = dir[j] * 15 + (rand() % 6) - 3; - } + R_ParticleExplosion(org); + break; + } + case Preset::Lightning: + { + R_RunParticleEffect_Lightning(org, dir, count); + break; + } + case Preset::Smoke: + { + R_RunParticleEffect_Smoke(org, dir, count); + break; + } + case Preset::Sparks: + { + R_RunParticleEffect_Sparks(org, dir, count); + break; + } + case Preset::GunSmoke: + { + R_RunParticleEffect_GunSmoke(org, dir, count); + break; + } + default: + { + assert(false); + break; } } } @@ -601,46 +1121,31 @@ R_LavaSplash */ void R_LavaSplash(vec3_t org) { - int i; - - int j; - - int k; - particle_t* p; - float vel; - vec3_t dir; - - for(i = -16; i < 16; i++) + for(int i = -16; i < 16; i++) { - for(j = -16; j < 16; j++) + for(int j = -16; j < 16; j++) { - for(k = 0; k < 1; k++) - { - if(!free_particles) - { - return; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = cl.time + 2 + (rand() & 31) * 0.02; - p->color = 224 + (rand() & 7); - p->type = pt_slowgrav; - - dir[0] = j * 8 + (rand() & 7); - dir[1] = i * 8 + (rand() & 7); - dir[2] = 256; - - p->org[0] = org[0] + dir[0]; - p->org[1] = org[1] + dir[1]; - p->org[2] = org[2] + (rand() & 63); - - VectorNormalize(dir); - vel = 50 + (rand() & 63); - VectorScale(dir, vel, p->vel); - } + makeNParticles(ptxCircle, 1, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.scale = 1.f; + p.die = cl.time + 2 + (rand() & 31) * 0.02; + p.color = 224 + (rand() & 7); + p.type = pt_static; + setAccGrav(p); + + const glm::vec3 dir{ // + j * 8 + (rand() & 7), // + i * 8 + (rand() & 7), // + 256}; + + p.org[0] = org[0] + dir[0]; + p.org[1] = org[1] + dir[1]; + p.org[2] = org[2] + (rand() & 63); + + const float vel = 50 + (rand() & 63); + p.vel = glm::normalize(dir) * vel; + }); } } } @@ -652,50 +1157,124 @@ R_TeleportSplash */ void R_TeleportSplash(vec3_t org) { - int i; - - int j; - - int k; - particle_t* p; - float vel; - vec3_t dir; - - for(i = -16; i < 16; i += 4) + for(int i = -16; i < 16; i += 4) { - for(j = -16; j < 16; j += 4) + for(int j = -16; j < 16; j += 4) { - for(k = -24; k < 32; k += 4) + for(int k = -24; k < 32; k += 4) { - if(!free_particles) - { - return; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - p->die = cl.time + 0.2 + (rand() & 7) * 0.02; - p->color = 7 + (rand() & 7); - p->type = pt_slowgrav; - - dir[0] = j * 8; - dir[1] = i * 8; - dir[2] = k * 8; - - p->org[0] = org[0] + i + (rand() & 3); - p->org[1] = org[1] + j + (rand() & 3); - p->org[2] = org[2] + k + (rand() & 3); - - VectorNormalize(dir); - vel = 50 + (rand() & 63); - VectorScale(dir, vel, p->vel); + makeNParticles(ptxCircle, 1, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = rnd(150, 255); + p.scale = rnd(0.6f, 1.f); + p.die = cl.time + 1.2 + (rand() & 7) * 0.2; + p.color = 7 + (rand() & 7); + p.type = pt_teleport; + setAccGrav(p, 0.2f); + + const glm::vec3 dir{ + j * 8, // + i * 8, // + k * 8 // + }; + + p.org[0] = org[0] + i + (rand() & 3); + p.org[1] = org[1] + j + (rand() & 3); + p.org[2] = org[2] + k + (rand() & 3); + + const float vel = 50 + (rand() & 63); + p.vel = glm::normalize(dir) * vel; + }); } } } } +static void R_SetRTRocketTrail(vec3_t start, particle_t& p) +{ + p.ramp = (rand() & 3); + p.color = ramp3[(int)p.ramp]; + p.type = pt_fire; + for(int j = 0; j < 3; j++) + { + p.org[j] = start[j] + ((rand() % 6) - 3); + } +} + +static void R_SetRTBlood(vec3_t start, particle_t& p) +{ + p.type = pt_static; + p.color = 67 + (rand() & 3); + for(int j = 0; j < 3; j++) + { + p.org[j] = start[j] + ((rand() % 6) - 3); + } +} + +static void R_SetRTTracer(vec3_t start, vec3_t end, particle_t& p, int type) +{ + static int tracercount; + + vec3_t vec; + VectorSubtract(end, start, vec); + + p.die = cl.time + 0.5; + p.type = pt_static; + if(type == 3) + { + p.color = 52 + ((tracercount & 4) << 1); + } + else + { + p.color = 230 + ((tracercount & 4) << 1); + } + + tracercount++; + + VectorCopy(start, p.org); + if(tracercount & 1) + { + p.vel[0] = 30 * vec[1]; + p.vel[1] = 30 * -vec[0]; + } + else + { + p.vel[0] = 30 * -vec[1]; + p.vel[1] = 30 * vec[0]; + } +} + +static void R_SetRTSlightBlood(vec3_t start, particle_t& p) +{ + p.type = pt_static; + p.color = 67 + (rand() & 3); + for(int j = 0; j < 3; j++) + { + p.org[j] = start[j] + ((rand() % 6) - 3); + } +} + +static void R_SetRTVoorTrail(vec3_t start, particle_t& p) +{ + p.color = 9 * 16 + 8 + (rand() & 3); + p.type = pt_static; + p.die = cl.time + 0.3; + for(int j = 0; j < 3; j++) + { + p.org[j] = start[j] + ((rand() & 15) - 8); + } +} + +static void R_SetRTCommon(particle_t& p) +{ + p.angle = rnd(0.f, 360.f); + p.alpha = 255; + p.scale = 0.7f; + setAccGrav(p, 0.05f); + VectorCopy(vec3_origin, p.vel); + p.die = cl.time + 2; +} + /* =============== R_RocketTrail @@ -703,17 +1282,25 @@ R_RocketTrail FIXME -- rename function and use #defined types instead of numbers =============== */ +constexpr float rate = 0.1f / 9.f; +float untilNext = rate; + void R_RocketTrail(vec3_t start, vec3_t end, int type) { - vec3_t vec; - float len; - int j; - particle_t* p; - int dec; - static int tracercount; + const float frametime = cl.time - cl.oldtime; + untilNext -= frametime; + if(untilNext > 0) + { + return; + } + + untilNext = rate; + + vec3_t vec; VectorSubtract(end, start, vec); - len = VectorNormalize(vec); + + int dec; if(type < 128) { dec = 3; @@ -724,100 +1311,117 @@ void R_RocketTrail(vec3_t start, vec3_t end, int type) type -= 128; } + float len = VectorNormalize(vec); while(len > 0) { len -= dec; - if(!free_particles) - { - return; - } - p = free_particles; - free_particles = p->next; - p->next = active_particles; - active_particles = p; - - VectorCopy(vec3_origin, p->vel); - p->die = cl.time + 2; - switch(type) { case 0: // rocket trail - p->ramp = (rand() & 3); - p->color = ramp3[(int)p->ramp]; - p->type = pt_fire; - for(j = 0; j < 3; j++) - { - p->org[j] = start[j] + ((rand() % 6) - 3); - } + { + makeNParticles(ptxCircle, 6, [&](particle_t& p) { + R_SetRTCommon(p); + R_SetRTRocketTrail(start, p); + }); + + makeNParticles(ptxSmoke, 1, [&](particle_t& p) { + p.alpha = 65; + p.die = cl.time + 1.5 * (rand() % 5); + p.color = rand() & 7; + p.scale = rnd(0.3f, 0.5f); + p.type = pt_txsmoke; + setAccGrav(p, -0.09f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = start[j] + ((rand() & 6) - 3); + p.vel[j] = rnd(-18, 18); + } + }); + break; + } case 1: // smoke smoke - p->ramp = (rand() & 3) + 2; - p->color = ramp3[(int)p->ramp]; - p->type = pt_fire; - for(j = 0; j < 3; j++) - { - p->org[j] = start[j] + ((rand() % 6) - 3); - } + { + makeNParticles(ptxSmoke, 1, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 65; + p.die = cl.time + 1.5 * (rand() % 5); + p.color = rand() & 7; + p.scale = rnd(0.3f, 0.5f); + p.type = pt_txsmoke; + setAccGrav(p, -0.09f); + + for(int j = 0; j < 3; j++) + { + p.org[j] = start[j] + ((rand() & 6) - 3); + p.vel[j] = rnd(-18, 18); + } + }); + break; + } case 2: // blood - p->type = pt_grav; - p->color = 67 + (rand() & 3); - for(j = 0; j < 3; j++) - { - p->org[j] = start[j] + ((rand() % 6) - 3); - } + { + makeNParticles(ptxCircle, 6, [&](particle_t& p) { + R_SetRTCommon(p); + R_SetRTBlood(start, p); + }); + + makeNParticles(ptxBloodMist, 1, [&](particle_t& p) { + p.angle = rnd(0.f, 360.f); + p.alpha = 32; + p.die = cl.time + 3.2; + p.color = 225; + p.ramp = rand() & 3; + p.scale = rnd(1.1f, 2.4f) * 15.f; + setAccGrav(p, -0.03f); + p.type = pt_txsmoke; + + for(int j = 0; j < 3; j++) + { + p.org[j] = start[j] + rnd(-8, 8); + p.vel[j] = rnd(-4, -4); + } + }); + break; + } - case 3: + case 3: [[fallthrough]]; case 5: // tracer - p->die = cl.time + 0.5; - p->type = pt_static; - if(type == 3) - { - p->color = 52 + ((tracercount & 4) << 1); - } - else - { - p->color = 230 + ((tracercount & 4) << 1); - } - - tracercount++; + { + makeNParticles(ptxCircle, 6, [&](particle_t& p) { + R_SetRTCommon(p); + R_SetRTTracer(start, end, p, type); + }); - VectorCopy(start, p->org); - if(tracercount & 1) - { - p->vel[0] = 30 * vec[1]; - p->vel[1] = 30 * -vec[0]; - } - else - { - p->vel[0] = 30 * -vec[1]; - p->vel[1] = 30 * vec[0]; - } break; + } case 4: // slight blood - p->type = pt_grav; - p->color = 67 + (rand() & 3); - for(j = 0; j < 3; j++) - { - p->org[j] = start[j] + ((rand() % 6) - 3); - } - len -= 3; + { + makeNParticles(ptxCircle, 6, [&](particle_t& p) { + R_SetRTCommon(p); + R_SetRTSlightBlood(start, p); + len -= 3; + }); + break; + } case 6: // voor trail - p->color = 9 * 16 + 8 + (rand() & 3); - p->type = pt_static; - p->die = cl.time + 0.3; - for(j = 0; j < 3; j++) - { - p->org[j] = start[j] + ((rand() & 15) - 8); - } + { + makeNParticles(ptxCircle, 6, [&](particle_t& p) { + R_SetRTCommon(p); + R_SetRTVoorTrail(start, p); + }); + break; + } } VectorAdd(start, vec, start); @@ -832,132 +1436,162 @@ R_DrawParticles */ void CL_RunParticles() { - particle_t* p; - - particle_t* kill; - int i; - float time1; - - float time2; - - float time3; - - float dvel; - - float frametime; + if(!r_particles.value) + { + return; + } - float grav; - extern cvar_t sv_gravity; + const float frametime = cl.time - cl.oldtime; + const float time3 = frametime * 15; + const float time2 = frametime * 10; + const float time1 = frametime * 5; + const float dvel = 4 * frametime; - frametime = cl.time - cl.oldtime; - time3 = frametime * 15; - time2 = frametime * 10; - time1 = frametime * 5; - grav = frametime * sv_gravity.value * 0.05; - dvel = 4 * frametime; + pMgr.cleanup(); - for(;;) - { - kill = active_particles; - if(kill && kill->die < cl.time) - { - active_particles = kill->next; - kill->next = free_particles; - free_particles = kill; - continue; - } - break; - } + forActiveParticles([&](particle_t& p) { + p.vel += p.acc * frametime; + p.org += p.vel * frametime; - for(p = active_particles; p; p = p->next) - { - for(;;) + switch(p.type) { - kill = p->next; - if(kill && kill->die < cl.time) + case pt_static: { - p->next = kill->next; - kill->next = free_particles; - free_particles = kill; - continue; + break; } - break; - } - - p->org[0] += p->vel[0] * frametime; - p->org[1] += p->vel[1] * frametime; - p->org[2] += p->vel[2] * frametime; - switch(p->type) - { - case pt_static: break; case pt_fire: - p->ramp += time1; - if(p->ramp >= 6) + { + p.ramp += time1; + if(p.ramp >= 6) { - p->die = -1; + p.die = -1; } else { - p->color = ramp3[(int)p->ramp]; + p.color = ramp3[(int)p.ramp]; } - p->vel[2] += grav; + break; + } case pt_explode: - p->ramp += time2; - if(p->ramp >= 8) + { + p.ramp += time2; + + if(p.ramp >= 8) { - p->die = -1; + p.die = -1; } else { - p->color = ramp1[(int)p->ramp]; + p.color = ramp1[(int)p.ramp]; } - for(i = 0; i < 3; i++) + + for(int i = 0; i < 3; i++) { - p->vel[i] += p->vel[i] * dvel; + p.vel[i] += p.vel[i] * dvel; } - p->vel[2] -= grav; + break; + } case pt_explode2: - p->ramp += time3; - if(p->ramp >= 8) + { + p.ramp += time3; + + if(p.ramp >= 8) { - p->die = -1; + p.die = -1; } else { - p->color = ramp2[(int)p->ramp]; + p.color = ramp2[(int)p.ramp]; } - for(i = 0; i < 3; i++) + + for(int i = 0; i < 3; i++) { - p->vel[i] -= p->vel[i] * frametime; + p.vel[i] -= p.vel[i] * frametime; } - p->vel[2] -= grav; + break; + } case pt_blob: - for(i = 0; i < 3; i++) + { + for(int i = 0; i < 3; i++) { - p->vel[i] += p->vel[i] * dvel; + p.vel[i] += p.vel[i] * dvel; } - p->vel[2] -= grav; + break; + } case pt_blob2: - for(i = 0; i < 2; i++) + { + for(int i = 0; i < 2; i++) { - p->vel[i] -= p->vel[i] * dvel; + p.vel[i] -= p.vel[i] * dvel; } - p->vel[2] -= grav; + + break; + } + + case pt_txexplode: + { + p.alpha -= 345.f * frametime; + p.scale += 135.f * frametime; + p.angle += 0.75f * frametime * (p.param0 == 0 ? 1.f : -1.f); + + break; + } + + case pt_txsmoke: + { + p.alpha -= 75.f * frametime; + p.scale += 47.f * frametime; + + break; + } + + case pt_lightning: + { + p.alpha -= 87.f * frametime; + p.scale -= 33.f * frametime; + + break; + } + + case pt_teleport: + { + p.alpha -= 85.f * frametime; + p.scale -= 0.1f * frametime; + + break; + } + + case pt_rock: + { + p.angle += 25.f * frametime * (p.param0 == 0 ? 1.f : -1.f); + + break; + } + + case pt_gunsmoke: + { + p.alpha -= 105.f * frametime; + p.scale += 68.f * frametime; + p.org[2] += 18.f * frametime; + break; + } - case pt_grav: - case pt_slowgrav: p->vel[2] -= grav; break; + default: + { + break; + } } - } + }); } /* @@ -968,159 +1602,82 @@ CL_RunParticles */ void R_DrawParticles() { - particle_t* p; - float scale; - vec3_t up; - - vec3_t right; - - vec3_t p_up; - - vec3_t p_right; - - vec3_t p_upright; // johnfitz -- p_ vectors - GLubyte color[4]; - - GLubyte* c; // johnfitz -- particle transparency - // johnfitz - // float alpha; //johnfitz -- particle transparency - if(!r_particles.value) { return; } - // ericw -- avoid empty glBegin(),glEnd() pair below; causes issues - // on AMD - if(!active_particles) - { - return; - } - + vec3_t up; VectorScale(vup, 1.5, up); - VectorScale(vright, 1.5, right); - GL_Bind(particletexture); - glEnable(GL_BLEND); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glDepthMask(GL_FALSE); // johnfitz -- fix for particle z-buffer bug + vec3_t right; + VectorScale(vright, 1.5, right); - if(r_quadparticles.value) // johnitz -- quads save fillrate - { - glBegin(GL_QUADS); - for(p = active_particles; p; p = p->next) - { - // hack a scale up to keep particles from disapearing - scale = (p->org[0] - r_origin[0]) * vpn[0] + - (p->org[1] - r_origin[1]) * vpn[1] + - (p->org[2] - r_origin[2]) * vpn[2]; - if(scale < 20) - { - scale = 1 + 0.08; // johnfitz -- added .08 to be consistent - } - else - { - scale = 1 + scale * 0.004; - } + using namespace quake::util; - scale /= 2.0; // quad is half the size of triangle + const auto glmUp = toVec3(up); + const auto glmRight = toVec3(right); + const auto glmROrigin = toVec3(r_origin); - scale *= texturescalefactor; // johnfitz -- compensate for - // apparent size of different - // particle textures + // TODO VR: this could be optimized a lot + // https://community.khronos.org/t/drawing-my-quads-faster/61312/2 + pMgr.forBuffers([&](gltexture_t* texture, const ImageData& imageData, + ParticleBuffer& pBuffer) { + (void)imageData; - // TODO VR: global particle scale - if(p->type == ptype_t::pt_explode || - p->type == ptype_t::pt_explode2) - { - scale *= 1.2f; - } - else - { - scale *= 0.6f; - } + GL_Bind(texture); + glEnable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDepthMask(GL_FALSE); // johnfitz -- fix for particle z-buffer bug + glBegin(GL_QUADS); + pBuffer.forActive([&](particle_t& p) { // johnfitz -- particle transparency and fade out - c = (GLubyte*)&d_8to24table[(int)p->color]; + GLubyte* c = (GLubyte*)&d_8to24table[(int)p.color]; + + GLubyte color[4]; color[0] = c[0]; color[1] = c[1]; color[2] = c[2]; - // alpha = CLAMP(0, p->die + 0.5 - cl.time, 1); - color[3] = 255; //(int)(alpha * 255); - glColor4ubv(color); - // johnfitz + color[3] = p.alpha > 0 ? p.alpha : 0; - glTexCoord2f(0, 0); - glVertex3fv(p->org); - - glTexCoord2f(0.5, 0); - VectorMA(p->org, scale, up, p_up); - glVertex3fv(p_up); - - glTexCoord2f(0.5, 0.5); - VectorMA(p_up, scale, right, p_upright); - glVertex3fv(p_upright); + glColor4ubv(color); - glTexCoord2f(0, 0.5); - VectorMA(p->org, scale, right, p_right); - glVertex3fv(p_right); + const auto xFwd = p.org - glmROrigin; - rs_particles++; // johnfitz //FIXME: just use r_numparticles - } - glEnd(); - } - else // johnitz -- triangles save verts - { - glBegin(GL_TRIANGLES); - for(p = active_particles; p; p = p->next) - { - // hack a scale up to keep particles from disapearing - scale = (p->org[0] - r_origin[0]) * vpn[0] + - (p->org[1] - r_origin[1]) * vpn[1] + - (p->org[2] - r_origin[2]) * vpn[2]; - if(scale < 20) - { - scale = 1 + 0.08; // johnfitz -- added .08 to be consistent - } - else - { - scale = 1 + scale * 0.004; - } + // TODO VR: `glm::rotate` is the bottleneck in debug mode (!) + const auto xUp = glm::rotate(glmUp, p.angle, xFwd); + const auto xRight = glm::rotate(glmRight, p.angle, xFwd); - scale *= texturescalefactor; // johnfitz -- compensate for - // apparent size of different - // particle textures - - // johnfitz -- particle transparency and fade out - c = (GLubyte*)&d_8to24table[(int)p->color]; - color[0] = c[0]; - color[1] = c[1]; - color[2] = c[2]; - // alpha = CLAMP(0, p->die + 0.5 - cl.time, 1); - color[3] = 255; //(int)(alpha * 255); - glColor4ubv(color); - // johnfitz + const auto halfScale = p.scale / 2.f; + const auto xLeft = -xRight; + const auto xDown = -xUp; + const auto xUpLeft = p.org + halfScale * xUp + halfScale * xLeft; + const auto xUpRight = p.org + halfScale * xUp + halfScale * xRight; + const auto xDownLeft = + p.org + halfScale * xDown + halfScale * xLeft; + const auto xDownRight = + p.org + halfScale * xDown + halfScale * xRight; glTexCoord2f(0, 0); - glVertex3fv(p->org); + glVertex3fv(glm::value_ptr(xDownLeft)); glTexCoord2f(1, 0); - VectorMA(p->org, scale, up, p_up); - glVertex3fv(p_up); + glVertex3fv(glm::value_ptr(xUpLeft)); - glTexCoord2f(0, 1); - VectorMA(p->org, scale, right, p_right); - glVertex3fv(p_right); + glTexCoord2f(1, 1); + glVertex3fv(glm::value_ptr(xUpRight)); - rs_particles++; // johnfitz //FIXME: just use r_numparticles - } + glTexCoord2f(0, 1); + glVertex3fv(glm::value_ptr(xDownRight)); + }); glEnd(); - } - glDepthMask(GL_TRUE); // johnfitz -- fix for particle z-buffer bug - glDisable(GL_BLEND); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glColor3f(1, 1, 1); + glDepthMask(GL_TRUE); // johnfitz -- fix for particle z-buffer bug + glDisable(GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glColor3f(1, 1, 1); + }); } @@ -1131,94 +1688,35 @@ R_DrawParticles_ShowTris -- johnfitz */ void R_DrawParticles_ShowTris() { - particle_t* p; - float scale; - vec3_t up; - - vec3_t right; - - vec3_t p_up; - - vec3_t p_right; - - vec3_t p_upright; - - if(!r_particles.value) { return; } + vec3_t up; VectorScale(vup, 1.5, up); - VectorScale(vright, 1.5, right); - if(r_quadparticles.value) - { - for(p = active_particles; p; p = p->next) - { - glBegin(GL_TRIANGLE_FAN); - - // hack a scale up to keep particles from disapearing - scale = (p->org[0] - r_origin[0]) * vpn[0] + - (p->org[1] - r_origin[1]) * vpn[1] + - (p->org[2] - r_origin[2]) * vpn[2]; - if(scale < 20) - { - scale = 1 + 0.08; // johnfitz -- added .08 to be consistent - } - else - { - scale = 1 + scale * 0.004; - } - - scale /= 2.0; // quad is half the size of triangle - - scale *= texturescalefactor; // compensate for apparent size of - // different particle textures + vec3_t right; + VectorScale(vright, 1.5, right); - glVertex3fv(p->org); + glBegin(GL_TRIANGLES); + forActiveParticles([&](particle_t& p) { + (void)p; - VectorMA(p->org, scale, up, p_up); - glVertex3fv(p_up); + // TODO VR: rewrite + /* + const float scale = p.scale; - VectorMA(p_up, scale, right, p_upright); - glVertex3fv(p_upright); + glVertex3fv(glm::value_ptr(p.org)); - VectorMA(p->org, scale, right, p_right); - glVertex3fv(p_right); + vec3_t p_up; + VectorMA(p.org, scale, up, p_up); + glVertex3fv(glm::value_ptr(p_up)); - glEnd(); - } - } - else - { - glBegin(GL_TRIANGLES); - for(p = active_particles; p; p = p->next) - { - // hack a scale up to keep particles from disapearing - scale = (p->org[0] - r_origin[0]) * vpn[0] + - (p->org[1] - r_origin[1]) * vpn[1] + - (p->org[2] - r_origin[2]) * vpn[2]; - if(scale < 20) - { - scale = 1 + 0.08; // johnfitz -- added .08 to be consistent - } - else - { - scale = 1 + scale * 0.004; - } - - scale *= texturescalefactor; // compensate for apparent size of - // different particle textures - - glVertex3fv(p->org); - - VectorMA(p->org, scale, up, p_up); - glVertex3fv(p_up); - - VectorMA(p->org, scale, right, p_right); - glVertex3fv(p_right); - } - glEnd(); - } + vec3_t p_right; + VectorMA(p.org, scale, right, p_right); + glVertex3fv(glm::value_ptr(p_right)); + */ + }); + glEnd(); } diff --git a/Quake/r_sprite.cpp b/Quake/r_sprite.cpp index 6e7be284..3cca8298 100644 --- a/Quake/r_sprite.cpp +++ b/Quake/r_sprite.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/r_world.cpp b/Quake/r_world.cpp index e3308c5c..fe89f74c 100644 --- a/Quake/r_world.cpp +++ b/Quake/r_world.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -226,7 +227,7 @@ R_BackFaceCull -- johnfitz -- returns true if the surface is facing away from vieworg ================ */ -qboolean R_BackFaceCull(msurface_t* surf) +bool R_BackFaceCull(msurface_t* surf) { double dot; @@ -490,7 +491,7 @@ void R_DrawTextureChains_Glow(qmodel_t* model, entity_t* ent, texchain_t chain) msurface_t* s; texture_t* t; gltexture_t* glt; - qboolean bound; + bool bound; for(i = 0; i < model->numtextures; i++) { @@ -622,7 +623,7 @@ void R_DrawTextureChains_Multitexture( msurface_t* s; texture_t* t; float* v; - qboolean bound; + bool bound; for(i = 0; i < model->numtextures; i++) { @@ -688,7 +689,7 @@ void R_DrawTextureChains_NoTexture(qmodel_t* model, texchain_t chain) int i; msurface_t* s; texture_t* t; - qboolean bound; + bool bound; for(i = 0; i < model->numtextures; i++) { @@ -730,7 +731,7 @@ void R_DrawTextureChains_TextureOnly( int i; msurface_t* s; texture_t* t; - qboolean bound; + bool bound; for(i = 0; i < model->numtextures; i++) { @@ -806,7 +807,7 @@ void R_DrawTextureChains_Water(qmodel_t* model, entity_t* ent, texchain_t chain) msurface_t* s; texture_t* t; glpoly_t* p; - qboolean bound; + bool bound; float entalpha; if(r_drawflat_cheatsafe || r_lightmap_cheatsafe) @@ -1087,7 +1088,7 @@ void R_DrawTextureChains_GLSL(qmodel_t* model, entity_t* ent, texchain_t chain) int i; msurface_t* s; texture_t* t; - qboolean bound; + bool bound; int lastlightmap; gltexture_t* fullbright = nullptr; float entalpha; diff --git a/Quake/render.hpp b/Quake/render.hpp index 3f5e330f..b8f88486 100644 --- a/Quake/render.hpp +++ b/Quake/render.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -54,7 +55,7 @@ typedef struct efrag_s typedef struct entity_s { - qboolean forcelink; // model changed + bool forcelink; // model changed int update_type; @@ -160,10 +161,12 @@ void R_NewMap(void); void R_ParseParticleEffect(void); +void R_ParseParticle2Effect(void); void R_RunParticleEffect(vec3_t org, vec3_t dir, int color, int count); +void R_RunParticle2Effect(vec3_t org, vec3_t dir, int preset, int count); +void R_RunParticleEffect_BulletPuff(vec3_t org, vec3_t dir, int color, int count); void R_RocketTrail(vec3_t start, vec3_t end, int type); void R_EntityParticles(entity_t* ent); -void R_BlobExplosion(vec3_t org); void R_ParticleExplosion(vec3_t org); void R_ParticleExplosion2(vec3_t org, int colorStart, int colorLength); void R_LavaSplash(vec3_t org); @@ -176,7 +179,7 @@ void R_PushDlights(void); // surface cache related // extern int reinit_surfcache; // if 1, surface cache is currently empty and -extern qboolean r_cache_thrash; // set if thrashing the surface cache +extern bool r_cache_thrash; // set if thrashing the surface cache int D_SurfaceCacheForRes(int width, int height); void D_FlushCaches(void); diff --git a/Quake/sbar.cpp b/Quake/sbar.cpp index 5e273a86..2bd05f86 100644 --- a/Quake/sbar.cpp +++ b/Quake/sbar.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -46,7 +47,7 @@ qpic_t* sb_face_quad; qpic_t* sb_face_invuln; qpic_t* sb_face_invis_invuln; -qboolean sb_showscores; +bool sb_showscores; int sb_lines; // scan lines to draw diff --git a/Quake/sbar.hpp b/Quake/sbar.hpp index b73cb76f..95ff9dbf 100644 --- a/Quake/sbar.hpp +++ b/Quake/sbar.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/screen.hpp b/Quake/screen.hpp index 40dbd9e9..d01f2d9c 100644 --- a/Quake/screen.hpp +++ b/Quake/screen.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -48,8 +49,8 @@ extern float scr_conlines; // lines of console to display extern int sb_lines; extern int clearnotify; // set to 0 whenever notify text is drawn -extern qboolean scr_disabled_for_loading; -extern qboolean scr_skipupdate; +extern bool scr_disabled_for_loading; +extern bool scr_skipupdate; extern cvar_t scr_viewsize; diff --git a/Quake/server.hpp b/Quake/server.hpp index d6f73ee9..ea0bb8ca 100644 --- a/Quake/server.hpp +++ b/Quake/server.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -31,7 +32,7 @@ typedef struct int maxclientslimit; struct client_s* clients; // [maxclients] int serverflags; // episode completion information - qboolean changelevel_issued; // cleared when at SV_SpawnServer + bool changelevel_issued; // cleared when at SV_SpawnServer } server_static_t; //============================================================================= @@ -44,10 +45,10 @@ typedef enum typedef struct { - qboolean active; // false if only a net client + bool active; // false if only a net client - qboolean paused; - qboolean loadgame; // handle connections specially + bool paused; + bool loadgame; // handle connections specially double time; @@ -88,10 +89,10 @@ typedef struct typedef struct client_s { - qboolean active; // false = client is free - qboolean spawned; // false = don't send datagrams - qboolean dropasap; // has been told to go to another level - qboolean sendsignon; // only valid before spawned + bool active; // false = client is free + bool spawned; // false = don't send datagrams + bool dropasap; // has been told to go to another level + bool sendsignon; // only valid before spawned double last_message; // reliable messages must be sent // periodically @@ -198,11 +199,14 @@ extern edict_t* sv_player; void SV_Init(void); -void SV_StartParticle(vec3_t org, vec3_t dir, int color, int count); +void SV_StartParticle( + const vec3_t org, const vec3_t dir, const int color, const int count); +void SV_StartParticle2( + const vec3_t org, const vec3_t dir, const int preset, const int count); void SV_StartSound(edict_t* entity, int channel, const char* sample, int volume, float attenuation); -void SV_DropClient(qboolean crash); +void SV_DropClient(bool crash); void SV_SendClientMessages(void); void SV_ClearDatagram(void); @@ -221,8 +225,8 @@ void SV_BroadcastPrintf(const char* fmt, ...) FUNC_PRINTF(1, 2); void SV_Physics(void); -qboolean SV_CheckBottom(edict_t* ent); -qboolean SV_movestep(edict_t* ent, vec3_t move, qboolean relink); +bool SV_CheckBottom(edict_t* ent); +bool SV_movestep(edict_t* ent, vec3_t move, bool relink); void SV_WriteClientdataToMessage(edict_t* ent, sizebuf_t* msg); diff --git a/Quake/snd_codec.cpp b/Quake/snd_codec.cpp index e47943fe..68c6839e 100644 --- a/Quake/snd_codec.cpp +++ b/Quake/snd_codec.cpp @@ -279,7 +279,7 @@ snd_stream_t* S_CodecOpenStreamAny(const char* filename) return stream; } -qboolean S_CodecForwardStream(snd_stream_t* stream, unsigned int type) +bool S_CodecForwardStream(snd_stream_t* stream, unsigned int type) { snd_codec_t* codec = codecs; @@ -321,7 +321,7 @@ snd_stream_t* S_CodecUtilOpen(const char* filename, snd_codec_t* codec) { snd_stream_t* stream; FILE* handle; - qboolean pak; + bool pak; long length; /* Try to open the file */ diff --git a/Quake/snd_codec.hpp b/Quake/snd_codec.hpp index db7518f8..43307eb0 100644 --- a/Quake/snd_codec.hpp +++ b/Quake/snd_codec.hpp @@ -50,7 +50,7 @@ typedef struct snd_codec_s snd_codec_t; typedef struct snd_stream_s { fshandle_t fh; - qboolean pak; + bool pak; char name[MAX_QPATH]; /* name of the source file */ snd_info_t info; stream_status_t status; diff --git a/Quake/snd_codeci.hpp b/Quake/snd_codeci.hpp index 9038180e..1a9de816 100644 --- a/Quake/snd_codeci.hpp +++ b/Quake/snd_codeci.hpp @@ -27,9 +27,9 @@ #define _SND_CODECI_H_ /* Codec internals */ -typedef qboolean (*CODEC_INIT)(void); +typedef bool (*CODEC_INIT)(void); typedef void (*CODEC_SHUTDOWN)(void); -typedef qboolean (*CODEC_OPEN)(snd_stream_t* stream); +typedef bool (*CODEC_OPEN)(snd_stream_t* stream); typedef int (*CODEC_READ)(snd_stream_t* stream, int bytes, void* buffer); typedef int (*CODEC_REWIND)(snd_stream_t* stream); typedef void (*CODEC_CLOSE)(snd_stream_t* stream); @@ -37,7 +37,7 @@ typedef void (*CODEC_CLOSE)(snd_stream_t* stream); struct snd_codec_s { unsigned int type; /* handled data type. (1U << n) */ - qboolean initialized; /* init succeedded */ + bool initialized; /* init succeedded */ const char* ext; /* expected extension */ CODEC_INIT initialize; CODEC_SHUTDOWN shutdown; @@ -48,7 +48,7 @@ struct snd_codec_s snd_codec_t* next; }; -qboolean S_CodecForwardStream(snd_stream_t* stream, unsigned int type); +bool S_CodecForwardStream(snd_stream_t* stream, unsigned int type); /* Forward a stream to another codec of 'type' type. */ #endif /* _SND_CODECI_H_ */ diff --git a/Quake/snd_dma.cpp b/Quake/snd_dma.cpp index ec70a503..0d271454 100644 --- a/Quake/snd_dma.cpp +++ b/Quake/snd_dma.cpp @@ -4,6 +4,7 @@ Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2011 O. Sezer Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -43,7 +44,7 @@ channel_t snd_channels[MAX_CHANNELS]; int total_channels; static int snd_blocked = 0; -static qboolean snd_initialized = false; +static bool snd_initialized = false; static dma_t sn; volatile dma_t* shm = nullptr; @@ -68,7 +69,7 @@ static int num_sfx; static sfx_t* ambient_sfx[NUM_AMBIENTS]; -static qboolean sound_started = false; +static bool sound_started = false; cvar_t bgmvolume = {"bgmvolume", "1", CVAR_ARCHIVE}; cvar_t sfxvolume = {"volume", "0.7", CVAR_ARCHIVE}; @@ -588,7 +589,7 @@ void S_StopSound(int entnum, int entchannel) } } -void S_StopAllSounds(qboolean clear) +void S_StopAllSounds(bool clear) { int i; diff --git a/Quake/snd_flac.cpp b/Quake/snd_flac.cpp index 5066e546..3e943769 100644 --- a/Quake/snd_flac.cpp +++ b/Quake/snd_flac.cpp @@ -233,7 +233,7 @@ static void flac_meta_func(const FLAC__StreamDecoder* decoder, } -static qboolean S_FLAC_CodecInitialize(void) +static bool S_FLAC_CodecInitialize(void) { return true; } @@ -242,7 +242,7 @@ static void S_FLAC_CodecShutdown(void) { } -static qboolean S_FLAC_CodecOpenStream(snd_stream_t* stream) +static bool S_FLAC_CodecOpenStream(snd_stream_t* stream) { flacfile_t* ff; int rc; diff --git a/Quake/snd_mikmod.cpp b/Quake/snd_mikmod.cpp index 23e73eb6..33cbc62e 100644 --- a/Quake/snd_mikmod.cpp +++ b/Quake/snd_mikmod.cpp @@ -79,7 +79,7 @@ static BOOL MIK_Eof(MREADER* r) return FS_feof(((mik_priv_t*)r)->fh); } -static qboolean S_MIKMOD_CodecInitialize(void) +static bool S_MIKMOD_CodecInitialize(void) { if(mikmod_codec.initialized) return true; @@ -127,7 +127,7 @@ static void S_MIKMOD_CodecShutdown(void) } } -static qboolean S_MIKMOD_CodecOpenStream(snd_stream_t* stream) +static bool S_MIKMOD_CodecOpenStream(snd_stream_t* stream) { mik_priv_t* priv; diff --git a/Quake/snd_mix.cpp b/Quake/snd_mix.cpp index 567b07d1..cd8699e1 100644 --- a/Quake/snd_mix.cpp +++ b/Quake/snd_mix.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2011 O. Sezer Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/snd_modplug.cpp b/Quake/snd_modplug.cpp index d3990289..61c91bac 100644 --- a/Quake/snd_modplug.cpp +++ b/Quake/snd_modplug.cpp @@ -49,7 +49,7 @@ static void S_MODPLUG_SetSettings(snd_stream_t* stream) } } -static qboolean S_MODPLUG_CodecInitialize(void) +static bool S_MODPLUG_CodecInitialize(void) { return true; } @@ -58,7 +58,7 @@ static void S_MODPLUG_CodecShutdown(void) { } -static qboolean S_MODPLUG_CodecOpenStream(snd_stream_t* stream) +static bool S_MODPLUG_CodecOpenStream(snd_stream_t* stream) { /* need to load the whole file into memory and pass it to libmodplug */ const long len = FS_filelength(&stream->fh); diff --git a/Quake/snd_mp3.cpp b/Quake/snd_mp3.cpp index 4899fb51..a9394793 100644 --- a/Quake/snd_mp3.cpp +++ b/Quake/snd_mp3.cpp @@ -272,7 +272,7 @@ static int mp3_madseek(snd_stream_t* stream, unsigned long offset) size_t initial_bitrate = p->Frame.header.bitrate; size_t consumed = 0; int vbr = 0; /* Variable Bit Rate, bool */ - qboolean depadded = false; + bool depadded = false; unsigned long to_skip_samples = 0; /* Reset all */ @@ -379,7 +379,7 @@ static int mp3_madseek(snd_stream_t* stream, unsigned long offset) return -1; } -static qboolean S_MP3_CodecInitialize(void) +static bool S_MP3_CodecInitialize(void) { return true; } @@ -388,7 +388,7 @@ static void S_MP3_CodecShutdown(void) { } -static qboolean S_MP3_CodecOpenStream(snd_stream_t* stream) +static bool S_MP3_CodecOpenStream(snd_stream_t* stream) { int err; diff --git a/Quake/snd_mp3tag.cpp b/Quake/snd_mp3tag.cpp index 408f0a07..5ad278ef 100644 --- a/Quake/snd_mp3tag.cpp +++ b/Quake/snd_mp3tag.cpp @@ -23,7 +23,7 @@ #include "snd_codec.hpp" #include "q_ctype.hpp" -static inline qboolean is_id3v1(const unsigned char* data, long length) +static inline bool is_id3v1(const unsigned char* data, long length) { /* http://id3.org/ID3v1 : 3 bytes "TAG" identifier and 125 bytes tag data */ @@ -33,7 +33,7 @@ static inline qboolean is_id3v1(const unsigned char* data, long length) } return true; } -static qboolean is_id3v2(const unsigned char* data, size_t length) +static bool is_id3v2(const unsigned char* data, size_t length) { /* ID3v2 header is 10 bytes: http://id3.org/id3v2.4.0-structure */ /* bytes 0-2: "ID3" identifier */ @@ -76,7 +76,7 @@ static long get_id3v2_len(const unsigned char* data, long length) } return size; } -static qboolean is_apetag(const unsigned char* data, size_t length) +static bool is_apetag(const unsigned char* data, size_t length) { /* http://wiki.hydrogenaud.io/index.php?title=APEv2_specification * Header/footer is 32 bytes: bytes 0-7 ident, bytes 8-11 version, @@ -147,14 +147,14 @@ static inline long get_lyrics3v2_len(const unsigned char* data, long length) if(length != 6) return 0; return strtol((const char*)data, nullptr, 10) + 15; } -static inline qboolean verify_lyrics3v2(const unsigned char* data, long length) +static inline bool verify_lyrics3v2(const unsigned char* data, long length) { if(length < 11) return false; if(memcmp(data, "LYRICSBEGIN", 11) == 0) return true; return false; } #define MMTAG_PARANOID -static qboolean is_musicmatch(const unsigned char* data, long length) +static bool is_musicmatch(const unsigned char* data, long length) { /* From docs/musicmatch.txt in id3lib: https://sourceforge.net/projects/id3lib/ Overall tag structure: @@ -429,7 +429,7 @@ int mp3_skiptags(snd_stream_t* stream) * or musicmatch tags, hence the loop here.. */ c_ape = 0; c_lyr = 0; - for(;;) + while(true) { if(!c_lyr) { diff --git a/Quake/snd_mpg123.cpp b/Quake/snd_mpg123.cpp index 94a61653..96377eee 100644 --- a/Quake/snd_mpg123.cpp +++ b/Quake/snd_mpg123.cpp @@ -53,7 +53,7 @@ static off_t mp3_seek(void* f, off_t offset, int whence) return (off_t)FS_ftell((fshandle_t*)f); } -static qboolean S_MP3_CodecInitialize(void) +static bool S_MP3_CodecInitialize(void) { if(!mp3_codec.initialized) { @@ -76,7 +76,7 @@ static void S_MP3_CodecShutdown(void) } } -static qboolean S_MP3_CodecOpenStream(snd_stream_t* stream) +static bool S_MP3_CodecOpenStream(snd_stream_t* stream) { long rate = 0; int encoding = 0, channels = 0; diff --git a/Quake/snd_opus.cpp b/Quake/snd_opus.cpp index 65889c88..440c8aa8 100644 --- a/Quake/snd_opus.cpp +++ b/Quake/snd_opus.cpp @@ -70,7 +70,7 @@ static const OpusFileCallbacks opc_qfs = { (int (*)(void*, opus_int64, int))opc_fseek, (opus_int64(*)(void*))opc_ftell, (int (*)(void*))opc_fclose}; -static qboolean S_OPUS_CodecInitialize(void) +static bool S_OPUS_CodecInitialize(void) { return true; } @@ -79,7 +79,7 @@ static void S_OPUS_CodecShutdown(void) { } -static qboolean S_OPUS_CodecOpenStream(snd_stream_t* stream) +static bool S_OPUS_CodecOpenStream(snd_stream_t* stream) { OggOpusFile* opFile; const OpusHead* op_info; diff --git a/Quake/snd_sdl.cpp b/Quake/snd_sdl.cpp index 295b4c51..d8367ed3 100644 --- a/Quake/snd_sdl.cpp +++ b/Quake/snd_sdl.cpp @@ -5,6 +5,7 @@ * Copyright (C) 1999-2005 Id Software, Inc. * Copyright (C) 2005-2012 O.Sezer * Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -88,7 +89,7 @@ static void SDLCALL paint_audio(void* unused, Uint8* stream, int len) } } -qboolean SNDDMA_Init(dma_t* dma) +bool SNDDMA_Init(dma_t* dma) { SDL_AudioSpec desired; int tmp; diff --git a/Quake/snd_umx.cpp b/Quake/snd_umx.cpp index 76e747f4..ea8681d2 100644 --- a/Quake/snd_umx.cpp +++ b/Quake/snd_umx.cpp @@ -346,7 +346,7 @@ static int process_upkg(fshandle_t* f, int32_t* ofs, int32_t* objsize) return probe_umx(f, (struct upkg_hdr*)header, ofs, objsize); } -static qboolean S_UMX_CodecInitialize(void) +static bool S_UMX_CodecInitialize(void) { return true; } @@ -355,7 +355,7 @@ static void S_UMX_CodecShutdown(void) { } -static qboolean S_UMX_CodecOpenStream(snd_stream_t* stream) +static bool S_UMX_CodecOpenStream(snd_stream_t* stream) { int type; int32_t ofs = 0, size = 0; diff --git a/Quake/snd_vorbis.cpp b/Quake/snd_vorbis.cpp index 95a4f966..4305dd3e 100644 --- a/Quake/snd_vorbis.cpp +++ b/Quake/snd_vorbis.cpp @@ -61,7 +61,7 @@ static ov_callbacks ovc_qfs = { (int (*)(void*, ogg_int64_t, int))ovc_fseek, (int (*)(void*))ovc_fclose, (long (*)(void*))FS_ftell}; -static qboolean S_VORBIS_CodecInitialize(void) +static bool S_VORBIS_CodecInitialize(void) { return true; } @@ -70,7 +70,7 @@ static void S_VORBIS_CodecShutdown(void) { } -static qboolean S_VORBIS_CodecOpenStream(snd_stream_t* stream) +static bool S_VORBIS_CodecOpenStream(snd_stream_t* stream) { OggVorbis_File* ovFile; vorbis_info* ovf_info; diff --git a/Quake/snd_wave.cpp b/Quake/snd_wave.cpp index 96ab99a7..1933fd8d 100644 --- a/Quake/snd_wave.cpp +++ b/Quake/snd_wave.cpp @@ -111,7 +111,7 @@ static int WAV_FindRIFFChunk(FILE* f, const char* chunk) WAV_ReadRIFFHeader ================= */ -static qboolean WAV_ReadRIFFHeader( +static bool WAV_ReadRIFFHeader( const char* name, FILE* file, snd_info_t* info) { char dump[16]; @@ -190,7 +190,7 @@ static qboolean WAV_ReadRIFFHeader( S_WAV_CodecOpenStream ================= */ -static qboolean S_WAV_CodecOpenStream(snd_stream_t* stream) +static bool S_WAV_CodecOpenStream(snd_stream_t* stream) { long start = stream->fh.start; @@ -245,7 +245,7 @@ static int S_WAV_CodecRewindStream(snd_stream_t* stream) return 0; } -static qboolean S_WAV_CodecInitialize(void) +static bool S_WAV_CodecInitialize(void) { return true; } diff --git a/Quake/snd_xmp.cpp b/Quake/snd_xmp.cpp index 416547dc..502e6c8b 100644 --- a/Quake/snd_xmp.cpp +++ b/Quake/snd_xmp.cpp @@ -44,7 +44,7 @@ static int S_XMP_StartPlay(snd_stream_t* stream) return xmp_start_player((xmp_context)stream->priv, stream->info.rate, fmt); } -static qboolean S_XMP_CodecInitialize(void) +static bool S_XMP_CodecInitialize(void) { return true; } @@ -53,7 +53,7 @@ static void S_XMP_CodecShutdown(void) { } -static qboolean S_XMP_CodecOpenStream(snd_stream_t* stream) +static bool S_XMP_CodecOpenStream(snd_stream_t* stream) { /* need to load the whole file into memory and pass it to libxmp * using xmp_load_module_from_memory() which requires libxmp >= 4.2. diff --git a/Quake/sv_main.cpp b/Quake/sv_main.cpp index e1dc94cf..920ac74e 100644 --- a/Quake/sv_main.cpp +++ b/Quake/sv_main.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -31,7 +32,7 @@ static char localmodels[MAX_MODELS][8]; // inline model names for precache int sv_protocol = PROTOCOL_FITZQUAKE; // johnfitz -extern qboolean pr_alpha_supported; // johnfitz +extern bool pr_alpha_supported; // johnfitz //============================================================================ @@ -152,23 +153,21 @@ SV_StartParticle Make sure the event gets sent to all clients ================== */ -void SV_StartParticle(vec3_t org, vec3_t dir, int color, int count) +void SV_StartParticle( + const vec3_t org, const vec3_t dir, const int color, const int count) { - int i; - - int v; - if(sv.datagram.cursize > MAX_DATAGRAM - 16) { return; } + MSG_WriteByte(&sv.datagram, svc_particle); MSG_WriteCoord(&sv.datagram, org[0], sv.protocolflags); MSG_WriteCoord(&sv.datagram, org[1], sv.protocolflags); MSG_WriteCoord(&sv.datagram, org[2], sv.protocolflags); - for(i = 0; i < 3; i++) + for(int i = 0; i < 3; i++) { - v = dir[i] * 16; + int v = dir[i] * 16; if(v > 127) { v = 127; @@ -183,6 +182,43 @@ void SV_StartParticle(vec3_t org, vec3_t dir, int color, int count) MSG_WriteByte(&sv.datagram, color); } +// TODO VR: repetition with above +/* +================== +SV_StartParticle2 + +Make sure the event gets sent to all clients +================== +*/ +void SV_StartParticle2( + const vec3_t org, const vec3_t dir, const int preset, const int count) +{ + if(sv.datagram.cursize > MAX_DATAGRAM - 16) + { + return; + } + + MSG_WriteByte(&sv.datagram, svc_particle2); + MSG_WriteCoord(&sv.datagram, org[0], sv.protocolflags); + MSG_WriteCoord(&sv.datagram, org[1], sv.protocolflags); + MSG_WriteCoord(&sv.datagram, org[2], sv.protocolflags); + for(int i = 0; i < 3; i++) + { + int v = dir[i] * 16; + if(v > 127) + { + v = 127; + } + else if(v < -128) + { + v = -128; + } + MSG_WriteChar(&sv.datagram, v); + } + MSG_WriteByte(&sv.datagram, preset); + MSG_WriteShort(&sv.datagram, count); +} + /* ================== SV_StartSound @@ -628,7 +664,7 @@ SV_VisibleToClient -- johnfitz PVS test encapsulated in a nice function ============= */ -qboolean SV_VisibleToClient( +bool SV_VisibleToClient( edict_t* client, edict_t* test, qmodel_t* worldmodel) { byte* pvs; @@ -1268,7 +1304,7 @@ void SV_WriteClientdataToMessage(edict_t* ent, sizebuf_t* msg) SV_SendClientDatagram ======================= */ -qboolean SV_SendClientDatagram(client_t* client) +bool SV_SendClientDatagram(client_t* client) { byte buf[MAX_DATAGRAM]; sizebuf_t msg; diff --git a/Quake/sv_move.cpp b/Quake/sv_move.cpp index 05b9e57d..72c73f31 100644 --- a/Quake/sv_move.cpp +++ b/Quake/sv_move.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -36,7 +37,7 @@ is not a staircase. */ int c_yes, c_no; -qboolean SV_CheckBottom(edict_t* ent) +bool SV_CheckBottom(edict_t* ent) { vec3_t mins; @@ -131,7 +132,7 @@ possible, no move is done, false is returned, and pr_global_struct->trace_normal is set to the normal of the blocking wall ============= */ -qboolean SV_movestep(edict_t* ent, vec3_t move, qboolean relink) +bool SV_movestep(edict_t* ent, vec3_t move, bool relink) { float dz; vec3_t oldorg; @@ -281,7 +282,7 @@ facing it. ====================== */ void PF_changeyaw(); -qboolean SV_StepDirection(edict_t* ent, float yaw, float dist) +bool SV_StepDirection(edict_t* ent, float yaw, float dist) { vec3_t move; @@ -467,7 +468,7 @@ SV_CloseEnough ====================== */ -qboolean SV_CloseEnough(edict_t* ent, edict_t* goal, float dist) +bool SV_CloseEnough(edict_t* ent, edict_t* goal, float dist) { int i; diff --git a/Quake/sv_phys.cpp b/Quake/sv_phys.cpp index 934a71ae..436556ea 100644 --- a/Quake/sv_phys.cpp +++ b/Quake/sv_phys.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -26,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "world.hpp" #include "util.hpp" +#include #include /* @@ -140,7 +142,7 @@ in a frame. Not used for pushmove objects, because they must be exact. Returns false if the entity removed itself. ============= */ -qboolean SV_RunThink(edict_t* ent) +bool SV_RunThink(edict_t* ent) { float thinktime; float oldframe; // johnfitz @@ -782,7 +784,7 @@ void SV_CheckStuck(edict_t* ent) SV_CheckWater ============= */ -qboolean SV_CheckWater(edict_t* ent) +bool SV_CheckWater(edict_t* ent) { vec3_t point; int cont; @@ -1065,8 +1067,6 @@ Trigger hand-touching actions (e.g. pick up an item, press a button) void SV_Handtouch(edict_t* ent) { // TODO VR: cleanup, too much unnecessary tracing and work - - using namespace quake::util; // Utility constants @@ -1120,14 +1120,13 @@ void SV_Handtouch(edict_t* ent) vec3_t qMaxs; toQuakeVec3(qMaxs, maxs); - const auto traceCheck = [&](const trace_t& trace) { if(!trace.ent) { return; } - const auto handCollisionCheck = [&](vec3_t handPos) { + const auto handCollisionCheck = [&](const int hand, vec3_t handPos) { vec3_t aMin, aMax, bMin, bMax; VectorAdd(trace.ent->v.origin, trace.ent->v.mins, aMin); VectorAdd(trace.ent->v.origin, trace.ent->v.maxs, aMax); @@ -1136,12 +1135,13 @@ void SV_Handtouch(edict_t* ent) if(quake::util::boxIntersection(aMin, aMax, bMin, bMax)) { + ent->v.touchinghand = hand; SV_Impact(ent, trace.ent, &entvars_t::handtouch); } }; - handCollisionCheck(ent->v.handpos); - handCollisionCheck(ent->v.offhandpos); + handCollisionCheck(0, ent->v.offhandpos); + handCollisionCheck(1, ent->v.handpos); }; const auto endHandPosition = [&](vec3_t out, vec3_t handPos, @@ -1501,7 +1501,7 @@ will fall if the floor is pulled out from under them. */ void SV_Physics_Step(edict_t* ent) { - qboolean hitsound; + bool hitsound; // freefall if not onground if(!((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) diff --git a/Quake/sv_user.cpp b/Quake/sv_user.cpp index 46218c0f..03aca7cf 100644 --- a/Quake/sv_user.cpp +++ b/Quake/sv_user.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -37,7 +38,7 @@ float* angles; float* origin; float* velocity; -qboolean onground; +bool onground; usercmd_t cmd; @@ -620,6 +621,10 @@ void SV_ReadClientMove(usercmd_t* move) move->offhandvelmag = MSG_ReadFloat(); host_client->edict->v.offhandvelmag = move->offhandvelmag; + // muzzlepos + readVec(move->muzzlepos); + VectorCopy(move->muzzlepos, host_client->edict->v.muzzlepos); + // read movement move->forwardmove = MSG_ReadShort(); move->sidemove = MSG_ReadShort(); @@ -644,7 +649,7 @@ SV_ReadClientMessage Returns false if the client should be killed =================== */ -qboolean SV_ReadClientMessage() +bool SV_ReadClientMessage() { int ret; int ccmd; diff --git a/Quake/sys.hpp b/Quake/sys.hpp index 30f0099c..9dd874ee 100644 --- a/Quake/sys.hpp +++ b/Quake/sys.hpp @@ -1,6 +1,7 @@ /* Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/sys_sdl_unix.cpp b/Quake/sys_sdl_unix.cpp index 967103b0..88cc4fcf 100644 --- a/Quake/sys_sdl_unix.cpp +++ b/Quake/sys_sdl_unix.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -49,7 +50,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif -qboolean isDedicated; +bool isDedicated; cvar_t sys_throttle = {"sys_throttle", "0.02", CVAR_ARCHIVE}; #define MAX_HANDLES 32 /* johnfitz -- was 10 */ diff --git a/Quake/sys_sdl_win.cpp b/Quake/sys_sdl_win.cpp index 562fd153..196cd0b1 100644 --- a/Quake/sys_sdl_win.cpp +++ b/Quake/sys_sdl_win.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2005 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -45,8 +46,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif -qboolean isDedicated; -qboolean Win95, Win95old, WinNT, WinVista; +bool isDedicated; +bool Win95, Win95old, WinNT, WinVista; cvar_t sys_throttle = {"sys_throttle", "0.02", CVAR_ARCHIVE}; static HANDLE hinput, houtput; @@ -365,7 +366,7 @@ void Sys_Error(const char* error, ...) { PL_ErrorDialog(text); } - else + else { WriteFile(houtput, errortxt2, strlen(errortxt2), &dummy, nullptr); WriteFile(houtput, text, strlen(text), &dummy, nullptr); @@ -427,7 +428,7 @@ const char* Sys_ConsoleInput() DWORD numevents; - for(;;) + while(true) { if(GetNumberOfConsoleInputEvents(hinput, &numevents) == 0) { diff --git a/Quake/util.hpp b/Quake/util.hpp index eaf35747..1f4072e2 100644 --- a/Quake/util.hpp +++ b/Quake/util.hpp @@ -3,6 +3,7 @@ #include "debugapi.h" #include "q_stdinc.hpp" +#define GLM_FORCE_INLINE #include #include @@ -13,6 +14,17 @@ #include #include +#if !defined(QUAKE_FORCEINLINE) +#if defined(_MSC_VER) +#define QUAKE_FORCEINLINE __forceinline +#elif defined(__GNUC__) && __GNUC__ > 3 +// Clang also defines __GNUC__ (as 4) +#define QUAKE_FORCEINLINE inline __attribute__((__always_inline__)) +#else +#define QUAKE_FORCEINLINE inline +#endif +#endif + namespace quake::util { template @@ -45,12 +57,14 @@ namespace quake::util OutputDebugStringA(stringCatSeparated(separator, xs...).data()); } - [[nodiscard]] constexpr glm::vec3 toVec3(const vec3_t& v) noexcept + [[nodiscard]] QUAKE_FORCEINLINE constexpr glm::vec3 toVec3( + const vec3_t& v) noexcept { return {v[0], v[1], v[2]}; } - constexpr void toQuakeVec3(vec3_t out, const glm::vec3& v) noexcept + QUAKE_FORCEINLINE constexpr void toQuakeVec3( + vec3_t out, const glm::vec3& v) noexcept { out[0] = v[0]; out[1] = v[1]; @@ -63,11 +77,14 @@ namespace quake::util constexpr auto maxLen = 25; assert(((strlen(labels) <= maxLen) && ...)); - return std::array{(std::string(maxLen - strlen(labels), ' ') + labels)...}; + return std::array{ + (std::string(maxLen - strlen(labels), ' ') + labels)...}; } - [[nodiscard]] constexpr bool boxIntersection(const vec3_t& aMin, - const vec3_t& aMax, const vec3_t& bMin, const vec3_t& bMax) + template + [[nodiscard]] constexpr bool boxIntersection(const TVec3AMin& aMin, + const TVec3AMax& aMax, const TVec3BMin& bMin, const TVec3BMax& bMax) { return aMin[0] <= bMax[0] && // aMin[1] <= bMax[1] && // @@ -96,8 +113,33 @@ namespace std namespace glm { template - [[nodiscard]] T get(const glm::vec& v) noexcept + [[nodiscard]] QUAKE_FORCEINLINE T get(const glm::vec& v) noexcept { return v[I]; } + + // TODO VR: + [[nodiscard]] QUAKE_FORCEINLINE constexpr glm::vec3 operator+( + const glm::vec3& lhs, const vec3_t& rhs) noexcept + { + return {lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2]}; + } + + [[nodiscard]] QUAKE_FORCEINLINE constexpr glm::vec3 operator+( + const vec3_t& lhs, const glm::vec3& rhs) noexcept + { + return {lhs[0] + rhs[0], lhs[1] + rhs[1], lhs[2] + rhs[2]}; + } + + [[nodiscard]] QUAKE_FORCEINLINE constexpr glm::vec3 operator-( + const glm::vec3& lhs, const vec3_t& rhs) noexcept + { + return {lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2]}; + } + + [[nodiscard]] QUAKE_FORCEINLINE constexpr glm::vec3 operator-( + const vec3_t& lhs, const glm::vec3& rhs) noexcept + { + return {lhs[0] - rhs[0], lhs[1] - rhs[1], lhs[2] - rhs[2]}; + } } // namespace glm diff --git a/Quake/vid.hpp b/Quake/vid.hpp index 99c23672..921f54d4 100644 --- a/Quake/vid.hpp +++ b/Quake/vid.hpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -90,8 +91,8 @@ void VID_SyncCvars(void); void VID_Toggle(void); void* VID_GetWindow(void); -qboolean VID_HasMouseOrInputFocus(void); -qboolean VID_IsMinimized(void); +bool VID_HasMouseOrInputFocus(void); +bool VID_IsMinimized(void); void VID_Lock(void); #endif /* __VID_DEFS_H */ diff --git a/Quake/view.cpp b/Quake/view.cpp index 45d9c022..1e5267ca 100644 --- a/Quake/view.cpp +++ b/Quake/view.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -576,7 +577,7 @@ void V_UpdateBlend() int i; int j; - qboolean blend_changed; + bool blend_changed; V_CalcPowerupCshift(); @@ -701,14 +702,6 @@ CalcGunAngle void CalcGunAngle( const int wpnCvarEntry, entity_t* viewent, const vec3_t& handrot) { - float yaw; - - float pitch; - - float move; - static float oldyaw = 0; - static float oldpitch = 0; - // Skip everything if we're doing VR Controller aiming. if(vr_enabled.value && vr_aimmode.value == VrAimMode::e_CONTROLLER) { @@ -723,12 +716,14 @@ void CalcGunAngle( viewent->angles[PITCH] = -(handrot[PITCH]) + rotOfs[0]; viewent->angles[YAW] = handrot[YAW] + rotOfs[1]; viewent->angles[ROLL] = handrot[ROLL] + rotOfs[2]; + return; } - yaw = r_refdef.aimangles[YAW]; - pitch = -r_refdef.aimangles[PITCH]; + static float oldyaw = 0; + static float oldpitch = 0; + float yaw = r_refdef.aimangles[YAW]; yaw = angledelta(yaw - r_refdef.viewangles[YAW]) * 0.4; if(yaw > 10) { @@ -738,6 +733,8 @@ void CalcGunAngle( { yaw = -10; } + + float pitch = -r_refdef.aimangles[PITCH]; pitch = angledelta(-pitch - r_refdef.viewangles[PITCH]) * 0.4; if(pitch > 10) { @@ -747,7 +744,8 @@ void CalcGunAngle( { pitch = -10; } - move = host_frametime * 20; + + const float move = host_frametime * 20; if(yaw > oldyaw) { if(oldyaw + move < yaw) @@ -1153,30 +1151,7 @@ void V_CalcRefdef2Test() } else { - // No off-hand without VR - } - - // johnfitz -- removed all gun position fudging code (was used to keep - // gun from getting covered by sbar) MarkV -- restored this with - // r_viewmodel_quake cvar - if(r_viewmodel_quake.value) - { - if(scr_viewsize.value == 110) - { - view->origin[2] += 1; - } - else if(scr_viewsize.value == 100) - { - view->origin[2] += 2; - } - else if(scr_viewsize.value == 90) - { - view->origin[2] += 1; - } - else if(scr_viewsize.value == 80) - { - view->origin[2] += 0.5; - } + // No off-hand without VR. } view->model = Mod_ForName("progs/hand.mdl", true); diff --git a/Quake/view.hpp b/Quake/view.hpp index 7cc960cd..ba106d90 100644 --- a/Quake/view.hpp +++ b/Quake/view.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/vr.cpp b/Quake/vr.cpp index 341e055b..093c539d 100644 --- a/Quake/vr.cpp +++ b/Quake/vr.cpp @@ -4,6 +4,7 @@ #include "util.hpp" #include "openvr.hpp" +#define GLM_FORCE_INLINE #include #include #include @@ -105,9 +106,9 @@ struct // main screen & 2D drawing extern void SCR_SetUpToDrawConsole(); extern void SCR_UpdateScreenContent(); -extern qboolean scr_drawdialog; +extern bool scr_drawdialog; extern void SCR_DrawNotifyString(); -extern qboolean scr_drawloading; +extern bool scr_drawloading; extern void SCR_DrawLoading(); extern void SCR_CheckDrawCenterString(); extern void SCR_DrawRam(); @@ -593,7 +594,8 @@ void InitWeaponCVar(cvar_t* cvar, const char* name, int i, const char* value) void InitWeaponCVars(int i, const char* id, const char* offsetX, const char* offsetY, const char* offsetZ, const char* scale, const char* roll = "0.0", const char* pitch = "0.0", - const char* yaw = "0.0") + const char* yaw = "0.0", const char* muzzleOffsetX = "0.0", + const char* muzzleOffsetY = "0.0", const char* muzzleOffsetZ = "0.0") { // clang-format off constexpr const char* nameOffsetX = "vr_wofs_x_nn"; @@ -604,6 +606,9 @@ void InitWeaponCVars(int i, const char* id, const char* offsetX, constexpr const char* nameRoll = "vr_wofs_roll_nn"; constexpr const char* namePitch = "vr_wofs_pitch_nn"; constexpr const char* nameYaw = "vr_wofs_yaw_nn"; + constexpr const char* nameMuzzleOffsetX = "vr_wofs_muzzle_x_nn"; + constexpr const char* nameMuzzleOffsetY = "vr_wofs_muzzle_y_nn"; + constexpr const char* nameMuzzleOffsetZ = "vr_wofs_muzzle_z_nn"; InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON], nameOffsetX, i, offsetX); InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON + 1], nameOffsetY, i, offsetY); @@ -613,9 +618,13 @@ void InitWeaponCVars(int i, const char* id, const char* offsetX, InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON + 5], nameRoll, i, roll); InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON + 6], namePitch, i, pitch); InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON + 7], nameYaw, i, yaw); + InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON + 8], nameMuzzleOffsetX, i, muzzleOffsetX); + InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON + 9], nameMuzzleOffsetY, i, muzzleOffsetY); + InitWeaponCVar(&vr_weapon_offset[i * VARS_PER_WEAPON + 10], nameMuzzleOffsetZ, i, muzzleOffsetZ); // clang-format on } +// TODO VR: get rid of this void InitAllWeaponCVars() { // clang-format off @@ -699,6 +708,10 @@ void VID_VR_Init() InitAllWeaponCVars(); + // VR: Fix grenade model flags to enable smoke trail. + qmodel_t* test = Mod_ForName("progs/grenade.mdl", true); + test->flags |= EF_GRENADE; + // Set the cvar if invoked from a command line parameter { // int i = COM_CheckParm("-vr"); @@ -718,7 +731,9 @@ void VR_InitGame() // ---------------------------------------------------------------------------- vr::VRActiveActionSet_t vrActiveActionSet; + vr::VRActionSetHandle_t vrashDefault; + vr::VRActionHandle_t vrahLocomotion; vr::VRActionHandle_t vrahTurn; vr::VRActionHandle_t vrahFire; @@ -727,9 +742,11 @@ vr::VRActionHandle_t vrahPrevWeapon; vr::VRActionHandle_t vrahNextWeapon; vr::VRActionHandle_t vrahEscape; vr::VRActionHandle_t vrahSpeed; +vr::VRActionHandle_t vrahLeftHaptic; +vr::VRActionHandle_t vrahRightHaptic; -// TODO VR: implement haptic feedback -vr::VRActionHandle_t vrahHaptic; +vr::VRInputValueHandle_t vrivhLeft; +vr::VRInputValueHandle_t vrivhRight; static void VR_InitActionHandles() { @@ -766,11 +783,28 @@ static void VR_InitActionHandles() readHandle("/actions/default/in/NextWeapon", vrahNextWeapon); readHandle("/actions/default/in/Escape", vrahEscape); readHandle("/actions/default/in/Speed", vrahSpeed); - readHandle("/actions/default/out/Haptic", vrahHaptic); + readHandle("/actions/default/out/LeftHaptic", vrahLeftHaptic); + readHandle("/actions/default/out/RightHaptic", vrahRightHaptic); vrActiveActionSet.ulActionSet = vrashDefault; vrActiveActionSet.ulRestrictedToDevice = vr::k_ulInvalidInputValueHandle; vrActiveActionSet.nPriority = 0; + + // ----------------------------------------------------------------------- + // VR: Get handles to the controllers. + const auto readInputSourceHandle = [](const char* name, + vr::VRInputValueHandle_t& handle) { + const auto rc = vr::VRInput()->GetInputSourceHandle(name, &handle); + + if(rc != vr::EVRInputError::VRInputError_None) + { + Con_Printf("Failed to read Steam VR input source handle, rc = %d", + (int)rc); + } + }; + + readInputSourceHandle("/user/hand/left", vrivhLeft); + readInputSourceHandle("/user/hand/right", vrivhRight); } // ---------------------------------------------------------------------------- @@ -1391,6 +1425,11 @@ void VR_UpdateScreenContent() auto* hdr = (aliashdr_t*)Mod_Extradata(cl.viewent.model); Mod_Weapon(cl.viewent.model->name, hdr); + // auto* testhdr = (aliashdr_t*)Mod_Extradata(test); + // testhdr->flags |= EF_GRENADE; + // VectorScale(testhdr->scale_origin, 0.5f, + // testhdr->scale_origin); + // BModels cannot be scaled, doesnt work // qmodel_t* test = Mod_ForName("maps/b_shell1.bsp", true); // auto* testhdr = (aliashdr_t*)Mod_Extradata(test); @@ -1485,34 +1524,66 @@ void VR_AddOrientationToViewAngles(vec3_t angles) angles[ROLL] = orientation[ROLL]; } -void VR_ShowCrosshair() +void VR_CalcWeaponMuzzlePos(vec3_t out) { - vec3_t forward; + // TODO VR: + vec3_t forward; vec3_t up; - vec3_t right; - vec3_t start; - vec3_t end; + /* + vec3_t ofs = {// + vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON].value, + vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 1].value, + vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 2].value + + vr_gunmodely.value}; + */ - vec3_t impact; - float size; + vec3_t muzzleOfs = { + vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 8].value, + vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 9].value, + vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 10].value}; + + const float scaleCorrect = + (vr_world_scale.value / 0.75f) * + vr_gunmodelscale.value; // initial version had 0.75 default world + // scale, so weapons reflect that + + using namespace quake::util; + // glm::vec3 finalOffsets{ofs[0], ofs[1], ofs[2]}; + glm::vec3 finalOffsets{0, 0, 0}; + finalOffsets = finalOffsets + muzzleOfs; + AngleVectors(cl.handrot[1], forward, right, up); + const auto glmForward = toVec3(forward); + const auto glmRight = toVec3(right); + const auto glmUp = toVec3(up); + + finalOffsets *= + vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 3].value * + scaleCorrect; + + + const auto fFwd = glmForward * finalOffsets[0]; + const auto fRight = glmRight * finalOffsets[1]; + const auto fUp = glmUp * finalOffsets[2]; - float alpha; - if(!sv_player) - { - return; - } - if((int)(sv_player->v.weapon) == IT_AXE) + // Con_Printf("%.2f %.2f %.2f\n", forward[0], forward[1], forward[2]); + + toQuakeVec3(out, toVec3(cl.handpos[1]) + fFwd + fRight + fUp); +} + +void VR_ShowCrosshair() +{ + if(!sv_player || (int)(sv_player->v.weapon) == IT_AXE) { return; } - size = CLAMP(0.0, vr_crosshair_size.value, 32.0); - alpha = CLAMP(0.0, vr_crosshair_alpha.value, 1.0); + const float size = CLAMP(0.0, vr_crosshair_size.value, 32.0); + const float alpha = CLAMP(0.0, vr_crosshair_alpha.value, 1.0); if(size <= 0 || alpha <= 0) { @@ -1528,25 +1599,20 @@ void VR_ShowCrosshair() glDisable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); + vec3_t forward; + vec3_t up; + vec3_t right; + vec3_t start; + vec3_t end; + vec3_t impact; + // calc the line and draw // VR TODO: Make the laser align correctly if(vr_aimmode.value == VrAimMode::e_CONTROLLER) { - VectorCopy(cl.handpos[1], start); - // TODO VR: repetition of ofs calculation - vec3_t ofs = {vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON].value, - vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 1].value, - vr_weapon_offset[weaponCVarEntry * VARS_PER_WEAPON + 2].value + - vr_gunmodely.value}; - AngleVectors(cl.handrot[1], forward, right, up); - vec3_t fwd2; - VectorCopy(forward, fwd2); - fwd2[0] *= vr_gunmodelscale.value * ofs[2]; - fwd2[1] *= vr_gunmodelscale.value * ofs[2]; - fwd2[2] *= vr_gunmodelscale.value * ofs[2]; - VectorAdd(start, fwd2, start); + VR_CalcWeaponMuzzlePos(start); } else { @@ -1661,11 +1727,11 @@ void VR_Draw2D() { // TODO: Make the menus' position sperate from the right hand. // Centered on last view dir? - VectorCopy(cl.viewangles, menu_angles) + VectorCopy(cl.viewangles, menu_angles); - // TODO VR: ? - if(vr_aimmode.value == VrAimMode::e_HEAD_MYAW || - vr_aimmode.value == VrAimMode::e_HEAD_MYAW_MPITCH) + // TODO VR: ? + if(vr_aimmode.value == VrAimMode::e_HEAD_MYAW || + vr_aimmode.value == VrAimMode::e_HEAD_MYAW_MPITCH) { menu_angles[PITCH] = 0; } @@ -1875,6 +1941,15 @@ struct VRAxisResult return {locomotion.y, locomotion.x, turn.x}; } +void VR_DoHaptic(const int hand, const float delay, const float duration, + const float frequency, const float amplitude) +{ + const auto hapticTarget = hand == 0 ? vrahLeftHaptic : vrahRightHaptic; + + vr::VRInput()->TriggerHapticVibrationAction(hapticTarget, delay, duration, + frequency, amplitude, vr::k_ulInvalidInputValueHandle); +} + [[nodiscard]] static VRAxisResult VR_DoInput() { { @@ -1951,12 +2026,32 @@ struct VRAxisResult in_speed.state = mustSpeed; + const auto doMenuHaptic = [&](const vr::VRInputValueHandle_t& origin) { + vr::VRInput()->TriggerHapticVibrationAction( + vrahLeftHaptic, 0, 0.1, 50, 0.5, origin); + + vr::VRInput()->TriggerHapticVibrationAction( + vrahRightHaptic, 0, 0.1, 50, 0.5, origin); + }; + + const auto doMenuKeyEventWithHaptic = + [&](const int key, const vr::InputDigitalActionData_t& i) { + const bool pressed = isRisingEdge(i); + + if(pressed) + { + doMenuHaptic(i.activeOrigin); + } + + Key_Event(key, pressed); + }; + if(key_dest == key_menu) { - Key_Event(K_ENTER, mustJump); - Key_Event(K_ESCAPE, mustEscape); - Key_Event(K_LEFTARROW, mustPrevWeapon); - Key_Event(K_RIGHTARROW, mustNextWeapon); + doMenuKeyEventWithHaptic(K_ENTER, inpJump); + doMenuKeyEventWithHaptic(K_ESCAPE, inpEscape); + doMenuKeyEventWithHaptic(K_LEFTARROW, inpPrevWeapon); + doMenuKeyEventWithHaptic(K_RIGHTARROW, inpNextWeapon); const auto doAxis = [&](const int quakeKeyNeg, const int quakeKeyPos) { const float lastVal = inpLocomotion.y - inpLocomotion.deltaY; @@ -1966,6 +2061,11 @@ struct VRAxisResult const bool posDown = val > 0.0f; if(posDown != posWasDown) { + if(posDown) + { + doMenuHaptic(inpLocomotion.activeOrigin); + } + Key_Event(quakeKeyNeg, posDown); } @@ -1973,6 +2073,11 @@ struct VRAxisResult const bool negDown = val < 0.0f; if(negDown != negWasDown) { + if(negDown) + { + doMenuHaptic(inpLocomotion.activeOrigin); + } + Key_Event(quakeKeyPos, negDown); } }; @@ -1983,7 +2088,7 @@ struct VRAxisResult { Key_Event(K_MOUSE1, mustFire); Key_Event(K_SPACE, mustJump); - Key_Event(K_ESCAPE, mustEscape); + doMenuKeyEventWithHaptic(K_ESCAPE, inpEscape); Key_Event('3', mustPrevWeapon); Key_Event('1', mustNextWeapon); } @@ -2010,6 +2115,9 @@ void VR_Move(usercmd_t* cmd) VectorCopy(cl.handvel[0], cmd->offhandvel); cmd->offhandvelmag = cl.handvelmag[0]; + // VR: Weapon muzzle position. + VR_CalcWeaponMuzzlePos(cmd->muzzlepos); + // VR: Buttons and instant controller actions. // VR: Query state of controller axes. const auto [fwdMove, sideMove, yawMove] = VR_DoInput(); diff --git a/Quake/vr.hpp b/Quake/vr.hpp index 6a0938f4..21dff49b 100644 --- a/Quake/vr.hpp +++ b/Quake/vr.hpp @@ -124,7 +124,7 @@ extern cvar_t vr_body_interactions; // TODO VR: not sure what this number should actually be... #define MAX_WEAPONS 20 -#define VARS_PER_WEAPON 8 +#define VARS_PER_WEAPON 11 extern cvar_t vr_weapon_offset[MAX_WEAPONS * VARS_PER_WEAPON]; extern int weaponCVarEntry; diff --git a/Quake/vr_menu.cpp b/Quake/vr_menu.cpp index 448199e9..71d2f19b 100644 --- a/Quake/vr_menu.cpp +++ b/Quake/vr_menu.cpp @@ -8,6 +8,10 @@ #include #include +// TODO VR: move to other menu? +extern cvar_t r_particles; +extern cvar_t r_particle_mult; + static int vr_options_cursor = 0; #define VR_MAX_TURN_SPEED 10.0f @@ -41,10 +45,6 @@ static void VR_MenuPrintOptionValue(int cx, int cy, VRMenuOpt option) switch(option) { - // TODO VR: - // case VRMenuOpt::VR_ENABLED: - // M_DrawCheckbox(cx, cy, (int)vr_enabled.value); - // break; case VRMenuOpt::VR_AIMMODE: switch((int)vr_aimmode.value) { @@ -176,6 +176,10 @@ static void VR_MenuPrintOptionValue(int cx, int cy, VRMenuOpt option) value_string = vr_viewkick.value == 0 ? "Off" : "On"; break; case VRMenuOpt::VR_MENU_DISTANCE: printAsStr(vr_menu_distance); break; + case VRMenuOpt::VR_PARTICLES: + value_string = r_particles.value == 0 ? "Off" : "On"; + break; + case VRMenuOpt::VR_PARTICLE_MULT: printAsStr(r_particle_mult); break; default: assert(false); break; } @@ -215,14 +219,6 @@ static void M_VR_KeyOption(int key, VRMenuOpt option) switch(option) { - // TODO VR: - // case VRMenuOpt::VR_ENABLED: - // TODO VR: fix and restore - // Cvar_SetValue( "vr_enabled", ! (int)vr_enabled.value ); - // if ( (int)vr_enabled.value ) { - // VR_MenuPlaySound( "items/r_item2.wav", 0.5 ); - // } - // break; case VRMenuOpt::VR_AIMMODE: intValue = (int)vr_aimmode.value; intValue = CLAMP(aimmode[0], isLeft ? intValue - 1 : intValue + 1, @@ -255,7 +251,7 @@ static void M_VR_KeyOption(int key, VRMenuOpt option) case VRMenuOpt::VR_ENABLE_JOYSTICK_TURN: adjustI(vr_enable_joystick_turn, 1, 0, 1); break; - case VRMenuOpt::VR_SNAP_TURN: adjustI(vr_snap_turn, 45, 0, 90); break; + case VRMenuOpt::VR_SNAP_TURN: adjustI(vr_snap_turn, 5, 0, 90); break; case VRMenuOpt::VR_TURN_SPEED: adjustF(vr_turn_speed, 0.25f, 0.f, VR_MAX_TURN_SPEED); break; @@ -300,6 +296,10 @@ static void M_VR_KeyOption(int key, VRMenuOpt option) case VRMenuOpt::VR_MENU_DISTANCE: adjustI(vr_menu_distance, 1, 24, 256); break; + case VRMenuOpt::VR_PARTICLES: adjustI(r_particles, 1, 0, 1); break; + case VRMenuOpt::VR_PARTICLE_MULT: + adjustF(r_particle_mult, 0.25f, 0.25f, 10.f); + break; default: assert(false); break; } @@ -372,19 +372,13 @@ void M_VR_Draw() int idx = 0; static const auto adjustedLabels = quake::util::makeAdjustedMenuLabels( - // TODO VR: - // "VR Enabled", - - "Aim Mode", "Deadzone", "Crosshair", "Crosshair Depth", "Crosshair Size", "Crosshair Alpha", "World Scale", "Movement mode", "Enable Joystick Turn", "Turn", "Turn Speed", "MSAA", "Gun Angle", "Floor Offset", "Gun Model Pitch", "Gun Model Scale", "Gun Model Z Offset", "Crosshair Z Offset", - // TODO VR: consider restoring for custom QC? - // "Projectile Spawn Z", "HUD Scale", "Menu Scale", "Gun Yaw", "Gun Z Offset", "Status Bar Mode", - "Viewkick", "Menu Distance"); + "Viewkick", "Menu Distance", "Particle Effects", "Particle Multiplier"); static_assert(adjustedLabels.size() == (int)VRMenuOpt::VR_MAX); @@ -418,6 +412,4 @@ void M_Menu_VR_f() // TODO VR: // * difficulty options -// * nicer explosion particles -// * speed adjustment options, sprinting // * vignette? diff --git a/Quake/vr_menu.hpp b/Quake/vr_menu.hpp index ca0fdba2..3c38107a 100644 --- a/Quake/vr_menu.hpp +++ b/Quake/vr_menu.hpp @@ -2,9 +2,6 @@ enum class VRMenuOpt { - // TODO VR: - // VR_ENABLED, - VR_AIMMODE, VR_DEADZONE, VR_CROSSHAIR, @@ -30,6 +27,8 @@ enum class VRMenuOpt VR_SBAR_MODE, VR_VIEWKICK, VR_MENU_DISTANCE, + VR_PARTICLES, + VR_PARTICLE_MULT, VR_MAX }; diff --git a/Quake/wad.cpp b/Quake/wad.cpp index 3834e546..605c492d 100644 --- a/Quake/wad.cpp +++ b/Quake/wad.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/wad.hpp b/Quake/wad.hpp index 349967bb..aee9f373 100644 --- a/Quake/wad.hpp +++ b/Quake/wad.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/Quake/world.cpp b/Quake/world.cpp index 49d0b437..e2619e59 100644 --- a/Quake/world.cpp +++ b/Quake/world.cpp @@ -3,6 +3,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2007-2008 Kristian Duske Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -435,24 +436,17 @@ void SV_TouchLinks(edict_t* ent) edict_t* target = list[i]; // thing that's being touched // re-validate in case of PR_ExecuteProgram having side effects that // make edicts later in the list no longer touch - if(target == ent || ent != sv_player) + if(target == ent || ent != sv_player /* TODO VR: hack */) { continue; } - // TODO VR: code repetition - constexpr float o = 1.f; - vec3_t handposmin{-o, -o, -o}; - VectorAdd(handposmin, ent->v.handpos, handposmin); - - vec3_t handposmax{o, o, o}; - VectorAdd(handposmax, ent->v.handpos, handposmax); - - vec3_t offhandposmin{-o, -o, -o}; - VectorAdd(offhandposmin, ent->v.offhandpos, offhandposmin); - - vec3_t offhandposmax{o, o, o}; - VectorAdd(offhandposmax, ent->v.offhandpos, offhandposmax); + // Add some size to the hands. + const glm::vec3 offsets{1.f, 1.f, 1.f}; + const auto handposmin = ent->v.handpos - offsets; + const auto handposmax = ent->v.handpos + offsets; + const auto offhandposmin = ent->v.offhandpos - offsets; + const auto offhandposmax = ent->v.offhandpos + offsets; const bool canBeHandTouched = target->v.handtouch && target->v.solid == SOLID_TRIGGER; @@ -460,11 +454,13 @@ void SV_TouchLinks(edict_t* ent) const bool entIntersects = !quake::util::boxIntersection( ent->v.absmin, ent->v.absmax, target->v.absmin, target->v.absmax); - const bool anyHandIntersects = - quake::util::boxIntersection( - handposmin, handposmax, target->v.absmin, target->v.absmax) || - quake::util::boxIntersection(offhandposmin, offhandposmax, - target->v.absmin, target->v.absmax); + const bool offHandIntersects = quake::util::boxIntersection( + offhandposmin, offhandposmax, target->v.absmin, target->v.absmax); + + const bool mainHandIntersects = quake::util::boxIntersection( + handposmin, handposmax, target->v.absmin, target->v.absmax); + + const bool anyHandIntersects = offHandIntersects || mainHandIntersects; const bool anyIntersection = vr_enabled.value ? anyHandIntersects : entIntersects; @@ -481,6 +477,15 @@ void SV_TouchLinks(edict_t* ent) pr_global_struct->other = EDICT_TO_PROG(ent); pr_global_struct->time = sv.time; + if (offHandIntersects) + { + ent->v.touchinghand = 0; + } + else if (mainHandIntersects) + { + ent->v.touchinghand = 1; + } + // VR: This is for things like ammo pickups and slipgates. PR_ExecuteProgram(target->v.handtouch); @@ -762,7 +767,7 @@ SV_RecursiveHullCheck ================== */ -qboolean SV_RecursiveHullCheck(hull_t* hull, int num, float p1f, float p2f, +bool SV_RecursiveHullCheck(hull_t* hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t* trace) { mclipnode_t* node; // johnfitz -- was dclipnode_t diff --git a/Quake/world.hpp b/Quake/world.hpp index 78d42287..3dc842b5 100644 --- a/Quake/world.hpp +++ b/Quake/world.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -31,9 +32,9 @@ typedef struct struct trace_t { - qboolean allsolid; // if true, plane is not valid - qboolean startsolid; // if true, the initial point was in a solid area - qboolean inopen, inwater; + bool allsolid; // if true, plane is not valid + bool startsolid; // if true, the initial point was in a solid area + bool inopen, inwater; float fraction; // time completed, 1.0 = didn't hit anything vec3_t endpos; // final position plane_t plane; // surface normal at impact @@ -82,7 +83,7 @@ trace_t SV_Move(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, // passedict is explicitly excluded from clipping checks (normally nullptr) -qboolean SV_RecursiveHullCheck(hull_t* hull, int num, float p1f, float p2f, +bool SV_RecursiveHullCheck(hull_t* hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t* trace); #endif /* _QUAKE_WORLD_H */ diff --git a/Quake/wpnoffset_menu.cpp b/Quake/wpnoffset_menu.cpp index f8680825..a5b20f82 100644 --- a/Quake/wpnoffset_menu.cpp +++ b/Quake/wpnoffset_menu.cpp @@ -33,7 +33,10 @@ static auto getCvars() vr_weapon_offset[idx * VARS_PER_WEAPON + 3], // Scale vr_weapon_offset[idx * VARS_PER_WEAPON + 7], // Roll vr_weapon_offset[idx * VARS_PER_WEAPON + 5], // Pitch - vr_weapon_offset[idx * VARS_PER_WEAPON + 6] // Yaw + vr_weapon_offset[idx * VARS_PER_WEAPON + 6], // Yaw + vr_weapon_offset[idx * VARS_PER_WEAPON + 8], // MuzzleOffsetX + vr_weapon_offset[idx * VARS_PER_WEAPON + 9], // MuzzleOffsetY + vr_weapon_offset[idx * VARS_PER_WEAPON + 10] // MuzzleOffsetZ ); // clang-format on } @@ -53,7 +56,7 @@ static void WpnOffset_MenuPrintOptionValue( M_Print(cx, cy, value_buffer); }; - const auto& [ox, oy, oz, sc, rr, rp, ry] = getCvars(); + const auto& [ox, oy, oz, sc, rr, rp, ry, mx, my, mz] = getCvars(); switch(option) { @@ -65,6 +68,9 @@ static void WpnOffset_MenuPrintOptionValue( case WpnOffsetMenuOpt::Roll: printAsStr(rr); break; case WpnOffsetMenuOpt::Pitch: printAsStr(rp); break; case WpnOffsetMenuOpt::Yaw: printAsStr(ry); break; + case WpnOffsetMenuOpt::MuzzleOffsetX: printAsStr(mx); break; + case WpnOffsetMenuOpt::MuzzleOffsetY: printAsStr(my); break; + case WpnOffsetMenuOpt::MuzzleOffsetZ: printAsStr(mz); break; default: assert(false); break; } } @@ -79,12 +85,12 @@ static void M_WpnOffset_KeyOption(int key, WpnOffsetMenuOpt option) CLAMP(min, isLeft ? cvar.value - incr : cvar.value + incr, max)); }; - const auto& [ox, oy, oz, sc, rr, rp, ry] = getCvars(); + const auto& [ox, oy, oz, sc, rr, rp, ry, mx, my, mz] = getCvars(); - constexpr float oInc = 0.1f; + const float oInc = in_speed.state ? 5.f : 0.1f; constexpr float oBound = 100.f; - constexpr float rInc = 0.5f; + const float rInc = in_speed.state ? 5.f : 0.5f; constexpr float rBound = 90.f; switch(option) @@ -103,6 +109,15 @@ static void M_WpnOffset_KeyOption(int key, WpnOffsetMenuOpt option) case WpnOffsetMenuOpt::Roll: adjustF(rr, rInc, -rBound, rBound); break; case WpnOffsetMenuOpt::Pitch: adjustF(rp, rInc, -rBound, rBound); break; case WpnOffsetMenuOpt::Yaw: adjustF(ry, rInc, -rBound, rBound); break; + case WpnOffsetMenuOpt::MuzzleOffsetX: + adjustF(mx, oInc, -oBound, oBound); + break; + case WpnOffsetMenuOpt::MuzzleOffsetY: + adjustF(my, oInc, -oBound, oBound); + break; + case WpnOffsetMenuOpt::MuzzleOffsetZ: + adjustF(mz, oInc, -oBound, oBound); + break; default: assert(false); break; } } @@ -179,9 +194,9 @@ void M_WpnOffset_Draw() y += 16; int idx = 0; - static const auto adjustedLabels = - quake::util::makeAdjustedMenuLabels("Offhand", "Offset X", "Offset Y", - "Offset Z", "Scale", "Roll", "Pitch", "Yaw"); + static const auto adjustedLabels = quake::util::makeAdjustedMenuLabels( + "Offhand", "Offset X", "Offset Y", "Offset Z", "Scale", "Roll", "Pitch", + "Yaw", "Muzzle Offset X", "Muzzle Offset Y", "Muzzle Offset Z"); static_assert(adjustedLabels.size() == (int)WpnOffsetMenuOpt::Max); diff --git a/Quake/wpnoffset_menu.hpp b/Quake/wpnoffset_menu.hpp index 56b819be..9e468b17 100644 --- a/Quake/wpnoffset_menu.hpp +++ b/Quake/wpnoffset_menu.hpp @@ -11,6 +11,9 @@ enum class WpnOffsetMenuOpt Roll, Pitch, Yaw, + MuzzleOffsetX, + MuzzleOffsetY, + MuzzleOffsetZ, Max }; diff --git a/Quake/zone.cpp b/Quake/zone.cpp index 599cca3a..1e02feb4 100644 --- a/Quake/zone.cpp +++ b/Quake/zone.cpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -428,7 +429,7 @@ void Hunk_Print(bool all) while(true) { - // + // // skip to the high hunk if done with low hunk // if(h == endlow) diff --git a/Quake/zone.hpp b/Quake/zone.hpp index a06cc08b..0e47e6b5 100644 --- a/Quake/zone.hpp +++ b/Quake/zone.hpp @@ -2,6 +2,7 @@ Copyright (C) 1996-2001 Id Software, Inc. Copyright (C) 2002-2009 John Fitzgibbons and others Copyright (C) 2010-2014 QuakeSpasm developers +Copyright (C) 2020-2020 Vittorio Romeo This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/README.md b/README.md index 6286224d..c0f6b363 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ * Rebalanced for VR *(hitboxes, difficulty, projectile speed)* * Steam VR Input API support *(can rebind inputs in Steam VR settings)* * Many customization options *(e.g. melee damage/range, hand/body item pickup, and more)* +* Brand new particle system *(smoke, blood, lightning effects, and more)* +* Haptic feedback *(weapons, melee, damage, interactions with items)* ## Disclaimer @@ -45,6 +47,20 @@ * [Installation Instructions](https://old.reddit.com/r/ValveIndex/comments/fbs1nh/quake_vr_release_trailer_v001/fj7205c/) +## Troubleshooting + +* > The game seems to work fine, but there is no audio! + + * Ensure that the correct audio output device is set (HMD) and that the volume is turned up. + + * Open the Desktop view from your Steam VR dashboard, and make sure that the Quake VR window is in focus. You can bring it in focus by clicking on it. + + * Check that the in-game audio settings are correct. + +* > The controls are not working, and I cannot create a new binding in the Steam VR settings! + + * This is a problem with `v0.0.2` that will be fixed in the next version, because I am only supplying bindings for Knuckles controllers. You can fix it by copying [these `.json` files](https://github.com/SuperV1234/quakevr/tree/develop_otherinputs/ReleaseFiles) in your installation folder. Sorry for the inconvenience! + ## Credits * Built on top of QuakeSpasm and existing forks @@ -57,6 +73,28 @@ *(Please forgive me if I am forgetting someone. I will update this list as needed.)* +## Fan Coverage + +*(Thanks everyone for playing Quake VR! If you have created content related to the mod, please let me know and I'll add it to this list.)* + +* VHS Productions's [gameplay video](https://www.youtube.com/watch?v=fwyHMHvGOiI) with commentary and webcam. + +* Sly VR's gameplay videos: [part 1](https://www.youtube.com/watch?v=lAlJubb64g0), [part 2](https://www.youtube.com/watch?v=M0Pv66638Hc), [part 3](https://www.youtube.com/watch?v=ST9w7dwW6Rw), and [part 4](https://www.youtube.com/watch?v=pzSvgJWMnr8). With commentary. + +* UploadVR [article](https://uploadvr.com/new-quake-vr-mod/) and [gameplay video](https://www.youtube.com/watch?v=fBzCdMSF2-U). + +* My own [let's play series](https://www.youtube.com/playlist?list=PLTEcWGdSiQemN50YKFbEpR9har292EJns) with developer commentary and webcam. Nightmare difficulty! + +* Elia1995's [gameplay video](https://www.youtube.com/watch?v=rvigiMdIT-M) with webcam. + +* Stoni's [gameplay video](https://www.youtube.com/watch?v=Jserap1p2Ho) with webcam and commentary. + +* Custom Gamer's [video](https://www.youtube.com/watch?v=eeqtFDf3tkM) showcasing his awesome custom map in VR! + +* Gamertag VR's [livestream video](https://www.youtube.com/watch?v=W1_WG_PHUpw) with webcam and commentary. + +* Tom's [gameplay video](https://www.youtube.com/watch?v=96xC_khtrUE). + ## CVars *(This list is not exhaustive. More options are exposed in the in-game menu, or available via the console.)* diff --git a/ReleaseFiles/Id1/config.cfg b/ReleaseFiles/Id1/config.cfg index 5bca8ef0..cd4f6a63 100644 --- a/ReleaseFiles/Id1/config.cfg +++ b/ReleaseFiles/Id1/config.cfg @@ -100,8 +100,8 @@ r_clearcolor "2" r_dynamic "1" r_novis "0" r_oldwater "1" +r_particle_mult "1" r_particles "1" -r_quadparticles "1" r_scale "1" r_shadows "0" r_viewmodel_quake "0" @@ -159,7 +159,7 @@ vr_menu_scale "0.2" vr_movement_mode "1" vr_msaa "9" vr_roomscale_jump "1" -vr_roomscale_jump_threshold "1" +vr_roomscale_jump_threshold "0.8" vr_sbar_mode "1" vr_sbar_offset_pitch "1" vr_sbar_offset_roll "-0.3" @@ -189,6 +189,66 @@ vr_wofs_id_17 "progs/hand.mdl" vr_wofs_id_18 "-1" vr_wofs_id_19 "-1" vr_wofs_id_20 "-1" +vr_wofs_muzzle_x_01 "0" +vr_wofs_muzzle_x_02 "29.099997" +vr_wofs_muzzle_x_03 "23.999996" +vr_wofs_muzzle_x_04 "20" +vr_wofs_muzzle_x_05 "37.399963" +vr_wofs_muzzle_x_06 "27.60001" +vr_wofs_muzzle_x_07 "49.300011" +vr_wofs_muzzle_x_08 "30" +vr_wofs_muzzle_x_09 "0.0" +vr_wofs_muzzle_x_10 "0.0" +vr_wofs_muzzle_x_11 "0.0" +vr_wofs_muzzle_x_12 "0.0" +vr_wofs_muzzle_x_13 "0.0" +vr_wofs_muzzle_x_14 "0.0" +vr_wofs_muzzle_x_15 "0.0" +vr_wofs_muzzle_x_16 "0.0" +vr_wofs_muzzle_x_17 "0.0" +vr_wofs_muzzle_x_18 "0.0" +vr_wofs_muzzle_x_19 "0.0" +vr_wofs_muzzle_x_20 "0.0" +vr_wofs_muzzle_y_01 "0.0" +vr_wofs_muzzle_y_02 "0" +vr_wofs_muzzle_y_03 "0" +vr_wofs_muzzle_y_04 "0.2" +vr_wofs_muzzle_y_05 "0.0" +vr_wofs_muzzle_y_06 "0.0" +vr_wofs_muzzle_y_07 "0" +vr_wofs_muzzle_y_08 "0.0" +vr_wofs_muzzle_y_09 "0.0" +vr_wofs_muzzle_y_10 "0.0" +vr_wofs_muzzle_y_11 "0.0" +vr_wofs_muzzle_y_12 "0.0" +vr_wofs_muzzle_y_13 "0.0" +vr_wofs_muzzle_y_14 "0.0" +vr_wofs_muzzle_y_15 "0.0" +vr_wofs_muzzle_y_16 "0.0" +vr_wofs_muzzle_y_17 "0.0" +vr_wofs_muzzle_y_18 "0.0" +vr_wofs_muzzle_y_19 "0.0" +vr_wofs_muzzle_y_20 "0.0" +vr_wofs_muzzle_z_01 "0.0" +vr_wofs_muzzle_z_02 "2.1" +vr_wofs_muzzle_z_03 "2.2" +vr_wofs_muzzle_z_04 "1.6" +vr_wofs_muzzle_z_05 "-1.3" +vr_wofs_muzzle_z_06 "0.0" +vr_wofs_muzzle_z_07 "0.0" +vr_wofs_muzzle_z_08 "3.2" +vr_wofs_muzzle_z_09 "0.0" +vr_wofs_muzzle_z_10 "0.0" +vr_wofs_muzzle_z_11 "0.0" +vr_wofs_muzzle_z_12 "0.0" +vr_wofs_muzzle_z_13 "0.0" +vr_wofs_muzzle_z_14 "0.0" +vr_wofs_muzzle_z_15 "0.0" +vr_wofs_muzzle_z_16 "0.0" +vr_wofs_muzzle_z_17 "0.0" +vr_wofs_muzzle_z_18 "0.0" +vr_wofs_muzzle_z_19 "0.0" +vr_wofs_muzzle_z_20 "0.0" vr_wofs_pitch_01 "0" vr_wofs_pitch_02 "0" vr_wofs_pitch_03 "0.0" @@ -210,7 +270,7 @@ vr_wofs_pitch_18 "0.0" vr_wofs_pitch_19 "0.0" vr_wofs_pitch_20 "0.0" vr_wofs_roll_01 "-8" -vr_wofs_roll_02 "-6.5" +vr_wofs_roll_02 "-6" vr_wofs_roll_03 "-8" vr_wofs_roll_04 "-5" vr_wofs_roll_05 "-6.5" @@ -230,7 +290,7 @@ vr_wofs_roll_18 "0.0" vr_wofs_roll_19 "0.0" vr_wofs_roll_20 "0.0" vr_wofs_scale_01 "0.34" -vr_wofs_scale_02 "0.46" +vr_wofs_scale_02 "0.43" vr_wofs_scale_03 "0.48" vr_wofs_scale_04 "0.48" vr_wofs_scale_05 "0.38" @@ -250,7 +310,7 @@ vr_wofs_scale_18 "0.5" vr_wofs_scale_19 "0.5" vr_wofs_scale_20 "0.5" vr_wofs_x_01 "2.8" -vr_wofs_x_02 "4.6" +vr_wofs_x_02 "5.2" vr_wofs_x_03 "8.399998" vr_wofs_x_04 "4.9" vr_wofs_x_05 "4.8" diff --git a/ReleaseFiles/Id1/pak3.pak b/ReleaseFiles/Id1/pak3.pak index 218b5b0b..4c7abf8b 100644 Binary files a/ReleaseFiles/Id1/pak3.pak and b/ReleaseFiles/Id1/pak3.pak differ diff --git a/ReleaseFiles/Id1/textures/particle_blood.tga b/ReleaseFiles/Id1/textures/particle_blood.tga new file mode 100644 index 00000000..3b9474c3 Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_blood.tga differ diff --git a/ReleaseFiles/Id1/textures/particle_blood_mist.tga b/ReleaseFiles/Id1/textures/particle_blood_mist.tga new file mode 100644 index 00000000..84d26695 Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_blood_mist.tga differ diff --git a/ReleaseFiles/Id1/textures/particle_explosion.tga b/ReleaseFiles/Id1/textures/particle_explosion.tga new file mode 100644 index 00000000..085080a7 Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_explosion.tga differ diff --git a/ReleaseFiles/Id1/textures/particle_gun_smoke.tga b/ReleaseFiles/Id1/textures/particle_gun_smoke.tga new file mode 100644 index 00000000..17c77f59 Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_gun_smoke.tga differ diff --git a/ReleaseFiles/Id1/textures/particle_lightning.tga b/ReleaseFiles/Id1/textures/particle_lightning.tga new file mode 100644 index 00000000..f8a5e730 Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_lightning.tga differ diff --git a/ReleaseFiles/Id1/textures/particle_rock.tga b/ReleaseFiles/Id1/textures/particle_rock.tga new file mode 100644 index 00000000..7bd40a49 Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_rock.tga differ diff --git a/ReleaseFiles/Id1/textures/particle_smoke.tga b/ReleaseFiles/Id1/textures/particle_smoke.tga new file mode 100644 index 00000000..cf7b7cb4 Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_smoke.tga differ diff --git a/ReleaseFiles/Id1/textures/particle_spark.tga b/ReleaseFiles/Id1/textures/particle_spark.tga new file mode 100644 index 00000000..33d829ee Binary files /dev/null and b/ReleaseFiles/Id1/textures/particle_spark.tga differ diff --git a/ReleaseFiles/actions.json b/ReleaseFiles/actions.json index 84fc7ade..1f98c965 100644 --- a/ReleaseFiles/actions.json +++ b/ReleaseFiles/actions.json @@ -1,6 +1,5 @@ { - "actions": [ - { + "actions": [{ "name": "/actions/default/in/Locomotion", "type": "vector2" }, @@ -33,34 +32,42 @@ "type": "boolean" }, { - "name": "/actions/default/out/Haptic", + "name": "/actions/default/out/LeftHaptic", "type": "vibration" - } - ], - "action_sets": [ + }, { - "name": "/actions/default", - "usage": "leftright" + "name": "/actions/default/out/RightHaptic", + "type": "vibration" } ], - "default_bindings": [ - { + "action_sets": [{ + "name": "/actions/default", + "usage": "leftright" + }], + "default_bindings": [{ "controller_type": "knuckles", "binding_url": "bindings_knuckles.json" - } - ], - "localization": [ + }, { - "language_tag": "en_US", - "/actions/default/in/Locomotion": "Locomotion", - "/actions/default/in/Turn": "Turn", - "/actions/default/in/Fire": "Fire", - "/actions/default/in/Jump": "Jump", - "/actions/default/in/PrevWeapon": "Previous Weapon", - "/actions/default/in/NextWeapon": "Next Weapon", - "/actions/default/in/Escape": "Escape", - "/actions/default/in/Speed": "Speed Modifier", - "/actions/default/out/Haptic": "Haptic" + "controller_type": "oculus_touch", + "binding_url": "bindings_touch.json" + }, + { + "controller_type": "generic", + "binding_url": "bindings_generic.json" } - ] + ], + "localization": [{ + "language_tag": "en_US", + "/actions/default/in/Locomotion": "Locomotion", + "/actions/default/in/Turn": "Turn", + "/actions/default/in/Fire": "Fire", + "/actions/default/in/Jump": "Jump", + "/actions/default/in/PrevWeapon": "Previous Weapon", + "/actions/default/in/NextWeapon": "Next Weapon", + "/actions/default/in/Escape": "Escape", + "/actions/default/in/Speed": "Speed Modifier", + "/actions/default/out/LeftHaptic": "Left Haptic", + "/actions/default/out/RightHaptic": "Right Haptic" + }] } diff --git a/ReleaseFiles/bindings_generic.json b/ReleaseFiles/bindings_generic.json new file mode 100644 index 00000000..74c8823d --- /dev/null +++ b/ReleaseFiles/bindings_generic.json @@ -0,0 +1,5 @@ +{ + "action_manifest_version": 0, + "controller_type": "generic", + "bindings": {} +} \ No newline at end of file diff --git a/ReleaseFiles/bindings_knuckles.json b/ReleaseFiles/bindings_knuckles.json index 2414aaf4..859876bd 100644 --- a/ReleaseFiles/bindings_knuckles.json +++ b/ReleaseFiles/bindings_knuckles.json @@ -1,101 +1,99 @@ { - "action_manifest_version" : 0, - "alias_info" : {}, - "bindings" : { - "/actions/default" : { - "chords" : [], - "haptics" : [ - { - "output" : "/actions/default/out/Haptic", - "path" : "/user/hand/left/output/haptic" - }, - { - "output" : "/actions/default/out/Haptic", - "path" : "/user/hand/right/output/haptic" - } - ], - "poses" : [], - "skeleton" : [], - "sources" : [ - { - "inputs" : { - "position" : { - "output" : "/actions/default/in/Locomotion" - } - }, - "mode" : "joystick", - "path" : "/user/hand/left/input/thumbstick" - }, - { - "inputs" : { - "position" : { - "output" : "/actions/default/in/Turn" - } - }, - "mode" : "joystick", - "path" : "/user/hand/right/input/thumbstick" - }, - { - "inputs" : { - "click" : { - "output" : "/actions/default/in/Fire" - } - }, - "mode" : "button", - "path" : "/user/hand/right/input/trigger" - }, - { - "inputs" : { - "click" : { - "output" : "/actions/default/in/Jump" - } - }, - "mode" : "button", - "path" : "/user/hand/right/input/a" - }, - { - "inputs" : { - "click" : { - "output" : "/actions/default/in/NextWeapon" - } - }, - "mode" : "button", - "path" : "/user/hand/right/input/b" - }, - { - "inputs" : { - "click" : { - "output" : "/actions/default/in/Escape" - } - }, - "mode" : "button", - "path" : "/user/hand/left/input/a" - }, - { - "inputs" : { - "click" : { - "output" : "/actions/default/in/PrevWeapon" - } - }, - "mode" : "button", - "path" : "/user/hand/left/input/b" - }, - { - "inputs" : { - "click" : { - "output" : "/actions/default/in/speed" - } - }, - "mode" : "button", - "path" : "/user/hand/left/input/trigger" - } - ] - } - }, - "category" : "steamvr_input", - "controller_type" : "knuckles", - "description" : "The default binding for Valve Index controllers", - "name": "Default Index Controller Binding", - "options" : {}, - "simulated_actions" : [] + "action_manifest_version": 0, + "alias_info": {}, + "bindings": { + "/actions/default": { + "chords": [], + "haptics": [{ + "output": "/actions/default/out/LeftHaptic", + "path": "/user/hand/left/output/haptic" + }, + { + "output": "/actions/default/out/RightHaptic", + "path": "/user/hand/right/output/haptic" + } + ], + "poses": [], + "skeleton": [], + "sources": [{ + "inputs": { + "position": { + "output": "/actions/default/in/Locomotion" + } + }, + "mode": "joystick", + "path": "/user/hand/left/input/thumbstick" + }, + { + "inputs": { + "position": { + "output": "/actions/default/in/Turn" + } + }, + "mode": "joystick", + "path": "/user/hand/right/input/thumbstick" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/Fire" + } + }, + "mode": "button", + "path": "/user/hand/right/input/trigger" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/Jump" + } + }, + "mode": "button", + "path": "/user/hand/right/input/a" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/NextWeapon" + } + }, + "mode": "button", + "path": "/user/hand/right/input/b" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/Escape" + } + }, + "mode": "button", + "path": "/user/hand/left/input/a" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/PrevWeapon" + } + }, + "mode": "button", + "path": "/user/hand/left/input/b" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/speed" + } + }, + "mode": "button", + "path": "/user/hand/left/input/trigger" + } + ] + } + }, + "category": "steamvr_input", + "controller_type": "knuckles", + "description": "The default binding for Valve Index controllers", + "name": "Default Index Controller Binding", + "options": {}, + "simulated_actions": [] } diff --git a/ReleaseFiles/bindings_touch.json b/ReleaseFiles/bindings_touch.json new file mode 100644 index 00000000..27e14cef --- /dev/null +++ b/ReleaseFiles/bindings_touch.json @@ -0,0 +1,99 @@ +{ + "action_manifest_version": 0, + "alias_info": {}, + "bindings": { + "/actions/default": { + "chords": [], + "haptics": [{ + "output": "/actions/default/out/LeftHaptic", + "path": "/user/hand/left/output/haptic" + }, + { + "output": "/actions/default/out/RightHaptic", + "path": "/user/hand/right/output/haptic" + } + ], + "poses": [], + "skeleton": [], + "sources": [{ + "inputs": { + "position": { + "output": "/actions/default/in/Locomotion" + } + }, + "mode": "joystick", + "path": "/user/hand/left/input/thumbstick" + }, + { + "inputs": { + "position": { + "output": "/actions/default/in/Turn" + } + }, + "mode": "joystick", + "path": "/user/hand/right/input/thumbstick" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/Fire" + } + }, + "mode": "button", + "path": "/user/hand/right/input/trigger" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/Jump" + } + }, + "mode": "button", + "path": "/user/hand/right/input/a" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/NextWeapon" + } + }, + "mode": "button", + "path": "/user/hand/right/input/b" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/Escape" + } + }, + "mode": "button", + "path": "/user/hand/left/input/x" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/PrevWeapon" + } + }, + "mode": "button", + "path": "/user/hand/left/input/y" + }, + { + "inputs": { + "click": { + "output": "/actions/default/in/speed" + } + }, + "mode": "button", + "path": "/user/hand/left/input/trigger" + } + ] + } + }, + "category": "steamvr_input", + "controller_type": "oculus_touch", + "description": "The default binding for Oculus Touch controllers", + "name": "Default Oculus Touch Controller Binding", + "options": {}, + "simulated_actions": [] +} diff --git a/Windows/CMakeLists.txt b/Windows/CMakeLists.txt index 90de23df..b8ed5087 100644 --- a/Windows/CMakeLists.txt +++ b/Windows/CMakeLists.txt @@ -96,7 +96,7 @@ add_executable(quakespasm-sdl2 "${CMAKE_CURRENT_SOURCE_DIR}/../Quake/vr.cpp" "${ set_target_properties(quakespasm-sdl2 PROPERTIES LINKER_LANGUAGE CXX) target_compile_features(quakespasm-sdl2 PUBLIC cxx_std_17) -target_compile_options(quakespasm-sdl2 PRIVATE -x c++ -Wall -Wextra -Wno-missing-field-initializers -fdiagnostics-color=always -Wpedantic) +target_compile_options(quakespasm-sdl2 PRIVATE -x c++ -Wall -Wextra -Wno-missing-field-initializers -fdiagnostics-color=always -Wpedantic -Wimplicit-fallthrough) target_compile_definitions(quakespasm-sdl2 PRIVATE USE_SDL2=1 _AMD64_=1) target_include_directories( @@ -109,8 +109,8 @@ target_include_directories( include(FindOpenGL) set(SDL2_LIBRARIES - "C:/pers/Quakespasm-OpenVR/Windows/SDL2/lib64/SDL2main.lib" - "C:/pers/Quakespasm-OpenVR/Windows/SDL2/lib64/SDL2.lib" - "C:/pers/Quakespasm-OpenVR/Windows/OpenVR/lib/win64/openvr_api.lib") + "C:/pers/quakevr/Windows/SDL2/lib64/SDL2main.lib" + "C:/pers/quakevr/Windows/SDL2/lib64/SDL2.lib" + "C:/pers/quakevr/Windows/OpenVR/lib/win64/openvr_api.lib") target_link_libraries(quakespasm-sdl2 ${OPENGL_gl_LIBRARY} ${SDL2_LIBRARIES} wsock32 winmm ws2_32) diff --git a/Windows/SDL2/include/SDL_stdinc.h b/Windows/SDL2/include/SDL_stdinc.h index 014675b7..ae5c1b65 100644 --- a/Windows/SDL2/include/SDL_stdinc.h +++ b/Windows/SDL2/include/SDL_stdinc.h @@ -439,10 +439,10 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) return; switch (dwords % 4) { - case 0: do { *_p++ = _val; /* fallthrough */ - case 3: *_p++ = _val; /* fallthrough */ - case 2: *_p++ = _val; /* fallthrough */ - case 1: *_p++ = _val; /* fallthrough */ + case 0: do { *_p++ = _val; [[fallthrough]]; + case 3: *_p++ = _val; [[fallthrough]]; + case 2: *_p++ = _val; [[fallthrough]]; + case 1: *_p++ = _val; } while ( --_n ); } #endif diff --git a/Windows/VisualStudio/quakespasm-sdl2.vcxproj b/Windows/VisualStudio/quakespasm-sdl2.vcxproj index cdf79dfa..7826b6dd 100644 --- a/Windows/VisualStudio/quakespasm-sdl2.vcxproj +++ b/Windows/VisualStudio/quakespasm-sdl2.vcxproj @@ -194,6 +194,9 @@ copy "$(SolutionDir)\..\SDL2\lib64\*.dll" "$(TargetDir)" CompileAsCpp stdcpp17 true + AnySuitable + Speed + true openvr_api.lib;libvorbisfile.lib;libvorbis.lib;libopusfile.lib;libopus.lib;libFLAC.lib;libogg.lib;libmad.lib;libmikmod.lib;ws2_32.lib;opengl32.lib;winmm.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) @@ -208,6 +211,9 @@ copy "$(SolutionDir)\..\SDL2\lib64\*.dll" "$(TargetDir)" copy "$(SolutionDir)\..\codecs\x64\*.dll" "$(TargetDir)" copy "$(SolutionDir)\..\SDL2\lib64\*.dll" "$(TargetDir)" + + C:\OHWorkspace\quakevr\make_pak.bat + @@ -259,7 +265,13 @@ copy "$(SolutionDir)\..\SDL2\lib64\*.dll" "$(TargetDir)" - + + false + false + false + Fast + false + diff --git a/Windows/codecs/include/mad.h b/Windows/codecs/include/mad.h index a2738e87..251291d3 100644 --- a/Windows/codecs/include/mad.h +++ b/Windows/codecs/include/mad.h @@ -312,7 +312,7 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) # elif defined(FPM_ARM) -/* +/* * This ARM V4 version is as accurate as FPM_64BIT but much faster. The * least significant bit is properly rounded at no CPU cycle cost! */ @@ -348,7 +348,7 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) #ifdef __thumb__ /* In Thumb-2, the RSB-immediate instruction is only allowed with a zero - operand. If needed this code can also support Thumb-1 + operand. If needed this code can also support Thumb-1 (simply append "s" to the end of the second two instructions). */ # define MAD_F_MLN(hi, lo) \ asm ("rsbs %0, %0, #0\n\t" \ diff --git a/make_pak.bat b/make_pak.bat index 55a0d991..2d072d74 100644 --- a/make_pak.bat +++ b/make_pak.bat @@ -2,5 +2,5 @@ C: cd C:\OHWorkspace\quakevr\QC .\frikqcc.exe -summary -nolog -nopause -Ot -Oi -Op -Oc -Od -Os -Ol -On -Of -Ou -Oo -Or -Oa +warn 2 -cos pak.exe -c -v pak3.pak progs.dat -xcopy /y C:\OHWorkspace\quakevr\QC\pak3.pak C:\OHWorkspace\quakevr\Windows\VisualStudio\Build-quakespasm-sdl2\x64\Debug\Id1 +:: xcopy /y C:\OHWorkspace\quakevr\QC\pak3.pak C:\OHWorkspace\quakevr\Windows\VisualStudio\Build-quakespasm-sdl2\x64\Debug\Id1 xcopy /y C:\OHWorkspace\quakevr\QC\pak3.pak C:\OHWorkspace\quakevr\ReleaseFiles\Id1 diff --git a/old/scratchpad.cpp b/old/scratchpad.cpp index 5358366e..1910e27c 100644 --- a/old/scratchpad.cpp +++ b/old/scratchpad.cpp @@ -101,3 +101,139 @@ void VR_Move(usercmd_t* cmd) // vec3_t adjhandpos; // VectorCopy(cl.handpos[1], adjhandpos); // adjhandpos[2] -= vr_projectilespawn_z_offset.value; + + + +class ParticleBuffer +{ +private: + // TODO VR: use raw buffer for more speed + std::vector _particles; + std::size_t _maxParticles; + +public: + void initialize(std::size_t maxParticles) + { + _maxParticles = maxParticles; + _particles.reserve(maxParticles); + } + + void cleanup() + { + _particles.erase( + std::remove_if(_particles.begin(), _particles.end(), + [](const particle_t& p) { return cl.time >= p.die; }), + _particles.end()); + } + + [[nodiscard]] particle_t& create() + { + return _particles.emplace_back(); + } + + template + void forActive(F&& f) + { + for(auto& p : _particles) + { + f(p); + } + } + + [[nodiscard]] bool reachedMax() const noexcept + { + return _particles.size() == _maxParticles; + } + + void clear() + { + _particles.clear(); + } + + [[nodiscard]] bool empty() const noexcept + { + return _particles.empty(); + } +}; + + + +class ParticleBuffer +{ +private: + particle_t* _particles; + particle_t* _aliveEnd; + particle_t* _end; + +public: + void initialize(const std::size_t maxParticles) noexcept + { + _particles = (particle_t*)Hunk_AllocName( + maxParticles * sizeof(particle_t), "particles"); + _aliveEnd = _particles; + _end = _particles + maxParticles; + } + + void cleanup() noexcept + { + const auto it = std::remove_if(_particles, _aliveEnd, + [](const particle_t& p) { return cl.time >= p.die; }); + +#if 0 + for(auto p = it; p != _aliveEnd; ++p) + { + p->~particle_t(); + } +#endif + + _aliveEnd = it; + } + + [[nodiscard]] particle_t& create() noexcept + { +#if 0 + const auto p = _aliveEnd++; + new(p) particle_t; + return *p; +#else + return *_aliveEnd++; +#endif + } + + template + void forActive(F&& f) noexcept + { + for(auto p = _particles; p != _aliveEnd; ++p) + { + f(*p); + } + } + + [[nodiscard]] bool reachedMax() const noexcept + { + return _aliveEnd == _end; + } + + void clear() noexcept + { +#if 0 + for(auto p = _particles; p != _aliveEnd; ++p) + { + p->~particle_t(); + } +#endif + + _aliveEnd = _particles; + } + + [[nodiscard]] bool empty() const noexcept + { + return _aliveEnd == _particles; + } +}; + + + // s = ftos(xdmg); + // sprint (self, "OFFHANDDMG: "); + // sprint (self, s); + // sprint (self, "\n");