⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actionmap.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 4 页
字号:
   pRetNode->deadZoneEnd   = 0.0;
   pRetNode->scaleFactor   = 1.0;

   pRetNode->consoleFunction = NULL;
   pRetNode->makeConsoleCommand = NULL;
   pRetNode->breakConsoleCommand = NULL;

   return pRetNode;
}

//------------------------------------------------------------------------------
void ActionMap::removeNode(const U32 inDeviceType, const U32 inDeviceInst, const U32 inModifiers, const U32 inAction)
{
   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
   //
   DeviceMap* pDeviceMap = NULL;
   U32 i;
   for (i = 0; i < mDeviceMaps.size(); i++) {
      if (mDeviceMaps[i]->deviceType == inDeviceType &&
          mDeviceMaps[i]->deviceInst == inDeviceInst) {
         pDeviceMap = mDeviceMaps[i];
         break;
      }
   }

   if (pDeviceMap == NULL)
      return;

   U32 realMods = inModifiers;
   if (realMods & SI_SHIFT)
      realMods |= SI_SHIFT;
   if (realMods & SI_CTRL)
      realMods |= SI_CTRL;
   if (realMods & SI_ALT)
      realMods |= SI_ALT;
   if (realMods & SI_MAC_OPT)
      realMods |= SI_MAC_OPT;

   for (i = 0; i < pDeviceMap->nodeMap.size(); i++) {
      if (pDeviceMap->nodeMap[i].modifiers == realMods &&
          pDeviceMap->nodeMap[i].action    == inAction) {
          dFree(pDeviceMap->nodeMap[i].makeConsoleCommand);
          dFree(pDeviceMap->nodeMap[i].breakConsoleCommand);
          pDeviceMap->nodeMap.erase(i);
      }
   }
}

//------------------------------------------------------------------------------
const ActionMap::Node* ActionMap::findNode(const U32 inDeviceType, const U32 inDeviceInst,
                    const U32 inModifiers,  const U32 inAction)
{
   // DMMTODO - Slow INITIAL implementation.  Replace with a faster version...
   //
   DeviceMap* pDeviceMap = NULL;
   U32 i;
   for (i = 0; i < mDeviceMaps.size(); i++)
   {
      if (mDeviceMaps[i]->deviceType == inDeviceType && mDeviceMaps[i]->deviceInst == inDeviceInst)
      {
         pDeviceMap = mDeviceMaps[i];
         break;
      }
   }

   if (pDeviceMap == NULL)
      return NULL;

   U32 realMods = inModifiers;
   if (realMods & SI_SHIFT)
      realMods |= SI_SHIFT;
   if (realMods & SI_CTRL)
      realMods |= SI_CTRL;
   if (realMods & SI_ALT)
      realMods |= SI_ALT;
   if (realMods & SI_MAC_OPT)
      realMods |= SI_MAC_OPT;

   for (i = 0; i < pDeviceMap->nodeMap.size(); i++)
   {
      if (pDeviceMap->nodeMap[i].action == KEY_ANYKEY && pDeviceMap->nodeMap[i].modifiers == realMods && dIsDecentChar(inAction))
         return &pDeviceMap->nodeMap[i];
      else if (pDeviceMap->nodeMap[i].modifiers == realMods && pDeviceMap->nodeMap[i].action    == inAction)
         return &pDeviceMap->nodeMap[i];
   }

   return NULL;
}

//------------------------------------------------------------------------------
bool ActionMap::findBoundNode( const char* function, U32 &devMapIndex, U32 &nodeIndex )
{
	// Loop through all of the existing nodes to find the one mapped to the
	// given function:
   for ( U32 i = 0; i < mDeviceMaps.size(); i++ )
   {
      const DeviceMap* dvcMap = mDeviceMaps[i];

      for ( U32 j = 0; j < dvcMap->nodeMap.size(); j++ )
      {
         const Node* node = &dvcMap->nodeMap[j];
			if ( !( node->flags & Node::BindCmd ) && ( dStricmp( function, node->consoleFunction ) == 0 ) )
         {
            devMapIndex = i;
            nodeIndex = j;
				return( true );
         }
		}
   }

   return( false );
}

