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.
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,