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

📄 actionmap.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 4 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "sim/actionMap.h"
#include "platform/event.h"
#include "console/console.h"
#include "platform/platform.h"
#include "platform/platformInput.h"
#include "platform/platformAssert.h"
#include "core/fileStream.h"
#include "core/resManager.h"

IMPLEMENT_CONOBJECT(ActionMap);

// This is used for determing keys that have ascii codes for the foreign keyboards. IsAlpha doesn't work on foreign keys.
#define dIsDecentChar(c) (((char(0xa0) <= (c)) && ((c) <= char(0xff))) || (( char(0x21) <= (c)) && ((c) <= char(0x7e))) || (( char(0x91) <= (c)) && ((c) <= char(0x92))))

struct CodeMapping
{
   const char* pDescription;
   U8  type;
   U32 code;
};

struct AsciiMapping
{
   const char* pDescription;
   U16         asciiCode;
};

extern CodeMapping gVirtualMap[];
extern AsciiMapping gAsciiMap[];

//------------------------------------------------------------------------------
//-------------------------------------- Action maps
//
Vector<ActionMap::BreakEntry> ActionMap::smBreakTable(__FILE__, __LINE__);


//------------------------------------------------------------------------------
ActionMap::ActionMap()
{
   VECTOR_SET_ASSOCIATION(mDeviceMaps);
}

//------------------------------------------------------------------------------
ActionMap::~ActionMap()
{
   for (U32 i = 0; i < mDeviceMaps.size(); i++)
      delete mDeviceMaps[i];
   mDeviceMaps.clear();
}

//------------------------------------------------------------------------------
ActionMap::DeviceMap::~DeviceMap()
{
   for(U32 i = 0; i < nodeMap.size(); i++)
   {
      dFree(nodeMap[i].makeConsoleCommand);
      dFree(nodeMap[i].breakConsoleCommand);
   }
}

//------------------------------------------------------------------------------
bool ActionMap::onAdd()
{
   if (Parent::onAdd() == false)
      return false;

   Sim::getActionMapGroup()->addObject(this);

   return true;
}

