Page 1 of 1

help with MCode

Posted: 25 Nov 2019, 00:20
by guest3456
so i've downloaded joedf's MCode4GCC and installed tdm-gcc 32bit

i've pasted in this pixelsearch function:
http://autohotkey.com/board/topic/89283-mcode-function-onlinegenerator-x86-and-x64/?p=584519

but i cannot get it to work. i have a full test script working with tic's pixelsearch which is included, but i cannot get rseding's to work

code below, and haystack image attached. please help. @Helgef @joedf @nnnik

maybe it has something to do with Rseding's version allowing me to pass multiple colors to search for? i'm not sure how i would pass multiple colors as unsigned char * through dllcall.

Code: Select all

#include Gdip_All.ahk

; My42Function := MCode("2,x86:uCoAAADD,x64:uCoAAADD")
; Msgbox % DllCall(My42Function,"cdecl")   ; works

pToken := Gdip_Startup()
pBitmapHaystack := Gdip_CreateBitmapFromFile("red_dot.png")
color := 0xFFFF0000
ret := Tic_PixelSearch(pBitmapHaystack, color, outx, outy)
msgbox, works!`n%ret%`n%outx%`n%outy%
ret := Rseding91_PixelSearch(pBitmapHaystack, color, outx, outy)
msgbox, fails!`n%ret%`n%outx%`n%outy%
Gdip_DisposeImage(pBitmapHaystack)
Gdip_Shutdown(pToken)
return


;// https://autohotkey.com/board/topic/89283-mcode-function-onlinegenerator-x86-and-x64/page-2#entry584519
Rseding91_PixelSearch(pBitmap, color, ByRef x, ByRef y)
{
   static PixSearch
   if (!PixSearch)
   {
      code := "2,x86:VVdWU4PsEIN8JFABi2wkMItcJDQPhfAAAACLRCRIOUQkQA+N4gAAAItEJECLdCQ8"
            . "D69EJDiNBLADRCQsiUQkDItEJAyJRCQEi0QkPIlEJAiLRCREOUQkPA+NkQAAAGaQ"
            . "hdt+c4tEJASLVCRMD7ZIAjHAAcorTCRMiQwkkI10JgAPtkyFAjnRf0c7DCR8Qot8"
            . "JAQPtnSFAQ+2TwGLfCRMAc85/n8rK0wkTDnOfCOLfCQED7Z0hQAPtg+LfCRMAc85"
            . "/n8NK0wkTDnOfWCQjXQmAIPAATnDdamDRCQIAYNEJAQEi0QkCDlEJEQPhXH///+D"
            . "RCRAAYt0JDiLRCRAAXQkDDlEJEgPhTb///+LRCQkxwD/////i0QkKMcA/////4PE"
            . "ELin5P//W15fXcOLRCQki3QkCIkwi0QkKIt0JECJMIPEEDHAW15fXcOQkJCQkJCQ"
      PixSearch := MCode(code)
   }

   Gdip_GetImageDimensions(pBitmap, Width, Height)
   if !(Width && Height)
           return -1

   if (E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1))
           return -2

   x := y := 0
   E := DllCall(PixSearch, "int*", x, "int*", y, "uint", Scan01, "uint", color, "int", 1, "int", Stride1, "int", 0, "int", 0, "int", Width, "int", Height, "int", 0, "int", 1, "cdecl uint")
   ; MsgBox, %ErrorLevel%`n%A_LastError%
   Gdip_UnlockBits(pBitmap, BitmapData1)
   return E
}



MCode(mcode)
{
  static e1 := 4, e2 := 1
  static c, ptr
  c := (A_PtrSize=8) ? "x64" : "x86"
  ptr := A_PtrSize ? "Ptr" : "UInt"

  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), "str", m3, "uint", 0, "uint", e%m1%, ptr, 0, "uint*", s, ptr, 0, ptr, 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, ptr, s, ptr)
  DllCall("VirtualProtect", ptr, p, ptr, s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), "str", m3, "uint", 0, "uint", e%m1%, ptr, p, "uint*", s, ptr, 0, ptr, 0))
    return p
  DllCall("GlobalFree", ptr, p)
}



;// https://autohotkey.com/board/topic/79077-gdip-pixelsearch/
Tic_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y)
{
        static _PixelSearch
        if !_PixelSearch
        {
                MCode_PixelSearch := "8B44241099535583E2035603C233F6C1F80239742418577E388B7C24148B6C24248B5424188D1C85000000008D64240033C085"
                . "D27E108BCF3929743183C00183C1043BC27CF283C60103FB3B74241C7CDF8B4424288B4C242C5F5EC700FFFFFFFF5DC701FFFFFFFF83C8FF5BC38B4C2"
                . "4288B54242C5F890189325E5D33C05BC3"

                VarSetCapacity(_PixelSearch, StrLen(MCode_PixelSearch)//2)
                Loop % StrLen(MCode_PixelSearch)//2      ;%
                        NumPut("0x" SubStr(MCode_PixelSearch, (2*A_Index)-1, 2), _PixelSearch, A_Index-1, "char")
        }
        Gdip_GetImageDimensions(pBitmap, Width, Height)
        if !(Width && Height)
                return -1

        if (E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1))
                return -2

        x := y := 0
        E := DllCall(&_PixelSearch, "uint", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int*", x, "int*", y)
        Gdip_UnlockBits(pBitmap, BitmapData1)
        return (E = "") ? -3 : E
}

Re: help with MCode  Topic is solved

Posted: 25 Nov 2019, 01:06
by Helgef
Try this,

Code: Select all

#include <Gdip_All>
setworkingdir %a_scriptdir%
; My42Function := MCode("2,x86:uCoAAADD,x64:uCoAAADD")
; Msgbox % DllCall(My42Function,"cdecl")   ; works

pToken := Gdip_Startup()
pBitmapHaystack := Gdip_CreateBitmapFromFile("red_dot.png")
color := 0xFFFF0000

;ret := Tic_PixelSearch(pBitmapHaystack, color, outx, outy)
;msgbox, works!`n%ret%`n%outx%`n%outy%