//------------------------------------------------------------------------------
bool ActionMap::processUnbind(const char *device, const char *action)
{
   U32 deviceType;
   U32 deviceInst;

   if(!getDeviceTypeAndInstance(device, deviceType, deviceInst))
      return false;
   EventDescriptor eventDescriptor;
   if (!createEventDescriptor(action, &eventDescriptor))
      return false;

   removeNode(deviceType, deviceInst, eventDescriptor.flags,eventDescriptor.eventCode);
   return true;
}

//------------------------------------------------------------------------------
// This function is for the use of the control remapper.
// It will only check against the console function (since all remappable commands are
// bound using bind and not bindCmd).
//
const char* ActionMap::getBinding( const char* command )
{
   U32 devMapIndex, nodeIndex;
   if ( findBoundNode( command, devMapIndex, nodeIndex ) )
   {
	   char buffer[256];

      const DeviceMap* deviceMap = mDeviceMaps[devMapIndex];
      char deviceBuffer[32];
		if ( !getDeviceName( deviceMap->deviceType, deviceMap->deviceInst, deviceBuffer ) )
         return( "" );

      const Node* node = &deviceMap->nodeMap[nodeIndex];
      const char* modifierString = getModifierString( node->modifiers );

      char keyBuffer[64];
      if ( !getKeyString( node->action, keyBuffer ) )
         return( "" );

      dSprintf( buffer, sizeof( buffer ), "%s\t%s%s", deviceBuffer, modifierString, keyBuffer );

	   // Copy the buffer and return it:
	   char* returnString = Con::getReturnBuffer( dStrlen( buffer ) + 1 );
	   dStrcpy( returnString, buffer );
	   return( returnString );				
   }

   return( "" );
}

//------------------------------------------------------------------------------
// This function is for the use of the control remapper.
// The intent of this function is to determine if the given event descriptor is already
// bound in this action map.  If so, this function returns the command it is bound to.
// If not, it returns NULL.
//
const char* ActionMap::getCommand( const char* device, const char* action )
{
	U32 deviceType;
	U32 deviceInst;
	if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
	{
		EventDescriptor eventDescriptor;
		if ( createEventDescriptor( action, &eventDescriptor ) )
		{
			const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
			if ( mapNode )
			{
				if ( mapNode->flags & Node::BindCmd )
				{
					S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2;
					char* returnString = Con::getReturnBuffer( bufferLen );
					dSprintf( returnString, bufferLen, "%s\t%s",
							( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ),
							( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) );					
					return( returnString );
				}					
				else
					return( mapNode->consoleFunction );					
			}
		}
	}

	return( "" );
}

//------------------------------------------------------------------------------
// This function returns whether or not the mapping specified is inverted.
// Obviously, this should only be used for axes.
bool ActionMap::isInverted( const char* device, const char* action )
{
	U32 deviceType;
	U32 deviceInst;
	if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
	{
		EventDescriptor eventDescriptor;
		if ( createEventDescriptor( action, &eventDescriptor ) )
		{
			const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
			if ( mapNode )
				return( mapNode->flags & Node::Inverted );
		}
	}

	Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
	return( false );
}

//------------------------------------------------------------------------------
F32 ActionMap::getScale( const char* device, const char* action )
{
	U32 deviceType;
	U32 deviceInst;
	if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
	{
		EventDescriptor eventDescriptor;
		if ( createEventDescriptor( action, &eventDescriptor ) )
		{
			const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
			if ( mapNode )
			{
			   if ( mapNode->flags & Node::HasScale )
				   return( mapNode->scaleFactor );
            else
               return( 1.0f );
         }
		}
	}

	Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
	return( 1.0f );
}

//------------------------------------------------------------------------------
const char* ActionMap::getDeadZone( const char* device, const char* action )
{
	U32 deviceType;
	U32 deviceInst;
	if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) )
	{
		EventDescriptor eventDescriptor;
		if ( createEventDescriptor( action, &eventDescriptor ) )
		{
			const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode );
			if ( mapNode )
			{
			   if ( mapNode->flags & Node::HasDeadZone )
            {
				   char buf[64];
				   dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd );
				   char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 );
				   dStrcpy( returnString, buf );
				   return( returnString );
				}
				else
				   return( "0 0" );				   		
			}
		}
	}

	Con::errorf( "The input event specified by %s %s is not in this action map!", device, action );
	return( "" );
}

