view Keyboard.cpp @ 2275:8193a64c7461

Слияние
author Ritor1
date Fri, 14 Mar 2014 09:32:42 +0600
parents aff7a7b072b7
children 9551756f46c4
line wrap: on
line source

#define _CRT_SECURE_NO_WARNINGS
#include "Keyboard.h"
#include "GUIWindow.h"
#include "Game.h"

#include "mm7_data.h"
#include "mm7_unsorted_subs.h"
#include "Vis.h"
#include "MM7.h"
#include "Actor.h"
#include "DecorationList.h"
#include "Indoor.h"
#include "viewport.h"
#include "AudioPlayer.h"
#include "Level/Decoration.h"

#include <tuple>
#include <vector>
#include <string>

struct KeyboardActionMapping *pKeyActionMap;


class CKeyListElement{
public:
  std::string m_keyName;
  unsigned char m_keyDefaultCode;
  unsigned short m_cmdId;
  KeyToggleType m_toggType;
  CKeyListElement(std::string keyName, unsigned char keyDefaultCode, unsigned short cmdId, KeyToggleType toggType):
    m_keyName(keyName),
    m_keyDefaultCode(keyDefaultCode),
    m_cmdId(cmdId),
    m_toggType(toggType)
  {

  }
};

std::array<CKeyListElement, 30>keyMappingParams = {
  CKeyListElement("KEY_FORWARD", VK_UP, INPUT_MoveForward, TOGGLE_Continuously),
  CKeyListElement("KEY_BACKWARD", VK_DOWN, INPUT_MoveBackwards, TOGGLE_Continuously),
  CKeyListElement("KEY_LEFT", VK_LEFT, INPUT_TurnLeft, TOGGLE_Continuously),
  CKeyListElement("KEY_RIGHT", VK_RIGHT, INPUT_TurnRight, TOGGLE_Continuously),
  CKeyListElement("KEY_ATTACK", 'A', INPUT_Attack, TOGGLE_OneTimePress),
  CKeyListElement("KEY_CASTREADY", 'S', INPUT_CastReady, TOGGLE_OneTimePress),
  CKeyListElement("KEY_YELL", 'Y', INPUT_Yell, TOGGLE_OneTimePress),
  CKeyListElement("KEY_JUMP", 'X', INPUT_Jump, TOGGLE_OneTimePress),
  CKeyListElement("KEY_COMBAT", VK_RETURN, INPUT_Combat, TOGGLE_OneTimePress),
  CKeyListElement("KEY_EVENTTRIGGER", VK_SPACE, INPUT_EventTrigger, TOGGLE_OneTimePress),
  CKeyListElement("KEY_CAST", 'C', INPUT_Cast, TOGGLE_OneTimePress),
  CKeyListElement("KEY_PASS", 'B', INPUT_Pass, TOGGLE_OneTimePress),
  CKeyListElement("KEY_CHARCYCLE", VK_TAB, INPUT_CharCycle, TOGGLE_OneTimePress),
  CKeyListElement("KEY_QUEST", 'Q', INPUT_Quest, TOGGLE_OneTimePress),
  CKeyListElement("KEY_QUICKREF", 'Z', INPUT_QuickRef, TOGGLE_OneTimePress),
  CKeyListElement("KEY_REST", 'R', INPUT_Rest, TOGGLE_OneTimePress),
  CKeyListElement("KEY_TIMECAL", 'T', INPUT_TimeCal, TOGGLE_OneTimePress),
  CKeyListElement("KEY_AUTONOTES", 'N', INPUT_Autonotes, TOGGLE_OneTimePress),
  CKeyListElement("KEY_MAPBOOK", 'M', INPUT_Mapbook, TOGGLE_OneTimePress),
  CKeyListElement("KEY_LOOKUP", VK_NEXT, INPUT_LookUp, TOGGLE_OneTimePress),
  CKeyListElement("KEY_LOOKDOWN", VK_DELETE, INPUT_LookDown, TOGGLE_OneTimePress),
  CKeyListElement("KEY_CENTERVIEWPT", VK_END, INPUT_CenterView, TOGGLE_OneTimePress),
  CKeyListElement("KEY_ZOOMIN", VK_ADD, INPUT_ZoomIn, TOGGLE_OneTimePress),
  CKeyListElement("KEY_ZOOMOUT", VK_SUBTRACT, INPUT_ZoomOut, TOGGLE_OneTimePress),
  CKeyListElement("KEY_FLYUP", VK_PRIOR, INPUT_FlyUp, TOGGLE_Continuously),
  CKeyListElement("KEY_FLYDOWN", VK_INSERT, INPUT_FlyDown, TOGGLE_Continuously),
  CKeyListElement("KEY_LAND", VK_HOME, INPUT_Land, TOGGLE_OneTimePress),
  CKeyListElement("KEY_ALWAYSRUN", 'U', INPUT_AlwaysRun, TOGGLE_OneTimePress),
  CKeyListElement("KEY_STEPLEFT", VK_OEM_4, INPUT_StrafeLeft, TOGGLE_Continuously),
  CKeyListElement("KEY_STEPRIGHT", VK_OEM_6, INPUT_StrafeRight, TOGGLE_Continuously)
}; 