makeColors(colors, color)
num_colors := 1
makeColors(byref color_out, colors*) {
	; make an unsigned int array from colors.
	local
	varsetcapacity(color_out, colors.length() * 4)
	for k, col in colors
		; edit: numput(col, color_out, "uint")
		numput(col, color_out, (k - 1) * 4, "uint")
}



ret := Rseding91_PixelSearch(pBitmapHaystack, colors, num_colors, outx, outy)
msgbox % "ret:`t" ret "`nx`t" outx "`ny`t" outy
Gdip_DisposeImage(pBitmapHaystack)
Gdip_Shutdown(pToken)
return



;// https://autohotkey.com/board/topic/89283-mcode-function-onlinegenerator-x86-and-x64/page-2#entry584519
Rseding91_PixelSearch(pBitmap, byref colors, num_colors, ByRef x, ByRef y)
{
   local
   static PixSearch
   ;if (!PixSearch)
   ;{
   ;   code := "2,x86:VVdWU4PsEIN8JFABi2wkMItcJDQPhfAAAACLRCRIOUQkQA+N4gAAAItEJECLdCQ8"
   ;         . "D69EJDiNBLADRCQsiUQkDItEJAyJRCQEi0QkPIlEJAiLRCREOUQkPA+NkQAAAGaQ"
   ;         . "hdt+c4tEJASLVCRMD7ZIAjHAAcorTCRMiQwkkI10JgAPtkyFAjnRf0c7DCR8Qot8"
   ;         . "JAQPtnSFAQ+2TwGLfCRMAc85/n8rK0wkTDnOfCOLfCQED7Z0hQAPtg+LfCRMAc85"
   ;         . "/n8NK0wkTDnOfWCQjXQmAIPAATnDdamDRCQIAYNEJAQEi0QkCDlEJEQPhXH///+D"
   ;         . "RCRAAYt0JDiLRCRAAXQkDDlEJEgPhTb///+LRCQkxwD/////i0QkKMcA/////4PE"
   ;         . "ELin5P//W15fXcOLRCQki3QkCIkwi0QkKIt0JECJMIPEEDHAW15fXcOQkJCQkJCQ"
   ;   PixSearch := MCode(code) ; returns blank
   ;}
	
	
	static flProtect:=0x40, flAllocationType:=0x1000 ; PAGE_EXECUTE_READWRITE ; MEM_COMMIT	
	static raw32:=[]
	static raw64:=[1447122753,1413567809,1398167381,418153288,3089415299,16777216,614763332,128,1221429581,1612991625,609519944,612666216,136,616336196,152,2686758027,1140850688,2955185291,251658240,53125,3158000640,43044,3247247104,1207959552,2303260771,2332566652,9446588,255918080,2370095023,48436,2554855424,1291215693,2370695169,2369847348,1241457732,109399181,2418326667,1275068416,4013553289,2422631293,2128905541,3054453849,2370372182,2370241093,692392196,280367050,2143435076,3526968376,3054449532,256115030,1107253430,1091640461,562027321,1103767876,427610937,1142339087,4267226639,287083841,2145073473,3391702024,2110994753,3229829192,3241756676,3347298165,3330492417,1979529476,3347267991,1946373121,960759844,11019452,2232352768,4294967152,608471880,4278241120,1224736767,1747207307,4294901959,2813919231,3959422948,1149978641,948527140,608471880,948520040,2202583089,1583028420,1547787615,1581342017,2428723009]
	static bin := ""
	if (bin == "") {
		if !bin:=DllCall("Kernel32.dll\VirtualAlloc", "Uptr",0, "Ptr", (raw:=A_PtrSize==4?raw32:raw64).length()*4, "Uint", flAllocationType, "Uint", flProtect, "Ptr")
			throw exception("oom")
		for k, i in raw
			NumPut(i,bin+(k-1)*4,"Int")
		raw32:="",raw64:=""
		PixSearch := bin
	}


   Gdip_GetImageDimensions(pBitmap, Width, Height)
   if !(Width && Height)
           return -1
   if (E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1))
           return -2
	
   x := y := 0
   ; (int * Foundx, int * Foundy, unsigned char * hScan, unsigned char * NeedleColors, int NumColors, int hStride, int sx1, int sy1, int sx2, int sy2, int v, int sd)
   E := DllCall(PixSearch, "int*", x, "int*", y, "ptr", Scan01, "ptr", &colors, "int", num_colors, "int", Stride1, "int", 0, "int", 0, "int", Width, "int", Height, "int", 0, "int", 1, "cdecl uint")
   ; MsgBox, %ErrorLevel%`n%A_LastError%
   Gdip_UnlockBits(pBitmap, BitmapData1)
   return E
}
The mcode() function returned blank, I also fixed the input to the dllcall. You need to pass an array of colors. Also note the use of ptr vs uint.

Cheers

Re: help with MCode

Posted: 25 Nov 2019, 01:18
by guest3456
Helgef wrote:
25 Nov 2019, 01:06
Try this,
Thank you so much. I'm getting exception "oom" if I run on 32bit ahk. It works on 64 bit ahk
I have no idea what your mcode is. Can you help me get something reproducable? that's why i was trying to use joedf's gcc script.

Helgef wrote:
25 Nov 2019, 01:06
The mcode() function returned blank, I also fixed the input to the dllcall. You need to pass an array of colors.
its not returning blank for me. (edit, its returning blank on ahk x64 because i don't specify 64bit mcode, only x86)
thanks it works with your makeColors func!

Code: Select all

#include Gdip_All.ahk

; Msgbox % MyFunction := MCode("2,x86:uCoAAADD,x64:uCoAAADD")
; Msgbox % DllCall(MyFunction,"cdecl")   ; works
pToken := Gdip_Startup()
pBitmapHaystack := Gdip_CreateBitmapFromFile("red_dot.png")
color := 0xFFFF0000
; ret := Tic_PixelSearch(pBitmapHaystack, color, outx, outy)
; msgbox, works!`n%ret%`n%outx%`n%outy%
makeColors(colors, color)
ret := Rseding91_PixelSearch(pBitmapHaystack, colors, 1, outx, outy)
msgbox, works!`n%ret%`n%outx%`n%outy%
Gdip_DisposeImage(pBitmapHaystack)
Gdip_Shutdown(pToken)
return

makeColors(byref color_out, colors*) {
	; make an unsigned int array from colors.
	local
	varsetcapacity(color_out, colors.length() * 4)
	for k, col in colors
		numput(col, color_out, "uint")
}

Rseding91_PixelSearch(pBitmap, ByRef colors, numcolors, ByRef x, ByRef y)
{
   static PixSearch
   if (!PixSearch)
   {
      code := "2,x86:VVdWU4PsEIN8JFABi2wkMItcJDQPhfAAAACLRCRIOUQkQA+N4gAAAItEJECLdCQ8"
                  . "D69EJDiNBLADRCQsiUQkDItEJAyJRCQEi0QkPIlEJAiLRCREOUQkPA+NkQAAAGaQ"
                  . "hdt+c4tEJASLVCRMD7ZIAjHAAcorTCRMiQwkkI10JgAPtkyFAjnRf0c7DCR8Qot8"
                  . "JAQPtnSFAQ+2TwGLfCRMAc85/n8rK0wkTDnOfCOLfCQED7Z0hQAPtg+LfCRMAc85"
                  . "/n8NK0wkTDnOfWCQjXQmAIPAATnDdamDRCQIAYNEJAQEi0QkCDlEJEQPhXH///+D"
                  . "RCRAAYt0JDiLRCRAAXQkDDlEJEgPhTb///+LRCQkxwD/////i0QkKMcA/////4PE"
                  . "ELin5P//W15fXcOLRCQki3QkCIkwi0QkKIt0JECJMIPEEDHAW15fXcOQkJCQkJCQ"
      msgbox % PixSearch := MCode(code)
   }

   Gdip_GetImageDimensions(pBitmap, Width, Height)
   if !(Width && Height)
           return -1

   if (E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1))
           return -2

   x := y := 0
   E := DllCall(PixSearch, "int*", x, "int*", y, "uint", Scan01, "uint", &colors, "int", 1, "int", Stride1, "int", 0, "int", 0, "int", Width, "int", Height, "int", 0, "int", 1, "cdecl uint")
   ; MsgBox, %ErrorLevel%`n%A_LastError%
   Gdip_UnlockBits(pBitmap, BitmapData1)
   return E
}



