AutoHotkey Community

It is currently May 26th, 2012, 7:39 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: May 9th, 2009, 10:46 pm 
Offline

Joined: May 6th, 2009, 6:53 pm
Posts: 2
Here is a script I made to remap the mouse to arrow keys for the new Telltale Games - Wallace & Gromit game. I thought I'd post it here in case anyone is interested.

Basicaly the game is a point-and-click adventure, that no longer allows you to use the mouse for movement. I did not like using the keyboard for movement so I created this script to map the outside edges of the screen to the arrow keys. Also if you hold the mouse button down, then it will lock to a small box. Then as you move the mouse in that box it will send the apropriate arrow keys. I also had to take into account playing fullscreen or windowed mode. And take into account the window border.

Full info on what the script does is posted here:
http://www.telltalegames.com/forums/sho ... php?t=8382

It can be tested on the demo available here:
http://www.telltalegames.com/wallaceandgromit
http://www.telltalegames.com/demo/wallaceandgromitdemo

It is my first script other then some quick keyboard macros, so be kind. :D

Code:
; Script Function:
;   Map mouse clicks at the edges of the screen as arrow keys
;   You can also move by holding down the button and dragging the mouse
;   The script will time out after 2 minutes if game is not launched
;   Press 'F' in windowed mode to free the cursor


; Set this to the W&G episode you want to run with this script
; 0 = Demo
episode := 1

; set options to 0=disable 1=enable
; Left Button options
useEdgesL  := 1
useCenterL := 1

; Right Button options
useEdgesR  := 1
useCenterR := 1

; how long in milliseconds to press mouse button in center screen before movement is controlled by mouse dragging
; left move delay
buttonDelayL := 150

; right move delay
buttonDelayR := 50

; movement box size in pixels
boxSize := 100

; pixels at edge used to select movement
; must be 1 to 25
borderPixels := 5


; ==================================
; only change values above this line
; ==================================

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
#SingleInstance ignore ; only allow 1 running script
SetTitleMatchMode, 3  ; Names must be exact

; check values
if (borderPixels < 1 OR borderPixels > 25)
{
  MsgBox, borderPixels value out of range
  ExitApp
}

timeDelayL  := buttonDelayL // 10
timeDelayR  := buttonDelayR // 10
movePixels := boxSize // 2
edgeMargin := movePixels * 2 + borderPixels
border := borderPixels
mouseLocked := 0

; setup paths and file
if (episode = 0)
{
gameFile = WallaceGromitDemo.exe
launcherName = Wallace & Gromit Demo
}
else if (episode = 1)
{
gameFile = WallaceGromit101.exe
launcherName = Fright of the Bumblebees
}
else if (episode = 2)
{
gameFile = WallaceGromit102.exe
launcherName = The Last Resort
}
else if (episode = 3)
{
gameFile = WallaceGromit103.exe
launcherName = Muzzled!
}
else if (episode = 4)
{
gameFile = WallaceGromit104.exe
launcherName = The Bogey Man
}
else
{
  MsgBox, Invalid Episode #
  ExitApp
}
gameReg  = SOFTWARE\Telltale Games\%gameFile%
RegRead, gameDir, HKEY_LOCAL_MACHINE, %gameReg% , Install Location

; this is the name of the game as shown on the task bar
; Demo, Ep1 and Ep2 all use the same name, so I assume all episodes will
gameName = Telltale Games


; launch game
Run, %gameFile%, %gameDir%, UseErrorLevel
if ErrorLevel = ERROR
{
  MsgBox, Episode %episode% could not be found
  ExitApp
}
winwait, %gameName%, , 120
if ErrorLevel
{
  ExitApp
}
gameID := WinExist(gameName)
WinActivate, ahk_id %gameID%
SetTimer, gameCheck  ; check every 250ms
; setup rect variable for DLL call
VarSetCapacity(rect, 16)
return


gameCheck:
;------------------------------
; quit script on game exit
;------------------------------
if ((mouseLocked AND isFullScreen()) OR !WinActive("ahk_id" . gameID))
{
  ; free the mouse if we switched modes or window no longer active
  DllCall("ClipCursor")
  mouseLocked := 0
}
IfWinNotExist, ahk_id %gameID%
{
  ; free the mouse just in case
  DllCall("ClipCursor")
  ExitApp
}
return


~LButton::
useEdges  := useEdgesL
useCenter := useCenterL
timeDelay := timeDelayL
testButton = LButton
Gosub, mouseToArrows
return


~RButton::
useEdges  := useEdgesR
useCenter := useCenterR
timeDelay := timeDelayR
testButton = RButton
Gosub, mouseToArrows
return


mouseToArrows:
;------------------------------
; process mouse movement
;------------------------------
usingCenterMove := 0
if (isFullScreen())
{
  ; fullscreen
  CoordMode, Mouse, Screen
  width  := A_ScreenWidth
  height := A_ScreenHeight
  winXpos := 0
  winYpos := 0
  winXoffset := 0
  winYoffset := 0
}
else
{
  ; only do mouse to key conversion in game window
  IfWinNotActive, ahk_id %gameID%
    Return,

  ; get window information
  CoordMode, Mouse, Relative
  WinGetPos, winXpos, winYpos, winWidth, winHeight, ahk_id %gameID%

  ; calculate border info from client window
  ; we do it at every mouse press because the size could change
  DllCall("GetClientRect", "UInt", gameID, "UInt", &rect)
  width  := NumGet(rect,  8, "int")
  height := NumGet(rect, 12, "int")
  winBorderPixels := (winWidth - width) // 2
  winBarPixels := winHeight - height - winBorderPixels

  ; free up mouse if on top bar
  MouseGetPos, , curY
  if (curY < winBarPixels)
    Return,

  winXoffset := winBorderPixels
  winYoffset := winBarPixels
  ; set top left of game window
  ; keep locking the window so the mouse does not get free
  mouseLocked := 1
  Gosub, lockWindow
}