std::array<std::tuple<const char*, const unsigned __int8>, 26> keyNameToCodeTranslationMap =
{
  std::tuple<const char*, const unsigned __int8>("UP", VK_UP),
  std::tuple<const char*, const unsigned __int8>("DOWN", VK_DOWN),
  std::tuple<const char*, const unsigned __int8>("LEFT", VK_LEFT),
  std::tuple<const char*, const unsigned __int8>("", VK_LEFT),
  std::tuple<const char*, const unsigned __int8>("RIGHT", VK_RIGHT),
  std::tuple<const char*, const unsigned __int8>("", VK_RIGHT),
  std::tuple<const char*, const unsigned __int8>("RETURN", VK_RETURN),
  std::tuple<const char*, const unsigned __int8>("SPACE", VK_SPACE),
  std::tuple<const char*, const unsigned __int8>("PAGE_DOWN", VK_NEXT),
  std::tuple<const char*, const unsigned __int8>("PAGE_UP", VK_PRIOR),
  std::tuple<const char*, const unsigned __int8>("TAB", VK_TAB),
  std::tuple<const char*, const unsigned __int8>("SUBTRACT", VK_SUBTRACT),
  std::tuple<const char*, const unsigned __int8>("ADD", VK_ADD),
  std::tuple<const char*, const unsigned __int8>("END", VK_END),
  std::tuple<const char*, const unsigned __int8>("DELETE", VK_DELETE),
  std::tuple<const char*, const unsigned __int8>("HOME", VK_HOME),
  std::tuple<const char*, const unsigned __int8>("INSERT", VK_INSERT),
  std::tuple<const char*, const unsigned __int8>("COMMA", VK_OEM_COMMA),
  std::tuple<const char*, const unsigned __int8>("DECIMAL", VK_DECIMAL),
  std::tuple<const char*, const unsigned __int8>("SEMICOLON", VK_OEM_1),
  std::tuple<const char*, const unsigned __int8>("PERIOD", VK_OEM_PERIOD),
  std::tuple<const char*, const unsigned __int8>("SLASH", VK_OEM_2),
  std::tuple<const char*, const unsigned __int8>("SQUOTE", VK_OEM_7),
  std::tuple<const char*, const unsigned __int8>("BACKSLASH", VK_OEM_5),
  std::tuple<const char*, const unsigned __int8>("BACKSPACE", VK_BACK),
  std::tuple<const char*, const unsigned __int8>("CONTROL", VK_CONTROL),
};

//----- (00459C68) --------------------------------------------------------
void KeyboardActionMapping::SetKeyMapping(int uAction, int vKey, KeyToggleType type)
{
  pVirtualKeyCodesMapping[uAction] = vKey;
  pToggleTypes[uAction] = type;
}

//----- (00459C82) --------------------------------------------------------
unsigned int KeyboardActionMapping::GetActionVKey(enum InputAction eAction)
{
  return this->pVirtualKeyCodesMapping[eAction];
}

