Hi,
in der letzten Zeit hab ich an einem Projekt gearbeitet, das das ganze _createNewBmp32 Zeug ersetzen (vereinfachen) soll. Man kann mit 5 Zeilen eine GUI erstellen und den ASM Code aufrufe, der die GUI füllt und es anzeigen. Zusätzlich soll es auch ein Stück weit bei Spielen helfen. Es gibt Funktionen zum Bilder laden, speichern und einfache Mausabfragen für Clientkoordinaten.
Der ein oder andere hat mich sicher in der SB verzweifeln sehen
GGEngine sollte ursprünglich GameGraphicsEngine heißen, es passt aber eigentlich eher GUI-Graphics oder ASM-Graphics-Engine
Das ganze hab ich in eine DLL verpackt und gleich noch eine Doku und ne UDF für geschrieben. Jetzt kann ich mit jeder Programmiersprachen ganz einfach einen Mustergenerator machen Und weil es so schön war, gibts eine Mustergeneratorversion als Beispiel dazu
CreateNewBMP32 ist jetzt in der Funktion IMGcreate drin. Ich hab es gehasst immer in meinen Dateien zu suchen, woher ich die kopieren kann
Die Doku ist in der Doku.txt (in der zip)
Hier 2 Beispiele (auch in der zip):
Mustergenerator
#include <GGEngine.au3>
#include <assembleit.au3>
$w=500
$h=500
$bildwert=0.01
_GGinit()
$gui=_GGGUIcreate("GGE ASM Test",$w,$h)
$ptr=_GGGUIgetIMGptr($gui)
_assembleit("float","_ASM","int",$w,"int",$h,"ptr",$ptr,"float",$bildwert)
_GGGUIupdate($gui)
While Not _GGGUIclosed($gui)
Sleep(10)
WEnd
_GGGUIdelete($gui)
_GGfree()
;Mein alter ASM-Code aus dem Mustergenerator (1:1)
Func _ASM()
_("use32")
_("org " & FasmGetBasePtr($Fasm))
_("finit") ;Co Prozessor starten
;
_("mov eax,[esp+4]") ;
_("mov [w],eax") ;w
_("mov eax,[esp+8]") ;
_("mov [h],eax") ;h
;startadresse in ebx, dann muss ebx immer nur um 4 erhöht werden, um das nächste pixel zu schreiben
_("mov ebx,[esp+12]") ;scan0
_("mov eax,[w]") ;an das ende setzen, weil die schleifen auch von hinten anfangen
_("imul eax,[h]") ;w*h
_("imul eax,4") ;je pixel 4 bytes: w*h*4
_("add ebx,eax") ;scan0 += size
_("sub ebx,4")
_("mov eax,[esp+16]") ;start / bildwert
_("mov [start],eax") ;
;register im coprostack belegen,
[/autoit] [autoit][/autoit] [autoit]_("fld [start]") ;st0=start
_("mov edx,[h]") ;Schleifenzähler edx für y, For $edx=$h to 0 Step -1
_("for_y:") ;Schleifenlabel
_("mov ecx,[w]") ;Schleifenzähler ecx für x
_("for_x:") ;Schleifenlabel
;Berechung
;st0=start
_("mov [ftemp],edx") ;st0=start
_("fild [ftemp]") ;st0=y st1=start
_("fmul st0,st1") ;st0=y*start st1=start
_("fptan") ;st0=1 st1=tangens !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!, (tan, in ASM umgekehrt, bgra)
_("fstp st0") ;stack sauber machen
_("mov [ftemp],ecx") ;
_("fild [ftemp]") ;st0=x st1=sin(y*start) st2=start
_("fmulp") ;st0=x*sin(y*start) st1=start
_("fistp dword[r]") ;st0=start ACHTUNG, entweder stack immer komplett leermachen oder einfach die werte weiterbenutzen!!
;ansonsten läuft der stack über...stackoverflow
_("mov [ftemp],edx") ;das ganze mit g und cos
_("fild [ftemp]") ;st0=y st1=start
_("fmul st0,st1") ;st0=y*start st1=start
_("fcos") ;
_("mov [ftemp],ecx") ;
_("fild [ftemp]") ;st0=x st1=y*start st2=start
_("fmulp") ;st1=x*(y*start) st1=start
_("fistp dword[g]") ;st0=start
_("mov [ftemp],edx") ;und b und tan
_("fild [ftemp]") ;
_("fmul st0,st1") ;
_("fsin") ;st0=sin(y*start) st1=start
_("mov [ftemp],ecx") ;st0=tangens
_("fild [ftemp]") ;
_("fmulp") ;
_("fistp dword[b]") ;st0=start, stack muss gecleant werden in der schleife!
_("mov byte[code=c],255") ;alpha auf 255 setzen
_("mov eax,dword[r]") ;die 4 aufeinanderfolgenden bytes holen
_("mov DWORD[ebx],eax") ;color in [ebx] (bild) schreiben
_("sub ebx,4") ;ein pixel weiter bzw. zurück
_("dec ecx") ;Zähler dekrementieren
_("jnz for_x") ;Wenn Zähler <> 0 dann wiederhole Schleife
_("dec edx") ;Zähler dekrementieren
_("jnz for_y") ;Wenn Zähler <> 0 dann wiederhole Schleife
_("fstp st0") ;stack sauber machen
_("fld [start]") ;Rückgabewert=Start / Bildwert
_("ret") ;Ende, Rückgabewert ist der letzte Wert des ERSTEN! Pixels (Scheife geht Rückwärts)
_("r db 0") ;
_("g db 0") ;
_("b db 0") ;
_("c dd 0") ;dummy, platz zum schreiben von dword nach [b]
_("ftemp dd 0.0") ;zum schreiben von edx/ecx auf floating stack
_("start dd 0.0") ;für berechnung
_("w dd 0") ;Speicher für Parameter reservieren
_("h dd 0") ;
EndFunc
BSP mit fast allen Funktionen
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <ScreenCapture.au3>
#include <GGEngine.au3>
_GGinit()
$gui=_GGGUIcreate("Test",500,500)
$hwnd=_GGGUIgetHWND($gui)
$img=DllStructCreate("dword["&(500*500)&"]",_GGGUIgetIMGptr($gui))
WinSetTitle($hwnd,"","Test - Neu")
[/autoit] [autoit][/autoit] [autoit]Local $screenbmp=_ScreenCapture_Capture("",0,0,249,249,True)
$screenimg=_GGIMGcreatefromBMP($screenbmp,250,250)
_WinAPI_DeleteObject($screenbmp)
$screenbmp=_GGIMGgetDC($screenimg)
_GGGUIdrawDC($gui,$screenbmp,0,0,250,250)
_GGIMGsave($screenimg,"screen.raw")
For $y=0 To 249
For $x=250 To 500
DllStructSetData($img,1,0xFF00FF00,$y*500+$x)
Next
Next
$buffer=_GGIMGcreate(250,250)
$bufptr=DllStructCreate("dword["&(250*250)&"]",_GGIMGgetPTR($buffer))
For $y=0 To 250
For $x=0 To 250
DllStructSetData($bufptr,1,0x7F00FF00,$y*250+$x)
Next
Next
_GGIMGdraw($screenimg,$buffer,0,0)
_GGGUIdraw($gui,$screenimg,0,250)
_GGIMGdelete($buffer)
_GGIMGdelete($screenimg)
_GGGUIupdate($gui)
[/autoit] [autoit][/autoit] [autoit]_GGGUIsavescreen($gui,"test.raw")
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]$loaded=_GGIMGcreatefromRAW("screen.raw")
[/autoit] [autoit][/autoit] [autoit]Local $mx=0,$my=0,$me=0
While True
If _GGGUIclosed($gui) Then ExitLoop
If _GGIsPressed(0x1B) And WinActive($hwnd) Then ExitLoop
$me=_GGGUIgetMouseEvent($gui,$mx,$my)
If $me=$GGDOWN And $mx>250 And $mx<500 And $my>250 And $my<500 Then ;DOWN
_GGGUIdraw($gui,$loaded,250,250)
_GGGUIupdate($gui)
ElseIf $me=$GGUP And $mx>250 And $mx<500 And $my>250 And $my<500 Then ;UP
For $y=250 To 500
For $x=250 To 500
DllStructSetData($img,1,0xFF000000,$y*500+$x)
Next
Next
_GGGUIupdate($gui)
EndIf
Sleep(10)
WEnd
_GGIMGdelete($loaded)
[/autoit] [autoit][/autoit] [autoit]_GGGUIdelete($gui)
_GGfree()
Exit 0
Beispiel mit GDI+ (only Autoit UDF) und neuen Funktionen.
Spoiler anzeigen
#include <GGEngine.au3>
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]_GGinit()
[/autoit] [autoit][/autoit] [autoit]$img=_GGIMGcreatefromFILE("Farben.jpg")
$w=_GGIMGgetW($img)
$h=_GGIMGgetH($img)
_GGIMGsavetoFILE($img,"Farben.png")
$gui=_GGGUIcreate("GGE GDI+ Image viewer",$w,$h)
[/autoit] [autoit][/autoit] [autoit]_GGGUIdraw($gui,$img,0,0)
_GGIMGdelete($img)
_GGGUIupdate($gui)
While Not _GGGUIclosed($gui)
Sleep(10)
WEnd
_GGGUIdelete($gui)
_GGfree()
Ich hatte keine Lust sämtliche Bildformate zu lernen zu entpacken und dann zu verwenden. Daher hab ich das einfachstmöglichste Format der Welt namens RAW erschaffen und gleich einen Converter dazu in die zip gepackt (mit AU3 Code)
Das UDF-include GGEngine.au3 und die DLL sind natürlich auch mit der zip
Mustergenerator-Beispiel Screenshot:
autoit.de/wcf/attachment/18632/
Ich hoffe es gefällt und hilft euch. Ich freu mich auf euer Feedback.
Viel Spaß
mfg
TheShadowAE
EDIT:
Ganz vergessen Andy zu danken, er hat mir mal wieder geholfen ein Problem zu lösen
EDIT: UPDATE:
Ich hab Andys genannten Fehler mal gefixt. Und hab mal für die, die es noch nicht haben, die assembleit angehangen.
UPDATE:
Ich habs geschafft, die DLL ist jetzt im include enthalten. Dh. man braucht nur die au3 und schon läuft alles Zusätzlich hab ich noch eine kleine Korrektur gemacht, wodurch beim Klicken ca. 100 Ticks weniger verbraucht werden
UPDATE:
Jetzt kann man jede Bildformate öffnen und speichern mit den neuen Funktionen (3. Beispiel) und Width und Height abfragen.