From 2cad75bc69f56d626a5beea064af06e00b81d3d4 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 14 Aug 2010 00:15:07 +0000 Subject: [PATCH] Attempting to fix/rework splitscreen. Removed the impulse2/+forward2 etc commands. Added +p2, -p2, p2 commands as a prefixed command instead. don't use + or - on them (so '+p2 forward' to move player 2 forward), this permits a simple generic way to send commands to a single player from an input device. rawinput mice will submit commands/movements based upon idx%maxsplits, they will correctly submit mouse clicks, which will be mapped through the +p2/+p3 commands as appropriate, so each mouse is purely for a single player. Fixed player model visibility in splitscreen mode. Ignoring allow_splitscreen for the local player, cl_splitscreen is technically now the only enabler (though you will need to configure rawinput or binds). Added support for { texturename prefixes. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3582 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 28 +++- engine/client/cl_input.c | 268 ++++++++++++++++--------------------- engine/client/cl_main.c | 3 - engine/client/cl_parse.c | 12 +- engine/client/cl_ui.c | 2 +- engine/client/clhl_game.c | 2 +- engine/client/client.h | 1 - engine/client/clq2_ents.c | 3 + engine/client/clq3_parse.c | 2 - engine/client/in_morphos.c | 22 +-- engine/client/in_sdl.c | 4 +- engine/client/in_win.c | 111 +++++++-------- engine/client/keys.c | 69 +++++++--- engine/client/keys.h | 2 +- engine/client/pr_csqc.c | 2 +- engine/client/r_surf.c | 38 ++++-- engine/client/render.h | 1 + engine/client/sys_win.c | 6 +- engine/client/view.c | 13 +- engine/d3d7/d3d7_rsurf.c | 2 - engine/gl/gl_alias.c | 11 ++ engine/gl/gl_model.c | 12 +- engine/gl/gl_model.h | 2 - engine/gl/gl_rmain.c | 2 +- engine/gl/gl_shader.c | 9 +- engine/gl/gl_vidnt.c | 10 +- engine/server/sv_ents.c | 19 +-- engine/server/sv_main.c | 3 +- 28 files changed, 351 insertions(+), 308 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 880cff62d..0a61d73ee 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -755,7 +755,7 @@ void DP5_ParseDelta(entity_state_t *s) s->flags = 0; if (i & RENDER_VIEWMODEL) s->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK; - if (i & RENDER_EXTERIORMODEL) + if (i & RENDER_EXTERIORMODEL) s->flags |= Q2RF_EXTERNALMODEL; } if (bits & E5_ORIGIN) @@ -1882,6 +1882,10 @@ void CL_LinkPacketEntities (void) if (state->effects & EF_NODEPTHTEST) ent->flags |= RF_NODEPTHTEST; + /*FIXME: pay attention to tags instead, so nexuiz can work with splitscreen*/ + if (ent->flags & Q2RF_EXTERNALMODEL) + ent->externalmodelview = ~0; + // set colormap if (state->colormap && (state->colormap <= MAX_CLIENTS) && (gl_nocolors.value == -1 || (ent->model/* && state->modelindex == cl_playerindex*/))) @@ -2658,6 +2662,7 @@ void CL_LinkPlayers (void) vec3_t angles; float *org; qboolean predictplayers; + model_t *model; if (!cl.worldmodel || cl.worldmodel->needload) return; @@ -2694,13 +2699,18 @@ void CL_LinkPlayers (void) if (info->spectator) continue; + //the extra modelindex check is to stop lame mods from using vweps with rings + if (state->command.impulse && cl.model_precache_vwep[0] && state->modelindex == cl_playerindex) + model = cl.model_precache_vwep[0]; + else + model = cl.model_precache[state->modelindex]; + // spawn light flashes, even ones coming from invisible objects if (r_powerupglow.value && !(r_powerupglow.value == 2 && j == cl.playernum[0]) && (state->effects & (EF_BLUE|EF_RED|EF_BRIGHTLIGHT|EF_DIMLIGHT))) { vec3_t colour; float radius; - org = (j == cl.playernum[0]) ? cl.simorg[0] : state->origin; colour[0] = 0; colour[1] = 0; colour[2] = 0; @@ -2737,6 +2747,13 @@ void CL_LinkPlayers (void) if (radius) { + vec3_t org; + int i; + VectorCopy(state->origin, org); + for (pnum = 0; pnum < cl.splitclients; pnum++) + VectorCopy(cl.simorg[pnum], org); + org[2] -= model->mins[2]; + org[2] += 24; radius += r_lightflicker.value?(rand()&31):0; CL_NewDlightRGB(j+1, org, radius, 0.1, colour[0], colour[1], colour[2])->flags &= ~LFLAG_ALLOW_FLASH; } @@ -2758,13 +2775,9 @@ void CL_LinkPlayers (void) cl_numvisedicts++; ent->keynum = j+1; ent->flags = 0; + ent->model = model; ent->forcedshader = NULL; - //the extra modelindex check is to stop lame mods from using vweps with rings - if (state->command.impulse && cl.model_precache_vwep[0] && state->modelindex == cl_playerindex) - ent->model = cl.model_precache_vwep[0]; - else - ent->model = cl.model_precache[state->modelindex]; ent->skinnum = state->skinnum; CL_UpdateNetFrameLerpState(false, state->frame, &cl.lerpplayers[j]); @@ -2809,6 +2822,7 @@ void CL_LinkPlayers (void) ent->origin[1] = cl.simorg[pnum][1]; ent->origin[2] = cl.simorg[pnum][2]+cl.crouch[pnum]; ent->flags |= Q2RF_EXTERNALMODEL; + ent->externalmodelview = (1< 0) + return (con_splitmodifier - 1)% cl.splitclients; + else if (cl_defaultsplitclient.ival > 0) + return cl_defaultsplitclient.ival % cl.splitclients; + else + return 0; +} + +void CL_Split_f(void) +{ + int tmp; + char *c; + c = Cmd_Argv(0); + tmp = con_splitmodifier; + if (*c == '+' || *c == '-') + { + con_splitmodifier = c[2]; + Cmd_ExecuteString(va("%c%s", *c, Cmd_Args()), Cmd_ExecLevel); + } + else + { + con_splitmodifier = c[1]; + Cmd_ExecuteString(Cmd_Args(), Cmd_ExecLevel); + } + con_splitmodifier = tmp; +} + /* =============================================================================== @@ -85,17 +129,15 @@ float cursor_screen[2]; qboolean cursor_active; + + + void KeyDown (kbutton_t *b) { int k; char *c; - int pnum; - c = Cmd_Argv(0); - pnum = atoi(c+strlen(c)-1); - if (c[1] == 'b'&&c[2] == 'u' && !atoi(c+strlen(c)-2)) - pnum = 0; - else if (pnum)pnum--; + int pnum = CL_TargettedSplit(); c = Cmd_Argv(1); if (c[0]) @@ -126,12 +168,7 @@ void KeyUp (kbutton_t *b) int k; char *c; - int pnum; - c = Cmd_Argv(0); - pnum = atoi(c+strlen(c)-1); - if (c[1] == 'b'&&c[2] == 'u' && !atoi(c+strlen(c)-2)) - pnum = 0; - else if (pnum)pnum--; + int pnum = CL_TargettedSplit(); c = Cmd_Argv(1); if (c[0]) @@ -161,15 +198,12 @@ void KeyUp (kbutton_t *b) void IN_KLookDown (void) {KeyDown(&in_klook);} void IN_KLookUp (void) {KeyUp(&in_klook);} void IN_MLookDown (void) {KeyDown(&in_mlook);} -void IN_MLookUp (void) { - char *c; - int pnum; - c = Cmd_Argv(0); - pnum = atoi(c+strlen(c)-1); - if (pnum)pnum--; -KeyUp(&in_mlook); -if ( !(in_mlook.state[pnum]&1) && lookspring.ival) - V_StartPitchDrift(pnum); +void IN_MLookUp (void) +{ + int pnum = CL_TargettedSplit(); + KeyUp(&in_mlook); + if ( !(in_mlook.state[pnum]&1) && lookspring.ival) + V_StartPitchDrift(pnum); } void IN_UpDown(void) {KeyDown(&in_up);} void IN_UpUp(void) {KeyUp(&in_up);} @@ -207,11 +241,7 @@ void IN_JumpDown (void) qboolean condition; - int pnum; - char *c; - c = Cmd_Argv(0); - pnum = atoi(c+strlen(c)-1); - if (pnum)pnum--; + int pnum = CL_TargettedSplit(); @@ -1766,132 +1796,6 @@ static char *VARGS vahunk(char *format, ...) return ret; } -void CL_RegisterSplitCommands(void) -{ - static int oldsplit; - char spn[8]; - int sp; - for (sp = 0; sp < MAX_SPLITS; sp++) - { - if (sp) - sprintf(spn, "%i", sp+1); - else - *spn = '\0'; - if (sp < cl.splitclients) - { - if (oldsplit & (1<= Q2CS_LIGHTS && i < Q2CS_LIGHTS+Q2MAX_LIGHTSTYLES) { -#ifdef PEXT_LIGHTSTYLECOL cl_lightstyle[i - Q2CS_LIGHTS].colour = 7; //white -#endif Q_strncpyz (cl_lightstyle[i - Q2CS_LIGHTS].map, s, sizeof(cl_lightstyle[i-Q2CS_LIGHTS].map)); cl_lightstyle[i - Q2CS_LIGHTS].length = Q_strlen(cl_lightstyle[i - Q2CS_LIGHTS].map); @@ -3899,6 +3893,8 @@ void CL_MuzzleFlash (int destsplit) dl = CL_AllocDlight (-i); VectorCopy (pl->origin, dl->origin); //set it's origin + if (pl->hullnum & 0x80) /*hull is 0-based, so origin is bottom of model, move the light up slightly*/ + dl->origin[2] += 24; AngleVectors(pl->viewangles, dl->axis[0], dl->axis[1], dl->axis[2]); AngleVectors (pl->viewangles, fv, rv, uv); //shift it up a little @@ -4901,9 +4897,7 @@ void CL_ParseServerMessage (void) i = MSG_ReadByte (); if (i >= MAX_LIGHTSTYLES) Host_EndGame ("svc_lightstyle > MAX_LIGHTSTYLES"); -#ifdef PEXT_LIGHTSTYLECOL cl_lightstyle[i].colour = 7; //white -#endif Q_strncpyz (cl_lightstyle[i].map, MSG_ReadString(), sizeof(cl_lightstyle[i].map)); cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); break; @@ -5771,9 +5765,7 @@ void CLNQ_ParseServerMessage (void) MSG_ReadString(); break; } -#ifdef PEXT_LIGHTSTYLECOL cl_lightstyle[i].colour = 7; //white -#endif Q_strncpyz (cl_lightstyle[i].map, MSG_ReadString(), sizeof(cl_lightstyle[i].map)); cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); break; diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index ed555cb69..326b1fb63 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -419,7 +419,7 @@ void VQ3_AddEntity(const q3refEntity_t *q3) if (q3->renderfx & Q3RF_DEPTHHACK) ent.flags |= Q2RF_DEPTHHACK; if (q3->renderfx & Q3RF_THIRD_PERSON) - ent.flags |= Q2RF_EXTERNALMODEL; + ent.externalmodelview = ~0; if (q3->renderfx & Q3RF_NOSHADOW) ent.flags |= RF_NOSHADOW; diff --git a/engine/client/clhl_game.c b/engine/client/clhl_game.c index 43a6a67fc..7cc24da87 100644 --- a/engine/client/clhl_game.c +++ b/engine/client/clhl_game.c @@ -755,7 +755,7 @@ int QDECL CLGHL_checkparm(char *str, const char **next) int QDECL CLGHL_keyevent(int key, int down) { if (key >= 241 && key <= 241+5) - Key_Event(K_MOUSE1+key-241, 0, down); + Key_Event(0, K_MOUSE1+key-241, 0, down); else Con_Printf("CLGHL_keyevent: Unrecognised HL key code\n"); return true; //fixme: check the return type diff --git a/engine/client/client.h b/engine/client/client.h index f3debcd32..2f6456202 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -821,7 +821,6 @@ extern float in_sensitivityscale; void CL_MakeActive(char *gamename); -void CL_RegisterSplitCommands(void); void CL_InitInput (void); void CL_SendCmd (double frametime, qboolean mainloop); void CL_SendMove (usercmd_t *cmd); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index 2d2b770e0..c2cdd320f 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1497,6 +1497,9 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) else ent.flags = renderfx; + if (renderfx & Q2RF_EXTERNALMODEL) + ent.externalmodelview = ~0; + // calculate angles if (effects & Q2EF_ROTATE) { // some bonus items auto-rotate diff --git a/engine/client/clq3_parse.c b/engine/client/clq3_parse.c index 31293efa8..2e5e8afa0 100644 --- a/engine/client/clq3_parse.c +++ b/engine/client/clq3_parse.c @@ -596,7 +596,6 @@ void CLQ3_ParseGameState(void) CL_MakeActive("Quake3Arena"); cl.splitclients = 1; - CL_RegisterSplitCommands(); { char buffer[2048]; @@ -1020,7 +1019,6 @@ void CLQ3_SendConnectPacket(netadr_t to) memset(&ccs, 0, sizeof(ccs)); cl.splitclients = 1; - CL_RegisterSplitCommands(); msg.data = data; msg.cursize = 0; msg.overflowed = msg.allowoverflow = 0; diff --git a/engine/client/in_morphos.c b/engine/client/in_morphos.c index a1dcd679d..aeb58684a 100644 --- a/engine/client/in_morphos.c +++ b/engine/client/in_morphos.c @@ -168,17 +168,17 @@ void IN_Commands(void) if (imsgs[i].ie_Code == NM_BUTTON_FOURTH) { - Key_Event(K_MOUSE4, 0, true); + Key_Event(0, K_MOUSE4, 0, true); } else if (imsgs[i].ie_Code == (NM_BUTTON_FOURTH|IECODE_UP_PREFIX)) { - Key_Event(K_MOUSE4, 0, false); + Key_Event(0, K_MOUSE4, 0, false); } if (key) { - Key_Event(key, 0, 1); - Key_Event(key, 0, 0); + Key_Event(0, key, 0, 1); + Key_Event(0, key, 0, 0); } } @@ -194,7 +194,7 @@ void IN_Commands(void) key = keyconv[imsgs[i].ie_Code]; if (key) - Key_Event(key, key, down); + Key_Event(0, key, key, down); else { if (developer.value) @@ -205,17 +205,17 @@ void IN_Commands(void) else if (imsgs[i].ie_Class == IECLASS_RAWMOUSE) { if (imsgs[i].ie_Code == IECODE_LBUTTON) - Key_Event(K_MOUSE1, 0, true); + Key_Event(0, K_MOUSE1, 0, true); else if (imsgs[i].ie_Code == (IECODE_LBUTTON|IECODE_UP_PREFIX)) - Key_Event(K_MOUSE1, 0, false); + Key_Event(0, K_MOUSE1, 0, false); else if (imsgs[i].ie_Code == IECODE_RBUTTON) - Key_Event(K_MOUSE2, 0, true); + Key_Event(0, K_MOUSE2, 0, true); else if (imsgs[i].ie_Code == (IECODE_RBUTTON|IECODE_UP_PREFIX)) - Key_Event(K_MOUSE2, 0, false); + Key_Event(0, K_MOUSE2, 0, false); else if (imsgs[i].ie_Code == IECODE_MBUTTON) - Key_Event(K_MOUSE3, 0, true); + Key_Event(0, K_MOUSE3, 0, true); else if (imsgs[i].ie_Code == (IECODE_MBUTTON|IECODE_UP_PREFIX)) - Key_Event(K_MOUSE3, 0, false); + Key_Event(0, K_MOUSE3, 0, false); mouse_x+= imsgs[i].ie_position.ie_xy.ie_x; mouse_y+= imsgs[i].ie_position.ie_xy.ie_y; diff --git a/engine/client/in_sdl.c b/engine/client/in_sdl.c index 73661c882..dd25758bb 100644 --- a/engine/client/in_sdl.c +++ b/engine/client/in_sdl.c @@ -264,7 +264,7 @@ void Sys_SendKeyEvents(void) case SDL_KEYUP: case SDL_KEYDOWN: - Key_Event(tbl_sdltoquake[event.key.keysym.sym], event.key.keysym.unicode, event.key.state); + Key_Event(0, tbl_sdltoquake[event.key.keysym.sym], event.key.keysym.unicode, event.key.state); break; case SDL_MOUSEMOTION: @@ -277,7 +277,7 @@ void Sys_SendKeyEvents(void) //Hmm. SDL allows for 255 buttons... if (event.button.button > sizeof(tbl_sdltoquakemouse)/sizeof(tbl_sdltoquakemouse[0])) event.button.button = sizeof(tbl_sdltoquakemouse)/sizeof(tbl_sdltoquakemouse[0]); - Key_Event(tbl_sdltoquakemouse[event.button.button-1], 0, event.button.state); + Key_Event(0, tbl_sdltoquakemouse[event.button.button-1], 0, event.button.state); break; case SDL_QUIT: diff --git a/engine/client/in_win.c b/engine/client/in_win.c index a3d9c48cf..3c9370a3d 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -76,6 +76,7 @@ typedef struct { } handles; int numbuttons; + int playerid; volatile int buttons; volatile int oldbuttons; @@ -274,7 +275,6 @@ RAWINPUT *raw; int ribuffersize; cvar_t in_rawinput = SCVAR("in_rawinput", "0"); -cvar_t in_rawinput_combine = SCVAR("in_rawinput_combine", "0"); cvar_t in_rawinput_rdp = SCVAR("in_rawinput_rdp", "0"); void IN_RawInput_DeRegister(void); @@ -376,11 +376,11 @@ void MW_Hook_Message (long buttons) buttons &= 0xFFFF; switch (buttons ^ old_buttons) { - case 8: Key_Event(K_MOUSE4, 0, buttons > old_buttons ? true : false); break; - case 16: Key_Event(K_MOUSE5, 0, buttons > old_buttons ? true : false); break; - case 32: Key_Event(K_MOUSE6, 0, buttons > old_buttons ? true : false); break; - case 64: Key_Event(K_MOUSE7, 0, buttons > old_buttons ? true : false); break; - case 128: Key_Event(K_MOUSE8, 0, buttons > old_buttons ? true : false); break; + case 8: Key_Event(0, K_MOUSE4, 0, buttons > old_buttons ? true : false); break; + case 16: Key_Event(0, K_MOUSE5, 0, buttons > old_buttons ? true : false); break; + case 32: Key_Event(0, K_MOUSE6, 0, buttons > old_buttons ? true : false); break; + case 64: Key_Event(0, K_MOUSE7, 0, buttons > old_buttons ? true : false); break; + case 128: Key_Event(0, K_MOUSE8, 0, buttons > old_buttons ? true : false); break; default: break; } @@ -1008,7 +1008,7 @@ int IN_RawInput_Register(void) int IN_RawInput_IsRDPMouse(char *cDeviceString) { - char cRDPString[] = "\\??\\Root#RDP_MOU#"; + char cRDPString[] = "\\\\?\\Root#RDP_MOU#"; int i; if (strlen(cDeviceString) < strlen(cRDPString)) { @@ -1142,6 +1142,7 @@ void IN_RawInput_Init(void) rawmice[rawmicecount].handles.rawinputhandle = pRawInputDeviceList[i].hDevice; rawmice[rawmicecount].numbuttons = 10; rawmice[rawmicecount].pos[0] = RI_INVALID_POS; + rawmice[rawmicecount].playerid = rawmicecount; rawmicecount++; } } @@ -1342,7 +1343,6 @@ void IN_Init (void) #ifdef USINGRAWINPUT Cvar_Register (&in_rawinput, "Input Controls"); - Cvar_Register (&in_rawinput_combine, "Input Controls"); Cvar_Register (&in_rawinput_rdp, "Input Controls"); #endif } @@ -1395,13 +1395,13 @@ void IN_MouseEvent (int mstate) if ( (mstate & (1<playerid % wpnum; + if (wpnum != pnum) + return; + // perform button actions for (i=0 ; inumbuttons ; i++) { if ( (mouse->buttons & (1<oldbuttons & (1<buttons & (1<oldbuttons & (1<oldbuttons = mouse->buttons; @@ -1444,15 +1452,15 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum) { while(mouse->wheeldelta <= -mfwt) { - Key_Event (K_MWHEELUP, 0, true); - Key_Event (K_MWHEELUP, 0, false); + Key_Event (pnum, K_MWHEELUP, 0, true); + Key_Event (pnum, K_MWHEELUP, 0, false); mouse->wheeldelta += mfwt; } while(mouse->wheeldelta >= mfwt) { - Key_Event (K_MWHEELDOWN, 0, true); - Key_Event (K_MWHEELDOWN, 0, false); + Key_Event (pnum, K_MWHEELDOWN, 0, true); + Key_Event (pnum, K_MWHEELDOWN, 0, false); mouse->wheeldelta -= mfwt; } } @@ -1749,29 +1757,18 @@ void IN_MouseMove (float *movements, int pnum) #ifdef USINGRAWINPUT if (rawmicecount) { - if ((in_rawinput_combine.value && pnum == 0) || cl.splitclients <= 1) + int x; + for (x = 0; x < rawmicecount; x++) { - // not the right way to do this but it'll work for now - int x; - - for (x = 0; x < rawmicecount; x++) - { - ProcessMouse(rawmice + x, movements, 0); - } - } - else if (pnum < rawmicecount) - { - ProcessMouse(rawmice + pnum, movements, pnum); + ProcessMouse(rawmice + x, movements, pnum); } } #endif - if (pnum == 0) - ProcessMouse(&sysmouse, movements, pnum); + ProcessMouse(&sysmouse, movements, pnum); #ifdef SERIALMOUSE - if (pnum == 1 || cl.splitclients<2) - ProcessMouse(&serialmouse, movements, pnum); + ProcessMouse(&serialmouse, movements, pnum); #endif } @@ -1827,6 +1824,7 @@ void IN_RawInput_MouseRead(HANDLE in_device_handle) { int i = 0, tbuttons, j; int dwSize; + int pnum; // get raw input if ((*_GRID)((HRAWINPUT)in_device_handle, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) == -1) @@ -1844,7 +1842,7 @@ void IN_RawInput_MouseRead(HANDLE in_device_handle) if ((*_GRID)((HRAWINPUT)in_device_handle, RID_INPUT, raw, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize ) { Con_Printf("Raw input: unable to add to get raw input header.\n"); return; - } + } // find mouse in our mouse list for (; i < rawmicecount; i++) @@ -1856,6 +1854,11 @@ void IN_RawInput_MouseRead(HANDLE in_device_handle) if (i == rawmicecount) // we're not tracking this mouse return; + pnum = cl.splitclients; + if (pnum < 1) + pnum = 1; + pnum = rawmice[i].playerid % pnum; + // movement if (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) { @@ -1876,38 +1879,38 @@ void IN_RawInput_MouseRead(HANDLE in_device_handle) // buttons if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) - Key_Event(K_MOUSE1, 0, true); + Key_Event(pnum, K_MOUSE1, 0, true); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_UP) - Key_Event(K_MOUSE1, 0, false); + Key_Event(pnum, K_MOUSE1, 0, false); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_DOWN) - Key_Event(K_MOUSE2, 0, true); + Key_Event(pnum, K_MOUSE2, 0, true); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_2_UP) - Key_Event(K_MOUSE2, 0, false); + Key_Event(pnum, K_MOUSE2, 0, false); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_DOWN) - Key_Event(K_MOUSE3, 0, true); + Key_Event(pnum, K_MOUSE3, 0, true); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_3_UP) - Key_Event(K_MOUSE3, 0, false); + Key_Event(pnum, K_MOUSE3, 0, false); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - Key_Event(K_MOUSE4, 0, true); + Key_Event(pnum, K_MOUSE4, 0, true); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_4_UP) - Key_Event(K_MOUSE4, 0, false); + Key_Event(pnum, K_MOUSE4, 0, false); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - Key_Event(K_MOUSE5, 0, true); + Key_Event(pnum, K_MOUSE5, 0, true); if (raw->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP) - Key_Event(K_MOUSE5, 0, false); + Key_Event(pnum, K_MOUSE5, 0, false); // mouse wheel if (raw->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) { // If the current message has a mouse_wheel message if ((SHORT)raw->data.mouse.usButtonData > 0) { - Key_Event(K_MWHEELUP, 0, true); - Key_Event(K_MWHEELUP, 0, false); + Key_Event(pnum, K_MWHEELUP, 0, true); + Key_Event(pnum, K_MWHEELUP, 0, false); } if ((SHORT)raw->data.mouse.usButtonData < 0) { - Key_Event(K_MWHEELDOWN, 0, true); - Key_Event(K_MWHEELDOWN, 0, false); + Key_Event(pnum, K_MWHEELDOWN, 0, true); + Key_Event(pnum, K_MWHEELDOWN, 0, false); } } @@ -1917,12 +1920,12 @@ void IN_RawInput_MouseRead(HANDLE in_device_handle) { if ( (tbuttons & (1<flags |= Q2RF_DEPTHHACK|Q2RF_WEAPONMODEL; if (rflags & CSQCRF_EXTERNALMODEL) - out->flags |= Q2RF_EXTERNALMODEL; + out->externalmodelview = ~0; if (rflags & CSQCRF_DEPTHHACK) out->flags |= Q2RF_DEPTHHACK; if (rflags & CSQCRF_ADDITIVE) diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index c4d279572..33c1d2955 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -941,9 +941,6 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, int stride = LMBLOCK_WIDTH*lightmap_bytes; - if (!surf->samples && currentmodel->lightdata && ambient >= 0) - return; - shift += 7; // increase to base value surf->cached_dlight = (surf->dlightframe == r_framecount); @@ -988,11 +985,22 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, } else if (!currentmodel->lightdata) { + /*fullbright if map is not lit*/ for (i=0 ; isamples) + { + /*no samples, but map is otherwise lit = pure black*/ + for (i=0 ; icached_light[0] = 0; + surf->cached_colour[0] = 0; + } else { // clear to no light @@ -1146,7 +1154,16 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, #endif { // set to full bright if no light data - if (r_fullbright.ival || !currentmodel->lightdata) + if (!surf->samples || !currentmodel->lightdata) + { + for (i=0 ; icached_light[0] = d_lightstylevalue[0]; + surf->cached_colour[0] = cl_lightstyle[0].colour; + } + else if (r_fullbright.ival) { for (i=0 ; ifromgame != fg_quake3) //no lightstyles on q3 maps + if (!fa->samples) + { + if (d_lightstylevalue[0] != fa->cached_light[0] + || cl_lightstyle[0].colour != fa->cached_colour[0]) + goto dynamic; + } + else { for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; maps++) if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] - #ifdef PEXT_LIGHTSTYLECOL - || cl_lightstyle[fa->styles[maps]].colour != fa->cached_colour[maps] - #endif - ) + || cl_lightstyle[fa->styles[maps]].colour != fa->cached_colour[maps]) goto dynamic; } diff --git a/engine/client/render.h b/engine/client/render.h index 5d73e3c75..3c932d9be 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -106,6 +106,7 @@ typedef struct entity_s framestate_t framestate; + unsigned int externalmodelview; int flags; refEntityType_t rtype; diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 9b61f9ff2..33a40976b 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -428,19 +428,19 @@ LRESULT CALLBACK LowLevelKeyboardProc (INT nCode, WPARAM wParam, LPARAM lParam) //Trap the Left Windowskey if (pkbhs->vkCode == VK_LWIN) { - Key_Event (K_LWIN, 0, !(pkbhs->flags & LLKHF_UP)); + Key_Event (0, K_LWIN, 0, !(pkbhs->flags & LLKHF_UP)); return 1; } //Trap the Right Windowskey if (pkbhs->vkCode == VK_RWIN) { - Key_Event (K_RWIN, 0, !(pkbhs->flags & LLKHF_UP)); + Key_Event (0, K_RWIN, 0, !(pkbhs->flags & LLKHF_UP)); return 1; } //Trap the Application Key (what a pointless key) if (pkbhs->vkCode == VK_APPS) { - Key_Event (K_APP, 0, !(pkbhs->flags & LLKHF_UP)); + Key_Event (0, K_APP, 0, !(pkbhs->flags & LLKHF_UP)); return 1; } diff --git a/engine/client/view.c b/engine/client/view.c index 079743081..a46da5933 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -990,10 +990,15 @@ void V_CalcRefdef (int pnum) V_CalcViewRoll (pnum); V_AddIdle (pnum); - if (view_message && view_message->flags & PF_GIB) - r_refdef.vieworg[2] += 8; // gib view height - else if (view_message && view_message->flags & PF_DEAD) - r_refdef.vieworg[2] -= 16; // corpse view height + if (cl.viewheight[pnum] == DEFAULT_VIEWHEIGHT) + { + if (view_message && view_message->flags & PF_GIB) + r_refdef.vieworg[2] += 8; // gib view height + else if (view_message && view_message->flags & PF_DEAD) + r_refdef.vieworg[2] -= 16; // corpse view height + else + r_refdef.vieworg[2] += DEFAULT_VIEWHEIGHT; + } else r_refdef.vieworg[2] += cl.viewheight[pnum]; diff --git a/engine/d3d7/d3d7_rsurf.c b/engine/d3d7/d3d7_rsurf.c index 24eb2c17a..04dd8b2de 100644 --- a/engine/d3d7/d3d7_rsurf.c +++ b/engine/d3d7/d3d7_rsurf.c @@ -1172,9 +1172,7 @@ void D3DR_RenderDynamicLightmaps (msurface_t *fa, int shift) for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ; maps++) if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps] - #ifdef PEXT_LIGHTSTYLECOL || cl_lightstyle[fa->styles[maps]].colour != fa->cached_colour[maps] - #endif ) { goto dynamic; diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index d5a144bf9..d85ec4227 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -221,6 +221,17 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum, unsigned int tc, bc; qboolean forced; + if (e->skinnum >= 100 && e->skinnum < 110) + { + shader_t *s; + s = R_RegisterSkin(va("gfx/skin%d.lmp", e->skinnum)); + if (!TEXVALID(s->defaulttextures.base)) + s->defaulttextures.base = R_LoadHiResTexture(va("gfx/skin%d.lmp", e->skinnum), NULL, 0); + s->defaulttextures.shader = s; + return &s->defaulttextures; + } + + if ((e->model->engineflags & MDLF_NOTREPLACEMENTS) && !ruleset_allow_sensative_texture_replacements.ival) forced = true; else diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 7ea8223a8..6f006bfef 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1088,9 +1088,9 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n")); tn.base = R_LoadReplacementTexture(mt->name, loadname, IF_NOALPHA); if (!TEXVALID(tn.base)) { - tn.base = R_LoadReplacementTexture(mt->name, "bmodels", IF_NOALPHA); + tn.base = R_LoadReplacementTexture(mt->name, "bmodels", (*mt->name == '{')?0:IF_NOALPHA); if (!TEXVALID(tn.base)) - tn.base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, IF_NOALPHA, 1); + tn.base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, (*mt->name == '{')?0:IF_NOALPHA, 1); } if (r_fb_bmodels.value) @@ -1098,11 +1098,11 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n")); snprintf(altname, sizeof(altname)-1, "%s_luma", mt->name); if (gl_load24bit.value) { - tn.fullbright = R_LoadReplacementTexture(altname, loadname, IF_NOALPHA); + tn.fullbright = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA); if (!TEXVALID(tn.fullbright)) - tn.fullbright = R_LoadReplacementTexture(altname, "bmodels", IF_NOALPHA); + tn.fullbright = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA); } - if (!TEXVALID(tn.fullbright)) //generate one (if possible). + if ((*mt->name != '{') && !TEXVALID(tn.fullbright)) //generate one (if possible). tn.fullbright = R_LoadTextureFB(altname, mipwidth, mipheight, mipbase, IF_NOGAMMA); } } @@ -2670,7 +2670,7 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms) surf = cl.worldmodel->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { - if (surf->flags&~(SURF_DONTWARP|SURF_PLANEBACK)) + if (surf->flags&~(SURF_DRAWALPHA|SURF_DONTWARP|SURF_PLANEBACK)) continue; Surf_StainSurf(surf, parms); } diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 50016e3ec..7dfc70b98 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -322,9 +322,7 @@ typedef struct msurface_s qbyte styles[MAXLIGHTMAPS]; int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap qboolean cached_dlight; // true if dynamic light in cache -#ifdef PEXT_LIGHTSTYLECOL qbyte cached_colour[MAXLIGHTMAPS]; -#endif #ifndef NOSTAINS qboolean stained; #endif diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index fa2412d0f..724e215e8 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -947,7 +947,7 @@ This is where they're filtered (based on which view is currently being drawn). */ qboolean R_ShouldDraw(entity_t *e) { - if (e->flags & Q2RF_EXTERNALMODEL && !r_refdef.externalview) + if (!r_refdef.externalview && (e->externalmodelview & (1<keynum-1)) return false; diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 5e7f97f38..d1a3c045c 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -1942,19 +1942,20 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2) #ifdef GLQUAKE if (((pass->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) || ((pass2->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) || - (pass->flags & SHADER_PASS_VIDEOMAP) || (pass2->flags & SHADER_PASS_VIDEOMAP) || - ((pass->shaderbits & SBITS_ATEST_BITS) && !(pass2->shaderbits & SBITS_MISC_DEPTHEQUALONLY))) + (pass->flags & SHADER_PASS_VIDEOMAP) || (pass2->flags & SHADER_PASS_VIDEOMAP)) { return; } if (pass2->rgbgen != RGB_GEN_IDENTITY || pass2->alphagen != ALPHA_GEN_IDENTITY) - { return; - } if (pass->rgbgen != RGB_GEN_IDENTITY || pass->alphagen != ALPHA_GEN_IDENTITY) return; + /*if its alphatest, don't merge with anything other than lightmap*/ + if ((pass->shaderbits & SBITS_ATEST_BITS) && (!(pass2->shaderbits & SBITS_MISC_DEPTHEQUALONLY) || pass2->texgen != T_GEN_LIGHTMAP)) + return; + // check if we can use multiple passes if (pass2->blendmode == GL_DOT3_RGB_ARB) { diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index c36fc5f62..06763e8b7 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -1471,7 +1471,7 @@ void ClearAllStates (void) // send an up event for each key, to make sure the server clears them all for (i=0 ; i<256 ; i++) { - Key_Event (i, 0, false); + Key_Event (0, i, 0, false); } Key_ClearStates (); @@ -1682,13 +1682,13 @@ LONG WINAPI GLMainWndProc ( { if ((short) HIWORD(wParam) > 0) { - Key_Event(K_MWHEELUP, 0, true); - Key_Event(K_MWHEELUP, 0, false); + Key_Event(0, K_MWHEELUP, 0, true); + Key_Event(0, K_MWHEELUP, 0, false); } else { - Key_Event(K_MWHEELDOWN, 0, true); - Key_Event(K_MWHEELDOWN, 0, false); + Key_Event(0, K_MWHEELDOWN, 0, true); + Key_Event(0, K_MWHEELDOWN, 0, false); } } break; diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 3403034f6..21154ad37 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -1468,9 +1468,6 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t * if (needcleanup < (j+1)) { needcleanup = (j+1); - MSG_WriteByte(&sv.multicast, svc_muzzleflash); - MSG_WriteShort(&sv.multicast, (j+1)); - SV_Multicast(ent->v->origin, MULTICAST_PVS); } } } @@ -1691,9 +1688,6 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t * if (needcleanup < (j+1)) { needcleanup = (j+1); - MSG_WriteByte(&sv.multicast, svc_muzzleflash); - MSG_WriteShort(&sv.multicast, (j+1)); - SV_Multicast(ent->v->origin, MULTICAST_PVS); } } } @@ -2418,9 +2412,6 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, if (needcleanup < e) { needcleanup = e; - MSG_WriteByte(&sv.multicast, svc_muzzleflash); - MSG_WriteShort(&sv.multicast, e); - SV_Multicast(ent->v->origin, MULTICAST_PVS); } } } @@ -2759,6 +2750,7 @@ void SV_CleanupEnts(void) { int e; edict_t *ent; + vec3_t org; if (!needcleanup) return; @@ -2767,7 +2759,16 @@ void SV_CleanupEnts(void) { ent = EDICT_NUM(svprogfuncs, e); if ((int)ent->v->effects & EF_MUZZLEFLASH) + { ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH; + + MSG_WriteByte(&sv.multicast, svc_muzzleflash); + MSG_WriteShort(&sv.multicast, e); + VectorCopy(ent->v->origin, org); + if (progstype == PROG_H2) + org[2] += 24; + SV_Multicast(org, MULTICAST_PVS); + } } needcleanup=0; } diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 24b5a5f41..29c0815f8 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -1814,7 +1814,8 @@ client_t *SVC_DirectConnect(void) else maxpacketentities = MAX_STANDARD_PACKET_ENTITIES; - if (!sv_allow_splitscreen.ival) + /*allow_splitscreen applies only to non-local clients, so that clients have only one enabler*/ + if (!sv_allow_splitscreen.ival && net_from.type != NA_LOOPBACK) numssclients = 1; if (!(protextsupported & PEXT_SPLITSCREEN))