diff --git a/D4WeakAura.ahk b/D4WeakAura.ahk index ffeb919..55e9bfa 100644 --- a/D4WeakAura.ahk +++ b/D4WeakAura.ahk @@ -15,6 +15,8 @@ SetControlDelay, -1 SendMode Input #Include Gdip_All.ahk +;SetTimer, Rumble, 1000 + ; Start GDI+ If !pToken := Gdip_Startup() { @@ -46,10 +48,22 @@ global drawDebug := False global f1Pressed := -1 global f3Pressed := -1 +global clonex := -1 +global cloney := -1 +global clonew := -1 +global cloneh := -1 +global clonedx := -1 +global clonedy := -1 global tempX := -1 global tempY := -1 global tempW := -1 global tempH := -1 +global rumbleStrength := 100 +global rumbleLength := 50 +global rumbleRepeats := 1 +global vibrationEnabled := True +global TargetScriptTitle := "Rumbler.ahk ahk_class AutoHotkey" +global LastRumbleSend := -1 ; Create a layered window (+E0x80000 : must be used for UpdateLayeredWindow to work!) that is always on top (+AlwaysOnTop), has no taskbar entry or caption Gui, Overlay: -Caption +E0x80000 +E0x20 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs @@ -185,6 +199,33 @@ render_section(section, G, pScreenshot) Gdip_DeletePen(debugPen) } } + Else if section.cloneOutputType == "Vibrate" + { + ARGB := Gdip_GetPixelColor(pScreenshot, 0, 0, 1) + if(section.cloneColor == ARGB) + { + rumbleIntensity := section.vibrationIntensity * 255 + rumbleLength := section.vibrationLength + rumbleRepeats := section.vibrationRepeats + data = %rumbleIntensity%|%rumbleLength%|%rumbleRepeats% + + if(A_TickCount >= LastRumbleSend + (rumbleLength * rumbleRepeats) + 300) + { + LastRumbleSend := A_TickCount + send_rumble(data,TargetScriptTitle) + } + + ;Rumbler(section.cloneTransparency * 255, 100, 2) + ;SetTimer, Rumble, 30 + } + + if drawDebug { + debugPen := Gdip_CreatePen(section.cloneColor, 2) + Gdip_DrawRectangle(G, debugPen, section.x, section.y, section.w, section.h) + Gdip_DrawLine(G, debugPen, section.x, section.y, A_ScreenWidth/2, 10) + Gdip_DeletePen(debugPen) + } + } Else{ if section.cloneRotation { @@ -258,46 +299,28 @@ should_render(ini, G) return ARGB == general.enableColor } +send_rumble(ByRef StringToSend, ByRef TargetScriptTitle) +{ + VarSetCapacity(CopyDataStruct, 3*A_PtrSize, 0) ; Set up the structure's memory area. + ; First set the structure's cbData member to the size of the string, including its zero terminator: + SizeInBytes := (StrLen(StringToSend) + 1) * (A_IsUnicode ? 2 : 1) + NumPut(SizeInBytes, CopyDataStruct, A_PtrSize) ; OS requires that this be done. + NumPut(&StringToSend, CopyDataStruct, 2*A_PtrSize) ; Set lpData to point to the string itself. + Prev_DetectHiddenWindows := A_DetectHiddenWindows + Prev_TitleMatchMode := A_TitleMatchMode + DetectHiddenWindows On + SetTitleMatchMode 2 + TimeOutTime := 10 ; Optional. Milliseconds to wait for response from receiver.ahk. Default is 5000 + ; Must use SendMessage not PostMessage. + SendMessage, 0x004A, 0, &CopyDataStruct,, %TargetScriptTitle%,,,, %TimeOutTime% ; 0x004A is WM_COPYDATA. + DetectHiddenWindows %Prev_DetectHiddenWindows% ; Restore original setting for the caller. + SetTitleMatchMode %Prev_TitleMatchMode% ; Same. + return ErrorLevel ; Return SendMessage's reply back to our caller. +} -;SetTimer, RenderLoop, -1 - -;~ RenderLoop: - ;~ active := GetRunningWindowText("Diablo IV") - ;~ Gdip_GraphicsClear(G) - ;~ if (showUI and active) - ;~ { - ;~ ini := iniObj(iniFilename) - - ;~ render := should_render(ini, G) - - ;~ if(render) - ;~ { - ;~ for section_name, section_data in ini { - ;~ if(section_name != "General") - ;~ { - ;~ pScreenshot := Screenshot(section_data.x,section_data.y,section_data.w,section_data.h) - ;~ render_section(section_data, G, pScreenshot) - ;~ } - ;~ else - ;~ { - ;~ if(drawDebug) { - ;~ debugPen := Gdip_CreatePen(0xffff0000, 1) - ;~ Gdip_DrawRectangle(G, debugPen, section_data.enableX-1, section_data.enableY-1, 2, 2) - ;~ debugPen := Gdip_CreatePen(0xbbff0000, 1) - ;~ Gdip_DrawLine(G, debugPen, Width/2, 0, Width/2, Height) - ;~ Gdip_DrawLine(G, debugPen, 0, Height/2, Width, Height/2) - ;~ } - ;~ } - ;~ } - ;~ } - - - ;~ } - ;~ UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) - ;~ Gdip_DisposeBitmap(pScreenshot) - ;~ Return - -Loop +SetTimer Looper, 16 + +Looper: { sT:=A_TickCount active := GetRunningWindowText("Diablo IV") @@ -320,12 +343,15 @@ Loop } else { + ; Edit mode MouseGetPos , xxxx, yyyy section_data.dx := xxxx - section_data.w section_data.dy := yyyy - section_data.h section_data.cloneTransparency := cloneToMoveTransparency section_data.cloneScale := cloneToMoveScale render_section(section_data, G, pScreenshot) + Options = x%0% y1p Left cbbffffff r4 s30 + Gdip_TextToGraphics(G, "Edit Mode: Scrollwheel up/down for transparency, Ctrl+Scrollwheel for size. Press F3 again to save!", Options, Font, Width, Height) } } else @@ -342,6 +368,18 @@ Loop } } + if(drawDebug) + { + Options = x%0% y1p Left cbbffffff r4 s30 + Gdip_TextToGraphics(G, "F1: New Overlay Rectangle Selection", Options, Font, Width, Height) + Options = x%0% y3p Left cbbffffff r4 s30 + Gdip_TextToGraphics(G, "F2: New Pixel Selection (check Readme for details)", Options, Font, Width, Height) + Options = x%0% y5p Left cbbffffff r4 s30 + Gdip_TextToGraphics(G, "F3: Edit Mode, Ctrl+F3: Delete Overlay under cursor", Options, Font, Width, Height) + Options = x%0% y7p Left cbbffffff r4 s30 + Gdip_TextToGraphics(G, "F4: Toggle Overlay, F5: Show Help / Debug View", Options, Font, Width, Height) + } + if(f1Pressed == 0) { MouseGetPos , tempX, tempY @@ -350,6 +388,8 @@ Loop debugPen := Gdip_CreatePen(0xffff0000, 1) Gdip_DrawRectangle(G, debugPen, clonex, cloney, tempW, tempH) Gdip_DeletePen(debugPen) + Options = x%10% y%0% Left cbbffffff r4 s30 + Gdip_TextToGraphics(G, "Use the mouse to draw a rectangle, press F1 again to submit.", Options, Font, Width, Height) } if(f1Pressed == 1) @@ -358,9 +398,9 @@ Loop pScreenshot := Screenshot(clonex,cloney,clonew,cloneh) Gdip_DrawImage(G, pScreenshot, tempX2, tempY2, clonew, cloneh) Gdip_DisposeBitmap(pScreenshot) + Options = x%10% y%0% Left cbbffffff r4 s30 + Gdip_TextToGraphics(G, "Move the mouse to where you want to position the overlay and press F1 again to submit.", Options, Font, Width, Height) } - - } UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height) Gdip_DisposeBitmap(pScreenshot) @@ -371,6 +411,7 @@ Loop sleepfor := 16-ticks DllCall("Sleep","UInt", sleepfor) } + return } @@ -401,9 +442,7 @@ iniObj(iniFilename) { Return ini } - -#IfWinActive Diablo IV -F1:: +f1Function() { if(f1Pressed < 0) { @@ -423,7 +462,8 @@ F1:: { MouseGetPos , clonedx, clonedy Gui, 2:Destroy - Gui, 2:Add, Text,, Enter the name: + Gui, 2:Add, Text,, Configure the Overlay + Gui, 2:Add, Text,, Enter an identifier: Gui, 2:Add, Edit, vMyInput, Gui, 2:Add, Text,, Transparency: Gui, 2:Add, Edit, vMyTransparency, @@ -436,40 +476,6 @@ F1:: return } -^F1:: -{ - MouseGetPos , enableX, enableY - pScreenshot := Screenshot(enableX, enableY, 1, 1) - ARGB := Gdip_GetPixelColor(pScreenshot, 0, 0, 1) - IniWrite, %ARGB%, %iniFilename%, General, enableColor - IniWrite, %enableX%, %iniFilename%, General, enableX - IniWrite, %enableY%, %iniFilename%, General, enableY - return -} - -F2:: -{ - MouseGetPos , clonedx, clonedy - cloneOutputType := "border" - - clonex := clonedx - cloney := clonedy - clonew := 8 - cloneh := 8 - clonedx := clonedx - clonedy := clonedy - - Gui, 2:Destroy - Gui, 2:Add, Text,, Enter a name: - Gui, 2:Add, Edit, vMyInput, - Gui, 2:Add, Text,, Where to put? - Gui, 2:Add, DropdownList,vMyDropdown,Left|Right|Top|Bottom|Full - Gui, 2:Add, Text,, Transparency - Gui, 2:Add, Edit, vMyTransparency, - Gui, 2:Add,Button,gOkBorder wp,Ok - Gui, 2:Show,,This is the title - return -} SaveClone: { @@ -534,6 +540,133 @@ did_we_click_on_clone(x,y,w,h, xxx, yyy, s, r) return inside } + +OkClone: + Gui, 2:Hide + GuiControlGet, MyDropdown,, MyDropdown + GuiControlGet, MyInput,, MyInput + GuiControlGet, MyTransparency,, MyTransparency + MsgBox, You selected %MyDropdown% and entered %MyInput% with transparency %MyTransparency%. + vclonename := MyInput + vwhere := MyDropdown + vtransparency := MyTransparency + + IniWrite, %clonex%, %iniFilename%, clone_%vclonename%, x + IniWrite, %cloney%, %iniFilename%, clone_%vclonename%, y + + IniWrite, %clonew%, %iniFilename%, clone_%vclonename%, w + IniWrite, %cloneh%, %iniFilename%, clone_%vclonename%, h + + IniWrite, %clonedx%, %iniFilename%, clone_%vclonename%, dx + IniWrite, %clonedy%, %iniFilename%, clone_%vclonename%, dy + + IniWrite, %A_ScreenHeight%, %iniFilename%, clone_%vclonename%, height + IniWrite, %A_ScreenWidth%, %iniFilename%, clone_%vclonename%, width + + IniWrite, %vclonename%, %iniFilename%, clone_%vclonename%, clonename + IniWrite, 1.0, %iniFilename%, clone_%vclonename%, cloneTransparency + IniWrite, %vwhere%, %iniFilename%, clone_%vclonename%, cloneOutputType + + random_color := generate_random_argb() + IniWrite, %random_color%, %iniFilename%, clone_%vclonename%, cloneColor + + clonex := -1 + cloney := -1 + clonew := -1 + cloneh := -1 + clonedx := -1 + clonedy := -1 + IniRead, sections, Filename + ini := iniObj(iniFilename) + + return + +OkBorder: + Gui, 2:Hide + GuiControlGet, MyDropdown,, MyDropdown + GuiControlGet, MyInput,, MyInput + GuiControlGet, MyTransparency,, MyTransparency + MsgBox, You selected %MyDropdown% and entered %MyInput% with transparency %MyTransparency%. + vclonename := MyInput + vwhere := MyDropdown + vtransparency := MyTransparency + + pScreenshot := Screenshot(clonex,cloney,1,1) + ARGB := Gdip_GetPixelColor(pScreenshot, 0, 0, 1) + + IniWrite, %clonex%, %iniFilename%, clone_%vclonename%, x + IniWrite, %cloney%, %iniFilename%, clone_%vclonename%, y + + IniWrite, %clonew%, %iniFilename%, clone_%vclonename%, w + IniWrite, %cloneh%, %iniFilename%, clone_%vclonename%, h + + IniWrite, %clonedx%, %iniFilename%, clone_%vclonename%, dx + IniWrite, %clonedy%, %iniFilename%, clone_%vclonename%, dy + + IniWrite, %A_ScreenHeight%, %iniFilename%, clone_%vclonename%, height + IniWrite, %A_ScreenWidth%, %iniFilename%, clone_%vclonename%, width + + IniWrite, %vclonename%, %iniFilename%, clone_%vclonename%, clonename + IniWrite, 1.0, %iniFilename%, clone_%vclonename%, cloneTransparency + IniWrite, %vwhere%, %iniFilename%, clone_%vclonename%, cloneOutputType + + random_color := generate_random_argb() + IniWrite, %ARGB%, %iniFilename%, clone_%vclonename%, cloneColor + + clonex := -1 + cloney := -1 + clonew := -1 + cloneh := -1 + clonedx := -1 + clonedy := -1 + IniRead, sections, Filename + ini := iniObj(iniFilename) + + return + + +#IfWinActive Diablo IV +F1:: +{ + f1Function() + return +} + +^F1:: +{ + MouseGetPos , enableX, enableY + pScreenshot := Screenshot(enableX, enableY, 1, 1) + ARGB := Gdip_GetPixelColor(pScreenshot, 0, 0, 1) + IniWrite, %ARGB%, %iniFilename%, General, enableColor + IniWrite, %enableX%, %iniFilename%, General, enableX + IniWrite, %enableY%, %iniFilename%, General, enableY + return +} + +F2:: +{ + MouseGetPos , clonedx, clonedy + cloneOutputType := "border" + + clonex := clonedx + cloney := clonedy + clonew := 8 + cloneh := 8 + clonedx := clonedx + clonedy := clonedy + + Gui, 2:Destroy + Gui, 2:Add, Text,, Enter an identifier: + Gui, 2:Add, Edit, vMyInput, + Gui, 2:Add, Text,, Where to display + Gui, 2:Add, DropdownList,vMyDropdown,Left|Right|Top|Full|Vibrate + Gui, 2:Add, Text,, Modifier (Transparency/Vibrate) + Gui, 2:Add, Edit, vMyTransparency, + Gui, 2:Add,Button,gOkBorder wp,Ok + Gui, 2:Show,,This is the title + return +} + F3:: { MouseGetPos , xxx, yyy @@ -645,90 +778,8 @@ WheelDown:: } return } - - #If -OkClone: - Gui, 2:Hide - GuiControlGet, MyDropdown,, MyDropdown - GuiControlGet, MyInput,, MyInput - GuiControlGet, MyTransparency,, MyTransparency - MsgBox, You selected %MyDropdown% and entered %MyInput% with transparency %MyTransparency%. - vclonename := MyInput - vwhere := MyDropdown - vtransparency := MyTransparency - - IniWrite, %clonex%, %iniFilename%, clone_%vclonename%, x - IniWrite, %cloney%, %iniFilename%, clone_%vclonename%, y - - IniWrite, %clonew%, %iniFilename%, clone_%vclonename%, w - IniWrite, %cloneh%, %iniFilename%, clone_%vclonename%, h - - IniWrite, %clonedx%, %iniFilename%, clone_%vclonename%, dx - IniWrite, %clonedy%, %iniFilename%, clone_%vclonename%, dy - - IniWrite, %A_ScreenHeight%, %iniFilename%, clone_%vclonename%, height - IniWrite, %A_ScreenWidth%, %iniFilename%, clone_%vclonename%, width - - IniWrite, %vclonename%, %iniFilename%, clone_%vclonename%, clonename - IniWrite, 1.0, %iniFilename%, clone_%vclonename%, cloneTransparency - IniWrite, %vwhere%, %iniFilename%, clone_%vclonename%, cloneOutputType - - random_color := generate_random_argb() - IniWrite, %random_color%, %iniFilename%, clone_%vclonename%, cloneColor - - clonex := -1 - cloney := -1 - clonew := -1 - cloneh := -1 - clonedx := -1 - clonedy := -1 - IniRead, sections, Filename - ini := iniObj(iniFilename) - - return - -OkBorder: - Gui, 2:Hide - GuiControlGet, MyDropdown,, MyDropdown - GuiControlGet, MyInput,, MyInput - GuiControlGet, MyTransparency,, MyTransparency - MsgBox, You selected %MyDropdown% and entered %MyInput% with transparency %MyTransparency%. - vclonename := MyInput - vwhere := MyDropdown - vtransparency := MyTransparency - - IniWrite, %clonex%, %iniFilename%, clone_%vclonename%, x - IniWrite, %cloney%, %iniFilename%, clone_%vclonename%, y - - IniWrite, %clonew%, %iniFilename%, clone_%vclonename%, w - IniWrite, %cloneh%, %iniFilename%, clone_%vclonename%, h - - IniWrite, %clonedx%, %iniFilename%, clone_%vclonename%, dx - IniWrite, %clonedy%, %iniFilename%, clone_%vclonename%, dy - - IniWrite, %A_ScreenHeight%, %iniFilename%, clone_%vclonename%, height - IniWrite, %A_ScreenWidth%, %iniFilename%, clone_%vclonename%, width - - IniWrite, %vclonename%, %iniFilename%, clone_%vclonename%, clonename - IniWrite, 1.0, %iniFilename%, clone_%vclonename%, cloneTransparency - IniWrite, %vwhere%, %iniFilename%, clone_%vclonename%, cloneOutputType - - random_color := generate_random_argb() - IniWrite, %random_color%, %iniFilename%, clone_%vclonename%, cloneColor - - clonex := -1 - cloney := -1 - clonew := -1 - cloneh := -1 - clonedx := -1 - clonedy := -1 - IniRead, sections, Filename - ini := iniObj(iniFilename) - - return - F4:: { showUI := !showUI diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..5c213aa --- /dev/null +++ b/README.MD @@ -0,0 +1,69 @@ +# D4 "WeakAura" + +## Prerequisited +- Get Autohotkey V1 -> https://www.autohotkey.com/ -> Download v1.1 +## How to start +- Double click on D4WeakAura.ahk +- Loads settings from settings-{ScreenWidth}x{ScreenHeight}.ini +- This starts the overlay +- Configured with basic Overlay + - Healthbar + - Resourcebar + - Trigger-Pixel (resposible for showing/hiding the UI) + - UI is hidden when Map is visible +- Press F4 to toggle UI +- Press F5 to show help and debug view + - in debug mode you can see the rectangles that are captured and where they are displayed, indicated by a line of the same color + +![](./images/Setup_Debug_Help.gif) + +---------------------------------------- + +## How to configure +### Rectangle Clone Mode +![](./images/Setup_new_Overlay.gif) + + - Used for Cooldowns or healthbar/resourcebar + - Press F1 to starting point for new rectangle + - Rectangle is drawn from starting point to current mouse position + - Press F1 again to stop drawing the rectangle + - Configuration window pops up + - set a unique identifier (e.g. "skill1") + - set transparency for the overlay + - set rotation for the overlay + - Press Okay + - The new overlay is immediatly added + +### Edit Rectangle Clone +![](./images/F3_Edit_Mode.gif) + + - Mouse over overlay + - Press F3 + - Overlay moves to mouseposition + - scrollwheel changes transparency + - ctrl+scrollwheel changes scale + - Press F3 again to save + +### Delete Rectangle Clone + + - Mouse over overlay + - Press ctrl+F3 + +### Pixel Clone Mode + - Useful for cooldowns in peripheral vision + - Press F2 to select a pixel on the screen + - The position and color of this pixel is saved + - Configuration window pops up + - set a unique identifier (e.g. "skill1") + - "Where to display" + - the Pixel Clone Mode takes the color value of the selected pixel + - displays it at the borders of the screen (Top/Left/Right/Full) + - set transparency for the overlay (doesn't work for now) + +### Vibrate Mode + - Useful for cooldowns + - Setup the same as Pixel Clone Mode + - Select Vibrate for "Where to display" + - Configure the vibration strength in the Modifier input + - Start the "Rumber.ahk" script to enable the rumble + - This sends the rumble to the first connected XInput Gamepad \ No newline at end of file diff --git a/Rumbler.ahk b/Rumbler.ahk new file mode 100644 index 0000000..0913fdc --- /dev/null +++ b/Rumbler.ahk @@ -0,0 +1,32 @@ +#SingleInstance +#Include XInput.ahk + +XInput_Init() +global vibrationEnabled := True + +OnMessage(0x004A, "Receive_WM_COPYDATA") ; 0x004A is WM_COPYDATA +return + +Receive_WM_COPYDATA(wParam, lParam) +{ + StringAddress := NumGet(lParam + 2*A_PtrSize) ; Retrieves the CopyDataStruct's lpData member. + CopyOfData := StrGet(StringAddress) ; Copy the string out of the structure. + ; Show it with ToolTip vs. MsgBox so we can return in a timely fashion: + params := StrSplit(CopyOfData, "|") + Rumble(params[1], params[2], params[3]) + return true ; Returning 1 (true) is the traditional way to acknowledge this message. +} + +Rumble(rumbleStrength, rumbleLength, rumbleRepeats) { + if(vibrationEnabled) { + + Loop, % rumbleRepeats + { + argh := XInput_SetState(0, 0*257, rumbleStrength*257) + Sleep, rumbleLength + argh := XInput_SetState(0, 0*257, 0*257) + } + } + argh := XInput_SetState(0, 0*257, 0*257) + return +} diff --git a/XInput.ahk b/XInput.ahk new file mode 100644 index 0000000..f29ce64 --- /dev/null +++ b/XInput.ahk @@ -0,0 +1,223 @@ +/* XInput by Lexikos + * Requires AutoHotkey 1.1+. + */ + +/* + Function: XInput_Init + + Initializes XInput.ahk with the given XInput DLL. + + Parameters: + dll - The path or name of the XInput DLL to load. +*/ +XInput_Init(dll:="") +{ + global + if _XInput_hm + return + + ;======== CONSTANTS DEFINED IN XINPUT.H ======== + + ; NOTE: These are based on my outdated copy of the DirectX SDK. + ; Newer versions of XInput may require additional constants. + + ; Device types available in XINPUT_CAPABILITIES + XINPUT_DEVTYPE_GAMEPAD := 0x01 + + ; Device subtypes available in XINPUT_CAPABILITIES + XINPUT_DEVSUBTYPE_GAMEPAD := 0x01 + + ; Flags for XINPUT_CAPABILITIES + XINPUT_CAPS_VOICE_SUPPORTED := 0x0004 + + ; Constants for gamepad buttons + XINPUT_GAMEPAD_DPAD_UP := 0x0001 + XINPUT_GAMEPAD_DPAD_DOWN := 0x0002 + XINPUT_GAMEPAD_DPAD_LEFT := 0x0004 + XINPUT_GAMEPAD_DPAD_RIGHT := 0x0008 + XINPUT_GAMEPAD_START := 0x0010 + XINPUT_GAMEPAD_BACK := 0x0020 + XINPUT_GAMEPAD_LEFT_THUMB := 0x0040 + XINPUT_GAMEPAD_RIGHT_THUMB := 0x0080 + XINPUT_GAMEPAD_LEFT_SHOULDER := 0x0100 + XINPUT_GAMEPAD_RIGHT_SHOULDER := 0x0200 + XINPUT_GAMEPAD_GUIDE := 0x0400 + XINPUT_GAMEPAD_A := 0x1000 + XINPUT_GAMEPAD_B := 0x2000 + XINPUT_GAMEPAD_X := 0x4000 + XINPUT_GAMEPAD_Y := 0x8000 + + ; Gamepad thresholds + XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE := 7849 + XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE := 8689 + XINPUT_GAMEPAD_TRIGGER_THRESHOLD := 30 + + ; Flags to pass to XInputGetCapabilities + XINPUT_FLAG_GAMEPAD := 0x00000001 + + ;=============== END CONSTANTS ================= + + if (dll = "") + Loop %A_WinDir%\System32\XInput1_*.dll + dll := A_LoopFileName + if (dll = "") + dll := "XInput1_3.dll" + + _XInput_hm := DllCall("LoadLibrary" ,"str",dll ,"ptr") + + if !_XInput_hm + throw Exception("Failed to initialize XInput: " dll " not found.") + + (_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"ptr",100 ,"ptr")) +|| (_XInput_GetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetState" ,"ptr")) + _XInput_SetState := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputSetState" ,"ptr") + _XInput_GetCapabilities := DllCall("GetProcAddress" ,"ptr",_XInput_hm ,"astr","XInputGetCapabilities" ,"ptr") + + if !(_XInput_GetState && _XInput_SetState && _XInput_GetCapabilities) + { + XInput_Term() + throw Exception("Failed to initialize XInput: function not found.") + } +} + +/* + Function: XInput_GetState + + Retrieves the current state of the specified controller. + + Parameters: + UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3. + + Returns: + The current state of the controller as an associative array. + + ErrorLevel: + If the function succeeds, ErrorLevel is ERROR_SUCCESS (zero). + If the controller is not connected, ErrorLevel is ERROR_DEVICE_NOT_CONNECTED (1167). + If the function fails, ErrorLevel is an error code defined in Winerror.h. + http://msdn.microsoft.com/en-us/library/ms681381.aspx + + Remarks: + XInput.dll returns controller state as a binary structure: + http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_state + http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_gamepad +*/ +XInput_GetState(UserIndex) +{ + global _XInput_GetState + + VarSetCapacity(xiState,16) + + if ErrorLevel := DllCall(_XInput_GetState ,"uint",UserIndex ,"uint",&xiState) + return 0 + + return { + (Join, + dwPacketNumber: NumGet(xiState, 0, "UInt") + wButtons: NumGet(xiState, 4, "UShort") + bLeftTrigger: NumGet(xiState, 6, "UChar") + bRightTrigger: NumGet(xiState, 7, "UChar") + sThumbLX: NumGet(xiState, 8, "Short") + sThumbLY: NumGet(xiState, 10, "Short") + sThumbRX: NumGet(xiState, 12, "Short") + sThumbRY: NumGet(xiState, 14, "Short") + )} +} + +/* + Function: XInput_SetState + + Sends data to a connected controller. This function is used to activate the vibration + function of a controller. + + Parameters: + UserIndex - [in] Index of the user's controller. Can be a value from 0 to 3. + LeftMotorSpeed - [in] Speed of the left motor, between 0 and 65535. + RightMotorSpeed - [in] Speed of the right motor, between 0 and 65535. + + Returns: + If the function succeeds, the return value is 0 (ERROR_SUCCESS). + If the controller is not connected, the return value is 1167 (ERROR_DEVICE_NOT_CONNECTED). + If the function fails, the return value is an error code defined in Winerror.h. + http://msdn.microsoft.com/en-us/library/ms681381.aspx + + Remarks: + The left motor is the low-frequency rumble motor. The right motor is the + high-frequency rumble motor. The two motors are not the same, and they create + different vibration effects. +*/ +XInput_SetState(UserIndex, LeftMotorSpeed, RightMotorSpeed) +{ + global _XInput_SetState + return DllCall(_XInput_SetState ,"uint",UserIndex ,"uint*",LeftMotorSpeed|RightMotorSpeed<<16) +} + +/* + Function: XInput_GetCapabilities + + Retrieves the capabilities and features of a connected controller. + + Parameters: + UserIndex - [in] Index of the user's controller. Can be a value in the range 0–3. + Flags - [in] Input flags that identify the controller type. + 0 - All controllers. + 1 - XINPUT_FLAG_GAMEPAD: Xbox 360 Controllers only. + + Returns: + The controller capabilities, as an associative array. + + ErrorLevel: + If the function succeeds, ErrorLevel is 0 (ERROR_SUCCESS). + If the controller is not connected, ErrorLevel is 1167 (ERROR_DEVICE_NOT_CONNECTED). + If the function fails, ErrorLevel is an error code defined in Winerror.h. + http://msdn.microsoft.com/en-us/library/ms681381.aspx + + Remarks: + XInput.dll returns capabilities via a binary structure: + http://msdn.microsoft.com/en-us/library/microsoft.directx_sdk.reference.xinput_capabilities +*/ +XInput_GetCapabilities(UserIndex, Flags) +{ + global _XInput_GetCapabilities + + VarSetCapacity(xiCaps,20) + + if ErrorLevel := DllCall(_XInput_GetCapabilities ,"uint",UserIndex ,"uint",Flags ,"ptr",&xiCaps) + return 0 + + return, + (Join + { + Type: NumGet(xiCaps, 0, "UChar"), + SubType: NumGet(xiCaps, 1, "UChar"), + Flags: NumGet(xiCaps, 2, "UShort"), + Gamepad: + { + wButtons: NumGet(xiCaps, 4, "UShort"), + bLeftTrigger: NumGet(xiCaps, 6, "UChar"), + bRightTrigger: NumGet(xiCaps, 7, "UChar"), + sThumbLX: NumGet(xiCaps, 8, "Short"), + sThumbLY: NumGet(xiCaps, 10, "Short"), + sThumbRX: NumGet(xiCaps, 12, "Short"), + sThumbRY: NumGet(xiCaps, 14, "Short") + }, + Vibration: + { + wLeftMotorSpeed: NumGet(xiCaps, 16, "UShort"), + wRightMotorSpeed: NumGet(xiCaps, 18, "UShort") + } + } + ) +} + +/* + Function: XInput_Term + Unloads the previously loaded XInput DLL. +*/ +XInput_Term() { + global + if _XInput_hm + DllCall("FreeLibrary","uint",_XInput_hm), _XInput_hm :=_XInput_GetState :=_XInput_SetState :=_XInput_GetCapabilities :=0 +} + +; TODO: XInputEnable, 'GetBatteryInformation and 'GetKeystroke. \ No newline at end of file diff --git a/images/F3_Edit_Mode.gif b/images/F3_Edit_Mode.gif new file mode 100644 index 0000000..eb1c607 Binary files /dev/null and b/images/F3_Edit_Mode.gif differ diff --git a/images/Setup_Debug_Help.gif b/images/Setup_Debug_Help.gif new file mode 100644 index 0000000..1de98eb Binary files /dev/null and b/images/Setup_Debug_Help.gif differ diff --git a/images/Setup_new_Overlay.gif b/images/Setup_new_Overlay.gif new file mode 100644 index 0000000..8d6b06f Binary files /dev/null and b/images/Setup_new_Overlay.gif differ diff --git a/images/image_debug.png b/images/image_debug.png new file mode 100644 index 0000000..e0f24ec Binary files /dev/null and b/images/image_debug.png differ diff --git a/settings-2560x1440.ini b/settings-2560x1440.ini index 6fd70d0..bf11f5d 100644 --- a/settings-2560x1440.ini +++ b/settings-2560x1440.ini @@ -1,3 +1,7 @@ +[General] +enableColor=0xff303b41 +enableX=1637 +enableY=1295 [clone_resource] x=1736 y=1230 @@ -6,12 +10,13 @@ h=180 dx=1190 dy=456 cloneName=a -cloneTransparency=0.5 +cloneTransparency=1.000000 cloneOutputType=clone cloneRotation=90 height=1440 width=2560 cloneColor=0xff234567 +cloneScale= [clone_health] x=804 y=1230 @@ -20,42 +25,66 @@ h=180 dx=1190 dy=440 cloneName=a -cloneTransparency=0.5 +cloneTransparency=0.800000 cloneOutputType=clone cloneRotation=90 height=1440 width=2560 cloneColor=0xff987654 cloneToMoveScale= -[General] -enableColor=0xff000404 -enableX=1635 -enableY=1301 -[clone_skill2top] -x=1151 +cloneScale= +[clone_skill3] +x=1201 +y=1304 +w=74 +h=70 +dx=1369 +dy=417 +clonename=skill3 +cloneTransparency=0.550000 +cloneOutputType=clone +cloneRotation=0 +height=1440 +width=2560 +cloneColor=0xFFB1469E +cloneScale=0.900000 +[clone_skill4] +x=1286 +y=1304 +w=72 +h=71 +dx=1119 +dy=416 +clonename=skill4 +cloneTransparency=0.5 +cloneOutputType=clone +cloneRotation=0 +height=1440 +width=2560 +cloneColor=0xFF4194DB +[clone_rage] +x=1318 y=1313 w=8 h=8 -dx=1151 +dx=1318 dy=1313 height=1440 width=2560 -clonename=skill2top -cloneTransparency=0.5 -cloneOutputType=Top -cloneColor=0xFF696BF0 -[clone_skill1] -x=1031 -y=1301 -w=76 -h=76 -dx=1368 -dy=474 -clonename=skill1 -cloneTransparency=0.450000 -cloneOutputType=clone -cloneRotation=0 +clonename=rage +cloneTransparency=1.0 +cloneOutputType=Left +cloneColor=0xff653414 +[clone_pulverizea] +x=1486 +y=1318 +w=8 +h=8 +dx=1486 +dy=1318 height=1440 width=2560 -cloneColor=0xFF4437D5 -cloneScale= +clonename=pulverizea +cloneTransparency=1.0 +cloneOutputType=Full +cloneColor=0xff9c451d