Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

MCodeGen - Easily transform C/C++ code into mcode


  • Please log in to reply
48 replies to this topic
Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
Anyone knows the reason why this script requires VS2005 or later? I only have access to VC6. Haven't tried it yet but I know it has version checks.

(AHK 1.0.48.05 and Win98SE) forever | My scripts are here


Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

I looked into it with my limited abilities and I think it has something to do with this: "EXTRN __allmul:PROC".

Right. The 32-bit compiler uses that function to do 64-bit multiplication and another function for division. Since the code is not self-contained/portable, it won't work as-is in your script.

For more information (such as alternative inline assembly), google "_allmul".

  • Guests
  • Last active:
  • Joined: --

Anyone knows the reason why this script requires VS2005 or later? I only have access to VC6. Haven't tried it yet but I know it has version checks.


I think you can download VS2005/2008 for free.

Drugwash
  • Members
  • 1078 posts
  • Last active: May 24 2016 04:20 PM
  • Joined: 07 Sep 2008
1. I run Windows98, it's incompatible
2. My GPRS traffic is limited, can't afford large downloads
3. I like to use what's "in the house"; if it ain't broken, don't fix it

Thanks for trying to help though.

(AHK 1.0.48.05 and Win98SE) forever | My scripts are here


Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
I've been trying to get x64 compling working and I was not able to with the original mcodegen script. So, i've made some changes to get it working.

Download
Requirements for compiling: Visual studio 2005 express or later installed
Additional requirements for x64 compiling: Windows SDK installed for whatever version of VS you are using.

For VS 2010 I used the SDK 7.1 for Windows 7 which can be found >Here<
If that link ever breaks you can find the SDK by searching for "Microsoft Windows SDK for Windows 7 and .NET Framework 4" it is version 7.1 that I used. Others may work but i've only ever tested with that one.

If anyone has problems, let me know and i'll try to get them fixed.



Changes:
x64 compiling requires you have Windows 64 bit
Added a "warning level 0" option to disable showing warnings
Errors are now shown seperate from warnings and without any extra hoobla
The code in edit window is saved on exit and when you compile instead of only when you hit compile

Bug fixes:
x64 compiling now works
-Before, it would generate errors about missing components and such
Warnings are now shown if there are any
-Before, they where only shown if there where also errors
Warning level is now correctly set
-Before, if you choose 4 it would default back to 1
Changed the script to use the most-recent version of VS if multiple versions are installed
-Before, it tried to do this but it didn't work right

Thanks to infogulch for writing the new regex parser.

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
If you've downloaded my updated MCode Gen before 9/6/2011 10:39 AM (UTC -5) please re-download it as there was a typo in the x64 compiling code that cause it to not operate correctly.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Requirements for compiling: Visual studio 2005 express or later installed
Additional requirements for x64 compiling: Windows SDK installed for whatever version of VS you are using.

FYI, Visual Studio isn't needed if you have the Windows SDK. For example, I have the SDK installed at F:\SDK:
RunWait %ComSpec% /c "
(Join&
F:\SDK\Windows\v7.1\Bin\SetEnv.Cmd /Release /[color=red]x86[/color]
cl.exe /TC [color=red]code.c[/color] /c /FAc /Fa"[color=red]code.cod[/color]" /O2 /W 0 /nologo
)"
Compiling for 64-bit is a simple matter of replacing /x86 with /x64.

I run this via SciTE. By calling DllCall("AllocConsole") first, the output of the compiler (errors, warnings, etc.) goes to SciTE's output pane.

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
Update

For anyone who has had there x64 compiler disapear on them you will want this update: <!-- m -->http://support.micro....com/kb/2519277<!-- m -->

I had that problem on both of my computers and that fixed it.

Sven
  • Members
  • 22 posts
  • Last active: Apr 05 2012 08:03 AM
  • Joined: 03 Aug 2011
How do I use this to get working results?