; check aspect ratio and adjust
if (width * 9 // height < 16)
{
  ; top and bottom letterboxed
  newHeight := width * 9 // 16
  edgeLeft  := 0
  edgeRight := width
  edgeUp    := (height - newHeight) // 2
  edgeDown  := edgeUp  + newHeight
}
else
{
  ; sides letterboxed
  newWidth  := height * 16 // 9
  edgeLeft  := (width   - newWidth) // 2
  edgeRight := edgeLeft + newWidth
  edgeUp    := 0
  edgeDown  := height
}

; bottom corner is one pixel in
edgeRight--
edgeDown--

if (useCenter = 1)
{
  timePressed := 0
  ; the valid center movement area
  centerLeft  := edgeLeft  + edgeMargin
  centerRight := edgeRight - edgeMargin
  centerUp    := edgeUp    + edgeMargin
  centerDown  := edgeDown  - edgeMargin
}

While GetKeyState(testButton)
{
  MouseGetPos, curX, curY
  if (!usingCenterMove)
  {
    ; adjust for window border
    curX -= winXoffset
    curY -= winYoffset
  }

  ; remap mouse to arrow keys
  ; only press the down key once
  if (useEdges = 1 OR usingCenterMove = 1)
  {
    if (curX < edgeLeft + border)
    {
      if (!downL)
      {
        Send {Left Down}
        downL := 1
      }
    }
    else
    {
      if (downL)
      {
        Send {Left Up}
        downL := 0
      }
    }

    if (curX > edgeRight - border)
    {
      if (!downR)
      {
        Send {Right Down}
        downR := 1
      }
    }
    else
    {
      if (downR)
      {
        Send {Right Up}
        downR := 0
      }
    }

    if (curY < edgeUp + border)
    {
      if (!downU)
      {
        Send {Up Down}
        downU := 1
      }
    }
    else
    {
      if (downU)
      {
        Send {Up Up}
        downU := 0
      }
    }

    if (curY > edgeDown - border)
    {
      if (!downD)
      {
        Send {Down Down}
        downD := 1
      }
    }
    else
    {
      if (downD)
      {
        Send {Down Up}
        downD := 0
      }
    }
  }

  if (useCenter AND !usingCenterMove)
  {
    ; start counting if in center of screen
    if (curX > centerLeft AND curX < centerRight AND curY > centerUp AND curY < centerDown)
    {
      timePressed++
      if (timePressed > timeDelay)
      {
        ; button down long enough, start using center move
        ; readjust mousepos to real and setup movement box
        curX += winXoffset
        curY += winYoffset
        edgeLeft  := curX - movePixels
        edgeUp    := curY - movePixels
        edgeRight := curX + movePixels
        edgeDown  := curY + movePixels
        ; fill the RECT structure with UInt values
        NumPut(winXpos + edgeLeft     , &rect +  0)
        NumPut(winYpos + edgeUp       , &rect +  4)
        NumPut(winXpos + edgeRight + 1, &rect +  8)
        NumPut(winYpos + edgeDown  + 1, &rect + 12)
        DllCall("ClipCursor", UInt, &rect)
        usingCenterMove := 1
        border := 1
      }
    }
    else
    {
      ; reset count when not in center
      timePressed := 0
    }
  }
Sleep, 10
}

if (usingCenterMove)
{
  ; free the cursor
  if (mouseLocked)
    Gosub, lockWindow
  else
    DllCall("ClipCursor")
  ; reset to view border
  border := borderPixels
}

; unpress any keys that are down
if (downL)
{
  Send {Left Up}
  downL := 0
}
if (downR)
{
  Send {Right Up}
  downR := 0
}
if (downU)
{
  Send {Up Up}
  downU := 0
}
if (downD)
{
  Send {Down Up}
  downD := 0
}
Return,


isFullScreen()
;------------------------------
; check to see if fullscreen
;------------------------------
{
  Global gameID
  WinGet, style, Style, ahk_id %gameID%
  ; 0x800000 is WS_BORDER.
  ; 0x20000000 is WS_MINIMIZE.
  ; no border and not minimized
  Return, (style & 0x20800000) ? 0 : 1
}


~f::
;------------------------------
; free mouse from window
;------------------------------
if (mouseLocked)
{
  IfWinActive, ahk_id %gameID%
  {
    ; free the cursor
    DllCall("ClipCursor")
    mouseLocked := 0
  }
}
Return,


lockWindow:
;------------------------------
; lock mouse to window
;------------------------------
; fill the RECT structure with UInt values
NumPut(winXpos + winBorderPixels,          &rect +  0)
NumPut(winYpos + winBarPixels,             &rect +  4)
NumPut(winXpos + winBorderPixels + width,  &rect +  8)
NumPut(winYpos + winBarPixels    + height, &rect + 12)
DllCall("ClipCursor", UInt, &rect)
Return,


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: bobbysoon, Google [Bot], jrav, Xx7 and 13 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group