MCode(mcode)
{
  static e1 := 4, e2 := 1
  static c, ptr
  c := (A_PtrSize=8) ? "x64" : "x86"
  ptr := A_PtrSize ? "Ptr" : "UInt"

  if (!regexmatch(mcode, "^([0-9]+),(" c ":|.*?," c ":)([^,]+)", m))
    return
  if (!DllCall("crypt32\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), "str", m3, "uint", 0, "uint", e%m1%, ptr, 0, "uint*", s, ptr, 0, ptr, 0))
    return
  p := DllCall("GlobalAlloc", "uint", 0, ptr, s, ptr)
  DllCall("VirtualProtect", ptr, p, ptr, s, "uint", 0x40, "uint*", op)
  if (DllCall("crypt32\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), "str", m3, "uint", 0, "uint", e%m1%, ptr, p, "uint*", s, ptr, 0, ptr, 0))
    return p
  DllCall("GlobalFree", ptr, p)
}



;// https://autohotkey.com/board/topic/79077-gdip-pixelsearch/
Tic_PixelSearch(pBitmap, ARGB, ByRef x, ByRef y)
{
        static _PixelSearch
        if !_PixelSearch
        {
                MCode_PixelSearch := "8B44241099535583E2035603C233F6C1F80239742418577E388B7C24148B6C24248B5424188D1C85000000008D64240033C085"
                . "D27E108BCF3929743183C00183C1043BC27CF283C60103FB3B74241C7CDF8B4424288B4C242C5F5EC700FFFFFFFF5DC701FFFFFFFF83C8FF5BC38B4C2"
                . "4288B54242C5F890189325E5D33C05BC3"

                VarSetCapacity(_PixelSearch, StrLen(MCode_PixelSearch)//2)
                Loop % StrLen(MCode_PixelSearch)//2      ;%
                        NumPut("0x" SubStr(MCode_PixelSearch, (2*A_Index)-1, 2), _PixelSearch, A_Index-1, "char")
        }
        Gdip_GetImageDimensions(pBitmap, Width, Height)
        if !(Width && Height)
                return -1

        if (E1 := Gdip_LockBits(pBitmap, 0, 0, Width, Height, Stride1, Scan01, BitmapData1))
                return -2

        x := y := 0
        E := DllCall(&_PixelSearch, "uint", Scan01, "int", Width, "int", Height, "int", Stride1, "uint", ARGB, "int*", x, "int*", y)
        Gdip_UnlockBits(pBitmap, BitmapData1)
        return (E = "") ? -3 : E
}


Helgef wrote:
25 Nov 2019, 01:06
Also note the use of ptr vs uint.
are you talking about the Scan parameter or the Colors param? i was using uint for AHK_Basic compatability

Re: help with MCode

Posted: 25 Nov 2019, 01:35
by Helgef
its not returning blank for me. (edit, its returning blank on ahk x64 because i don't specify 64bit mcode, only x86)
And I only supplied the 64bit code, that is why it doesn't work on 32 ;)
Did my b64 output look right?
I didn't look at your mcode string just replaced it when it didn't work.
are you talking about the Scan parameter or the Colors param? i was using uint for AHK_Basic compatability
Yes. Then I assume 64 bit is not available anyways.

Cheers.

Re: help with MCode

Posted: 25 Nov 2019, 01:43
by guest3456
Helgef wrote:
25 Nov 2019, 01:35
And I only supplied the 64bit code, that is why it doesn't work on 32 ;)
one last thing, on both your mcode and mine, if we give a fake color, the output variables are correctly set to -1 as in Rsedings C code, however AHK reports the ret value as 4294960295 rather than the -7001 like the C code says

EDIT:

sorry, i see we return "cdecl UINT" rather than "INT". that fixes it

Re: help with MCode

Posted: 25 Nov 2019, 02:37
by guest3456
Helgef wrote:
25 Nov 2019, 01:06
You need to pass an array of colors.
another q:

this works on yours:

Code: Select all

makeColors(colors, 0xFFFF0000)
this fails

Code: Select all

makeColors(colors, 0xFFFF0000, 0xFF000000)
not sure why, since the first color should be found and return true. but with multiple colors, the pixelsearch is returning false

Re: help with MCode

Posted: 25 Nov 2019, 02:56
by Helgef
Helgef wrote:numput(col, color_out, "uint")
:facepalm:

Code: Select all

numput(col, color_out, (k - 1) * 4, "uint")

Re: help with MCode

Posted: 25 Nov 2019, 09:57
by joedf
So just a little recap here for me,
Is MCode4GCC working correctly for you @guest3456 ?

Re: help with MCode

Posted: 25 Nov 2019, 11:06
by guest3456
joedf wrote:
25 Nov 2019, 09:57
So just a little recap here for me,
Is MCode4GCC working correctly for you @guest3456 ?
yep, so far so good, the error was with how i was passing the color param as unsigned char *. Helgef fixed it