C++ source code:
extern "C" __declspec (dllexport) void Gdip_ImageSearch(unsigned char * HayStack, unsigned char * Needle, int w1, int h1, int w2, int h2, int WindowX, int WindowY, int WindowW, int WindowH, int Stride1, int Stride2, int * x, int * y, int tc, int varia)
{
   int tx, ty;
   int offset1 = Stride1/4, offset2 = Stride2/4;
   int R1, R2, G1, G2, B1, B2, o1, o2;
   int tcR = (tc & 0x00ff0000) >> 16, tcG = (tc & 0x0000ff00) >> 8, tcB = tc & 0x000000ff; // transforms tc to usable values
   int WindowX2 = WindowX+WindowW-w2+1, WindowY2 = WindowY+WindowH-h2+1; // calculates window maximas inside HayStack
   unsigned char sample[5][3];
   int samplePos[5][2];
   int sampleSize = 0;

   if (WindowX2>w1)
   {
      WindowX2 = w1;
   }
   if (WindowY2>h1)
   {
      WindowY2 = h1;
   }

   // choose a smallish sample containing only opaque colors that will be used to confirm candidates
   for (int y2 = 0; y2 < h2; ++y2)
   {
      for (int x2 = 0; x2 < w2; ++x2)
      {
         o2 = (4*x2)+(y2*Stride2);
         if (Needle[2+o2] != tcR || Needle[1+o2] != tcG || Needle[o2] != tcB)
         {
            samplePos[sampleSize][0] = x2;
            samplePos[sampleSize][1] = y2;
            sample[sampleSize][0] = Needle[2+o2];
            sample[sampleSize][1] = Needle[1+o2];
            sample[sampleSize][2] = Needle[o2];
            if (++sampleSize >= 5)
            {
               goto SampleCompleted;
            }
         }
      }
   }
SampleCompleted:

   for (int y1 = WindowY; y1 < WindowY2; ++y1)
   {
      for (int x1 = WindowX; x1 < WindowX2; ++x1)
      {
         // first confirm it's a valid candidate
         for (int loop = 0; loop < sampleSize; ++loop)
         {
            o1 = (4*(x1+samplePos[loop][0]))+((y1+samplePos[loop][1])*Stride1);
            R1 = HayStack[2+o1]; G1 = HayStack[1+o1]; B1 = HayStack[o1];
            R2 = sample[loop][0]; G2 = sample[loop][1]; B2 = sample[loop][2];
            if (R1 > R2 + varia || R1 < R2 - varia || G1 > G2 + varia || G1 < G2 - varia || B1 > B2 + varia || B1 < B2 - varia)
               goto NoMatch;
         }

         // thorough candidate analysis
         ty = y1;
         for (int y2 = 0; y2 < h2; ++y2)
         {
            tx = x1;
            for (int x2 = 0; x2 < w2; ++x2)
            {
               o2 = (4*x2)+(y2*Stride2);
               R2 = Needle[2+o2]; G2 = Needle[1+o2]; B2 = Needle[o2];
               if (R2 != tcR || G2 != tcG || B2 != tcB)
               {
                  o1 = (4*tx)+(ty*Stride1);
                  R1 = HayStack[2+o1]; G1 = HayStack[1+o1]; B1 = HayStack[o1];

                  if (R1 > R2 + varia || R1 < R2 - varia || G1 > G2 + varia || G1 < G2 - varia || B1 > B2 + varia || B1 < B2 - varia)
                     goto NoMatch;
               }
               tx++;
            }
            ty++;
         }
         x[0] = x1-1; y[0] = y1;
         return;
NoMatch:
         continue;
      }
   }
   x[0] = -1; y[0] = -1;
   return;
}
Thanks go to Ax. This is the code I'm trying to work on. Running this untouched source code through MCodeGen however results in machine code that doesn't work. I've tried MCodeGen in conjunction with Microsoft Visual Studio 2010 Express, 2008 Express and 2005 Express. Nothing works.

Here's an example in which the machine code clearly works:
#SingleInstance, Force
#NoEnv
SetBatchLines, -1

#include GDip.ahk

If !pToken := Gdip_Startup()
{
   MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
   ExitApp
}
OnExit, Exit

pBitmapHayStack := Gdip_BitmapFromScreen(0) ; Haystack: entire screen
Random, whereX, 1, A_ScreenWidth - 100
Random, whereY, 1, A_ScreenHeight - 100
pBitmapNeedle := Gdip_BitmapFromScreen(whereX . "|" . whereY . "|" . 100 . "|" . 100) ; Needle: some random part of the screen
Gdip_SetBitmapToClipboard(pBitmapNeedle) ; Bah, for convenience

Width1 := Gdip_GetImageWidth(pBitmapHayStack), Height1 := Gdip_GetImageHeight(pBitmapHayStack)
Width2 := Gdip_GetImageWidth(pBitmapNeedle), Height2 := Gdip_GetImageHeight(pBitmapNeedle)
E1 := Gdip_LockBits(pBitmapHayStack, 0, 0, Width1, Height1, Stride1, Scan01, tmp)
E2 := Gdip_LockBits(pBitmapNeedle, 0, 0, Width2, Height2, Stride2, Scan02, tmp)