//--------------------------------------------------------------------------
void ActionMap::dumpActionMap(const char* fileName, const bool append) const
{
   if (fileName != NULL) {
      // Dump the deletion, and creation script commands, followed by all the binds
      //  to a script.

      FileStream iostrm;
      if ( !ResourceManager->openFileForWrite( iostrm, fileName, append ? FileStream::WriteAppend : FileStream::Write ) )
      {
         Con::errorf( "Unable to open file '%s' for writing.", fileName );
         return;
      }

      char lineBuffer[1024];
      if ( append )
         iostrm.setPosition( iostrm.getStreamSize() );
      else
      {
         // IMPORTANT -- do NOT change the following line, it identifies the file as an input map file
         dStrcpy( lineBuffer, "// Torque Input Map File\n" );
         iostrm.write( dStrlen( lineBuffer ), lineBuffer );
      }

      dSprintf(lineBuffer, 1023, "%s.delete();\n"
                                 "new ActionMap(%s);\n", getName(), getName());
      iostrm.write(dStrlen(lineBuffer), lineBuffer);

      // Dump all the binds to the console...
      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
         const DeviceMap* pDevMap = mDeviceMaps[i];

         char devbuffer[32];
         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);

         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
            const Node& rNode = pDevMap->nodeMap[j];

            const char* pModifierString = getModifierString(rNode.modifiers);

            char objectbuffer[64];
            if (getKeyString(rNode.action, objectbuffer) == false)
               continue;

            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";

            dSprintf(lineBuffer, 1023, "%s.%s(%s, \"%s%s\"",
                                        getName(),
                                        command,
                                        devbuffer,
                                        pModifierString, objectbuffer);

            if (rNode.flags & (Node::HasScale|Node::HasDeadZone|Node::Ranged|Node::Inverted)) {
               char buff[10];
               U32 curr = 0;
               buff[curr++] = ',';
               buff[curr++] = ' ';
               if (rNode.flags & Node::HasScale)
                  buff[curr++] = 'S';
               if (rNode.flags & Node::Ranged)
                  buff[curr++] = 'R';
               if (rNode.flags & Node::HasDeadZone)
                  buff[curr++] = 'D';
               if (rNode.flags & Node::Inverted)
                  buff[curr++] = 'I';
               buff[curr] = '\0';

               dStrcat(lineBuffer, buff);
            }

            if (rNode.flags & Node::HasDeadZone) {
               char buff[64];
               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
               dStrcat(lineBuffer, buff);
            }

            if (rNode.flags & Node::HasScale) {
               char buff[64];
               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
               dStrcat(lineBuffer, buff);
            }

            if (rNode.flags & Node::BindCmd) {
               if (rNode.makeConsoleCommand) {
                  dStrcat(lineBuffer, ", \"");
                  U32 pos = dStrlen(lineBuffer);
                  expandEscape(lineBuffer + pos, rNode.makeConsoleCommand);
                  dStrcat(lineBuffer, "\"");
               } else {
                  dStrcat(lineBuffer, ", \"\"");
               }
               if (rNode.breakConsoleCommand) {
                  dStrcat(lineBuffer, ", \"");
                  U32 pos = dStrlen(lineBuffer);
                  expandEscape(lineBuffer + pos, rNode.breakConsoleCommand);
                  dStrcat(lineBuffer, "\"");
               }
               else
                  dStrcat(lineBuffer, ", \"\"");
            } else {
               dStrcat(lineBuffer, ", ");
               dStrcat(lineBuffer, rNode.consoleFunction);
            }

            dStrcat(lineBuffer, ");\n");
            iostrm.write(dStrlen(lineBuffer), lineBuffer);
         }
      }

      iostrm.close();
   }
   else {
      // Dump all the binds to the console...
      for (S32 i = 0; i < mDeviceMaps.size(); i++) {
         const DeviceMap* pDevMap = mDeviceMaps[i];

         char devbuffer[32];
         getDeviceName(pDevMap->deviceType, pDevMap->deviceInst, devbuffer);

         for (S32 j = 0; j < pDevMap->nodeMap.size(); j++) {
            const Node& rNode = pDevMap->nodeMap[j];

            const char* pModifierString = getModifierString(rNode.modifiers);

            char keybuffer[64];
            if (getKeyString(rNode.action, keybuffer) == false)
               continue;

            const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind";

            char finalBuffer[1024];
            dSprintf(finalBuffer, 1023, "%s.%s(%s, \"%s%s\"",
                                        getName(),
                                        command,
                                        devbuffer,
                                        pModifierString, keybuffer);

            if (rNode.flags & (Node::HasScale|Node::HasDeadZone|Node::Ranged|Node::Inverted)) {
               char buff[10];
               U32 curr = 0;
               buff[curr++] = ',';
               buff[curr++] = ' ';
               if (rNode.flags & Node::HasScale)
                  buff[curr++] = 'S';
               if (rNode.flags & Node::Ranged)
                  buff[curr++] = 'R';
               if (rNode.flags & Node::HasDeadZone)
                  buff[curr++] = 'D';
               if (rNode.flags & Node::Inverted)
                  buff[curr++] = 'I';
               buff[curr] = '\0';

               dStrcat(finalBuffer, buff);
            }

            if (rNode.flags & Node::HasDeadZone) {
               char buff[64];
               dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
               dStrcat(finalBuffer, buff);
            }

            if (rNode.flags & Node::HasScale) {
               char buff[64];
               dSprintf(buff, 63, ", %g", rNode.scaleFactor);
               dStrcat(finalBuffer, buff);
            }

            if (rNode.flags & Node::BindCmd) {
               if (rNode.makeConsoleCommand) {
                  dStrcat(finalBuffer, ", \"");
                  dStrcat(finalBuffer, rNode.makeConsoleCommand);
                  dStrcat(finalBuffer, "\"");
               } else {
                  dStrcat(finalBuffer, ", \"\"");
               }
               if (rNode.breakConsoleCommand) {
                  dStrcat(finalBuffer, ", \"");
                  dStrcat(finalBuffer, rNode.breakConsoleCommand);
                  dStrcat(finalBuffer, "\"");
               }
               else
                  dStrcat(finalBuffer, ", \"\"");
            } else {
               dStrcat(finalBuffer, ", ");
               dStrcat(finalBuffer, rNode.consoleFunction);
            }

            dStrcat(finalBuffer, ");");
            Con::printf(finalBuffer);
         }
      }
   }
}

