From 1a9d580bd5a354ca122dbe35456136cdde5d9ed7 Mon Sep 17 00:00:00 2001 From: ceski <56656010+ceski-1@users.noreply.github.com> Date: Sat, 23 Dec 2023 15:29:10 -0800 Subject: [PATCH] More mouse improvements (#1348) * Check `oldlookdir` before disabling `centering` When turning off mouselook/padlook, keep view centering enabled until `oldlookdir` is zero, meaning when the player's view actually appears centered. * Move `viewangleoffset` * Check dead state set by `P_KillMobj()` * Smooth composite/mouse turning transitions Blend interpolated composite input (e.g. keyboard) turning with direct mouse turning to prevent choppy transitions. * Group inputs by composite/gamepad/mouse * Update carry/input calculations This also enables shorttics (lowres_turn) with fast mouse polling. * Add mouse smoothing toggle With mouse smoothing disabled (default), mouse movements are immediately reflected in each frame update, with the game simulation following behind. The higher the framerate, the lower the perceived input lag. With mouse smoothing enabled, mouse movements are delayed by up to one tic (~29 ms) due to interpolation. When recording older format demos with reduced turning resolution (or when using `-shorttics`), interpolation may still be preferred for smoother turning. * Rename "mouse smoothing" to "raw mouse input" * Skip calculations when using interpolation --- src/d_main.c | 7 +- src/g_game.c | 410 ++++++++++++++++++++++++++----------------------- src/g_game.h | 3 +- src/i_input.c | 1 - src/i_system.h | 2 + src/i_video.c | 12 +- src/m_menu.c | 4 + src/m_misc.c | 7 + src/p_user.c | 17 +- src/r_main.c | 33 ++-- src/r_main.h | 2 + src/r_state.h | 5 +- 12 files changed, 288 insertions(+), 215 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index ba884f7f..885e61dd 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -174,9 +174,10 @@ int eventhead, eventtail; // void D_PostEvent(event_t *ev) { - if (ev->type == ev_mouse && !menuactive && gamestate == GS_LEVEL && !paused) + if (ev->type == ev_mouse) { G_MouseMovementResponder(ev); + G_PrepTiccmd(); return; } @@ -239,9 +240,9 @@ void D_Display (void) // [AM] Figure out how far into the current tic we're in as a fixed_t. fractionaltic = I_GetFracTime(); - if (window_focused) + if (!menuactive && gamestate == GS_LEVEL && !paused && mouse_raw_input) { - I_ReadMouse(); + I_StartDisplay(); } } diff --git a/src/g_game.c b/src/g_game.c index f3c8554f..08492a19 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -171,19 +171,18 @@ static int mousex; static int mousey; boolean dclick; -// Skip mouse if using a controller and recording in strict mode (DSDA rule). -static boolean skip_mouse = true; - -typedef struct cmd_carry_s +typedef struct carry_s { double angle; double pitch; - double strafe; + double side; double vert; -} cmd_carry_t; + short lowres; +} carry_t; -static cmd_carry_t cmd_prev_carry; -static cmd_carry_t cmd_carry; +static carry_t prevcarry; +static carry_t carry; +static ticcmd_t basecmd; boolean joyarray[MAX_JSB+1]; // [FG] support more joystick buttons boolean *joybuttons = &joyarray[1]; // allow [-1] @@ -369,93 +368,101 @@ static void G_DemoSkipTics(void) } } -static int CarryError(double value, double *prev_carry, double *carry) +static int CarryError(double value, const double *prevcarry, double *carry) { - const double desired = value + *prev_carry; + const double desired = value + *prevcarry; const int actual = lround(desired); *carry = desired - actual; return actual; } -static int CalcMouseAngle(int mousex) +static int CarryAngle(double angle) { - if (mouseSensitivity_horiz) - { - const double angle = (I_AccelerateMouse(mousex) * - (mouseSensitivity_horiz + 5) * 8 / 10); - return CarryError(angle, &cmd_prev_carry.angle, &cmd_carry.angle); - } - else - { - cmd_prev_carry.angle = 0.0; - cmd_carry.angle = 0.0; - return 0; - } + return CarryError(angle, &prevcarry.angle, &carry.angle); } -static int CalcMousePitch(int mousey) +static int CarryMousePitch(double pitch) { - if (mouseSensitivity_vert_look) - { - const double pitch = (I_AccelerateMouse(mouse_y_invert ? -mousey : mousey) * - (mouseSensitivity_vert_look + 5) / 10); - return CarryError(pitch, &cmd_prev_carry.pitch, &cmd_carry.pitch); - } - else - { - cmd_prev_carry.pitch = 0.0; - cmd_carry.pitch = 0.0; - return 0; - } + return CarryError(pitch, &prevcarry.pitch, &carry.pitch); } -static int CalcMouseStrafe(int mousex) +static int CarryMouseVert(double vert) { - if (mouseSensitivity_horiz_strafe) - { - const double desired = (cmd_prev_carry.strafe + I_AccelerateMouse(mousex) * - (mouseSensitivity_horiz_strafe + 5) * 2 / 10); - const int actual = lround(desired * 0.5) * 2; // Even values only. - cmd_carry.strafe = desired - actual; - return actual; - } - else - { - cmd_prev_carry.strafe = 0.0; - cmd_carry.strafe = 0.0; - return 0; - } + return CarryError(vert, &prevcarry.vert, &carry.vert); } -static int CalcMouseVert(int mousey) +static int CarryMouseSide(double side) { - if (mouseSensitivity_vert) - { - const double vert = (I_AccelerateMouse(mousey) * - (mouseSensitivity_vert + 5) / 10); - return CarryError(vert, &cmd_prev_carry.vert, &cmd_carry.vert); - } - else - { - cmd_prev_carry.vert = 0.0; - cmd_carry.vert = 0.0; - return 0; - } + const double desired = side + prevcarry.side; + const int actual = lround(desired * 0.5) * 2; // Even values only. + carry.side = desired - actual; + return actual; } -void G_MouseMovementResponder(const event_t *ev) +static short CarryLowResAngle(short angle) { - if (strictmode && demorecording && skip_mouse) - return; + const short desired = angle + prevcarry.lowres; + // Round to nearest 256 for single byte turning. From Chocolate Doom. + const short actual = (desired + 128) & 0xFF00; + carry.lowres = desired - actual; + return actual; +} - mousex += ev->data2; - mousey += ev->data3; +static double CalcMouseAngle(int mousex) +{ + if (!mouseSensitivity_horiz) + return 0.0; + + return (I_AccelerateMouse(mousex) * (mouseSensitivity_horiz + 5) * 8 / 10); +} + +static double CalcMousePitch(int mousey) +{ + if (!mouseSensitivity_vert_look) + return 0.0; + + return (I_AccelerateMouse(mousey) * direction[mouse_y_invert] * + (mouseSensitivity_vert_look + 5) / 10); +} + +static double CalcMouseSide(int mousex) +{ + if (!mouseSensitivity_horiz_strafe) + return 0.0; + + return (I_AccelerateMouse(mousex) * + (mouseSensitivity_horiz_strafe + 5) * 2 / 10); +} + +static double CalcMouseVert(int mousey) +{ + if (!mouseSensitivity_vert) + return 0.0; + + return (I_AccelerateMouse(mousey) * (mouseSensitivity_vert + 5) / 10); +} + +void G_PrepTiccmd(void) +{ + ticcmd_t *cmd = &basecmd; if (!M_InputGameActive(input_strafe)) - localview.angle = CalcMouseAngle(mousex); + { + localview.rawangle = -CalcMouseAngle(mousex); + cmd->angleturn = CarryAngle(localview.rawangle); + if (lowres_turn) + { + cmd->angleturn = CarryLowResAngle(cmd->angleturn); + } + localview.angle = cmd->angleturn << 16; + } if (mouselook) - localview.pitch = CalcMousePitch(mousey); + { + const double pitch = CalcMousePitch(mousey); + cmd->lookdir = CarryMousePitch(pitch); + localview.pitch = cmd->lookdir; + } } // @@ -467,98 +474,67 @@ void G_MouseMovementResponder(const event_t *ev) void G_BuildTiccmd(ticcmd_t* cmd) { - boolean strafe; - int speed; - int tspeed; - int forward; - int side; + const boolean strafe = M_InputGameActive(input_strafe); + const boolean turnleft = M_InputGameActive(input_turnleft); + const boolean turnright = M_InputGameActive(input_turnright); + // [FG] speed key inverts autorun + const int speed = autorun ^ M_InputGameActive(input_speed); // phares + int angle = 0; + int pitch = 0; + int forward = 0; + int side = 0; int newweapon; // phares - ticcmd_t *base; extern boolean boom_weapon_state_injection; static boolean done_autoswitch = false; // Assume localview can be used unless mouse input is interrupted by other - // inputs that apply turning or looking up/down (e.g. keyboard or gamepad). - localview.useangle = !lowres_turn; + // inputs that apply looking up/down (e.g. gamepad). localview.usepitch = true; G_DemoSkipTics(); - base = I_BaseTiccmd(); // empty, or external driver - memcpy(cmd, base, sizeof *cmd); + memcpy(cmd, &basecmd, sizeof(*cmd)); + memset(&basecmd, 0, sizeof(basecmd)); cmd->consistancy = consistancy[consoleplayer][maketic%BACKUPTICS]; - strafe = M_InputGameActive(input_strafe); - // [FG] speed key inverts autorun - speed = autorun ^ M_InputGameActive(input_speed); // phares - - forward = side = 0; - - // use two stage accelerative turning - // on the keyboard and joystick - if (M_InputGameActive(input_turnleft) || - M_InputGameActive(input_turnright)) - turnheld += ticdup; - else - turnheld = 0; - - if (turnheld < SLOWTURNTICS) - tspeed = 2; // slow turn - else - tspeed = speed; + // Composite input // turn 180 degrees in one keystroke? // phares - // | - if (STRICTMODE(M_InputGameActive(input_reverse))) // V - { - cmd->angleturn += (short)QUICKREVERSE; // ^ - localview.useangle = false; - M_InputGameDeactivate(input_reverse); // | - } // phares + if (STRICTMODE(M_InputGameActive(input_reverse))) + { + angle += QUICKREVERSE; + M_InputGameDeactivate(input_reverse); + } // let movement keys cancel each other out + if (turnleft || turnright) + { + turnheld += ticdup; - if (strafe) + if (strafe) { - if (M_InputGameActive(input_turnright)) + if (turnright) side += sidemove[speed]; - if (M_InputGameActive(input_turnleft)) + if (turnleft) side -= sidemove[speed]; - - if (analog_controls && controller_axes[axis_turn]) - { - fixed_t x = axis_move_sens * controller_axes[axis_turn] / 10; - x = direction[invert_turn] * x; - side += FixedMul(sidemove[speed], x); - } } - else + else { - if (M_InputGameActive(input_turnright)) - { - cmd->angleturn -= angleturn[tspeed]; - localview.useangle = false; - } - if (M_InputGameActive(input_turnleft)) - { - cmd->angleturn += angleturn[tspeed]; - localview.useangle = false; - } + // use two stage accelerative turning on the keyboard and joystick + const int tspeed = ((turnheld < SLOWTURNTICS) ? 2 : speed); - if (analog_controls && controller_axes[axis_turn]) - { - fixed_t x = controller_axes[axis_turn]; - - // response curve to compensate for lack of near-centered accuracy - x = FixedMul(FixedMul(x, x), x); - - x = direction[invert_turn] * axis_turn_sens * x / 10; - cmd->angleturn -= FixedMul(angleturn[1], x); - localview.useangle = false; - } + if (turnright) + angle -= angleturn[tspeed]; + if (turnleft) + angle += angleturn[tspeed]; } + } + else + { + turnheld = 0; + } if (M_InputGameActive(input_forward)) forward += forwardmove[speed]; @@ -569,14 +545,37 @@ void G_BuildTiccmd(ticcmd_t* cmd) if (M_InputGameActive(input_strafeleft)) side -= sidemove[speed]; + // Gamepad + if (analog_controls) { + if (controller_axes[axis_turn]) + { + if (strafe) + { + fixed_t x = axis_move_sens * controller_axes[axis_turn] / 10; + x = direction[invert_turn] * x; + side += FixedMul(sidemove[speed], x); + } + else + { + fixed_t x = controller_axes[axis_turn]; + + // response curve to compensate for lack of near-centered accuracy + x = FixedMul(FixedMul(x, x), x); + + x = direction[invert_turn] * axis_turn_sens * x / 10; + angle -= FixedMul(angleturn[1], x); + } + } + if (controller_axes[axis_forward]) { fixed_t y = axis_move_sens * controller_axes[axis_forward] / 10; y = direction[invert_forward] * y; forward -= FixedMul(forwardmove[speed], y); } + if (controller_axes[axis_strafe]) { fixed_t x = axis_move_sens * controller_axes[axis_strafe] / 10; @@ -592,12 +591,63 @@ void G_BuildTiccmd(ticcmd_t* cmd) y = FixedMul(FixedMul(y, y), y); y = direction[invert_look] * axis_look_sens * y / 10; - cmd->lookdir -= FixedMul(lookspeed[0], y); - localview.usepitch = false; + pitch -= FixedMul(lookspeed[0], y); } } - // buttons + // Mouse + + if (strafe) + { + const double mouseside = CalcMouseSide(mousex); + side += CarryMouseSide(mouseside); + } + + if (!mouselook && !novert) + { + const double mousevert = CalcMouseVert(mousey); + forward += CarryMouseVert(mousevert); + } + + // Update/reset + + if (angle) + { + angle = CarryAngle(localview.rawangle + angle); + if (lowres_turn) + { + angle = CarryLowResAngle(angle); + } + localview.ticangleturn = angle - cmd->angleturn; + cmd->angleturn = angle; + } + + if (pitch) + { + cmd->lookdir = pitch; + localview.usepitch = false; + } + + if (forward > MAXPLMOVE) + forward = MAXPLMOVE; + else if (forward < -MAXPLMOVE) + forward = -MAXPLMOVE; + if (side > MAXPLMOVE) + side = MAXPLMOVE; + else if (side < -MAXPLMOVE) + side = -MAXPLMOVE; + + cmd->forwardmove = forward; + cmd->sidemove = side; + + mousex = mousey = 0; + localview.angle = 0; + localview.pitch = 0; + localview.rawangle = 0.0; + prevcarry = carry; + + // Buttons + cmd->chatchar = HU_dequeueChatChar(); if (M_InputGameActive(input_fire)) @@ -716,33 +766,6 @@ void G_BuildTiccmd(ticcmd_t* cmd) cmd->buttons |= BT_USE; } - if (strafe) - side += CalcMouseStrafe(mousex); - else - cmd->angleturn -= localview.angle; - - if (mouselook) - cmd->lookdir += localview.pitch; - else if (!novert) - forward += CalcMouseVert(mousey); - - mousex = mousey = 0; - localview.angle = 0; - localview.pitch = 0; - cmd_prev_carry = cmd_carry; - - if (forward > MAXPLMOVE) - forward = MAXPLMOVE; - else if (forward < -MAXPLMOVE) - forward = -MAXPLMOVE; - if (side > MAXPLMOVE) - side = MAXPLMOVE; - else if (side < -MAXPLMOVE) - side = -MAXPLMOVE; - - cmd->forwardmove += forward; - cmd->sidemove += side; - // special buttons if (sendpause) { @@ -768,26 +791,6 @@ void G_BuildTiccmd(ticcmd_t* cmd) sendjoin = false; cmd->buttons |= BT_JOIN; } - - // low-res turning - - if (lowres_turn) - { - static signed short carry = 0; - signed short desired_angleturn; - - desired_angleturn = cmd->angleturn + carry; - - // round angleturn to the nearest 256 unit boundary - // for recording demos with single byte values for turn - - cmd->angleturn = (desired_angleturn + 128) & 0xff00; - - // Carry forward the error from the reduced resolution to the - // next tic, so that successive small movements can accumulate. - - carry = desired_angleturn - cmd->angleturn; - } } // @@ -898,8 +901,9 @@ static void G_DoLoadLevel(void) memset (gamekeydown, 0, sizeof(gamekeydown)); mousex = mousey = 0; memset(&localview, 0, sizeof(localview)); - memset(&cmd_carry, 0, sizeof(cmd_carry)); - memset(&cmd_prev_carry, 0, sizeof(cmd_prev_carry)); + memset(&carry, 0, sizeof(carry)); + memset(&prevcarry, 0, sizeof(prevcarry)); + memset(&basecmd, 0, sizeof(basecmd)); sendpause = sendsave = paused = false; // [FG] array size! memset (mousearray, 0, sizeof(mousearray)); @@ -970,7 +974,6 @@ static boolean G_StrictModeSkipEvent(event_t *ev) { first_event = false; enable_mouse = true; - skip_mouse = false; } return !enable_mouse; @@ -991,6 +994,23 @@ static boolean G_StrictModeSkipEvent(event_t *ev) return false; } +boolean G_MouseMovementResponder(event_t *ev) +{ + if (G_StrictModeSkipEvent(ev)) + { + return true; + } + + if (ev->type == ev_mouse) + { + mousex += ev->data2; + mousey += ev->data3; + return true; + } + + return false; +} + // // G_Responder // Get info needed to make ticcmd_ts for the players. @@ -1105,8 +1125,10 @@ boolean G_Responder(event_t* ev) return true; } - if (G_StrictModeSkipEvent(ev)) + if (G_MouseMovementResponder(ev)) + { return true; // eat events + } switch (ev->type) { @@ -1130,10 +1152,6 @@ boolean G_Responder(event_t* ev) mousebuttons[ev->data1] = false; return true; - case ev_mouse: - G_MouseMovementResponder(ev); - return true; // eat events - case ev_joyb_down: if (ev->data1 < MAX_JSB) joybuttons[ev->data1] = true; diff --git a/src/g_game.h b/src/g_game.h index 84e46892..f28529fd 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -30,7 +30,8 @@ #define MBF21_GAME_OPTION_SIZE (21 + MBF21_COMP_TOTAL) -void G_MouseMovementResponder(const event_t *ev); +void G_PrepTiccmd(void); +boolean G_MouseMovementResponder(event_t *ev); boolean G_Responder(event_t *ev); boolean G_CheckDemoStatus(void); void G_DeathMatchSpawnPlayer(int playernum); diff --git a/src/i_input.c b/src/i_input.c index 2a7a4012..1ee33e62 100644 --- a/src/i_input.c +++ b/src/i_input.c @@ -403,7 +403,6 @@ void I_ReadMouse(void) int x, y; static event_t ev; - SDL_PumpEvents(); SDL_GetRelativeMouseState(&x, &y); if (x != 0 || y != 0) diff --git a/src/i_system.h b/src/i_system.h index 0dbd1412..3057a340 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -45,6 +45,8 @@ void I_StartFrame (void); void I_StartTic (void); +void I_StartDisplay(void); + // Asynchronous interrupt functions should maintain private queues // that are read by the synchronous functions // to be converted into events. diff --git a/src/i_video.c b/src/i_video.c index 44b3dbf5..40ca2467 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -418,15 +418,25 @@ static void I_GetEvent(void) // void I_StartTic (void) { + I_GetEvent(); + if (window_focused) { I_ReadMouse(); } - I_GetEvent(); I_UpdateJoystick(); } +void I_StartDisplay(void) +{ + if (window_focused) + { + SDL_PumpEvents(); + I_ReadMouse(); + } +} + // // I_StartFrame // diff --git a/src/m_menu.c b/src/m_menu.c index 6e128f6c..348610a2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3941,6 +3941,7 @@ enum { gen5_mouse3, gen5_mouse_accel, gen5_mouse_accel_threshold, + gen5_mouse_raw_input, gen5_end1, gen5_title2, @@ -4165,6 +4166,9 @@ setup_menu_t gen_settings5[] = { // General Settings screen5 {"Mouse threshold", S_NUM, m_null, M_X, M_Y + gen5_mouse_accel_threshold * M_SPC, {"mouse_acceleration_threshold"}}, + {"Raw mouse input", S_YESNO, m_null, M_X, + M_Y+ gen5_mouse_raw_input * M_SPC, {"mouse_raw_input"}}, + {"", S_SKIP, m_null, M_X, M_Y + gen5_end1*M_SPC}, {"Miscellaneous" ,S_SKIP|S_TITLE, m_null, M_X, M_Y + gen5_title2*M_SPC}, diff --git a/src/m_misc.c b/src/m_misc.c index d8114609..fd1da7e0 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2059,6 +2059,13 @@ default_t defaults[] = { "adjust mouse acceleration threshold" }, + { + "mouse_raw_input", + (config_t *) &mouse_raw_input, NULL, + {1}, {0, 1}, number, ss_none, wad_no, + "Raw mouse input for turning/looking (0 = Interpolate, 1 = Raw)" + }, + // [FG] invert vertical axis { "mouse_y_invert", diff --git a/src/p_user.c b/src/p_user.c index fba3c56e..06e9c889 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -190,6 +190,12 @@ void P_MovePlayer (player_t* player) mo->angle += cmd->angleturn << 16; onground = mo->z <= mo->floorz; + if (player == &players[consoleplayer]) + { + localview.ticangle += localview.ticangleturn << 16; + localview.ticangleturn = 0; + } + // killough 10/98: // // We must apply thrust to the player and bobbing separately, to avoid @@ -353,6 +359,11 @@ void P_PlayerThink (player_t* player) player->oldlookdir = player->lookdir; player->oldrecoilpitch = player->recoilpitch; + if (player == &players[consoleplayer]) + { + localview.oldticangle = localview.ticangle; + } + // killough 2/8/98, 3/21/98: // (this code is necessary despite questions raised elsewhere in a comment) @@ -386,7 +397,11 @@ void P_PlayerThink (player_t* player) if (abs(player->lookdir) < 8 * MLOOKUNIT) { player->lookdir = 0; - player->centering = false; + + if (player->oldlookdir == 0) + { + player->centering = false; + } } player->slope = PLAYER_SLOPE(player); diff --git a/src/r_main.c b/src/r_main.c index 2efd3f86..45ce5c9e 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -48,6 +48,7 @@ fixed_t projection; fixed_t viewx, viewy, viewz; angle_t viewangle; localview_t localview; +boolean mouse_raw_input; fixed_t viewcos, viewsin; player_t *viewplayer; extern lighttable_t **walllights; @@ -648,10 +649,12 @@ void R_SetupFrame (player_t *player) leveltime > oldleveltime) { const boolean use_localview = ( + // Don't use localview when interpolation is preferred. + mouse_raw_input && // Don't use localview if the player is spying. player == &players[consoleplayer] && // Don't use localview if the player is dead. - player->health > 0 && + player->playerstate != PST_DEAD && // Don't use localview if the player just teleported. !player->mo->reactiontime && // Don't use localview if a demo is playing. @@ -667,12 +670,16 @@ void R_SetupFrame (player_t *player) // Use localview unless the player or game is in an invalid state or if // mouse input was interrupted, in which case fall back to interpolation. - if (localview.useangle && use_localview) - viewangle = player->mo->angle - ((short)localview.angle << FRACBITS) + viewangleoffset; + if (use_localview) + { + viewangle = (player->mo->angle + localview.angle - localview.ticangle + + R_InterpolateAngle(localview.oldticangle, localview.ticangle, + fractionaltic)); + } else - viewangle = R_InterpolateAngle(player->mo->oldangle, player->mo->angle, fractionaltic) + viewangleoffset; + viewangle = R_InterpolateAngle(player->mo->oldangle, player->mo->angle, fractionaltic); - if (localview.usepitch && use_localview && !player->centering && player->lookdir) + if (localview.usepitch && use_localview && !player->centering) pitch = (player->lookdir + localview.pitch) / MLOOKUNIT; else pitch = (player->oldlookdir + (player->lookdir - player->oldlookdir) * FIXED2DOUBLE(fractionaltic)) / MLOOKUNIT; @@ -682,13 +689,17 @@ void R_SetupFrame (player_t *player) } else { - viewx = player->mo->x; - viewy = player->mo->y; - viewz = player->viewz; // [FG] moved here - viewangle = player->mo->angle + viewangleoffset; - // [crispy] pitch is actual lookdir and weapon pitch - pitch = player->lookdir / MLOOKUNIT + player->recoilpitch; + viewx = player->mo->x; + viewy = player->mo->y; + viewz = player->viewz; // [FG] moved here + viewangle = player->mo->angle; + // [crispy] pitch is actual lookdir and weapon pitch + pitch = player->lookdir / MLOOKUNIT + player->recoilpitch; } + + // 3-screen display mode. + viewangle += viewangleoffset; + extralight = player->extralight; extralight += STRICTMODE(LIGHTBRIGHT * extra_level_brightness); diff --git a/src/r_main.h b/src/r_main.h index 20264e9a..6a127223 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -81,6 +81,8 @@ extern lighttable_t *fixedcolormap; // range of [0.0, 1.0). Used for interpolation. extern fixed_t fractionaltic; +extern boolean mouse_raw_input; + // [AM] Interpolate between two angles. angle_t R_InterpolateAngle(angle_t oangle, angle_t nangle, fixed_t scale); diff --git a/src/r_state.h b/src/r_state.h index 4c0401d3..6c14ec3e 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -90,8 +90,11 @@ extern side_t *sides; typedef struct localview_s { - boolean useangle; boolean usepitch; + angle_t oldticangle; + angle_t ticangle; + int ticangleturn; + double rawangle; int angle; int pitch; } localview_t;