//----- (00459C8D) --------------------------------------------------------
KeyboardActionMapping::KeyboardActionMapping()
{
  uLastKeyPressed = 0;
  field_204 = 0;
  pWindow = nullptr;

  SetDefaultMapping();
  ReadMappings();

  ResetKeys();

  uGameMenuUI_CurentlySelectedKeyIdx = -1;
}
// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;

//----- (00459CC4) --------------------------------------------------------
void KeyboardActionMapping::SetDefaultMapping()
{
  for ( size_t i = 0; i < keyMappingParams.size(); i++)
  {
    SetKeyMapping(keyMappingParams[i].m_cmdId, keyMappingParams[i].m_keyDefaultCode, keyMappingParams[i].m_toggType);
  }
}

//----- (00459E3F) --------------------------------------------------------
void KeyboardActionMapping::ResetKeys()
{
  for (uint i = 0; i < 30; ++i)
    GetAsyncKeyState(pVirtualKeyCodesMapping[i]);
}

//----- (00459E5A) --------------------------------------------------------
void KeyboardActionMapping::EnterText(int a2, int max_string_len, GUIWindow *pWindow)
{
  KeyboardActionMapping *v4; // esi@1

  v4 = this;
  memset(this->pPressedKeysBuffer, 0, 0x101u);
  v4->uNumKeysPressed = 0;
  if ( a2 )
    v4->field_204 = 2;
  else
    v4->field_204 = 1;
  v4->max_input_string_len = max_string_len;
  v4->pWindow = pWindow;
  pWindow->receives_keyboard_input_2 = WINDOW_INPUT_IN_PROGRESS;
}

//----- (00459ED1) --------------------------------------------------------
void KeyboardActionMapping::SetWindowInputStatus(int a2)
{
  field_204 = 0;
  if ( pWindow )
    pWindow->receives_keyboard_input_2 = a2;
}

//----- (00459F10) --------------------------------------------------------
bool KeyboardActionMapping::ProcessTextInput(unsigned int a2)
{
  pKeyActionMap->uLastKeyPressed = a2;
  if ( uGameMenuUI_CurentlySelectedKeyIdx == -1 )
  {
    if ( pKeyActionMap->field_204 != 1 && pKeyActionMap->field_204 != 2 )
      return 0;
    if ( a2 == VK_BACK)
    {
      if (pKeyActionMap->uNumKeysPressed > 0)
      {
        --pKeyActionMap->uNumKeysPressed;
        pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
      }
    }
    else if ( a2 == VK_RETURN )
    {
      pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CONFIRMED);
    }
    else if ( a2 == VK_ESCAPE )
    {
      pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CANCELLED);
    }
    else if (this->uNumKeysPressed < this->max_input_string_len)
    {
      if ( pKeyActionMap->field_204 == 1 )
      {
        if ( a2 != VK_TAB )
        {
          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
          ++pKeyActionMap->uNumKeysPressed;
          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
        }
      }
      else if (pKeyActionMap->field_204 == 2)
      {
        if ( isdigit(a2))
        {
          pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
          ++pKeyActionMap->uNumKeysPressed;
        }
      }
    }
  }
  else
  {
    pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = a2;
    ++pKeyActionMap->uNumKeysPressed;
    pKeyActionMap->pPressedKeysBuffer[pKeyActionMap->uNumKeysPressed] = 0;
    pKeyActionMap->SetWindowInputStatus(WINDOW_INPUT_CONFIRMED);
  }
  return 1;
}
// 506E68: using guessed type int uGameMenuUI_CurentlySelectedKeyIdx;