//--------------------------------------------------------------------------
bool ActionMap::createEventDescriptor(const char* pEventString, EventDescriptor* pDescriptor)
{
#ifdef TGE_RPG
	if(!pEventString || !pEventString[0])
		return false;
#endif

   char copyBuffer[256];
   dStrcpy(copyBuffer, pEventString);

   // Do we have modifiers?
   char* pSpace = dStrchr(copyBuffer, ' ');
   char* pObjectString;
   if (pSpace != NULL) {
      // Yes.  Parse them out...
      //
      pDescriptor->flags = 0;
      pObjectString      = pSpace + 1;
      pSpace[0]          = '\0';

      char* pModifier = dStrtok(copyBuffer, "-");
      while (pModifier != NULL) {
         if (dStricmp(pModifier, "shift") == 0) {
            pDescriptor->flags |= SI_SHIFT;
         } else if (dStricmp(pModifier, "ctrl") == 0) {
            pDescriptor->flags |= SI_CTRL;
         } else if (dStricmp(pModifier, "alt") == 0) {
            pDescriptor->flags |= SI_ALT;
         } else if (dStricmp(pModifier, "cmd") == 0) {
            pDescriptor->flags |= SI_ALT;
         } else if (dStricmp(pModifier, "opt") == 0) {
            pDescriptor->flags |= SI_MAC_OPT;
         }

         pModifier = dStrtok(NULL, "-");
      }
   } else {
      // No.
      pDescriptor->flags = 0;
      pObjectString      = copyBuffer;
   }

   // Now we need to map the key string to the proper KEY code from event.h
   //
   AssertFatal(dStrlen(pObjectString) != 0, "Error, no key was specified!");

   if (dStrlen(pObjectString) == 1)
   {
      if (dIsDecentChar(*pObjectString)) // includes foreign chars
      {
         U16 asciiCode = (*pObjectString);
         // clear out the FF in upper 8bits for foreign keys??
         asciiCode &= 0xFF;
         U16 keyCode = Input::getKeyCode(asciiCode);
         if ( keyCode >= KEY_0 )
         {
            pDescriptor->eventType = SI_KEY;
            pDescriptor->eventCode = keyCode;
            return true;
         }
         else if (dIsalpha(*pObjectString) == true)
         {
            pDescriptor->eventType = SI_KEY;
            pDescriptor->eventCode = KEY_A+dTolower(*pObjectString)-'a';
            return true;
         }
         else if (dIsdigit(*pObjectString) == true)
         {
            pDescriptor->eventType = SI_KEY;
            pDescriptor->eventCode = KEY_0+(*pObjectString)-'0';
            return true;
         }
      }
      return false;
   }
   else
   {
      pDescriptor->eventCode = 0;
      // Gotta search through the Ascii table...
      for (U16 i = 0; gAsciiMap[i].asciiCode != 0xFFFF; i++)
      {
         if (dStricmp(pObjectString, gAsciiMap[i].pDescription) == 0)
         {
            U16 asciiCode = gAsciiMap[i].asciiCode;
            U16 keyCode   = Input::getKeyCode(asciiCode);
            if ( keyCode >= KEY_0 )
            {
               pDescriptor->eventType = SI_KEY;
               pDescriptor->eventCode = keyCode;
               return(true);

            }
            else
            {
               break;
            }
         }
      }
      // Didn't find an ascii match. Check the virtual map table
      for (U32 j = 0; gVirtualMap[j].code != 0xFFFFFFFF; j++)
      {
         if (dStricmp(pObjectString, gVirtualMap[j].pDescription) == 0)
         {
            pDescriptor->eventType = gVirtualMap[j].type;
            pDescriptor->eventCode = gVirtualMap[j].code;
            return true;
         }
      }
   }
   return false;
}

//------------------------------------------------------------------------------
ActionMap::Node* ActionMap::getNode(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) {
      mDeviceMaps.increment();
      mDeviceMaps.last() = new DeviceMap;
      pDeviceMap = mDeviceMaps.last();

      pDeviceMap->deviceInst = inDeviceInst;
      pDeviceMap->deviceType = inDeviceType;
   }

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

   // If we're here, the node doesn't exist.  create it.
   pDeviceMap->nodeMap.increment();

   Node* pRetNode = &pDeviceMap->nodeMap.last();
   pRetNode->modifiers = inModifiers;
   pRetNode->action    = inAction;

   pRetNode->flags         = 0;
   pRetNode->deadZoneBegin = 0.0;

⌨️ 快捷键说明

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