MCode(Gdip_ImageSearch, "83ec2c8b4424688bc8c1f91081e1ff00000053894c241c558bc8568b742460"
. "c1f90825ff00000081e1ff000000578b7c245889442430894c242c8b4c24608bc72b4424508d"
. "5408018b44245c8bc82b4c24548954241c8d4c31018b7424483bd6894c24207e068bd6897424"
. "1c8b74244c3bce7e068bce897424203bc1894424780f8d710100000faf4424688b5c24448b6c"
. "24408944244c3bfa8bf7897424480f8d3c0100008b54244c33c9894c24648954245c8b442464"
. "3b442454894c24180f8d4e010000837c245000c7442414000000000f8ecf0000008d43018d14"
. "b5000000008d34018bcb895424602bc883c1028bd32bd0894c2424895424388d6424008b4424"
. "240fb60c300fb604320fb63e894424103b4c242875103b7c242c750a8b44243039442410745b"
. "8b54245c8b44246003c20fb65428020fb65c28010fb60428894424348b44247c8d2c013bd57f"
. "6c2bc83bd17c668d0c073bd97f5f2bf83bdf7c598b4c24108b5424348d3c013bd77f4a2bc83b"
. "d17c448b5c24448b5424388b6c24408b44241483442460044083c6043b442450894424140f8c"
. "61ffffff8b7424488b4c24188b5424680154245cff442464034c246ce9f7feffff8b7424488b"
. "54241c8b5c24448b6c2440463bf2897424480f8cccfeffff8b7c24588b4c24208b442468ff44"
. "24780144244c394c24780f8ca0feffff8b4c24708b5424745f5e5dc701ffffffffc702ffffff"
. "ff5b83c42cc38b4c24708b5424748b4424784e5f89315e5d89025b83c42cc3")

Time1 := A_TickCount
VarSetCapacity(x, 8, 0), VarSetCapacity(y, 8, 0)
Loop, 5
   DllCall(&Gdip_ImageSearch, "uint", Scan01, "uint", Scan02, "int", Width1, "int", Height1, "int", Width2, "int", Height2, "int", 0, "int", 0, "int", A_ScreenWidth, "int", A_ScreenHeight, "int", Stride1, "int", Stride2, "int*", x, "int*", y, "int", 0, "int", 10)
Result1:=A_TickCount-Time1

IfNotExist, tmp.bmp
{
   Gdip_SaveBitmapToFile(pBitmapNeedle, "tmp.bmp")
   CoordMode, Pixel
   Time1 := A_TickCount
   Loop, 5
      ImageSearch,x2, y2, 0, 0, A_ScreenWidth, A_ScreenHeight, *Trans0 *10 tmp.bmp
   Result2:=A_TickCount-Time1
   FileDelete, tmp.bmp
}

MsgBox, % "Time for 5 Gdip_ImageSearch searches: " Result1 "ms`nx: " x "`ny: " y "`n`n Time for 5 ImageSearch searches: " Result2 "ms`nx: " x2 "`ny: " y2 ;%

Gdip_UnlockBits(pBitmapHayStack, tmp), Gdip_UnlockBits(pBitmapNeedle, tmp)
Gdip_DisposeImage(pBitmapHayStack), Gdip_DisposeImage(pBitmapNeedle)
return