//----- (00459FFC) --------------------------------------------------------
void KeyboardActionMapping::ReadMappings()
{
  char str[32];

  for (size_t i = 0; i < keyMappingParams.size(); i++)
  {
    const char* keyName = keyMappingParams[i].m_keyName.c_str();
    short commandDefaultKeyCode = keyMappingParams[i].m_keyDefaultCode;
    short commandId = keyMappingParams[i].m_cmdId;
    KeyToggleType toggType = keyMappingParams[i].m_toggType;

    ReadWindowsRegistryString(keyName, str, 32, "DEFAULT");
    if ( strcmp(str, "DEFAULT") && ( TranslateKeyNameToKeyCode(str) != -1) )
    {
      pVirtualKeyCodesMapping[commandId] = TranslateKeyNameToKeyCode(str);
    }
    else
    {
      pVirtualKeyCodesMapping[commandId] = commandDefaultKeyCode;
    }
    pToggleTypes[commandId] = toggType;
  }

  bAlwaysRun = ReadWindowsRegistryInt("valAlwaysRun", 0) != 0;
  bFlipOnExit = ReadWindowsRegistryInt("FlipOnExit", 0) != 0;
}

//----- (0045A960) --------------------------------------------------------
void KeyboardActionMapping::StoreMappings()
{

  const char *v2; // eax@1

  for ( size_t i = 0; i < keyMappingParams.size(); i++)
  {
    v2 = GetVKeyDisplayName(pVirtualKeyCodesMapping[keyMappingParams[i].m_cmdId]);
    WriteWindowsRegistryString(keyMappingParams[i].m_keyName.c_str(), v2);
  }
}

//----- (0045ABCA) --------------------------------------------------------
const unsigned __int8 KeyboardActionMapping::TranslateKeyNameToKeyCode(const char *Str)
{
  if (strlen(Str) == 1)
  {
    if( Str[0] >= 65 && Str[0] <= 90 )
      return *Str;
    else
      return 0xFF;
  }

  for ( size_t i = 0; i < keyNameToCodeTranslationMap.size(); i++)
  {
    if (!strcmp(Str, std::get<0>(keyNameToCodeTranslationMap[i])))
      return std::get<1>(keyNameToCodeTranslationMap[i]);
  }
  return 0xFF;
}

//----- (0045AE2C) --------------------------------------------------------
const char * KeyboardActionMapping::GetVKeyDisplayName(unsigned char a1)
{
  static char static_sub_45AE2C_string_69ADE0_keyName[32];

  if ( a1 >= 65 && a1 <= 90 )
  {
    static_sub_45AE2C_string_69ADE0_keyName[0] = a1;
    static_sub_45AE2C_string_69ADE0_keyName[1] = '\0';
    return static_sub_45AE2C_string_69ADE0_keyName;
  }

  for ( size_t i = 0; i < keyNameToCodeTranslationMap.size(); i++)
  {
    if ( a1 == std::get<1>(keyNameToCodeTranslationMap[i]))
    {
      const char* keyName =  std::get<0>(keyNameToCodeTranslationMap[i]);
      strcpy_s(static_sub_45AE2C_string_69ADE0_keyName, keyName);
      return static_sub_45AE2C_string_69ADE0_keyName;
    }
  }

  strcpy_s(static_sub_45AE2C_string_69ADE0_keyName, "- -");
  return static_sub_45AE2C_string_69ADE0_keyName;
}


//----- (0045B019) --------------------------------------------------------
void Keyboard::EnterCriticalSection()
{
}

//----- (0045B06E) --------------------------------------------------------
bool Keyboard::IsShiftHeld()
{
  return (GetAsyncKeyState(VK_SHIFT) & 0x8001) != 0;
}

//----- (0045B0A9) --------------------------------------------------------
bool Keyboard::IsKeyBeingHeld(int vKey)
{
  return (GetAsyncKeyState(vKey) & 0x8001) != 0;
}

