// // G_BuildTiccmd // Builds a ticcmd from all of the available inputs // or reads it from the demo buffer. // If recording a demo, write it out // void G_BuildTiccmd (ticcmd_t *cmd) { int strafe; int speed; int tspeed; int forward; int side; int look; int fly; ticcmd_t *base; base = I_BaseTiccmd (); // empty, or external driver memcpy (cmd,base,sizeof(*cmd)); strafe = Actions[ACTION_STRAFE]; speed = Actions[ACTION_SPEED]; if (cl_run) speed ^= 1; forward = side = look = fly = 0; // GhostlyDeath -- USE takes us out of spectator mode if ((&consoleplayer())->spectator && Actions[ACTION_USE] && connected) { MSG_WriteMarker(&net_buffer, clc_spectate); MSG_WriteByte(&net_buffer, false); } // [RH] only use two stage accelerative turning on the keyboard // and not the joystick, since we treat the joystick as // the analog device it is. if ((Actions[ACTION_LEFT]) || (Actions[ACTION_RIGHT])) turnheld += 1; else turnheld = 0; if (turnheld < SLOWTURNTICS) tspeed = 2; // slow turn else tspeed = speed; // let movement keys cancel each other out if (strafe) { if (Actions[ACTION_RIGHT]) side += sidemove[speed]; if (Actions[ACTION_LEFT]) side -= sidemove[speed]; } else { if (Actions[ACTION_RIGHT]) cmd->ucmd.yaw -= angleturn[tspeed]; if (Actions[ACTION_LEFT]) cmd->ucmd.yaw += angleturn[tspeed]; } if (Actions[ACTION_LOOKUP]) look += lookspeed[speed]; if (Actions[ACTION_LOOKDOWN]) look -= lookspeed[speed]; if (Actions[ACTION_MOVEUP]) fly += flyspeed[speed]; if (Actions[ACTION_MOVEDOWN]) fly -= flyspeed[speed]; if (Actions[ACTION_KLOOK]) { if (Actions[ACTION_FORWARD]) look += lookspeed[speed]; if (Actions[ACTION_BACK]) look -= lookspeed[speed]; } else { if (Actions[ACTION_FORWARD]) forward += forwardmove[speed]; if (Actions[ACTION_BACK]) forward -= forwardmove[speed]; } if (Actions[ACTION_MOVERIGHT]) side += sidemove[speed]; if (Actions[ACTION_MOVELEFT]) side -= sidemove[speed]; // buttons if (Actions[ACTION_ATTACK] && ConsoleState == c_up && !headsupactive) // john - only add attack when console up cmd->ucmd.buttons |= BT_ATTACK; if (Actions[ACTION_USE]) cmd->ucmd.buttons |= BT_USE; if (Actions[ACTION_JUMP]) cmd->ucmd.buttons |= BT_JUMP; // [RH] Handle impulses. If they are between 1 and 7, // they get sent as weapon change events. if (Impulse >= 1 && Impulse <= 7) { cmd->ucmd.buttons |= BT_CHANGE; cmd->ucmd.buttons |= (Impulse - 1) << BT_WEAPONSHIFT; } else { cmd->ucmd.impulse = Impulse; } Impulse = 0; // [RH] Scale joystick moves to full range of allowed speeds if (strafe || lookstrafe) side += (MAXPLMOVE * joyxmove) / 256; else cmd->ucmd.yaw -= (angleturn[1] * joyxmove) / 256; // [RH] Scale joystick moves over full range if (Actions[ACTION_MLOOK]) { if (invertmouse) look -= (joyymove * 32767) / 256; else look += (joyymove * 32767) / 256; } else { forward += (MAXPLMOVE * joyymove) / 256; } if ((Actions[ACTION_MLOOK]) || (cl_mouselook && sv_freelook)) { int val; val = (int)((float)(mousey * 16) * m_pitch); if (invertmouse) look -= val; else look += val; } else { if (novert == 0) // [Toke - Mouse] acts like novert.exe { forward += (int)((float)mousey * m_forward); } } if (sendcenterview) { sendcenterview = false; look = -32768; } else { if (look > 32767) look = 32767; else if (look < -32767) look = -32767; } if (strafe || lookstrafe) side += (int)((float)mousex * m_side); else cmd->ucmd.yaw -= (int)((float)(mousex*0x8) * m_yaw); mousex = mousey = 0; if (forward > MAXPLMOVE) forward = MAXPLMOVE; else if (forward < -MAXPLMOVE) forward = -MAXPLMOVE; if (side > MAXPLMOVE) side = MAXPLMOVE; else if (side < -MAXPLMOVE) side = -MAXPLMOVE; cmd->ucmd.forwardmove += forward; cmd->ucmd.sidemove += side; cmd->ucmd.pitch = look; cmd->ucmd.upmove = fly; // special buttons if (sendpause) { sendpause = false; cmd->ucmd.buttons = BT_SPECIAL | BTS_PAUSE; } if (sendsave) { sendsave = false; cmd->ucmd.buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT); } cmd->ucmd.forwardmove <<= 8; cmd->ucmd.sidemove <<= 8; // [RH] 180-degree turn overrides all other yaws if (turntick) { turntick--; cmd->ucmd.yaw = (ANG180 / TURN180_TICKS) >> 16; } joyxmove = 0; joyymove = 0; }
// // G_BuildTiccmd // Builds a ticcmd from all of the available inputs // or reads it from the demo buffer. // If recording a demo, write it out // void G_BuildTiccmd (ticcmd_t* cmd, idUserCmdMgr * userCmdMgr, int newTics ) { int i; int speed; int tspeed; int forward; int side; ticcmd_t* base; base = I_BaseTiccmd (); // empty, or external driver memcpy (cmd,base,sizeof(*cmd)); cmd->consistancy = ::g->consistancy[::g->consoleplayer][::g->maketic%BACKUPTICS]; // Grab the tech5 tic so we can convert it to a doom tic. if ( userCmdMgr != NULL ) { const int playerIndex = DoomLib::GetPlayer(); if( playerIndex < 0 ) { return; } #ifdef ID_ENABLE_NETWORKING const int lobbyIndex = gameLocal->GetLobbyIndexFromDoomLibIndex( playerIndex ); const idLocalUser * const localUser = session->GetGameLobbyBase().GetLocalUserFromLobbyUser( lobbyIndex ); #else const int lobbyIndex = 0; const idLocalUser * const localUser = session->GetSignInManager().GetMasterLocalUser(); #endif if ( localUser == NULL ) { return; } usercmd_t * tech5commands[2] = { 0, 0 }; const int numCommands = userCmdMgr->GetPlayerCmds( lobbyIndex, tech5commands, 2 ); usercmd_t prevTech5Command; usercmd_t curTech5Command; // Use default commands if the manager didn't have enough. if ( numCommands == 1 ) { curTech5Command = *(tech5commands)[0]; } if ( numCommands == 2 ) { prevTech5Command = *(tech5commands)[0]; curTech5Command = *(tech5commands)[1]; } const bool isRunning = IsPlayerRunning( curTech5Command ); // tech5 move commands range from -127 o 127. Scale to doom range of -25 to 25. const float scaledForward = curTech5Command.forwardmove / 127.0f; if ( isRunning ) { cmd->forwardmove = scaledForward * 50.0f; } else { cmd->forwardmove = scaledForward * 25.0f; } // tech5 move commands range from -127 o 127. Scale to doom range of -24 to 24. const float scaledSide = curTech5Command.rightmove / 127.0f; if ( isRunning ) { cmd->sidemove = scaledSide * 40.0f; } else { cmd->sidemove = scaledSide * 24.0f; } idAngles angleDelta; angleDelta.pitch = SHORT2ANGLE( curTech5Command.angles[ 0 ] ) - SHORT2ANGLE( prevTech5Command.angles[ 0 ] ); angleDelta.yaw = SHORT2ANGLE( curTech5Command.angles[ 1 ] ) - SHORT2ANGLE( prevTech5Command.angles[ 1 ] ); angleDelta.roll = 0.0f; angleDelta.Normalize180(); // We will be running a number of tics equal to newTics before we get a new command from tech5. // So to keep input smooth, divide the angles between all the newTics. if ( newTics > 0 ) { angleDelta.yaw /= newTics; } // idAngles is stored in degrees. Convert to doom format. cmd->angleturn = DegreesToDoomAngleTurn( angleDelta.yaw ); // Translate buttons //if ( curTech5Command.inhibited == false ) { // Attack 1 attacks always, whether in the automap or not. if ( curTech5Command.buttons & BUTTON_ATTACK ) { cmd->buttons |= BT_ATTACK; } #if 0 // Attack 2 only attacks if not in the automap, because when in the automap, // it is the zoom function. if ( curTech5Command.buttons & BUTTON_ATTACK2 ) { if ( !::g->automapactive ) { cmd->buttons |= BT_ATTACK; } } #endif // Try to read any impulses that have happened. static int oldImpulseSequence = 0; if( oldImpulseSequence != curTech5Command.impulseSequence ) { G_PerformImpulse( curTech5Command.impulse, cmd ); } oldImpulseSequence = curTech5Command.impulseSequence; // weapon toggle for (i=0 ; i<NUMWEAPONS-1 ; i++) { if ( usercmdGen->KeyState( i + 1 ) ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= (i - 1) <<BT_WEAPONSHIFT; break; } } if ( curTech5Command.buttons & BUTTON_USE || curTech5Command.buttons & BUTTON_JUMP ) { cmd->buttons |= BT_USE; } // TODO: PC #if 0 if ( curTech5Command.buttons & BUTTON_WEAP_NEXT ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= 1 << BT_WEAPONSHIFT; } if ( curTech5Command.buttons & BUTTON_WEAP_PREV ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= 0 << BT_WEAPONSHIFT; } if( curTech5Command.buttons & BUTTON_WEAP_0 ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= 2 << BT_WEAPONSHIFT; } if( curTech5Command.buttons & BUTTON_WEAP_1 ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= 3 << BT_WEAPONSHIFT; } if( curTech5Command.buttons & BUTTON_WEAP_2 ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= 4 << BT_WEAPONSHIFT; } if( curTech5Command.buttons & BUTTON_WEAP_3 ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= 5 << BT_WEAPONSHIFT; } #endif //} return; } // DHM - Nerve :: Always Run setting idLocalUser * user = session->GetSignInManager().GetLocalUserByIndex( DoomLib::GetPlayer() ); if( user ) { // TODO: PC #if 0 idPlayerProfileDoom * profile = static_cast< idPlayerProfileDoom * >( user->GetProfile() ); if( profile && profile->GetAlwaysRun() ) { speed = !::g->gamekeydown[::g->key_speed]; } else #endif { speed = ::g->gamekeydown[::g->key_speed]; } } else { // Should not happen. speed = !::g->gamekeydown[::g->key_speed]; } forward = side = 0; // use two stage accelerative turning // on the keyboard and joystick if (/*:g->joyxmove != 0 ||*/ ::g->gamekeydown[::g->key_right] || ::g->gamekeydown[::g->key_left] || ::g->mousex != 0) ::g->turnheld += ::g->ticdup; else ::g->turnheld = 0; if (::g->turnheld < SLOWTURNTICS) tspeed = 2; // slow turn else tspeed = speed; // clamp for turning int mousex = ::g->mousex; int mousey = ::g->mousey; G_MouseClamp( &mousex, &mousey ); if (::g->gamekeydown[::g->key_right] /*|| ::g->joyxmove > 0*/) cmd->angleturn -= ::g->angleturn[tspeed]; else if (::g->mousex > 0) { cmd->angleturn -= tspeed == 1 ? 2 * mousex : mousex; } if (::g->gamekeydown[::g->key_left] /*|| ::g->joyxmove < 0*/) cmd->angleturn += ::g->angleturn[tspeed]; else if (::g->mousex < 0) { cmd->angleturn += tspeed == 1 ? -2 * mousex : -mousex; } if (::g->mousey > 0 || ::g->mousey < 0) { //forward += ::g->forwardmove[speed]; forward += speed == 1 ? 2 * ::g->mousey : ::g->mousey; } /* if (::g->mousey < 0) { forward -= ::g->forwardmove[speed]; } */ /* if (::g->gamekeydown[::g->key_straferight]) side += ::g->sidemove[speed]; if (::g->gamekeydown[::g->key_strafeleft]) side -= ::g->sidemove[speed]; */ if ( ::g->joyxmove > 0 || ::g->joyxmove < 0 ) { side += speed == 1 ? 2 * ::g->joyxmove : ::g->joyxmove; } // buttons if (::g->gamekeydown[::g->key_fire] || ::g->mousebuttons[::g->mousebfire] || ::g->joybuttons[::g->joybfire]) cmd->buttons |= BT_ATTACK; if (::g->gamekeydown[::g->key_use] || ::g->joybuttons[::g->joybuse] ) cmd->buttons |= BT_USE; // DHM - Nerve :: In the intermission or finale screens, make START also create a 'use' command. if ( (::g->gamestate == GS_INTERMISSION || ::g->gamestate == GS_FINALE) && ::g->gamekeydown[KEY_ESCAPE] ) { cmd->buttons |= BT_USE; } // weapon toggle for (i=0 ; i<NUMWEAPONS-1 ; i++) { if (::g->gamekeydown['1'+i]) { cmd->buttons |= BT_CHANGE; cmd->buttons |= i<<BT_WEAPONSHIFT; break; } } ::g->mousex = ::g->mousey = 0; 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 (::g->sendpause) { ::g->sendpause = false; cmd->buttons = BT_SPECIAL | BTS_PAUSE; } if (::g->sendsave) { ::g->sendsave = false; cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (::g->savegameslot<<BTS_SAVESHIFT); } }