/* ================== IN_RumbleFrame ================== */ void IN_RumbleFrame (void) { // Check to see if we need to pause rumbling if(cl_paused->integer && !rumbleStatus[IN_GetMainController()].paused) { IN_PauseRumbling(IN_GetMainController()); } else if(!cl_paused->integer && rumbleStatus[IN_GetMainController()].paused) { IN_UnPauseRumbling(IN_GetMainController()); } // Update the states IN_UpdateRumbleFromStates(); }
/********* IN_ControllerMustBePlugged *********/ static bool IN_ControllerMustBePlugged(int controller) { if( cls.state == CA_LOADING || cls.state == CA_CONNECTING || cls.state == CA_CONNECTED || cls.state == CA_CHALLENGING || cls.state == CA_PRIMED || cls.state == CA_CINEMATIC) { return false; } // If we're at the splash screen, have no controllers anymore, and there // was a controller ever inserted into the machine: extern bool Sys_QuickStart(); if( inSplashMenu->integer && !wasPlugged[0] && !wasPlugged[1] && !wasPlugged[2] && !wasPlugged[3] && hadAController ) return true; // If we're at the splash screen, and anything else above is false // (we have another controller, or there's never been a controller): if( inSplashMenu->integer ) return false; // OK. In all other cases, we need the main controller: return (controller == IN_GetMainController()); }
//----------------------------------------------------------------------------- // Name: SetVoiceMask // Desc: Updates the voice mask to be used //----------------------------------------------------------------------------- void CVoiceManager::SetVoiceMask( int maskIndex ) { assert( maskIndex >= 0 && maskIndex < NUM_VOICEMASKS ); m_VoiceMask = maskIndex; m_XHVVoiceManager.SetVoiceMask( IN_GetMainController(), &g_VoiceMasks[m_VoiceMask].mask ); }
//----------------------------------------------------------------------------- // Name: LeaveSession() // Desc: Blows away any leftover sockets, etc... Called when leaving a session //----------------------------------------------------------------------------- void CVoiceManager::LeaveSession( void ) { // Ensure that we're actually in a session to leave if( !m_bRunning ) return; // Clean up XHV and voice state m_XHVVoiceManager.ClearRemoteTalkers(); m_XHVVoiceManager.SetProcessingMode( IN_GetMainController(), XHV_INACTIVE_MODE ); // Close down the sockets m_DirectSock.Close(); m_ReliableSock.Close(); for( int i = 0; i < MAX_CLIENTS; ++i ) { if( m_ClientSockets[i].inUse ) { closesocket( m_ClientSockets[i].sock ); m_ClientSockets[i].inUse = false; } } /* for( SocketList::iterator it = m_ClientSockets.begin(); it < m_ClientSockets.end(); ++it ) { closesocket( it->sock ); } m_ClientSockets.clear(); */ m_bRunning = false; }
/********* IN_PadPlugged *********/ void IN_PadPlugged(int controller) { if(!wasPlugged[controller]) { Com_Printf("\tController %d plugged\n",controller); } if(IN_ControllerMustBePlugged(controller)&& SG_GameAllowedToSaveHere(qtrue)) { //If UI is dealing with this controller, tell it to stop. if(uiControllerNotification == controller || (_UIRunning && cls.state != CA_ACTIVE )) { IN_ClearControllerUnplugged(); } } else { if (controller == IN_GetMainController()) { //store somehow for checking again later mainControllerDelayedUnplug &= ~(1 << controller); } } wasPlugged[controller] = true; noControllersConnected = false; hadAController = true; }
//----------------------------------------------------------------------------- // Name: SetMute // Desc: Sets the mute state for the given user to the specified state. // Updates XHV, and also our user's global mute list (if logged on). //----------------------------------------------------------------------------- void CVoiceManager::SetMute( XUID xuid, BOOL bMuted ) { // First, set the mute state in XHV m_XHVVoiceManager.SetMute( xuid, IN_GetMainController(), bMuted ); // If we're logged on, we need to update our global list if( logged_on ) { // Make the change to our mutelist if( bMuted ) XOnlineMutelistAdd( IN_GetMainController(), xuid ); else XOnlineMutelistRemove( IN_GetMainController(), xuid ); // Signal that we've made a change. This forces Tick() to refresh // our list, just in case. m_MuteState = MUTE_WORKING; } // If the user is in our game currently, send them a message: int idx; for( idx = 0; idx < MAX_ONLINE_PLAYERS; ++idx ) { if( xbOnlineInfo.xbPlayerList[idx].isActive && XOnlineAreUsersIdentical( &xuid, &xbOnlineInfo.xbPlayerList[idx].xuid ) ) break; } // If they're not in the game, nothing else to do if( idx == MAX_ONLINE_PLAYERS ) return; // Update our flags, and let the other person know: XBPlayerInfo *plyrInfo = &xbOnlineInfo.xbPlayerList[idx]; if( bMuted ) { plyrInfo->flags |= MUTED_PLAYER; SendVoiceInfo( VOICEINFO_ADDREMOTEMUTE, plyrInfo ); } else { plyrInfo->flags &= ~(MUTED_PLAYER); SendVoiceInfo( VOICEINFO_REMOVEREMOTEMUTE, plyrInfo ); } return; }
/********** IN_CommonUpdate Updates thumbstick events based on _padInfo and ui_thumbStickMode **********/ void IN_CommonUpdate() { extern int Key_GetCatcher( void ); _UIRunning = Key_GetCatcher() == KEYCATCH_UI; // if the UI is running, then let all gamepad sticks work, else only main controller if(_UIRunning) Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[1].x * 4.0f, _padInfo.joyInfo[1].y * -4.0f, 0, NULL ); else if(_padInfo.padId == IN_GetMainController()) { // Find out how to configure the thumbsticks //int thumbStickMode = Cvar_Get("ui_thumbStickMode", "0" , 0)->integer; int thumbStickMode = cl_thumbStickMode->integer; switch(thumbStickMode) { case 0: // Configure left thumbstick to move forward/back & strafe left/right Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[0].x * 127.0f, 0, NULL ); Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[0].y * 127.0f, 0, NULL ); // Configure right thumbstick for freelook Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[1].x * 48.0f, _padInfo.joyInfo[1].y * 48.0f, 0, NULL ); break; case 1: // Configure left thumbstick for freelook Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[0].x * 48.0f, _padInfo.joyInfo[0].y * 48.0f, 0, NULL ); // Configure right thumbstick to move forward/back & strafe left/right Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[1].x * 127.0f, 0, NULL ); Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[1].y * 127.0f, 0, NULL ); break; case 2: // Configure left thumbstick to move forward/back & turn left/right Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[0].y * 127.0f, 0, NULL ); Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[0].x * 48.0f, 0.0f, 0, NULL ); // Configure right thumbstick to look up/down & strafe left/right Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[1].x * 127.f, 0, NULL ); Sys_QueEvent( 0, SE_MOUSE, 0.0f, _padInfo.joyInfo[1].y * 48.0f, 0, NULL ); break; case 3: // Configure left thumbstick to look up/down & strafe left/right Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_SIDE, _padInfo.joyInfo[0].x * 127.f, 0, NULL ); Sys_QueEvent( 0, SE_MOUSE, 0.0f, _padInfo.joyInfo[0].y * 48.0f, 0, NULL ); // Configure right thumbstick to move forward/back & turn left/right Sys_QueEvent( 0, SE_JOYSTICK_AXIS, AXIS_FORWARD, _padInfo.joyInfo[1].y * 127.0f, 0, NULL ); Sys_QueEvent( 0, SE_MOUSE, _padInfo.joyInfo[1].x * 48.0f, 0.0f, 0, NULL ); break; default: break; } } }
void FF_XboxSaberRumble( void ) { int s; s = IN_CreateRumbleScript(IN_GetMainController(), 1, true); if (s != -1) { // Add the state and execute IN_AddRumbleState(s, 55000, 55000, 100); IN_ExecuteRumbleScript(s); } }
//----------------------------------------------------------------------------- // Name: IsVoiceAllowed // Desc: Do we have a communicator, and if so, should we use it? //----------------------------------------------------------------------------- bool CVoiceManager::IsVoiceAllowed( void ) { // Without a headset, or with voice disabled, we can't talk. if( !CommunicatorPresent() || m_bVoiceDisabled ) return false; // OK. We have a headset, and we're on syslink, so it's good. if( !logged_on ) return true; return XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ); }
// extern void G_DemoKeypress(); // extern void CG_SkipCredits(void); void IN_CommonJoyPress(int controller, fakeAscii_t button, bool pressed) { // Check for special cases for map hack // This should be #ifdef'd out in FINAL_BUILD, but I really don't care. // If someone wants to copy the retail version to their modded xbox and // edit the config file to turn on maphack, let them. if (Cvar_VariableIntegerValue("cl_maphack")) { if (_UIRunning && button == A_JOY11 && pressed) { // Left trigger -> F1 Sys_QueEvent( 0, SE_KEY, A_F1, pressed, 0, NULL ); return; } else if (_UIRunning && button == A_JOY12 && pressed) { // Right trigger -> F2 Sys_QueEvent( 0, SE_KEY, A_F2, pressed, 0, NULL ); return; } else if (_UIRunning && button == A_JOY4 && pressed) { // Start button -> F3 IN_SetMainController(controller); Sys_QueEvent( 0, SE_KEY, A_F3, pressed, 0, NULL ); return; } } if(IN_GetMainController() == controller || _UIRunning) { // Always map start button to ESCAPE if (!_UIRunning && button == A_JOY4 && cls.state != CA_CINEMATIC) Sys_QueEvent( 0, SE_KEY, A_ESCAPE, pressed, 0, NULL ); #ifdef DEBUG_CONTROLLER if (controller != 3) #endif Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL ); } #ifdef DEBUG_CONTROLLER if (controller == 3 && pressed) { HandleDebugJoystickPress(button); return; } #endif }
//----------------------------------------------------------------------------- // Name: OnPlayerJoined // Desc: Called whenever someone is going to start sending or receiving chat. // Originally intended for first-join only, but now it re-checks mute // lists and such as well. //----------------------------------------------------------------------------- HRESULT CVoiceManager::OnPlayerJoined( XBPlayerInfo *plyrInfo ) { // Register the new player with XHV m_XHVVoiceManager.RegisterRemoteTalker( plyrInfo->xuid ); // VVFIXME - fancier priority scheme needed! m_XHVVoiceManager.SetRemoteTalkerPriority( plyrInfo->xuid, IN_GetMainController(), XHV_PLAYBACK_PRIORITY_MAX ); // Scan for the player in our mute list for( int i = 0; i < m_MuteListSize; ++i ) { if( XOnlineAreUsersIdentical( &m_MuteList[i].xuid, &plyrInfo->xuid ) ) { // OK. We don't like this person. Mark them muted, and tell them. plyrInfo->flags |= MUTED_PLAYER; m_XHVVoiceManager.SetMute( plyrInfo->xuid, IN_GetMainController(), TRUE ); SendVoiceInfo( VOICEINFO_ADDREMOTEMUTE, plyrInfo ); break; } } return S_OK; }
void FF_XboxShake(float intensity, int duration) { int s; s = IN_CreateRumbleScript(IN_GetMainController(), 1, true); if (s != -1) { int speed; // figure out the speed speed = (FF_SH_MIN_MOTOR_SPEED) + (FF_SH_MOTOR_SPEED_MODIFIER * intensity); // Add the state and execute IN_AddRumbleState(s, speed, speed, duration); IN_ExecuteRumbleScript(s); } }
static void IN_DisplayControllerUnplugged(int controller) { uiControllerNotification = controller; bool noControllersConnected = !wasPlugged[0] && !wasPlugged[1] && !wasPlugged[2] && !wasPlugged[3]; if ( !( cls.keyCatchers & KEYCATCH_UI ) ) { if ( cls.state == CA_ACTIVE ) { if (controller == IN_GetMainController()) { Cvar_SetValue("ControllerOutNum", controller); UI_SetActiveMenu( "ingame","noController" ); } } } else // UI { if(inSplashMenu->integer && noControllersConnected) { Cvar_SetValue("ControllerOutNum", 4); UI_SetActiveMenu("ui_popup", "noController"); } else if( controller == IN_GetMainController()) { Cvar_SetValue("ControllerOutNum", controller); UI_SetActiveMenu("ui_popup", "noController"); } } // END JLF }
bool Cheat_Yellow_Stage2( void ) { if(!enableYellowStage2) return false; if(IN_GetMainController() != 0) return false; if( g_entities[0].client && isDeathAnimation(g_entities[0].client->ps.legsAnim)) enableYellowMode = true; else enableYellowMode = false; return enableYellowMode; }
void FF_XboxDamage(int damage, float xpos) { int s; s = IN_CreateRumbleScript(IN_GetMainController(), 1, true); if (s != -1) { int leftMotorSpeed; int rightMotorSpeed; int duration; float per; duration = 175; // how much damage? if(damage > 100) { per = 1.0; } else { per = damage/100; } if(xpos >= -0.2 && xpos <= 0.2) // damge to center { leftMotorSpeed = rightMotorSpeed = (FF_DA_MIN_MOTOR_SPEED)+(FF_DA_MOTOR_SPEED_MODIFIER * per); } else if(xpos > 0.2) // damage to right { rightMotorSpeed = (FF_DA_MIN_MOTOR_SPEED)+(FF_DA_MOTOR_SPEED_MODIFIER * per); leftMotorSpeed = 0; } else // damage to left { leftMotorSpeed = (FF_DA_MIN_MOTOR_SPEED)+(FF_DA_MOTOR_SPEED_MODIFIER * per);; rightMotorSpeed = 0; } // Add the state and execute IN_AddRumbleState(s, leftMotorSpeed, rightMotorSpeed, duration); IN_ExecuteRumbleScript(s); } }
//----------------------------------------------------------------------------- // Name: SetVoiceOptions // Desc: Used by the UI to adjust voice through speakers and voice disable // voiceMode: 0 (disabled), 1 (speakers), 2 (enabled) //----------------------------------------------------------------------------- void CVoiceManager::SetVoiceOptions( int voiceMode ) { // Do nothing if we are banned - this might not be right if( logged_on && !XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ) ) return; // This should never happen, but... bool commPresent = CommunicatorPresent(); if( !commPresent && (voiceMode == 2) ) voiceMode = 1; // Store new settings: m_bVoiceDisabled = (voiceMode == 0); m_XHVVoiceManager.SetVoiceThroughSpeakers( (voiceMode == 1) ); // Update our friend notification: we have voice if not disabled, and we have a comm: if( logged_on ) XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_VOICE, (commPresent && !m_bVoiceDisabled) ); // Update our own player information, and inform other players if we're in a session if( m_bRunning ) { // We can receive voice as long as it's not disabled: if( !m_bVoiceDisabled ) xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_RECV; else xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_RECV; // We can send voice only if it's really enabled (implies that we have a comm): if( voiceMode == 2 ) xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_SEND; else xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_SEND; // Send our new state to everyone, if we have a communicator, we always // send HAVEVOICE, for TCR reasons: if( commPresent && !m_bVoiceDisabled ) SendVoiceInfo( VOICEINFO_HAVEVOICE, NULL ); else SendVoiceInfo( (VOICEINFO)voiceMode, NULL ); } }
//----------------------------------------------------------------------------- // Name: UpdateMuteList() // Desc: Fetches the user's mute list from the Live servers, and copies it // to the local stored version. We assume that we keep our own mute flags // current, and thus don't bother to update them here. (It's a waste). //----------------------------------------------------------------------------- void CVoiceManager::UpdateMuteList( void ) { if( !logged_on ) return; XONLINETASK_HANDLE handle; HRESULT hr = XOnlineMutelistGet( IN_GetMainController(), MAX_MUTELISTUSERS, NULL, &handle, &m_MuteList[0], &m_MuteListSize ); if( hr != S_OK ) { XOnlineTaskClose( handle ); m_MuteListSize = 0; return; } do { hr = XOnlineTaskContinue( handle ); } while( hr == XONLINETASK_S_RUNNING ); XOnlineTaskClose( handle ); }
bool Cheat_Yellow_Stage1( void ) { if(IN_GetMainController() != 1) return false; if(yellowModeLevel == 0) // step one, in a cutscene { extern bool in_camera; if(in_camera) { yellowModeLevel++; return true; } } else if( yellowModeLevel == 1 ) // step two, during the splash screen { if(inSplashMenu->integer) { yellowModeLevel++; return true; } } else if( yellowModeLevel == 2 ) // step three, while force hud is active { if(cg.forceHUDActive) { yellowModeLevel++; return true; } } if(yellowModeLevel == 3) // eveything is ok, now reset and move to stage 2 { enableYellowStage2 = true; yellowModeLevel = 4; return true; } return false; }
/********* IN_PadUnplugged *********/ void IN_PadUnplugged(int controller) { if(wasPlugged[controller]) { Com_Printf("\tController %d unplugged\n",controller); } //JLF moved wasPlugged[controller] = false; //IN_CheckForNoControllers(); if(IN_ControllerMustBePlugged(controller)&& SG_GameAllowedToSaveHere(qtrue)) { //If UI isn't busy, inform it about controller loss. if(uiControllerNotification == -1 && Cvar_VariableIntegerValue("ControllerOutNum")<0) { IN_DisplayControllerUnplugged(controller); mainControllerDelayedUnplug &= ~( 1<< controller); } // else // mainControllerDelayedUnplug = 1 << controller; } else { if ( controller == IN_GetMainController()) { //store somehow for checking again later mainControllerDelayedUnplug = 1 << controller; } } // wasPlugged[controller] = false; }
/********* IN_ControllerMustBePlugged *********/ static bool IN_ControllerMustBePlugged(int controller) { if( cls.state == CA_LOADING || cls.state == CA_CONNECTING || cls.state == CA_CONNECTED || cls.state == CA_CHALLENGING || cls.state == CA_PRIMED || cls.state == CA_CINEMATIC) { return false; } if(!_UIRunning && controller == IN_GetMainController()) { return true; } if(noControllersConnected) { return true; } return false; }
// extern void G_DemoKeypress(); // extern void CG_SkipCredits(void); void IN_CommonJoyPress(int controller, fakeAscii_t button, bool pressed) { // Check for special cases for map hack #ifndef FINAL_BUILD if (Cvar_VariableIntegerValue("cl_maphack")) { if (_UIRunning && button == A_JOY11 && pressed) { // Left trigger -> F1 Sys_QueEvent( 0, SE_KEY, A_F1, pressed, 0, NULL ); return; } else if (_UIRunning && button == A_JOY12 && pressed) { // Right trigger -> F2 Sys_QueEvent( 0, SE_KEY, A_F2, pressed, 0, NULL ); return; } else if (_UIRunning && button == A_JOY4 && pressed) { // Start button -> F3 IN_SetMainController(controller); Sys_QueEvent( 0, SE_KEY, A_F3, pressed, 0, NULL ); return; } } #endif if(IN_GetMainController() == controller || _UIRunning) { // Always map start button to ESCAPE if (!_UIRunning && button == A_JOY4 && cls.state != CA_CINEMATIC) Sys_QueEvent( 0, SE_KEY, A_ESCAPE, pressed, 0, NULL ); #ifndef FINAL_BUILD if (controller != 3 || !cheatPadEnabled) #endif Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL ); } /* if (pressed) { G_DemoKeypress(); } //Hacky! Skip the credits if start is pressed. if(button == K_JOY4 && pressed) { CG_SkipCredits(); } */ #ifndef FINAL_BUILD if (controller == 3 && pressed && cheatPadEnabled) { HandleDebugJoystickPress(button); return; } #endif /* extern int player1ControllerId; extern int player2ControllerId; extern bool checkForPlayerControllers; extern bool controllerUnplugged; // If the game isn't started yet if ((ClientManager::Shared().cls.cgameStarted == qfalse) && (!controllerUnplugged)) { // and player1 doesnt have a controllerid, then assign client 1 to this controller if (player1ControllerId == -1) { ClientManager::ActivateClient(0); if (ClientManager::ActiveController() != controller) ClientManager::SetActiveController(controller); } // player1 has a controller that is different then input recieved, and player2 doesnt have a controller and there are 2 clients else if (player1ControllerId != controller && player2ControllerId == -1 && ClientManager::NumClients() > 1) { ClientManager::ActivateClient(1); if (ClientManager::ActiveController() != controller) ClientManager::SetActiveController(controller); } } if (ClientManager::ActivateByControllerId(controller)) { #ifdef _XBOX //Check the status of the white or black buttons. if (button == K_JOY9) { ClientManager::ActiveClient().whiteButtonDown = pressed; } else if(button == K_JOY10) { ClientManager::ActiveClient().blackButtonDown = pressed; } //Ignore white/black button presses if inv/force/weap select is up. //This is ugly. It basically says return if the UI isn't running, if //we got a white or black button, and if the inv/force/weapon select is //running. if(!_UIRunning && (button == K_JOY9 || button == K_JOY10) && (ClientManager::ActiveClient().cg.inventorySelectTime + WEAPON_SELECT_TIME > ClientManager::ActiveClient().cg.time || ClientManager::ActiveClient().cg.forcepowerSelectTime + WEAPON_SELECT_TIME > ClientManager::ActiveClient().cg.time || ClientManager::ActiveClient().cg.weaponSelectTime + WEAPON_SELECT_TIME > ClientManager::ActiveClient().cg.time)) { if(!pressed) { //And it just gets hackier! Is that a word? It is now! //If we've released the button and it wasn't down too long... if((button == K_JOY9 && ClientManager::ActiveClient().whiteButtonHoldTime < MAX_WB_HOLD_TIME) || (button == K_JOY10 && ClientManager::ActiveClient().whiteButtonHoldTime < MAX_WB_HOLD_TIME)) { //If we've already let the button press through previously, //just send a release message. Otherwise send both a press //and release. if(ClientManager::ActiveClient().keys[button].down) { Sys_QueEvent( 0, SE_KEY, button, false, 0, NULL ); } else { Sys_QueEvent( 0, SE_KEY, button, true, 0, NULL ); Sys_QueEvent( 0, SE_KEY, button, false, 0, NULL ); } } } return; } #endif if (!_UIRunning) { Sys_QueEvent( 0, SE_KEY, button, pressed, 0, NULL ); } else { // int clientNum = ClientManager::ActiveClientNum(); int clientNum = 0; // VVFIXME int qL = uiQueueLen[clientNum]; if(qL < 5) { uiKeyQueue[clientNum][qL].button = UIJoy2Key(button); uiKeyQueue[clientNum][qL].pressed = pressed; uiQueueLen[clientNum]++; } //Sys_QueEvent(0, SE_KEY, UIJoy2Key(button), pressed, 0, NULL); } */ /* } */ }
//----------------------------------------------------------------------------- // Name: CommunicatorStatusUpdate // Desc: XHV Callback - called when the engine detects that the status of a // communicator has changed. May not be called if a communicator // is quickly removed and re-inserted, but in that case there is // nothing the game has to do. //----------------------------------------------------------------------------- HRESULT CVoiceManager::CommunicatorStatusUpdate( DWORD dwPort, XHV_VOICE_COMMUNICATOR_STATUS status ) { // If we're not initialized, then do nothing if( !m_bInitialized ) return S_OK; if( status == XHV_VOICE_COMMUNICATOR_STATUS_INSERTED ) { // Got a new headset: // Let the UI know that we have a headset, so it can enable things! Cvar_SetValue( "ui_headset", 1 ); // Awful UI hack. If we're on the online options screen, move off any item // that just became disabled. menuDef_t *menu = Menu_GetFocused(); if( menu && !Q_stricmp(menu->window.name, "xbl_onlineoptions") ) { VM_Call( uivm, UI_KEY_EVENT, A_CURSOR_DOWN, qtrue ); // Send a "move the cursor down" // Also, if we had "Speakers" selected, switch it to "Enabled" if( Cvar_VariableIntegerValue( "ui_voiceMode" ) == 1 ) Cvar_SetValue( "ui_voiceMode", 2 ); } // Always re-route voice to headset m_XHVVoiceManager.SetVoiceThroughSpeakers( FALSE ); // Don't do anything else if banned, or voice is disabled: if( m_bVoiceDisabled || (logged_on && !XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ) ) ) return S_OK; // If we're logged onto live, update our voice flag if( logged_on ) XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_VOICE, true ); // Finally, if we're in a session, update our status and tell everyone: if( m_bRunning ) { xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_RECV; xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_SEND; SendVoiceInfo( VOICEINFO_HAVEVOICE, NULL ); } } else if( status == XHV_VOICE_COMMUNICATOR_STATUS_REMOVED ) { // Lost a headset: // Let the UI know that we don't have a headset, so it can disable things! Cvar_SetValue( "ui_headset", 0 ); // Awful UI hack. If we're on the online options screen, move off any item // that just became disabled. menuDef_t *menu = Menu_GetFocused(); if( menu && !Q_stricmp(menu->window.name, "xbl_onlineoptions") ) { VM_Call( uivm, UI_KEY_EVENT, A_CURSOR_UP, qtrue ); // Send a "move the cursor up" // Also, if we had "Enabled" selected, that's no longer valid. Change ui_voiceMode: if( Cvar_VariableIntegerValue( "ui_voiceMode" ) == 2 ) Cvar_SetValue( "ui_voiceMode", 1 ); } // If the user pulls the headset and it was set to "speakers" or "enabled", // then change to "speakers" m_XHVVoiceManager.SetVoiceThroughSpeakers( !m_bVoiceDisabled ); // Don't do anything else if banned, or voice is disabled: if( m_bVoiceDisabled || (logged_on && !XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ) ) ) return S_OK; // If we're logged onto live, update our voice flag if( logged_on ) XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_VOICE, false ); // Finally, if we're in a session, update our status and tell everyone: if( m_bRunning ) { xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_RECV; xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_SEND; SendVoiceInfo( VOICEINFO_SPEAKERS, NULL ); } } return S_OK; }
//----------------------------------------------------------------------------- // Name: JoinSession() // Desc: Opens the reliable socket to the host, this puts us in the chat system // Old code then sent a Join, and then waited for an accept. And THEN // called StartVoice() to get voice running. I do that all now - hope // no other problems surface. //----------------------------------------------------------------------------- void CVoiceManager::JoinSession( void ) { // If we were already in a session, then don't do anything. if( m_bRunning ) return; // The direct socket is a non-blocking socket on port DIRECT_PORT. BOOL bSuccess = m_DirectSock.Open( CXBSocket::Type_VDP ); if( !bSuccess ) { Com_Error( ERR_FATAL, "Couldn't open VDP socket: %i\n", WSAGetLastError() ); } CXBSockAddr directAddr( INADDR_ANY, DIRECT_PORT ); INT iResult = m_DirectSock.Bind( directAddr.GetPtr() ); assert( iResult != SOCKET_ERROR ); DWORD dwNonBlocking = 1; iResult = m_DirectSock.IoCtlSocket( FIONBIO, &dwNonBlocking ); assert( iResult != SOCKET_ERROR ); // Create a reliable socket for low-bandwidth messages that need to be // sent reliably. bSuccess = m_ReliableSock.Open( CXBSocket::Type_TCP ); assert( bSuccess ); CXBSockAddr reliableAddr( INADDR_ANY, RELIABLE_PORT ); iResult = m_ReliableSock.Bind( reliableAddr.GetPtr() ); assert( iResult != SOCKET_ERROR ); iResult = m_ReliableSock.IoCtlSocket( FIONBIO, &dwNonBlocking ); assert( iResult != SOCKET_ERROR ); // Above code was in InitSockets() // Grab some useful things: bool commPresent = CommunicatorPresent(); bool speakers = VoiceThroughSpeakers(); // Being banned forces voice to be disabled: if( logged_on && !XOnlineIsUserVoiceAllowed( XBLLoggedOnUsers[ IN_GetMainController() ].xuid.dwUserFlags ) ) m_bVoiceDisabled = true; // Disabled voice implies (and overrides) no speakers: if( m_bVoiceDisabled ) { m_XHVVoiceManager.SetVoiceThroughSpeakers( FALSE ); speakers = false; } // If not disabled, we can always listen (through speakers) if( !m_bVoiceDisabled ) xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_RECV; else xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_RECV; // To talk, we need a communicator, and we need to not be banned, // and speakers needs to be off, and voice needs to be enabled: if( commPresent && !speakers && !m_bVoiceDisabled ) xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags |= VOICE_CAN_SEND; else xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].flags &= ~VOICE_CAN_SEND; // Open up a reliable socket to the host - this will be used // for low-bandwidth communication. We have to wait for the connection // to complete before doing anything else? if( com_sv_running->integer ) { // Start listening for new clients m_ReliableSock.Listen(); } else { // This now triggers everyone knowing that we're ready for voice CXBSockAddr saHost( xbc.SrvAddr, RELIABLE_PORT ); m_ReliableSock.Connect( saHost.GetPtr() ); // Wait for the socket to finish connecting BOOL socketWritable; while ( !m_ReliableSock.Select( NULL, &socketWritable, NULL ) ) ; // We send a voiceinfo message to tell people our voice configuration VOICEINFO vState; if( m_bVoiceDisabled ) vState = VOICEINFO_NOVOICE; else if( commPresent ) vState = VOICEINFO_HAVEVOICE; else vState = VOICEINFO_SPEAKERS; SendVoiceInfo( vState, NULL ); } // Code that used to be in StartVoice() m_msgVoiceData.GetMsgVoiceData().wVoicePackets = 0; m_VoiceTimer = Sys_Milliseconds() + VOICE_PACKET_INTERVAL; // Put communicator into voice chat mode m_XHVVoiceManager.SetProcessingMode( IN_GetMainController(), XHV_VOICECHAT_MODE ); // If we don't have a communicator, and we're not banned, send voice to speakers //m_XHVVoiceManager.SetVoiceThroughSpeakers( !commPresent && !voiceBanned ); // Finally, register everyone that's already in the game and can send or receive voice: for( int i = 0; i < MAX_ONLINE_PLAYERS; ++i ) { if( i == xbOnlineInfo.localIndex || !xbOnlineInfo.xbPlayerList[i].isActive || !(xbOnlineInfo.xbPlayerList[i].flags & VOICE_CAN_RECV) ) { continue; } // We should never get here as a server assert( !com_sv_running->integer ); OnPlayerJoined( &xbOnlineInfo.xbPlayerList[i] ); } // Reset initial channel m_Channel = CHAN_PRIMARY; // Set our voice mask from user settings: SetVoiceMask( Settings.voiceMask ); // And try to re-apply the stored voice mode: SetVoiceOptions( Settings.voiceMode ); m_bRunning = true; }
void IN_CommonJoyPress(int controller, fakeAscii_t button, bool pressed) { #ifdef XBOX_DEMO // Reset the demo timer so that we don't auto-reboot to CDX extern void Demo_TimerKeypress( void ); Demo_TimerKeypress(); #endif lastControllerUsed = controller; // Cheat system hooks. The right thumbstick button has to be held for a cheat: if (button == A_JOY3) { if (pressed) { // Just pressed the right thumstick in. Reset cheat detector enteringCheat = true; cheatLength = 0; } else { enteringCheat = false; if (cheatLength == 6) { for( int i = 0; i < numCheats; ++i) { if( memcmp( &cheats[i].buttons[0], &curCheat[0], sizeof(curCheat) ) == 0 ) { if(cheats[i].function()) S_StartLocalSound( S_RegisterSound( "sound/vehicles/x-wing/s-foil" ), CHAN_AUTO ); } } } } } else if (enteringCheat && pressed) { // Handle all other buttons while entering a cheat if (cheatLength == 6 || (button != A_JOY5 && button != A_JOY6 && button != A_JOY7 && button != A_JOY8)) { // If we press too many buttons, or anything but the D-pad, cancel entry: enteringCheat = false; cheatLength = 0; } else { // We pressed a d-pad button, we're entering a cheat, and there's still room curCheat[cheatLength++] = button; } } // Check for special cases for map hack #ifndef FINAL_BUILD if (Cvar_VariableIntegerValue("cl_maphack")) { if (_UIRunning && button == A_JOY11 && pressed) { // Left trigger -> F1 Sys_QueEvent( 0, SE_KEY, A_F1, pressed, 0, NULL ); return; } else if (_UIRunning && button == A_JOY12 && pressed) { // Right trigger -> F2 Sys_QueEvent( 0, SE_KEY, A_F2, pressed, 0, NULL ); return; } else if (_UIRunning && button == A_JOY4 && pressed) { // Start button -> F3 //IN_SetMainController(controller); Sys_QueEvent( 0, SE_KEY, A_F3, pressed, 0, NULL ); return; } } #endif if(inSplashMenu->integer) { // START always works, A only works if the popup isn't shown: if(button == A_JOY4 || (button == A_JOY15 && controllerOut->integer < 0)) { Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL ); } return; } int controllerout = controllerOut->integer; if(controllerout != -1) { if(controllerout == controller && (button == A_JOY4))// || button == A_JOY15)) Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL ); return; } if(IN_GetMainController() == controller ) { // Always map start button to ESCAPE if (!_UIRunning && button == A_JOY4 && cls.state != CA_CINEMATIC) Sys_QueEvent( 0, SE_KEY, A_ESCAPE, pressed, 0, NULL ); #ifdef DEBUG_CONTROLLER if (controller != 3) #endif Sys_QueEvent( 0, SE_KEY, _UIRunning ? UIJoy2Key(button) : button, pressed, 0, NULL ); } #ifdef DEBUG_CONTROLLER if (controller == 3 && pressed) { HandleDebugJoystickPress(button); return; } #endif //JLF }
void FF_Play(ffFX_e effect) { int s; // script id static int const_rumble[2] = {-1}; // script id for constant rumble int client; // super huge switch for rumble effects switch(effect) { case fffx_AircraftCarrierTakeOff: case fffx_BasketballDribble: case fffx_CarEngineIdle: case fffx_ChainsawIdle: case fffx_ChainsawInAction: case fffx_DieselEngineIdle: case fffx_Jump: s = IN_CreateRumbleScript(IN_GetMainController(), 2, true); if (s != -1) { IN_AddRumbleState(s, 50000, 10000, 200); IN_AddRumbleState(s, 0, 0, 10); IN_ExecuteRumbleScript(s); } break; case fffx_Land: s = IN_CreateRumbleScript(IN_GetMainController(), 2, true); if (s != -1) { IN_AddRumbleState(s, 50000, 10000, 200); IN_AddRumbleState(s, 0, 0, 10); IN_ExecuteRumbleScript(s); } break; case fffx_MachineGun: s = IN_CreateRumbleScript(IN_GetMainController(), 2, true); if (s != -1) { IN_AddRumbleState(s, 56000, 20000, 230); IN_AddRumbleState(s, 0, 0, 10); IN_ExecuteRumbleScript(s); } break; case fffx_Punched: case fffx_RocketLaunch: case fffx_SecretDoor: case fffx_SwitchClick: // used by saber s = IN_CreateRumbleScript(IN_GetMainController(), 1, true); if (s != -1) { IN_AddRumbleState(s, 30000, 10000, 120); IN_ExecuteRumbleScript(s); } break; case fffx_WindGust: case fffx_WindShear: case fffx_Pistol: s = IN_CreateRumbleScript(IN_GetMainController(), 2, true); if (s != -1) { IN_AddRumbleState(s, 50000, 10000, 200); IN_AddRumbleState(s, 0, 0, 10); IN_ExecuteRumbleScript(s); } break; case fffx_Shotgun: case fffx_Laser1: case fffx_Laser2: case fffx_Laser3: case fffx_Laser4: case fffx_Laser5: case fffx_Laser6: case fffx_OutOfAmmo: case fffx_LightningGun: case fffx_Missile: case fffx_GatlingGun: s = IN_CreateRumbleScript(IN_GetMainController(), 2, true); if (s != -1) { IN_AddRumbleState(s, 39000, 0, 220); IN_AddRumbleState(s, 0, 0, 10); IN_ExecuteRumbleScript(s); } break; case fffx_ShortPlasma: case fffx_PlasmaCannon1: case fffx_PlasmaCannon2: case fffx_Cannon: case fffx_FallingShort: case fffx_FallingMedium: s = IN_CreateRumbleScript(IN_GetMainController(), 1, true); if (s != -1) { IN_AddRumbleState(s, 25000,10000, 230); IN_ExecuteRumbleScript(s); } break; case fffx_FallingFar: s = IN_CreateRumbleScript(IN_GetMainController(), 1, true); if (s != -1) { IN_AddRumbleState(s, 32000,10000, 230); IN_ExecuteRumbleScript(s); } break; case fffx_StartConst: client = IN_GetMainController(); if(const_rumble[client] == -1) { const_rumble[client] = IN_CreateRumbleScript(IN_GetMainController(), 9, true); if (const_rumble[client] != -1) { IN_AddEffectFade4(const_rumble[client], 0,0, 50000, 0, 2000); IN_AddRumbleState(const_rumble[client], 50000, 0, 300); IN_AddEffectFade4(const_rumble[client], 50000,50000, 0, 0, 1000); IN_ExecuteRumbleScript(const_rumble[client]); } } break; case fffx_StopConst: client = IN_GetMainController(); if (const_rumble[client] == -1) return; IN_KillRumbleScript(const_rumble[client]); const_rumble[client] = -1; break; default: Com_Printf("No rumble script is defined for fffx_id = %i\n",effect); break; } }
//----------------------------------------------------------------------------- // Name: ProcessVoiceInfo() // Desc: Process the voiceport message //----------------------------------------------------------------------------- void CVoiceManager::ProcessVoiceInfo( const MsgVoiceInfo& msg, const CXBSockAddr& saFrom ) { // We can't just look at the INADDR of the sender, since this message // may have been relayed by the host int idx; for ( idx = 0; idx < MAX_ONLINE_PLAYERS; ++idx ) { if( xbOnlineInfo.xbPlayerList[idx].isActive && xbOnlineInfo.xbPlayerList[idx].refIndex == msg.srcRefIndex ) break; } // If we get a message from an invalid player, ignore it if( idx == MAX_ONLINE_PLAYERS ) { Com_Printf( "ERROR: VoiceInfo from invalid player!\n" ); return; } XBPlayerInfo *srcPlyr = &xbOnlineInfo.xbPlayerList[idx]; // This message may or may not be intended for us. If there's no // destination player specified, it's meant for everyone. Otherwise, // we should only process it if it's got our name on it if( msg.dstRefIndex == -1 || msg.dstRefIndex == xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].refIndex ) { switch( msg.action ) { case VOICEINFO_NOVOICE: // This player wants no voice, or has been banned srcPlyr->flags &= ~VOICE_CAN_SEND; srcPlyr->flags &= ~VOICE_CAN_RECV; break; case VOICEINFO_SPEAKERS: // This player will only be receiving voice, not sending it srcPlyr->flags &= ~VOICE_CAN_SEND; srcPlyr->flags |= VOICE_CAN_RECV; // We still register them with XHV, to check against our mute list OnPlayerJoined( srcPlyr ); break; case VOICEINFO_HAVEVOICE: // This player will be sending and receiving voice srcPlyr->flags |= VOICE_CAN_SEND; srcPlyr->flags |= VOICE_CAN_RECV; // Register them with XHV, and check mute lists OnPlayerJoined( srcPlyr ); break; case VOICEINFO_ADDREMOTEMUTE: // We've been muted by someone srcPlyr->flags |= REMOTE_MUTED; m_XHVVoiceManager.SetRemoteMute( srcPlyr->xuid, IN_GetMainController(), TRUE ); break; case VOICEINFO_REMOVEREMOTEMUTE: // We've been un-muted by someone srcPlyr->flags &= ~(REMOTE_MUTED); m_XHVVoiceManager.SetRemoteMute( srcPlyr->xuid, IN_GetMainController(), FALSE ); break; default: assert( FALSE ); break; } } // If the host wasn't the recipient of this message, or the message // is intended for all players, it's the host's responsibility to // relay it to all clients if( com_sv_running->integer ) { InfoMessage msgVoiceInfo; msgVoiceInfo.GetMsgVoiceInfo() = msg; if( msg.dstRefIndex == -1 ) { // Intended for everyone - send to all BUT the source // for( SocketList::iterator it = m_ClientSockets.begin(); // it < m_ClientSockets.end(); // ++it ) for( int i = 0; i < MAX_CLIENTS; ++i ) { if( !m_ClientSockets[i].inUse ) continue; ClientSocket *it = &m_ClientSockets[i]; if( it->sa.sin_addr.s_addr != saFrom.GetInAddr().s_addr ) { CXBSockAddr saDest( it->sa ); SendInfoMessage( &msgVoiceInfo, &saDest ); } } } else if( msg.dstRefIndex != xbOnlineInfo.xbPlayerList[xbOnlineInfo.localIndex].refIndex ) { // Intended for a specific player (not us) - Find that player and send to them for( int i = 0; i < MAX_ONLINE_PLAYERS; ++i ) { if( xbOnlineInfo.xbPlayerList[i].isActive && xbOnlineInfo.xbPlayerList[i].refIndex == msg.dstRefIndex ) { CXBSockAddr saDest( xbOnlineInfo.xbPlayerList[i].inAddr, RELIABLE_PORT ); SendInfoMessage( &msgVoiceInfo, &saDest ); } } } } }
//----------------------------------------------------------------------------- // Name: CommunicatorPresent // Desc: Tells whether or not we have a communicator plugged in //----------------------------------------------------------------------------- bool CVoiceManager::CommunicatorPresent( void ) { XHV_LOCAL_TALKER_STATUS status; m_XHVVoiceManager.GetLocalTalkerStatus( IN_GetMainController(), &status ); return status.communicatorStatus == XHV_VOICE_COMMUNICATOR_STATUS_INSERTED; }
void SV_SpawnServer( char *server, qboolean killBots, ForceReload_e eForceReload ) { int i; int checksum; qboolean isBot; char systemInfo[16384]; const char *p; SV_SendMapChange(); RE_RegisterMedia_LevelLoadBegin(server, eForceReload); // shut down the existing game if it is running SV_ShutdownGameProgs(); Com_Printf ("------ Server Initialization ------\n"); Com_Printf ("Server: %s\n",server); /* Ghoul2 Insert Start */ // de allocate the snapshot entities if (svs.snapshotEntities) { delete[] svs.snapshotEntities; svs.snapshotEntities = NULL; } /* Ghoul2 Insert End */ SV_SendMapChange(); #ifdef _XBOX // disable vsync during load for speed qglDisable(GL_VSYNC); #endif // if not running a dedicated server CL_MapLoading will connect the client to the server // also print some status stuff CL_MapLoading(); #ifndef DEDICATED // make sure all the client stuff is unloaded CL_ShutdownAll(); #endif CM_ClearMap(); #ifdef _XBOX R_DeleteTextures(); #endif // clear the whole hunk because we're (re)loading the server Hunk_Clear(); #ifdef _XBOX SV_ClearLastLevel(); ClientManager::ActivateClient(0); #endif R_InitSkins(); R_InitShaders(qtrue); // This was in SV_DedicatedSpawn, but it gets in the way of my memory maps: if( com_dedicated->integer ) { // Textures have been blown away - need to kill font system so it // will re-register shaders when UI re-scans menu files below: extern void R_ShutdownFonts( void ); R_ShutdownFonts(); } ClientManager::ClientActiveRelocate( !com_dedicated->integer && !ClientManager::splitScreenMode ); #if defined(_XBOX) && !defined(FINAL_BUILD) //Useful for memory debugging. Please don't delete. Comment out if //necessary. extern void Z_DisplayLevelMemory(int, int, int); extern void Z_Details_f(void); extern void Z_TagPointers(memtag_t); Z_DisplayLevelMemory(0, 0, 0); Z_TagPointers( TAG_ALL ); Z_Details_f(); #endif // init client structures and svs.numSnapshotEntities if ( !Cvar_VariableValue("sv_running") ) { SV_Startup(); } else { // check for maxclients change if ( sv_maxclients->modified ) { SV_ChangeMaxClients(); } } // Do dedicated server-specific startup if ( com_dedicated->integer ) { SV_DedicatedSpawn(server); } // Xbox - Correct various problems with broken rules settings when people // change gametype in-game, etc... SV_FixBrokenRules(); SV_SendMapChange(); /* Ghoul2 Insert Start */ // clear out those shaders, images and Models as long as this // isnt a dedicated server. /* if ( !com_dedicated->integer ) { #ifndef DEDICATED R_InitImages(); R_InitShaders(); R_ModelInit(); #endif } else */ if (com_dedicated->integer) { R_SVModelInit(); } SV_SendMapChange(); // clear pak references FS_ClearPakReferences(0); /* Ghoul2 Insert Start */ // allocate the snapshot entities on the hunk // svs.snapshotEntities = (struct entityState_s *)Hunk_Alloc( sizeof(entityState_t)*svs.numSnapshotEntities, h_high ); svs.nextSnapshotEntities = 0; // allocate the snapshot entities svs.snapshotEntities = new entityState_s[svs.numSnapshotEntities]; // we CAN afford to do this here, since we know the STL vectors in Ghoul2 are empty memset(svs.snapshotEntities, 0, sizeof(entityState_t)*svs.numSnapshotEntities); /* Ghoul2 Insert End */ // toggle the server bit so clients can detect that a // server has changed svs.snapFlagServerBit ^= SNAPFLAG_SERVERCOUNT; // set nextmap to the same map, but it may be overriden // by the game startup or another console command Cvar_Set( "nextmap", "map_restart 0"); // Cvar_Set( "nextmap", va("map %s", server) ); // wipe the entire per-level structure SV_ClearServer(); for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) { sv.configstrings[i] = CopyString(""); } //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END // make sure we are not paused Cvar_Set("cl_paused", "0"); // get a new checksum feed and restart the file system srand(Com_Milliseconds()); sv.checksumFeed = ( ((int) rand() << 16) ^ rand() ) ^ Com_Milliseconds(); FS_Restart( sv.checksumFeed ); #ifdef _XBOX CL_StartHunkUsers(); CM_LoadMap( va("maps/%s.bsp", server), qfalse, &checksum ); // RE_LoadWorldMap(va("maps/%s.bsp", server)); // Start up voice system if it isn't running yet. (ie, if we're on syslink) if( !logged_on ) g_Voice.Initialize(); #else CM_LoadMap( va("maps/%s.bsp", server), qfalse, &checksum ); #endif SV_SendMapChange(); // set serverinfo visible name Cvar_Set( "mapname", server ); Cvar_Set( "sv_mapChecksum", va("%i",checksum) ); // serverid should be different each time sv.serverId = com_frameTime; sv.restartedServerId = sv.serverId; Cvar_Set( "sv_serverid", va("%i", sv.serverId ) ); // clear physics interaction links SV_ClearWorld (); // media configstring setting should be done during // the loading stage, so connected clients don't have // to load during actual gameplay sv.state = SS_LOADING; // load and spawn all other entities SV_InitGameProgs(); // don't allow a map_restart if game is modified sv_gametype->modified = qfalse; // run a few frames to allow everything to settle for ( i = 0 ;i < 3 ; i++ ) { //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END VM_Call( gvm, GAME_RUN_FRAME, svs.time ); SV_BotFrame( svs.time ); svs.time += 100; } //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END // create a baseline for more efficient communications SV_CreateBaseline (); for (i=0 ; i<sv_maxclients->integer ; i++) { // send the new gamestate to all connected clients if (svs.clients[i].state >= CS_CONNECTED) { char *denied; if ( svs.clients[i].netchan.remoteAddress.type == NA_BOT ) { if ( killBots ) { SV_DropClient( &svs.clients[i], "" ); continue; } isBot = qtrue; } else { isBot = qfalse; } // connect the client again denied = (char *)VM_ExplicitArgPtr( gvm, VM_Call( gvm, GAME_CLIENT_CONNECT, i, qfalse, isBot ) ); // firstTime = qfalse if ( denied ) { // this generally shouldn't happen, because the client // was connected before the level change // SV_DropClient( &svs.clients[i], denied ); SV_DropClient( &svs.clients[i], "@MENUS_LOST_CONNECTION" ); } else { if( !isBot ) { // when we get the next packet from a connected client, // the new gamestate will be sent svs.clients[i].state = CS_CONNECTED; } else { client_t *client; sharedEntity_t *ent; client = &svs.clients[i]; client->state = CS_ACTIVE; ent = SV_GentityNum( i ); ent->s.number = i; client->gentity = ent; client->deltaMessage = -1; client->nextSnapshotTime = svs.time; // generate a snapshot immediately VM_Call( gvm, GAME_CLIENT_BEGIN, i ); } } } } // run another frame to allow things to look at all the players VM_Call( gvm, GAME_RUN_FRAME, svs.time ); SV_BotFrame( svs.time ); svs.time += 100; //rww - RAGDOLL_BEGIN G2API_SetTime(svs.time,0); //rww - RAGDOLL_END if ( sv_pure->integer ) { // the server sends these to the clients so they will only // load pk3s also loaded at the server p = FS_LoadedPakChecksums(); Cvar_Set( "sv_paks", p ); if (strlen(p) == 0) { Com_Printf( "WARNING: sv_pure set but no PK3 files loaded\n" ); } p = FS_LoadedPakNames(); Cvar_Set( "sv_pakNames", p ); // if a dedicated pure server we need to touch the cgame because it could be in a // seperate pk3 file and the client will need to load the latest cgame.qvm if ( com_dedicated->integer ) { SV_TouchCGame(); } } else { Cvar_Set( "sv_paks", "" ); Cvar_Set( "sv_pakNames", "" ); } // the server sends these to the clients so they can figure // out which pk3s should be auto-downloaded p = FS_ReferencedPakChecksums(); Cvar_Set( "sv_referencedPaks", p ); p = FS_ReferencedPakNames(); Cvar_Set( "sv_referencedPakNames", p ); // save systeminfo and serverinfo strings Q_strncpyz( systemInfo, Cvar_InfoString_Big( CVAR_SYSTEMINFO ), sizeof( systemInfo ) ); cvar_modifiedFlags &= ~CVAR_SYSTEMINFO; SV_SetConfigstring( CS_SYSTEMINFO, systemInfo ); SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) ); cvar_modifiedFlags &= ~CVAR_SERVERINFO; // any media configstring setting now should issue a warning // and any configstring changes should be reliably transmitted // to all clients sv.state = SS_GAME; // send a heartbeat now so the master will get up to date info SV_Heartbeat_f(); Hunk_SetMark(); /* MrE: 2000-09-13: now called in CL_DownloadsComplete // don't call when running dedicated if ( !com_dedicated->integer ) { // note that this is called after setting the hunk mark with Hunk_SetMark CL_StartHunkUsers(); } */ // Xbox - Dedicated servers need to do extra work here. Most of this is done in // cl_parse normally, but that never runs in this case: if ( com_dedicated->integer ) { // Normally, we start advertising when we get the first snapshot. // Do it now. This is also necessary so that Net_GetXNKID works below. XBL_MM_Advertise(); // We need to put ourselves into the playerlist. xbOnlineInfo.localIndex = DEDICATED_SERVER_INDEX; XBPlayerInfo *plyrInfo = &xbOnlineInfo.xbPlayerList[DEDICATED_SERVER_INDEX]; memset( plyrInfo, 0, sizeof(XBPlayerInfo) ); // We get the first refIndex plyrInfo->refIndex = svs.clientRefNum++; // Address information plyrInfo->xbAddr = *Net_GetXNADDR( NULL ); XNetXnAddrToInAddr( &plyrInfo->xbAddr, Net_GetXNKID(), &plyrInfo->inAddr ); // Gamertag and XUID Q_strncpyz( plyrInfo->name, Cvar_VariableString("name"), sizeof(plyrInfo->name) ); XONLINE_USER *pUser; if (logged_on && (pUser = &XBLLoggedOnUsers[ IN_GetMainController() ]) && (pUser->hr == S_OK)) plyrInfo->xuid = pUser->xuid; else plyrInfo->xuid.qwUserID = plyrInfo->refIndex; plyrInfo->isActive = true; // Start up the voice chat session g_Voice.JoinSession(); // And mark ourselves as playing, so that others can join our game: XBL_F_SetState( XONLINE_FRIENDSTATE_FLAG_PLAYING, true ); } }