//----- (0045B0CE) --------------------------------------------------------
bool Keyboard::WasKeyPressed(int vKey)
{
  return (GetAsyncKeyState(vKey) & 1) != 0;
}
//----- (0046A14B) --------------------------------------------------------
void OnPressSpace()
{
  //SHORT v0; // ax@2
  /*int *v1; // eax@2
  char *v2; // ebx@5
  unsigned int v3; // esi@5
  signed int v4; // edi@7
  unsigned int v5; // edx@7
  int v6; // ecx@8
  int v7; // eax@8
  int v8; // ecx@17
  int *v9; // esi@22
  signed int v10; // ebx@22
  int i; // edi@23
  int v12; // edx@24
  int v13; // ecx@24
  int j; // esi@28
  int v16; // [sp+4h] [bp-1Ch]@0
  char *v17; // [sp+8h] [bp-18h]@5
  unsigned int v18; // [sp+Ch] [bp-14h]@5
  int v19; // [sp+10h] [bp-10h]@8
  int *v20; // [sp+14h] [bp-Ch]@5
  int *v21; // [sp+18h] [bp-8h]@7
  int v22; // [sp+1Ch] [bp-4h]@4*/

  //if ( pRenderer->pRenderD3D )
  {
    pGame->PickKeyboard(Keyboard::IsKeyBeingHeld(VK_CONTROL), &vis_sprite_filter_3, &vis_door_filter);
    int pid = pGame->pVisInstance->get_picked_object_zbuf_val();
    if ( pid != -1 )
      DoInteractionWithTopmostZObject(pid & 0xFFFF, PID_ID(pid));
    return;
  }

  
  // software render stuff following
  /*
  static int dword_720660[100]; // 720660
  static int dword_7207F0[100]; // 7207F0

  v22 = 0;
  v1 = (int *)((signed int)(viewparams->uScreen_BttmR_X + viewparams->uScreen_topL_X) >> 1);//wrong pointer
  if ( (signed int)viewparams->uScreen_topL_Y < (signed int)viewparams->uScreen_BttmR_Y )
  {
	  v2 = (char *)v1 - 50;
	  v1 = (int *)((char *)v1 + 50);
	  v3 = 640 * viewparams->uScreen_topL_Y;
	  v17 = v2;
	  v20 = v1;
	  v18 = ((viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y - 1) >> 1) + 1;
	  do
	  {
		if ( (signed int)v2 < (signed int)v20 )
		{
			v1 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
			v21 = &pRenderer->pActiveZBuffer[(int)&v2[v3]];
			v4 = v22;
			v5 = (((char *)v20 - v2 - 1) >> 1) + 1;
			do
			{
			  v6 = 0;
			  v7 = *v1 & 0xFFFF;
			  v19 = 0;
			  if ( v4 > 0 )
			  {
				do
				{
				  if ( dword_7207F0[v6] == v7 )
					break;
				  ++v6;
				  v19 = v6;
				}
				while ( v6 < v22 );
			  }
			  if ( PID_TYPE(v7) == OBJECT_Decoration)
			  {
				v16 = (unsigned int)PID_ID(v7);
				if ( (signed int)(((unsigned int)*v21 >> 16)
								- pDecorationList->pDecorations[pLevelDecorations[(unsigned int)PID_ID(v7)].uDecorationDescID].uRadius) <= 512 )
				  if ( v19 == v22 && v4 < 100 )
				  {
					++v22;
					++v4;
					v8 = *v21;
					dword_7207F0[v4 - 1] = v7;
					dword_720660[v4 - 1] = v8;
				  }
			  }
			  else if ( (unsigned int)*v21 <= 0x2000000 )
			  {
				  if ( v19 == v22 && v4 < 100 )
				  {
					++v22;
					++v4;
					v8 = *v21;
					dword_7207F0[v4 - 1] = v7;
					dword_720660[v4 - 1] = v8;
				  }
			  }
			  v1 = v21 + 2;
			  --v5;
			  v21 += 2;
			}
			while ( v5 );
			v2 = v17;
		}
		v3 += 1280;
		--v18;
	  }
	  while ( v18 );
  }
  if ( v22 > 0 )
  {
    v9 = dword_720660;
    v10 = 1;
    do
    {
      for ( i = v10; i < v22; ++i )
      {
        v12 = *v9;
        v13 = dword_720660[i];
        if ( v13 < *v9 )
        {
          *v9 = v13;
          dword_720660[i] = v12;
        }
      }
      ++v10;
      ++v9;
      LOBYTE(v1) = v10 - 1;
    }
    while ( v10 - 1 < v22 );
  }
  for ( j = 0; j < v22; ++j )
  {
    LOBYTE(v1) = DoInteractionWithTopmostZObject(dword_720660[j] & 0xFFFF, v16);
    if ( !(char)v1 )
      break;
  }*/
}