//------------------------------------------------------------------------------
const char* ActionMap::buildActionString( const InputEvent* event )
{
	const char* modifierString = getModifierString( event->modifier );

	char objectBuffer[64];
	if ( !getKeyString( event->objInst, objectBuffer ) )
		return( "" );

	U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2;	
	char* returnString = Con::getReturnBuffer( returnLen );
	dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer );
	return( returnString );
}

//------------------------------------------------------------------------------
bool ActionMap::getDeviceTypeAndInstance(const char *pDeviceName, U32 &deviceType, U32 &deviceInstance)
{
   U32 offset = 0;
   if (dStrnicmp(pDeviceName, "keyboard", dStrlen("keyboard")) == 0) {
      deviceType      = KeyboardDeviceType;
      offset = dStrlen("keyboard");
   } else if (dStrnicmp(pDeviceName, "mouse", dStrlen("mouse")) == 0) {
      deviceType      = MouseDeviceType;
      offset = dStrlen("mouse");
   } else if (dStrnicmp(pDeviceName, "joystick", dStrlen("joystick")) == 0) {
      deviceType      = JoystickDeviceType;
      offset = dStrlen("joystick");
   } else {
      return false;
   }
   if (dStrlen(pDeviceName) > offset) {
      const char* pInst = pDeviceName + offset;
      S32 instNum = dAtoi(pInst);
      if (instNum < 0)
         deviceInstance = 0;
      else
         deviceInstance = instNum;
   } else {
      deviceInstance = 0;
   }
   return true;
}

//------------------------------------------------------------------------------
bool ActionMap::getDeviceName(const U32 deviceType, const U32 deviceInstance, char* buffer)
{
   switch (deviceType) {
     case KeyboardDeviceType:
      dStrcpy(buffer, "keyboard");
      break;

     case MouseDeviceType:
      dSprintf(buffer, 16, "mouse%d", deviceInstance);
      break;

     case JoystickDeviceType:
      dSprintf(buffer, 16, "joystick%d", deviceInstance);
      break;

     default:
      Con::errorf( "ActionMap::getDeviceName: unknown device type specified, %d (inst: %d)", deviceType, deviceInstance);
      return false;
   }

   return true;
}

//------------------------------------------------------------------------------
const char* ActionMap::getModifierString(const U32 modifiers)
{
	U32 realModifiers = modifiers;
	if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT )
		realModifiers |= SI_SHIFT;
	if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL )
		realModifiers |= SI_CTRL;
	if ( modifiers & SI_LALT || modifiers & SI_RALT )
		realModifiers |= SI_ALT;
	if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT )
		realModifiers |= SI_MAC_OPT;

   switch (realModifiers & (SI_SHIFT|SI_CTRL|SI_ALT|SI_MAC_OPT)) {
#if defined(TORQUE_OS_MAC)
      // optional code, to output alt as cmd on mac.
      // interpreter sees them as the same...
     case (SI_SHIFT|SI_CTRL|SI_ALT):
      return "shift-ctrl-cmd ";

     case (SI_SHIFT|SI_ALT):
      return "shift-cmd ";

     case (SI_CTRL|SI_ALT):
      return "ctrl-cmd ";

     case (SI_ALT):
      return "cmd ";
#else
     case (SI_SHIFT|SI_CTRL|SI_ALT):
      return "shift-ctrl-alt ";

     case (SI_SHIFT|SI_ALT):
      return "shift-alt ";

     case (SI_CTRL|SI_ALT):
      return "ctrl-alt ";

     case (SI_ALT):
      return "alt ";
#endif
     case (SI_SHIFT|SI_CTRL):
      return "shift-ctrl ";

     case (SI_SHIFT):
      return "shift ";

     case (SI_CTRL):
      return "ctrl ";

// plus new mac cases:
     case (SI_SHIFT|SI_CTRL|SI_MAC_OPT):
      return "shift-ctrl-opt ";

     case (SI_SHIFT|SI_MAC_OPT):
      return "shift-opt ";

     case (SI_CTRL|SI_MAC_OPT):
      return "ctrl-opt ";

     case (SI_MAC_OPT):
      return "opt ";

     case 0:
      return "";

     default:
      AssertFatal(false, "Error, should never reach the default case in getModifierString");
      return "";
   }
}

//------------------------------------------------------------------------------
bool ActionMap::getKeyString(const U32 action, char* buffer)
{
   U16 asciiCode = Input::getAscii(action, STATE_LOWER);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -