GameClient::GameClient(bool IsAliveCheck, bool IsOpcodeCheck) :Session(SESSION_CLIENT) { SetControlFlag(CONTROL_FLAG_USE_SEND_QUEUE); if (IsAliveCheck) { SetControlFlag(CONTROL_FLAG_CHECK_ALIVE); } if (IsOpcodeCheck) { SetControlFlag(CONTROL_FLAG_CHECK_OPCODE); } SetPacketEncoder(&_packetEncoder); pServer = (GameServer*)_GetApp(); }
hsBool plAvatarInputInterface::InterpretInputEvent( plInputEventMsg *pMsg ) { if( fInputMap == nil ) return false; plMouseMap *mouseMap = fInputMap->fMouseMap; plKeyEventMsg* pKeyMsg = plKeyEventMsg::ConvertNoRef(pMsg); if( pKeyMsg ) { // Handled by key bindings } if (fMouseDisabled) return false; plMouseEventMsg* pMouseMsg = plMouseEventMsg::ConvertNoRef(pMsg); if (pMouseMsg) { uint32_t oldButtonState = fInputMap->fButtonState; // check for button presses... if (fInputMap->fButtonState & kLeftButtonDown) { fInputMap->fButtonState |= kLeftButtonRepeat; } if (fInputMap->fButtonState & kRightButtonDown) { fInputMap->fButtonState |= kRightButtonRepeat; } if (fInputMap->fButtonState & kMiddleButtonDown) { fInputMap->fButtonState |= kMiddleButtonRepeat; } if (pMouseMsg->GetButton() == kLeftButtonDown) { fInputMap->fButtonState |= kLeftButtonDown; } if (pMouseMsg->GetButton() == kLeftButtonUp) { fInputMap->fButtonState &= ~kLeftButtonDown; fInputMap->fButtonState &= ~kLeftButtonRepeat; } if (pMouseMsg->GetButton() == kRightButtonDown) { fInputMap->fButtonState |= kRightButtonDown; } if (pMouseMsg->GetButton() == kRightButtonUp) { fInputMap->fButtonState &= ~kRightButtonDown; fInputMap->fButtonState &= ~kRightButtonRepeat; } if (pMouseMsg->GetButton() == kMiddleButtonDown) { fInputMap->fButtonState |= kMiddleButtonDown; } if (pMouseMsg->GetButton() == kMiddleButtonUp) { fInputMap->fButtonState &= ~kMiddleButtonDown; fInputMap->fButtonState &= ~kMiddleButtonRepeat; } if( oldButtonState != fInputMap->fButtonState || pMouseMsg->GetDX() != 0.f || pMouseMsg->GetDY() != 0.f ) { fCursorTimeout = 0.f; // Reset cursor opacity timeout thingy } /* NOTE: I see that this interface always returns true for mouse messages, even if it does nothing with them. It ends up working because this interface is always last in the stack. Seems like a bad idea, but it works so far and I'm not going to change it unless it obviously breaks something. Still, since we say that we've handled any mouse message, I'm taking the liberty of making things simple. If a button is down, we reserve focus. If not, we release it. If things ever change so that an interface below us expects us to return false for messages we don't care about, we'll have to be more careful about reserving focus. */ if (fInputMap->fButtonState & kAnyButtonDown) fManager->SetCurrentFocus(this); else fManager->ReleaseCurrentFocus(this); for (int i=0; i < mouseMap->fMap.Count(); i++) { // is this control already set? if (IHasControlFlag(mouseMap->fMap[i]->fCode)) { // Control isn't enabled, ignore if (!IControlCodeEnabled(mouseMap->fMap[i]->fCode)) return true; // can we disable this control? hsBool disable = false; // can we disable this control based on a button? if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButton && !(fInputMap->fButtonState & kLeftButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButton && !(fInputMap->fButtonState & kRightButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButton && !(fInputMap->fButtonState & kMiddleButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && (fInputMap->fButtonState & kLeftButtonRepeat)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && (fInputMap->fButtonState & kRightButtonRepeat)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && (fInputMap->fButtonState & kMiddleButtonRepeat)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && !(fInputMap->fButtonState & kLeftButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && !(fInputMap->fButtonState & kRightButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && !(fInputMap->fButtonState & kMiddleButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonRepeat && !(fInputMap->fButtonState & kLeftButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonRepeat && !(fInputMap->fButtonState & kRightButtonDown)) disable = true; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonRepeat && !(fInputMap->fButtonState & kMiddleButtonDown)) disable = true; // can we disable this control based on the cursor position? if (!CursorInBox(pMouseMsg, mouseMap->fMap[i]->fBox) && mouseMap->fMap[i]->fControlFlags & kControlFlagBoxDisable) disable = true; if (disable) { IDeactivateCommand(mouseMap->fMap[i]); continue; } // is it a range control? If so we need to re-send the command if ((mouseMap->fMap[i]->fControlFlags & kControlFlagRangePos) || (mouseMap->fMap[i]->fControlFlags & kControlFlagRangeNeg)) { plCtrlCmd* pCmd = new plCtrlCmd( this ); pCmd->fControlActivated = true; pCmd->fControlCode = mouseMap->fMap[i]->fCode; float pct = 0.0f; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangePos) { if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent) pct = hsABS((mouseMap->fMap[i]->fBox.fX - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX)); else pct = hsABS((mouseMap->fMap[i]->fBox.fZ - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ)); } else if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangeNeg) { if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent) pct = hsABS((mouseMap->fMap[i]->fBox.fY - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX)); else pct = hsABS((mouseMap->fMap[i]->fBox.fW - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ)); } pCmd->fPct = pct; if (pct == 1.0f || pct == -1.0f) { delete pCmd; break; } pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate; fMessageQueue->Append(pCmd); } if (mouseMap->fMap[i]->fControlFlags & kControlFlagDelta) { plCtrlCmd* pCmd = new plCtrlCmd( this ); pCmd->fControlActivated = true; pCmd->fControlCode = mouseMap->fMap[i]->fCode; float pct = 0.0f; if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent) pct = pMouseMsg->GetDX(); else pct = pMouseMsg->GetDY(); if (pct == 0.f) { delete pCmd; continue; } pCmd->fPct = pct; pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate; fMessageQueue->Append(pCmd); } } else // if it is an 'always if in box' command see if it's not in the box if ( (mouseMap->fMap[i]->fControlFlags & kControlFlagInBox) && (!CursorInBox(pMouseMsg, mouseMap->fMap[i]->fBox)) ) { plCtrlCmd* pCmd = new plCtrlCmd( this ); pCmd->fControlActivated = false; pCmd->fControlCode = mouseMap->fMap[i]->fCode; pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate; fMessageQueue->Append(pCmd); continue; } else // the control is not set, see if we should set it. { // is the control disabled? if (fDisabledControls.IsBitSet(mouseMap->fMap[i]->fCode)) continue; // is the cursor in the appropriate box? if (CursorInBox(pMouseMsg, mouseMap->fMap[i]->fBox)) { // do we require a button? if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButton && !(fInputMap->fButtonState & kLeftButtonDown)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButton && !(fInputMap->fButtonState & kRightButtonDown)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButton && !(fInputMap->fButtonState & kMiddleButtonDown)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && (fInputMap->fButtonState & kLeftButtonRepeat)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && (fInputMap->fButtonState & kRightButtonRepeat)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && (fInputMap->fButtonState & kMiddleButtonRepeat)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonRepeat && !(fInputMap->fButtonState & kLeftButtonRepeat)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonRepeat && !(fInputMap->fButtonState & kRightButtonRepeat)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonRepeat && !(fInputMap->fButtonState & kMiddleButtonRepeat)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonEx && !(fInputMap->fButtonState & kLeftButtonDown)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonEx && !(fInputMap->fButtonState & kLeftButtonDown)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonEx && !(fInputMap->fButtonState & kMiddleButtonDown)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagLeftButtonUp && !(pMouseMsg->GetButton() == kLeftButtonUp)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRightButtonUp && !(pMouseMsg->GetButton() == kRightButtonUp)) continue; if (mouseMap->fMap[i]->fControlFlags & kControlFlagMiddleButtonUp && !(pMouseMsg->GetButton() == kMiddleButtonUp)) continue; // okay, we're in the box and either we don't require a button or our button is pressed. // so set the command as 'enabled' // UNLESS it has kControlFlagInBox, which means we want it sent every frame it is in the box if (!(mouseMap->fMap[i]->fControlFlags & kControlFlagInBox)) SetControlFlag(mouseMap->fMap[i]->fCode); // issue the command plCtrlCmd* pCmd = new plCtrlCmd( this ); pCmd->fControlActivated = true; pCmd->fControlCode = mouseMap->fMap[i]->fCode; pCmd->fNetPropagateToPlayers = mouseMap->fMap[i]->fControlFlags & kControlFlagNetPropagate; // figure out what percent (if any) float pct = 0.0f; if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangePos) { if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent) pct = hsABS((mouseMap->fMap[i]->fBox.fX - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX)); else pct = hsABS((mouseMap->fMap[i]->fBox.fZ - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ)); } else if (mouseMap->fMap[i]->fControlFlags & kControlFlagRangeNeg) { if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent) pct = hsABS((mouseMap->fMap[i]->fBox.fY - pMouseMsg->GetXPos()) / (mouseMap->fMap[i]->fBox.fY - mouseMap->fMap[i]->fBox.fX)); else pct = hsABS((mouseMap->fMap[i]->fBox.fW - pMouseMsg->GetYPos()) / (mouseMap->fMap[i]->fBox.fW - mouseMap->fMap[i]->fBox.fZ)); } pCmd->fPct = pct; if (pct == 1.0f || pct == -1.0f) { delete pCmd; break; } if (mouseMap->fMap[i]->fControlFlags & kControlFlagDelta) { if (mouseMap->fMap[i]->fControlFlags & kControlFlagXAxisEvent) pct = pMouseMsg->GetDX(); else pct = pMouseMsg->GetDY(); pCmd->fPct = pct; } // and add it to the list fMessageQueue->Append(pCmd); continue; } } } return true; } return false; }