MCode(ByRef code, hex)
{
   VarSetCapacity(code, StrLen(hex)//2)
   Loop % StrLen(hex)//2      ;%
      NumPut("0x" SubStr(hex, 2*A_Index-1, 2), code, A_Index-1, "char")
}

Exit:
Gdip_Shutdown(pToken)
ExitApp
return
Thanks again to Ax.

The machine code I get by using MCodeGen is quite different:

"558D6C24C881EC98000000A10000000033C58945348B45708B4D788945AC8B45"
	. "748BD1C1FA108945B8B8FF00000023D08955B08BD123C8C1FA0823D08B45582B"
	. "455053894DB48B4D60568D440801578B7D5C8BCF2B4D548955A88B55648D4C11"
	. "018B554833F68945D4894DD08975EC3BC27E038955D48B454C3BC87E038945D0"
	. "8975F43975540F8E9D00000033D28955E4EB0233F68975F83975507E748B45EC"
	. "6BC0038BF20355448D4405256A02598A0C110FB6D93B5DB075158B5D440FB65C"
	. "1E013B5DA875080FB61A3B5DB474318B7DEC8B5DF8FF45EC8848FF8B4D448A4C"
	. "0E0188088A0A895CFDFC8B5DF488480183C003837DEC05895CFD008B7D5C7D29"
	. "FF45F88B4DF883C60483C2043B4D507C9BFF45F48B55E403556C8B45F48955E4"
	. "3B45540F8C6AFFFFFF897DF83B7DD00F8DCD0100000FAF7D688B4D7C8B554089"
	. "7DE48B45588945E8E9970100008365F000837DEC000F8E9A0000008D75258B45"
	. "F08B7CC500037DF88B44C5FC0FAF7D680345E80FB65E018D04870FB67C020289"
	. "7DDC0FB67C02010FB604108945F40FB646FF895DD88D1C08897DE00FB63E395D"
	. "DC0F8F370100002BC13945DC0F8C2C0100008D040F3945E00F8F200100002BF9"
	. "397DE00F8C150100008B45D88D3C08397DF40F8F060100002BC13945F40F8CFB"
	. "000000FF45F08B45F083C6033B45EC0F8C69FFFFFF8B45E433FF897DCC8945C0"
	. "8B45CC897DBC3B45540F8D110100008365C400837D50000F8EAD0000008B5DE8"
	. "8B7544C1E302895DC88D46018BDE2BD883C3028975F003F82945F0895DA48B45"
	. "A40FB634388B5DF00FB6070FB61C3B8945A0895DD83B75B0750C3B45A875078B"
	. "45B43BD8744E8B45C80345C00FB65C1002895DDC0FB65C10010FB604108945F4"
	. "8D040E895DE03945DC7F532BF13975DC7C4C8B45A08D34083BDE7F422BC13BD8"
	. "7C3C8B45D88D34083975F47F312BC13945F47C2AFF45C48B45C48345C80483C7"
	. "043B45500F8C74FFFFFF8B45680145C08B7DBCFF45CC037D6CE922FFFFFFFF45"
	. "E88B45E83B45D40F8C60FEFFFF8B4568FF45F80145E48B45F83B45D00F8C40FE"
	. "FFFF8B45AC8308FF8B45B88308FF8B4D345F5E33CD5BE80000000083C538C9C3"
	. "8B45E88B4DAC4889018B45F88B4DB88901EBDB"




Any clues?

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
The MCode gen script can only transform basic C/C++ code. It has problems with anything external (function calls mainly) and it does not handle string (char[]) references well.

Those would be the primary reasons I can think of that the code would not work. It also wont work with 64 bit multiplication/division (but it doesn't use that in the code you pasted).

You can look at the .asm file generated by the code for clues as to what is going wrong - it's stored in the temp directory.

Sven
  • Members
  • 22 posts
  • Last active: Apr 05 2012 08:03 AM
  • Joined: 03 Aug 2011
Got it. It was an issue with the compiler, which had to be set to compile .dll files in two places.

  • Guests
  • Last active:
  • Joined: --
Does anyone still have this one available? I'd be eternally grateful. :)

  • Guests
  • Last active:
  • Joined: --
Lol I was a bit absent minded there. Let this be a warning to all you who consider reducing sleep to 0x3dcccccd of the available time to spend the rest of their days with coding or at least pretending to do so while drooling on the keyboard.

RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

 

 

Got it. It was an issue with the compiler, which had to be set to compile .dll files in two places.

 

 

Where do you set this property?

 

Thanks.

 

And would this be able to get compiled?

 

#include <Windows.h>
using namespace std;

int main()
{


        HWND hsc = FindWindow("MineSweeper", NULL);

        DWORD id;
        GetWindowThreadProcessId(hsc, &id);
       HANDLE _hsc = OpenProcess(PROCESS_VM_READ, FALSE, id);
     byte Value;

    ReadProcessMemory(_hsc, (void *) 0x0037C9B8, &Value, sizeof(Value), NULL);
    CloseHandle(_hsc);
    return Value;
}

 

 

I'm trying to write a c++ memory read function which will be faster than AHKs - and this is just a basic test example.

 

Many thanks.



Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010

I'm trying to write a c++ memory read function which will be faster than AHKs - and this is just a basic test example.

 

Many thanks.

 

 All of the functions in your C++ function can be written in AHK using DllCall to get the same result and the speed difference wouldn't be noticable.