Apfelmaennchen in FASM-Assembler Update incl. FLUG!

  • Update 24/03/2010 Etwas Finetuning an den Funktionen, FASM-Assembler(download) integriert, big thx to Ward @ https://autoit.de/www.autoitscript.com
    Bitte testen und bei Problemen Betriebssystem 32/64 Bit und auch Info´s zum den Prozessor(!) (übertaktet usw.) mitteilen!
    -zzt nur als 32-Bitversion lauffähig....
    -ein "Flug" durch das Apfelmännchen (KEIN Video, sondern live berechnet) ist nun möglich! Das Fenster kann während des Fluges geändert werden, sowie auch die Farbpaletten.
    -Palettenfarben werden sofort geändert
    -Beim Speichern des Bildes werden die Koordinaten in die Datei fractalsave.dat geschrieben, von dort können die "Zielkoordinaten" für einen eigenen Flug in den Quellcode eingetragen werden.

    Update 07/03/2010 Farbpalette eingefügt, beliebige Paletten integrierbar, alle Farbwünsche sind möglich ^^, "Bild zurück" funktioniert auch jetzt

    Hallo zusammen,
    die "alten Zeiten" hatten mich wieder eingeholt, als ich beim Aufräumen einige 5 1/4´´-Disketten fand mit der Aufschrift "Apfelmännchen in Assembler". Leider konnnte der damals aktuelle (und das Viech läuft immer noch!) 8088 "ORGINAL IBM-PC" die Disketten nicht mehr lesen, kein Wunder nach 25 Jahren^^
    Damals hatte ich in Basic (erst GW- dann Turbo-bzw. Powerbasic) und Inlineassembler programmiert, die schriftlichen Unterlagen (Handabschriften der Programme, denn Drucker konnte sich kaum ein Normalsterblicher leisten) werden meine Urenkel irgendwann der thermischen Verwertung zuführen.
    Jedenfalls konnte ich mich noch daran erinnern, daß ich mir für den 8088 extra einen Co-Prozessor 8087 gekauft hatte, welcher die floating-point Berechnungen extrem (4,77 MHz) beschleunigte. Die Berechnung des Apfelmännchens passte vom Code genau in den 8 Register (a 80-Bit) großen Stack des Coprozessors, welcher PARALLEL zum eigentlichen Prozessor arbeiten konnte und so bei geschickter Programmierung sehr effizient einsetzbar ist.
    Naja, daran hat sich nicht viel geändert, der Coprozessorstack ist heutzutage immer noch 8 Register groß (80 Bit) , und weil man heutzutage alles als neu verkaufen kann, was einen neuen Namen hat, hat man diese Register "neu erfunden" und MMX genannt. "Ursprünglich stand das Kürzel MMX für Matrix Math Extensions, wurde allerdings von Intel marketingbedingt in Multi Media Extension umbenannt.[1]"(Zitat Wikipedia)

    Naja, das frühere Basic ist heutzutage AutoIt gewichen, und der Inlineassembler.....ja, den gibts bei AutoIt auch (fast jedenfalls^^)
    Also hab ich mich wieder in die Bits und Bytes gestürzt, und mit einer Handvoll Assemblerbefehlen (es sind immer noch dieselben wie früher :rock: ) AutoIt einen "Turbo" verpasst. Zum "Apfelmännchen" bzw. der Mandelbrotmenge sag ich jetzt weniger, im Anhang findet sich ein simples AutoIt-Script mit der Darstellung (geistert hier auch irgendwo im Forum herum).

    Natürlich kann man auch einfach einen C-Compiler anwerfen, eine DLL erstellen und diese aufrufen. Aber einfach kann jeder^^ *******//EDIT Ja, der FASM-Assembler kann auch dll´s erstellen.....//**********
    Ausserdem sollte man bemerken, daß sich der Aufwand nur bei langen Berechnungen lohnt, oder wenn es SEHR schnell sein muss, Beispiele finden sich für Verschlüsselung usw...

    Nun zum Programm, es ist ziemlich ausführlich dokumentiert, wenn irgendetwas unklar sein sollte, immer Fragen!
    Erstellt wird ein Bild der Mandelbrotmenge, die Berechnung der "Farbtiefe" der einzelnen Pixel und der gesamten Bitmap wurde mittels des Assemblerprogramms realisiert. Dabei ist erwähnenswert, daß die eigentliche Berechnung unabhängig von der GUI erfolgt, es ist also ohne weiteres möglich, ein 8000x6000 Pixel großes Bild zu erstellen, ohne daß man eine GUI erstellen muss. Ich bin gerade dabei, das Programm so auszulegen, daß auch Mehrkernprozessoren unterstützt werden. Bei Quadcores sollte eine Geschwindigkeitserhöhung um mindestens Faktor 3 drin sein.
    Was bei der Assemblerprogrammierung beachtet werden muß, es gibt KEINERLEI Fehleranzeigen, jeder Fehler führt unweigerlich zum Absturz (des Programms), allerdings ist es möglich, Register- und Speicherinhalte an AutoIt zurückzugeben und dort anzeigen zu lassen. Debugging (und evtl. einen Debugger) setze ich voraus, andererseits lernt man so extrem viel.
    Der vom Assembler erstellte Bytecode wird als Datei abgespeichert und kann von jedem Debugger eingelesen werden. Weiterhin ist dieser Bytecode, und das ist ein sehr feiner Nebeneffekt, direkt aus AutoIt OHNE Assembler ausführbar! Das heisst, wenn der Code funktioniert, reichen 5 Zeilen AutoIt-Code, um das Programm ablaufen zu lassen.
    Der Assemblercode ist etwas seltsam geworden, denn der von mir verwendete (AutoIt-Assembler) erlaubt keine Vorwärtssprünge (rückwärts gehts^^) zu einem Label, das heisst, bei jedem Vorwärtssprung müssen die Bytes der Prozessor-Opcodes gezählt oder ein Debugger angeworfen werden, sehr lästig das ganze, aber leider halten sich die Beteiligten mit Informationen SEHR bedeckt, vieles habe ich durch T&E herausgefunden :( Man sollte also so wenig wie möglich nach vorne springen....
    ********//EDIT Sprünge, Makros und die gesamte moderne Assemblersyntax sind problemlos verwendbar// ************
    Die GUI ist sehr bescheiden, die Fenstergröße lässt sich verändern und ein Kontextmenü (rechtsklick in die Grafik) stellt Optionen bereit. Ein Linksklick in die Grafik "zoomt" an der dortigen Position. Weiterhin sollte man beachten, daß, solange der Assemblercode läuft, keine Rückmeldung von AutoIt erfolgt! Aus diesem Grund habe ich mich dazu entschlossen, nach jeder berechneten Zeile in der Grafik aus dem Assemblercode einen Call einer einfachen AutoIt-Funktion aufzurufen, gewissermaßen ein Erlauben von Interrupts. Dieser Call frisst zwar enorm Performance, allerdings ist so gewährleistet, daß das Fenster auf Eingaben reagieren kann. Versucht mal, während der Berechnung zu minimieren....

    Eine Bitte hab ich noch an die Pinselquäler, Fachrichtung Farbpaletten. Zur Zeit ist die grafische Ausgabe "bunt", d.h. das Pixel wird einfach aus der berechneten Iterationstiefe bestimmt. Um die aus dem Internet bekannten "schönen" Bilder zu kommen, muß/sollte das Programm mit einer bzw. mehreren Farbpaletten arbeiten. Wer Ideen hat, her damit!
    EDIT /Palette eingefügt, weitere folgen....
    Die "schönen" Bilder unterscheiden sich nämlich ausschliesslich in dieser Palette, die eigentlichen Bildinformationen sind identisch!

    Hier mal Beispielbilder, mit dem Programm erstellt:
    [Blockierte Grafik: http://www.abload.de/thumb/test3curq.jpg][Blockierte Grafik: http://www.abload.de/thumb/test1pueo.jpg][Blockierte Grafik: http://www.abload.de/thumb/testtulu.jpg][Blockierte Grafik: http://www.abload.de/thumb/testrcm8.jpg]

    Spoiler anzeigen
    [autoit]

    #include <FASM.au3>
    #include <WinAPI.au3>
    #include <Memory.au3>
    #include <ScreenCapture.au3>
    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <MemoryConstants.au3>
    #include <StructureConstants.au3>
    #include <GuiMenu.au3>
    #include <MemoryDll.au3>
    ;#include <GDIConstants.au3>
    ;Thx to Ward from http://www.AutoIt.com for the great FASM.AU3
    ;http://www.autoitscript.com/forum/index.ph…ndpost&p=782727

    [/autoit] [autoit][/autoit] [autoit]

    ;#include <GDIConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)
    Opt("MouseCoordMode", 2)
    Opt("PixelCoordMode", 2)

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $DIB_RGB_COLORS = 0

    [/autoit] [autoit][/autoit] [autoit]

    Global $winx = 800 ;größe der CLIENT-Fläche!
    Global $winy = 600 ;größe der CLIENT-Fläche!

    [/autoit] [autoit][/autoit] [autoit]

    Global $height, $width, $bitmap, $ptr, $pbitmap, $pixelstruct, $zoom
    Global $iwidth, $iheight, $hgui, $hdc, $adib, $hcdc, $breite, $tiefe, $maxiter
    Global $cx, $cy, $clics, $count = 0, $minimized, $contextflag, $flightflag=0, $newwindowflag=0
    global $exitflag=0
    Global $wintitle = "Apfelmaennchen by Andy (http://www.AutoIt.de)"

    [/autoit] [autoit][/autoit] [autoit]

    Global $hgui = GUICreate($wintitle, $winx, $winy, -1, -1, $WS_OVERLAPPEDWINDOW); @DesktopWidth, @DesktopHeight)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_WindowEvents", $hgui)
    GUISetOnEvent($GUI_EVENT_MINIMIZE, "_WindowEvents")
    GUISetOnEvent($GUI_EVENT_MAXIMIZE, "_WindowEvents")
    GUISetOnEvent($GUI_EVENT_RESTORE, "_WindowEvents")
    GUISetOnEvent($GUI_EVENT_RESIZED, "_WindowEvents")
    GUISetOnEvent($GUI_EVENT_PRIMARYDown, "_MouseEvents") ;beim UP der linken Maustaste die func aufrufen

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $context = GUICtrlCreateContextMenu(-1)
    $item1 = GUICtrlCreateMenuItem("Save Picture", $context)
    $item2 = GUICtrlCreateMenuItem("Zoom backwards", $context)
    ;$item3 = GUICtrlCreateMenuItem("Load Picture/File", $context)
    $item4 = GUICtrlCreateMenu("Render flight to a nice place....", $context)
    $item4_1 = GUICtrlCreateMenuItem("Example 1", $item4)
    $item4_2 = GUICtrlCreateMenuItem("Example 2", $item4)
    $item4_3 = GUICtrlCreateMenuItem("Example 3", $item4)
    $item4_4 = GUICtrlCreateMenuItem("Example 4", $item4)
    $item5 = GUICtrlCreateMenu("Zoom", $context)
    $item5_1 = GUICtrlCreateMenuItem("Zoom x2", $item5,0,1)
    $item5_2 = GUICtrlCreateMenuItem("Zoom x3", $item5,1,1)
    $item5_3 = GUICtrlCreateMenuItem("Zoom x4", $item5,2,1)
    $item5_4 = GUICtrlCreateMenuItem("Zoom x1.2", $item5,3,1)
    $item6 = GUICtrlCreateMenu("Palette", $context)
    $item6_1 = GUICtrlCreateMenuItem("Palette1", $item6,0,1)
    $item6_2 = GUICtrlCreateMenuItem("Palette2", $item6,1,1)
    $item6_3 = GUICtrlCreateMenuItem("Palette3", $item6,2,1)
    $item6_4 = GUICtrlCreateMenuItem("Palette4", $item6,3,1)
    $item7 = GUICtrlCreateMenuItem("Start new", $context)

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetOnEvent($item1, "_SavePic")
    GUICtrlSetOnEvent($item2, "_PicBack")
    ;GUICtrlSetOnEvent($item3, "_LoadPic")
    GUICtrlSetOnEvent($item4_1, "_Flightrender")
    GUICtrlSetOnEvent($item4_2, "_Flightrender")
    GUICtrlSetOnEvent($item4_3, "_Flightrender")
    GUICtrlSetOnEvent($item4_4, "_Flightrender")
    GUICtrlSetOnEvent($item5_1, "_zoom")
    GUICtrlSetOnEvent($item5_2, "_zoom")
    GUICtrlSetOnEvent($item5_3, "_zoom")
    GUICtrlSetOnEvent($item5_4, "_zoom")
    GUICtrlSetOnEvent($item6_1, "_palette1")
    GUICtrlSetOnEvent($item6_2, "_palette2")
    GUICtrlSetOnEvent($item6_3, "_palette3")
    GUICtrlSetOnEvent($item6_4, "_palette4")
    GUICtrlSetOnEvent($item7, "_startnew")

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetState($item5_3,$gui_checked)
    GUICtrlSetState($item6_1,$gui_checked)

    [/autoit] [autoit][/autoit] [autoit]

    Global $AsmObj = FAsmInit() ;init assembler
    Global $pointer ;pointer auf die Bitmapdaten initialisieren, byref für _createbitmap32()
    Global $hbitmap ;hbitmap initialisieren , byref _createbitmap32()
    Global $hpicDC = _CreateNewBmp32($winx, $winy, $pointer, $hbitmap) ;neue 32-Bit-Bitmap erstellen, pointer ist nun die Startadresse der Bitmapdaten, hbitmap zum einfachen speichern usw

    [/autoit] [autoit][/autoit] [autoit]

    Global $pointer_palette ;pointer auf die Bitmapdaten initialisieren, byref für _createbitmap32()
    Global $hbitmap_palette ;hbitmap initialisieren , byref _createbitmap32()
    Global $hpicDC_palette = _CreateNewBmp32($winx, $winy, $pointer_palette, $hbitmap_palette) ;neue 32-Bit-Bitmap für die mit der Farbpalette eingefärbte Bitmap erstellen, pointer ist nun die Startadresse der Bitmapdaten, hbitmap zum einfachen speichern usw

    [/autoit] [autoit][/autoit] [autoit]

    Global $hwinDC = _WinAPI_GetDC($hgui) ;DeviceContext der GUI holen, brauchen wir zum blitten der Bitmaps

    [/autoit] [autoit][/autoit] [autoit]

    ;Struct erstellen, auf diese Daten greift der Assembler zu
    ;ich arbeite mit Absicht hier nicht mit den Basepointern, dazu später mehr^^
    ;Übergabeparameter Name Parameter Größe Adresse(im asm-prog bzw Speicher)
    Global $asmstack = DllStructCreate("double startx;" & _;$x0, 8 Byte [EBP]
    "double starty;" & _;$y0, 8 Byte [EBP+08]
    "double stepx;" & _;$stepx 8 Byte [EBP+10]
    "double stepy;" & _;$stepy 8 Byte [EBP+18]
    "int tiefe;" & _ ;$tiefe, 4 Byte [EBP+20]
    "int maxiter;" & _ ;$maxiter, 4 Byte [EBP+24]
    "ptr bmpdata;" & _ ;$bmpdata, 4 Byte [EBP+28]
    "int winwidth;" & _ ;$winwidth, 4 Byte [EBP+2C]
    "int winheight;" & _ ;winheight) 4 Byte [EBP+30]
    "ptr callback;" & _ ;callback 4 Byte [EBP+34]
    "ptr bmppalette;" & _ ;2. bitmap 4 Byte [EBP+38]
    "ptr palette;" & _ ;Farbpalette 4 Byte [EBP+3C]
    "byte [300]"); [EBP+40] platz zum sichern der FPU-Register

    [/autoit] [autoit][/autoit] [autoit]

    Global $data_palette = DllStructCreate("byte[1024]") ;256 colors * 4Byte(32Bitcolor)
    ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $data_palette = ' & DllStructGetPtr($data_palette) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $showpercentfunc = DllCallbackRegister("showpercent", "int", "") ;aus dem Assemblerprogramm kann man AutoIt-Funktionen aufrufen!
    ;$a = DllCallbackGetPtr($showpercentfunc)

    [/autoit] [autoit][/autoit] [autoit]

    Global $bytecode = _build_Asmcode() ;erstellt den bytecode aus den Assembleranweisungen
    ;Bytecode: 0x55DBE38BAC2408000000DD8510000000DD8518000000DD8500000000DD8508000000D9C1D9C18BBD280000008B852C0000008B9D30000000F7E3C1E00203C78BD8C7C000000000C7C1000000008B95200000008BB538000000EB34C7C0000000005253AB33D2C7C3FF000000F7F3C1E2028B853C00000003D08B820100000089065B5A81C6040000003BFB75CC5DC3DDD8DDD8D9C3DEC2C7C0000000003B8D2C0000007C2AC7C100000000DDB540000000608B8534000000FFD061DDA540000000D9C2DEC1DD8500000000D9CADDD841D9C1D9C1D9C1D8C8D9C1D8C8DEE9D8C4D9CADEC9D8C0D8C2D9C0D8C8D9C2D8C8DEC1DB9D200000003995200000000F875DFFFFFF3B85240000000F874BFFFFFF40EBC1
    ;folgende Zeilen sind nur nötig, wenn man direkt den Bytecode (ohne Assembler) ausführen möchte
    ; only nessecary if you want to run the bytecode without assembler
    Global $pMemory = _MemVirtualAlloc(0, StringLen($bytecode) / 2, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ;speicher anfordern für den assemblercode, kann auch ausgelagert werden
    Global $tCode = DllStructCreate("byte[" & StringLen($bytecode) / 2 & "]", $pMemory) ;unser Programmcode soll in diesen Speicherbereich
    DllStructSetData($tCode, 1, $bytecode) ;Bytecode des Assemblerprogramms in den reservierten Speicherbereich schreiben

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("_ShowPic", 500) ;alle 500ms das Bild darstellen

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _startnew() ;initialisiere startparameter
    GUISetState() ;gui zeigen
    _showpic() ;bitblt bitmap into GUI
    _palette1() ;palettendaten in die struct schreiben

    [/autoit] [autoit][/autoit] [autoit]

    While 1 ;main loop
    Sleep(10) ;OnEventmode....
    if $flightflag then flight() ;Menu: Flug ausgewählt
    if $newwindowflag then _newwindow() ;size of GUI changed
    ;tooltip(hex(pixelgetcolor(MouseGetPos(0),MouseGetPos(1),$hgui)/2)&" "&hex($maxiter)&" "&hex($tiefe)) ;anzeige der Pixelfarbe unter dem Mauszeiger
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _NewWindow() ;creates new bitmaps to bitblt into the GUI
    $newwindowflag=0
    $winsize = WinGetClientSize($hgui);fenstergröße bestimmen
    $winx = $winsize[0] ;client-width
    $winy = $winsize[1] ;client-height
    If $winy < 10 Then
    $winy = 10 ;falls das Fenster zu klein wird, bleibt immer noch die Bitmap erhalten
    $winx=10
    endif
    _deletebitmap32($hpicDC, $pointer, $hbitmap);alte bitmap und DC löschen , sets pointer=0, delete hbitmap-object
    _deletebitmap32($hpicDC_palette, $pointer_palette, $hbitmap_palette)
    $hpicDC = _CreateNewBmp32($winx, $winy, $pointer, $hbitmap) ;neue 32-Bit-Bitmap erstellen mit aktueller Fenster-Client-Größe, pointer ist die Startadresse der Bitmapdaten
    $hpicDC_palette = _CreateNewBmp32($winx, $winy, $pointer_palette, $hbitmap_palette) ;neue 32-Bit-Bitmap erstellen mit aktueller Fenster-Client-Größe, pointer ist die Startadresse der Bitmapdaten
    _RenderPic() ;Grafik erstellen
    EndFunc ;==>_NewWindow

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Build_Asmcode()
    FAsmReset($AsmObj)

    [/autoit] [autoit][/autoit] [autoit]

    ;hier gehts los^^
    FasmAdd($AsmObj, " use32 ");
    FasmAdd($AsmObj, " push ebp ");Basepointer Register sichern, not really needed, there is no registerpressure^^

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " finit ");copro init
    FasmAdd($AsmObj, " mov ebp,dword[ESP+08h] ");lade den Inhalt der 2-Byte-Adresse an der position des 1. Elementes der asmstack-struct ins register EBP (pointer auf die struct)
    ;EBP ist nun ganz normal zu verwenden und zeigt auf die übergebenen Parameter
    FasmAdd($AsmObj, " fld qword[EBP+10h] ");lade die 4 bytes(qword) an der Position Structanfang+10h Bytes in den Coprozessor-Stack st0=stepx
    ;Damit man nachvollziehen kann, wie die Berechnung vor sich geht, zeige ich immer den aktuellen Copro-Stack
    ;st0 =stepx
    FasmAdd($AsmObj, " fld qword[EBP+18h] ");st0=stepy
    ;st0 =stepy
    ;st1 =stepx
    FasmAdd($AsmObj, " fld qword[EBP] ");st0=startx=x0 x-position
    ;st0 =x0
    ;st1 =stepy
    ;st2 =stepx
    FasmAdd($AsmObj, " fld qword[EBP+08h] ");st0=starty y0
    ;st0 =y0
    ;st1 =x0
    ;st2 =stepy
    ;st3 =stepx
    FasmAdd($AsmObj, " fld st1 ");st0=x
    ;st0 =x
    ;st1 =y0
    ;st2 =x0
    ;st3 =stepy
    ;st4 =stepx
    FasmAdd($AsmObj, " fld st1 ");st0=y 10
    ;st0 =y
    ;st1 =x
    ;st2 =y0
    ;st3 =x0
    ;st4 =stepy
    ;st5 =stepx

    [/autoit] [autoit][/autoit] [autoit]

    ;alle für die Berechnung notwendigen Parameter in die Prozessor-Register eintragen

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " mov edi,dword[EBP+28h] ");startadresse bitmapdaten
    FasmAdd($AsmObj, " mov eax,dword[EBP+2Ch] ");eax=winwidth
    FasmAdd($AsmObj, " mov ebx,dword[EBP+30h] ");ebx=winheight
    FasmAdd($AsmObj, " mul ebx ");eax = winheight*winwidth
    FasmAdd($AsmObj, " shl eax,2 ");eax = winheight*winwidth*4 jedes pixel besteht aus 4 Byte
    FasmAdd($AsmObj, " add eax,edi ");eax = Adresse letztes pixel der Bitmap
    FasmAdd($AsmObj, " mov ebx,eax ");EBX = Adresse letztes pixel der Bitmap
    FasmAdd($AsmObj, " mov eax,0 ");EAX = wird die Anzahl der berechneten Iterationen
    FasmAdd($AsmObj, " mov ecx,0 ");ECX = counter für Pixelposition in einer Zeile, wenn >width, dann wieder 0
    FasmAdd($AsmObj, " mov edx,dword[EBP+20h] ");EDX = tiefe 20
    FasmAdd($AsmObj, " mov esi,dword[EBP+38h] ");Pointer auf die 2. Bitmap, diese enthält die durch die Palette umgewandelten Farbpixel
    ;~ FasmAdd($AsmObj, " mov eax,esi ")
    ;~ FasmAdd($AsmObj, " pop ebp ");register wiederherstellen
    ;~ FasmAdd($AsmObj, " ret ");Rücksprung nach AutoIt

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " mainloop: ");Einsprungpunkt für die schleife
    FasmAdd($AsmObj, " jmp berechnung ");springe in die Berechnung der Iteration nach @berechnung
    FasmAdd($AsmObj, " limit: ");Rücksprungpunkt aus der Berechnung der MAXIteration = EAX, limit erreicht
    FasmAdd($AsmObj, " mov eax,0 ");Rücksprungpunkt aus der Berechnung der Iteration = EAX , gewissermassen die "Farbe"
    FasmAdd($AsmObj, " ergebnis: ");Rücksprungpunkt aus der Berechnung der Iteration = EAX , gewissermassen die "Farbe"

    [/autoit] [autoit][/autoit] [autoit]

    ;Hier ist der Rücksprungpunkt der Berechnungsroutine, in EAX steht die Anzahl der Iterationen also gewissermassen die "Farbe"
    ;EAX (4 Byte)) wird als "Farbe (AABBGGRR auch 4 Byte)" direkt an die Speicherstelle des Pixels geschrieben
    ;hier könnte man auch direkt auf eine Farbpalette zugreifen oder den EAX-Wert durch Berechnungen anpassen
    ;allerdings müssen die Adressen der absoluten Vorwärtssprünge (der jmp nach loop: und vor ergebnis:) von Hand angepasst werden => Debugger hilft
    FasmAdd($AsmObj, " push edx ");EDX sichern auf den Stack ACHTUNG! Ergebnis von mul ist EDX:EAX!!!! EDX wird verändert !
    FasmAdd($AsmObj, " push ebx ");uuuuhhhh, registerpressure^^
    FasmAdd($AsmObj, " mov dword[EDI],eax ");stosd ^^, speichere EAX an adresse ES:EDI (EDI+4) position des pixels in der bitmap
    ;nun in der zweiten Bitmap die Pixelfarbe aus der Palette holen
    FasmAdd($AsmObj, " xor edx,edx ");EDX=0 30
    FasmAdd($AsmObj, " mov ebx,0FFh ");EBX=255
    FasmAdd($AsmObj, " div ebx ");in EAX steht nun die integerdivision, in EDX steht der Rest! =>edx=modulo(eax,ebx)

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " mov eax,dword[EBP+3Ch] ");anfang der palette
    FasmAdd($AsmObj, " shl edx,2 ");edx=edx*4 4 Byte pro Farbe in der palette
    FasmAdd($AsmObj, " add edx,eax ");Adresse der Farbe in der palette
    FasmAdd($AsmObj, " mov eax,dword[edx+01] ");Farbe in der palette
    FasmAdd($AsmObj, " mov dword[ESI],eax ");Farbe aus der palette in die 2. Bitmap schreiben

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " pop ebx ")
    FasmAdd($AsmObj, " pop edx ");EDX vom Stack

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " add EDI,4 ");4 Byte dahinter ist die nächste Pixeladresse(Orginaldaten) 40
    FasmAdd($AsmObj, " add ESI,4 ");4 Byte dahinter ist die nächste Pixeladresse(2.Bitmap)
    FasmAdd($AsmObj, " cmp edi,ebx ");Vergleich aktuelle Pixeladresse mit der letzten Pixeladresse der Bitmap
    FasmAdd($AsmObj, " jne mainloop ");springe, wenn nicht gleich (Jump if Not Equal) nach loop: , wenn gleich dann sind alle Pixel berechnet

    [/autoit] [autoit][/autoit] [autoit]

    ; FasmAdd($AsmObj, " finit ");copro init
    FasmAdd($AsmObj, " pop ebp ");register wiederherstellen
    FasmAdd($AsmObj, " ret ");Rücksprung nach AutoIt

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " berechnung: ")
    ;stack bereinigen, aktuellex x und y auf den stack
    FasmAdd($AsmObj, " fstp st0 ");POP stack
    ;st0 =x
    ;st1 =y0
    ;st2 =x0
    ;st3 =stepy
    ;st4 =stepx
    FasmAdd($AsmObj, " fstp st0 ");POP stack
    ;st0 =y0
    ;st1 =x0
    ;st2 =stepy
    ;st3 =stepx
    ;******************x0=x0+stepx
    FasmAdd($AsmObj, " fld st3 ");st0=stepx
    ;st0 =stepx
    ;st1 =y0
    ;st2 =x0
    ;st3 =stepy
    ;st4 =stepx
    FasmAdd($AsmObj, " faddp st2,st0 ");st2=x0+stepx POP 50
    ;st0 =y0
    ;st1 =x0+stepx
    ;st2 =stepy
    ;st3 =stepx

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " mov eax,0 ");ax = 0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " cmp ecx,dword[EBP+2Ch] ");vgl ecx mit fensterbreite
    FasmAdd($AsmObj, " jl start1 ");wenn micht größer, dann springe zum start1 +2c 16 ohne callback
    FasmAdd($AsmObj, " mov ecx,0 ");zähler an den Zeilenanfang der Bitmap
    FasmAdd($AsmObj, " fsave [ebp+40h] ");alle Coprozessorregister und den Copro-stack sichern
    FasmAdd($AsmObj, " pushad ");alle Prozessorregister sichern
    FasmAdd($AsmObj, " mov eax,dword[EBP+34h] ");Adresse der AutoItfunktion in eax laden, evtl Parameter vorher auf den stack pushen
    FasmAdd($AsmOBj, " call eax ");AutoIt-Funktion aufrufen, erlaubt einen Interrupt, ansonsten wäre das Fenster während der gesamten Berechnung blockiert
    FasmAdd($AsmObj, " popad ");Prozessorregister alle wiederherstellen
    FasmAdd($AsmObj, " frstor [ebp+40h] ");coproregister und coprostack wiederherstellen 60
    FasmAdd($AsmObj, " fld st2 ");y0=y0+stepy
    ;st0 =stepy
    ;st1 =y0
    ;st2 =x0
    ;st3 =stepy
    ;st4 =stepx
    FasmAdd($AsmObj, " faddp st1,st0 ");y0=y0+stepy und POP
    ;st0 =y0+stepy
    ;st1 =x0
    ;st2 =stepy
    ;st3 =stepx
    FasmAdd($AsmObj, " fld qword[EBP] ");st0= startx, die spaltenziffern bleiben immer gleich
    ;st0 =startx=neues x0
    ;st1 =y0
    ;st2 =x0
    ;st3 =stepy
    ;st4 =stepx
    FasmAdd($AsmObj, " fxch st2 ");tausche st2 mit st0
    ;st0 =x0
    ;st1 =y0
    ;st2 =startx=neues x0
    ;st3 =stepy
    ;st4 =stepx
    FasmAdd($AsmObj, " fstp st0 ");POP
    ;st0 =y0
    ;st1 =x0
    ;st2 =stepy
    ;st3 =stepx

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " start1: ");Stack wieder aufbauen für die Berechnung

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " inc ecx ");ecx=ecx+1 = ein pixel weiter
    FasmAdd($AsmObj, " fld st1 ");x => st0
    ;st0 =x
    ;st1 =y0
    ;st2 =x0
    ;st3 =stepy
    ;st4 =stepx
    FasmAdd($AsmObj, " fld st1 ");y => st0
    ;st0 =y
    ;st1 =x
    ;st2 =y0
    ;st3 =x0
    ;st4 =stepy
    ;st5 =stepx

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " start: ");die "innere schleife" , Berechnung von x^2-y^2+x0 und 2*x*y+y0 und vergleich 70
    FasmAdd($AsmObj, " fld st1 ");x => st0
    ;st0 =x
    ;st1 =y
    ;st2 =x
    ;st3 =y0
    ;st4 =x0
    FasmAdd($AsmObj, " fmul st0,st0 ");st0 = x^2
    ;st0 =x^2
    ;st1 =y
    ;st2 =x
    ;st3 =y0
    ;st4 =x0
    FasmAdd($AsmObj, " fld st1 "); y=> st0
    ;st0 =y
    ;st1 =x^2
    ;st2 =y
    ;st3 =x
    ;st4 =y0
    ;st5 =x0
    FasmAdd($AsmObj, " fmul st0,st0 ");st0 = y^2
    ;st0 =y^2
    ;st1 =x^2
    ;st2 =y
    ;st3 =x
    ;st4 =y0
    ;st5 =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fsubp st1,st0 ");st0 = x^2-y^2
    ;st0 =x^2-y^2
    ;st1 =y
    ;st2 =x
    ;st3 =y0
    ;st4 =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fadd st0,st4 ");st0 = x^2-y^2+x0

    [/autoit] [autoit][/autoit] [autoit]

    ;st0 =x^2-y^2+x0
    ;st1 =y
    ;st2 =x
    ;st3 =y0
    ;st4 =x0
    FasmAdd($AsmObj, " fxch st2 ");st0 = x

    [/autoit] [autoit][/autoit] [autoit]

    ;st0 =x
    ;st1 =y
    ;st2 =x^2-y^2+x0
    ;st3 =y0
    ;st4 =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fmulp st1,st0 ");st0 = x*y
    ;st0 =y*x
    ;st1 =x^2-y^2+x0
    ;st2 =y0
    ;st3 =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fadd st0,st0 ");st0 = x*y+x*y = 2*x*y
    ;st0 =2*y*x
    ;st1 =x^2-y^2+x0
    ;st2 =y0
    ;st3 =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fadd st0,st2 ");st0 = x*y+x*y+y = 2*x*y+y0 80
    ;st0 =2*y*x+y0 neues y
    ;st1 =x^2-y^2+x0 neues x
    ;st2 =y0
    ;st(§) =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fld st0 ");st0 = y
    ;st0 =y
    ;st1 =2*y*x+y0 neues y
    ;st2 =x^2-y^2+x0 neues x
    ;st3 =y0
    ;st4 =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fmul st0,st0 ");st0 = y^2
    ;st0 =y^2
    ;st1 =2*y*x+y0 neues y
    ;st2 =x^2-y^2+x0 neues x
    ;st3 =y0
    ;st4 =x0
    FasmAdd($AsmObj, " fld st2 ");st0 = x
    ;st0 =x
    ;st1 =y^2
    ;st2 =2*y*x+y0 neues y
    ;st3 =x^2-y^2+x0 neues x
    ;st4 =y0
    ;st5 =x0
    FasmAdd($AsmObj, " fmul st0,st0 ");st0 = x^2
    ;st0 =x^2
    ;st1 =y^2
    ;st2 =2*y*x+y0 neues y
    ;st3 =x^2-y^2+x0 neues x
    ;st4 =y0
    ;st5 =x0
    FasmAdd($AsmObj, " faddp st1,st0 ");st0 = y^2+x^2
    ;FasmAdd($AsmObj, " jmp [user='213939']Exit[/user] ");ansonsten wieder zum :start
    ;st0 =y^2+x^2
    ;st1 =2*y*x+y0 neues y
    ;st2 =x^2-y^2+x0 neues x
    ;st3 =y0
    ;st4 =x0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " fistp dword [EBP+20h] ");aktuellen wert speichern
    ;st1 =2*y*x+y0 neues y
    ;st2 =x^2-y^2+x0 neues x
    ;st3 =y0
    ;st4 =x0
    FasmAdd($AsmObj, " fwait ")
    FasmAdd($AsmObj, " cmp dword[EBP+20h],edx ");ist y^2+x^2>tiefe vergleich
    FasmAdd($AsmObj, " ja ergebnis ");wenn y^2+x^2 > tiefe dann farbe=eax ausgeben
    FasmAdd($AsmObj, " cmp eax,dword[EBP+24h] ");vgl maxiter mit aktueller iteration
    FasmAdd($AsmObj, " ja limit ");wenn größer, dann farbe=0 ausgeben 90
    FasmAdd($AsmObj, " inc eax ");ax = ax + 1
    FasmAdd($AsmObj, " jmp start ");ansonsten wieder zum :start
    ;ende ASM

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $bindata = String(FAsmGetBinary($AsmObj)) ;bytecode
    $file = FileOpen("mandel_asm.bin", 18) ;in Datei zum debuggen UND um den Inlinecode für den CallWindowProcW()-call zu erhalten!!!
    FileWrite($file, $bindata)
    FileClose($file)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("Assembler Bytecode: " & $bindata & @CRLF)
    Return $bindata ;der binärcode wird zurückgegeben
    EndFunc ;==>_Build_Asmcode

    [/autoit] [autoit][/autoit] [autoit]

    Func Asm_mandel($centerx, $centery, $breite, $tiefe, $maxiter, $pointer, $winwidth, $winheight)
    $f = $winwidth / $winheight ;verhältnis fensterbreite/fensterhöhe
    ;Daten in die Struct eintragen, diese Daten werden vom Assemblerprogramm benutzt
    ;man kann diese Parameter auch "normal" z.B. per MemoryFuncCall("int:cdecl", AsmGetPtr($AsmObj), "ptr", dllstructgetptr($asmstack),"double",$parameter1,"int",Parameter2.....) aufrufen
    ;aber mit dieser Methode hat man den Vorteil, auch DIREKT den Bytecode verwenden zu können, ohne jedes mal den Assembler-Code zu assemblieren
    ;ausserdem muss man sich beim Rücksprung nicht um das Aufräumen des Stacks kümmern...
    DllStructSetData($asmstack, "startx", $centerx - $breite * 0.5 * (($f - 1) * ($f > 1) + 1)) ;abhängig vom verhältnis ist fensterinhalt immer quadratisch, rund um das Zentrum
    DllStructSetData($asmstack, "starty", $centery - $breite * 0.5 * ((1 - $f) * ($f > 1) + $f)) ;
    DllStructSetData($asmstack, "stepx", $breite / $winwidth * (($f - 1) * ($f > 1) + 1))
    DllStructSetData($asmstack, "stepy", $breite / $winheight * ((1 - $f) * ($f > 1) + $f))
    DllStructSetData($asmstack, "tiefe", $tiefe)
    DllStructSetData($asmstack, "maxiter", $maxiter)
    DllStructSetData($asmstack, "bmpdata", $pointer) ;zeiger auf die bitmapdaten
    DllStructSetData($asmstack, "winwidth", $winwidth);fensterbreite
    DllStructSetData($asmstack, "winheight", $winheight);fensterhöhe
    DllStructSetData($asmstack, "callback", DllCallbackGetPtr($showpercentfunc));Zeiger auf die Einsprungadresse der AutoIt-Func
    DllStructSetData($asmstack, "bmppalette", $pointer_palette);fensterhöhe
    DllStructSetData($asmstack, "palette", DllStructGetPtr($data_palette));fensterhöhe
    ;entweder kann man nun aus dem Assembler den....
    ;$ret=MemoryFuncCall("int:cdecl", FAsmGetFuncPtr($AsmObj), "ptr", dllstructgetptr($asmstack)) ;Assembler aufrufen und Code starten
    ;_arraydisplay($ret) ;alle rückgabeparameter ansehen
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & hex($ret[0]) & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    ;return ;wer mag, kann das return auskommentieren und den MemoryFuncCall() und dann den unteren Code laufen lassen

    [/autoit] [autoit][/autoit] [autoit]

    ;....aufrufen, oder auch die folgende Variante:
    ;sie hat den Vorteil, daß man den fertigen Bytecode aufrufen kann OHNE den Assembler vorher aufzurufen!
    ;da die user32.dll in jedem windows vorhanden ist, benötigt man für das Starten des Bytecodes keine weiteren Dateien
    $ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", $pMemory, "ptr", DllStructGetPtr($asmstack), "int", 0, "int", 0, "int", 0); unsere assemblerfunktion wird aufgerufen
    ;_arraydisplay($ret) alle Übergabeparameter bzw Rückgabeparameter anschauen
    EndFunc ;==>Asm_mandel

    [/autoit] [autoit][/autoit] [autoit]

    Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe $HDC und $ptr und handle auf die Bitmapdaten
    $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
    $tBMI = DllStructCreate($tagBITMAPINFO) ;Struktur der Bitmapinfo erstellen und Daten eintragen
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4);Structgröße abzüglich der Daten für die Palette
    DllStructSetData($tBMI, "Width", $iwidth)
    DllStructSetData($tBMI, "Height", -$iheight) ;minus =standard = bottomup
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32) ;32 Bit = 4 Bytes => AABBGGRR
    $adib = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', $DIB_RGB_COLORS, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hbmp = $adib[0] ;hbitmap handle auf die Bitmap, auch per GDI+ zu verwenden
    $ptr = $adib[4] ;pointer auf den Anfang der Bitmapdaten, vom Assembler verwendet
    ;_arraydisplay($adib)
    _WinAPI_SelectObject($hcdc, $hbmp) ;objekt hbitmap in DC
    Return $hcdc ;DC der Bitmap zurückgeben
    EndFunc ;==>_CreateNewBmp32

    [/autoit] [autoit][/autoit] [autoit]

    Func _DeleteBitmap32($DC, $ptr, $hbmp)
    _WinAPI_DeleteDC($DC)
    _WinAPI_DeleteObject($hbmp)
    $ptr = 0
    EndFunc ;==>_DeleteBitmap32

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _MouseEvents()
    if $flightflag or $newwindowflag then return ;during flight
    $mouse = GUIGetCursorInfo($hgui)
    If $mouse[2] Then ;linke maustaste im Fenster
    $f = $winx / $winy ;verhältnis fensterbreite/fensterhöhe
    $cx = $cx - $breite * (($f - 1) * ($f > 1) + 1) * (0.5 - $mouse[0] / $winx) ;neuer Anfang der Berechnung an der Mausposition für x...
    $cy = $cy - $breite * ((1 - $f) * ($f > 1) + $f) * (0.5 - $mouse[1] / $winy) ;...und y- Koordinate
    $breite = $breite / $zoom ;neue Fenstergröße willkürlich auf 1/$zoom des ursprünglichen Bildes
    ;$tiefe =int($tiefe* 1.2)
    If $breite > 0.01 Then
    $maxiter = 250
    Else
    $maxiter = (Log($breite) / Log(1.3)) ^ 2
    EndIf
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $maxiter = ' & $maxiter & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $clics += 1
    $count = 0
    _RenderPic()
    EndIf
    EndFunc ;==>_MouseEvents

    [/autoit] [autoit][/autoit] [autoit]

    Func _RenderPic()
    Opt("GUIOnEventMode", 0) ;oneventmode ausschalten, es soll verhindert werden, daß während des bildaufbaus die gui verändert wird
    If $breite < 1E-17 Then MsgBox(0, "Apfelmaennchen", "Eine weitere Vergrößerung könnte infolge der Bereichunterschreitung für 64-Bit-Fließkommazahlen zu unvorhersehbaren Ergebnissen führen :o) ")
    $t = TimerInit()
    $g = Asm_mandel($cx, $cy, $breite, $tiefe, $maxiter, $pointer, $winx, $winy) ;Assemblercode aufrufen, Bitmap wird im Speicher erstellt
    $m = TimerDiff($t)
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    _showpic()
    Opt("GUIOnEventMode", 1)
    WinSetTitle($hgui, "", $wintitle)
    EndFunc ;==>_RenderPic

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _showpic()
    _WinAPI_BitBlt($hwinDC, 0, 0, $winx, $winy, $hpicDC_palette, 0, 0, $srccopy) ;Bitmap in GUI kopieren
    EndFunc ;==>_ShowPic

    [/autoit] [autoit][/autoit] [autoit]

    Func showpercent() ;Wird aus dem Assemblerprogramm aufgerufen, erlaubt Interrupt, ansonsten ist das Fenster für den Zeitraum der Berechnung blockiert!

    [/autoit] [autoit][/autoit] [autoit]

    if $flightflag then return ;during flight
    $count += 1 ;zähler für den Fortschritt der Berechnung
    ;nur jeden 10. Aufruf ans Fenster weitergeben, sonst wird zu sehr gebremst^^
    If $count / 10 = Int($count / 10) Then _WinAPI_SetWindowText($hgui, "Berechnung läuft, bitte warten...." & Int($count * 100 / $winy) & "%")
    ;eventuelle Returnwerte können natürlich vom Assembler ausgewertet werden
    EndFunc ;==>showpercent

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _WindowEvents() ;Fenstergröße geändert usw
    ;MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$isrendering' & @lf & @lf & 'Return:' & @lf &@gui_ctrlid) ;### Debug MSGBOX
    Switch @GUI_CtrlId ;je nach event
    Case $GUI_EVENT_CLOSE ;GUI geschlossen
    FAsmExit($AsmObj)
    _MemVirtualFree($pMemory, 512, $MEM_RELEASE) ;speicher für assemblerdaten freigeben
    _WinAPI_DeleteObject($hbitmap) ;bitmap löschen
    _WinAPI_DeleteObject($hbitmap_palette) ;bitmap löschen
    _WinAPI_DeleteDC($hpicDC) ;DC der Bitmap freigeben
    _WinAPI_DeleteDC($hpicDC_palette) ;DC der Bitmap freigeben
    _WinAPI_ReleaseDC(0, $hdc) ;
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Case $GUI_EVENT_MINIMIZE ;GUI minimiert
    $minimized = 1

    [/autoit] [autoit][/autoit] [autoit]

    Case $GUI_EVENT_MAXIMIZE ;GUI maximiert
    $count = 0
    $newwindowflag=1

    [/autoit] [autoit][/autoit] [autoit]

    Case $GUI_EVENT_RESTORE ;GUI wiederhergestellt
    $count = 0
    If $minimized Then
    $minimized = 0
    Else
    $newwindowflag=1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case $GUI_EVENT_RESIZED ;GUI Größe verändert
    If $contextflag = 1 Then ;manchmal bekommt das GUI vom Contextmenü ein RESIZED-Event.....
    $contextflag = 0
    $count = 0
    Else
    $count = 0
    $newwindowflag=1
    EndIf
    EndSwitch
    EndFunc ;==>_WindowEvents

    [/autoit] [autoit][/autoit] [autoit]

    Func _SavePic() ;speichert Bild und die aktuellen Koordinaten in einer Datei
    $contextflag = 1
    $imgpath = FileSaveDialog("Datei speichern", @ScriptDir, "(*.jpg;*.bmp;*.png)", 16)
    If @error Then Return
    If StringMid($imgpath, StringLen($imgpath) - 3, 1) <> "." Then $imgpath &= ".JPG"
    _ScreenCapture_SaveImage($imgpath, $hbitmap_palette)
    $path = StringLeft($imgpath, StringInStr($imgpath, "\", 1, -1)) & "fractalsave.dat"
    $file = FileOpen($path, 9)
    If @error Then Return MsgBox(0, "Apfelmaennchen-ERROR", "Can not open datafile " & $path & "\fractalsave.dat")
    FileWriteLine($file, $imgpath)
    FileWriteLine($file, "cx=" & $cx)
    FileWriteLine($file, "cy=" & $cy)
    FileWriteLine($file, "breite=" & $breite)
    FileWriteLine($file, "tiefe=" & $tiefe)
    FileWriteLine($file, "maxiter=" & $maxiter)
    FileWriteLine($file, ";*****************************")
    FileClose($file)
    $contextflag = 0
    EndFunc ;==>_SavePic

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _PicBack() ;contextmenu Bild zurück
    $contextflag = 1
    _showpic()
    $breite = $breite * $zoom ;neue Fenstergröße willkürlich auf 1/$zoom des ursprünglichen Bildes
    $tiefe = 4
    $maxiter = Int($maxiter / 1.2)
    _newwindow()
    $contextflag = 0
    EndFunc ;==>_PicBack

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _FlightRender() ;Contextmenu Flug rendern
    $flightflag=1
    Switch @GUI_CtrlId
    Case $item4_1
    $cx = -1.76853670262974 ;koordinaten des Flugziels
    $cy = -0.000753954632767545
    _palette1()
    Case $item4_2
    $cx = -1.2546083918954
    $cy = 0.381668128065955
    $cx=0.439737459322262
    $cy=-0.358206511283955
    _palette2()
    Case $item4_3
    $cx = -0.105349652406611
    $cy = 0.925719416059085
    _palette4()
    Case $item4_4
    $cx = -0.711196644430243
    $cy = 0.353463499946954
    _palette3()
    EndSwitch
    endfunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func Flight()
    AdlibUnRegister("_ShowPic") ;alle 500ms das Bild darstellen
    guictrlsetstate($item4,$GUI_DISABLE)
    $flightflag=1
    $breite = 5
    $tiefe = 5
    $maxiter = 110
    $zoom = 1.05
    WinMove($hgui, "", Default, Default, 200, 230)
    _newwindow()
    For $i=3 to 1 step -1
    WinSettitle($hgui,"",$i)
    sleep(1000)
    next
    $exitflag=0
    $contextflag = 1
    $wintitle = "Flight..."
    For $i = 1 To 600
    If $i < 100 Then Sleep(30)
    If $i > 400 Then $zoom = 1.1
    If $i > 450 Then $zoom = 1.2
    $breite /= $zoom
    if $newwindowflag then _newWindow()
    _renderpic()
    if $exitflag then exitloop
    If $breite < 3E-17 Then
    MsgBox(0, "Fractalflight", "...this is the End of the flight!" & @CRLF & @CRLF & "The magnification ratio to the first picture is now a trillion, which is one million millions....i hope you have enjoyed it!")
    If BitAnd(wingetstate($hgui), 16) then guisetstate(@sw_restore,$hgui)
    ExitLoop
    EndIf
    $maxiter *= 1.008
    ;consolewrite($i&" "&$maxiter & @CRLF )
    Next
    $wintitle = "Apfelmaennchen by Andy (http://www.AutoIt.de)"
    WinMove($hgui, "", Default, Default, 800, 600)
    _startnew()
    ; _renderpic()
    $contextflag = 0
    $flightflag=0
    guictrlsetstate($item4,$GUI_ENABLE)
    AdlibRegister("_ShowPic", 500) ;alle 500ms das Bild darstellen
    EndFunc ;==>_FlightRender

    [/autoit] [autoit][/autoit] [autoit]

    Func _Loadpic() ;contextmenu Bild laden, bzw Koordinaten aus Datei
    $contextflag = 1
    _showpic()
    ToolTip("Coming soon :o)")
    Sleep(1000)
    ToolTip("")
    $contextflag = 0
    EndFunc ;==>_Loadpic

    [/autoit] [autoit][/autoit] [autoit]

    Func _zoom() ;zoomen
    $contextflag = 1
    Switch @GUI_CtrlId
    Case $item5_1
    $zoom = 2
    Case $item5_2
    $zoom = 3
    Case $item5_3
    $zoom = 4
    Case $item5_4
    $zoom = 1.2
    EndSwitch
    $contextflag = 0
    EndFunc ;==>_zoom

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Palette1()
    $contextflag = 1
    GUICtrlSetState($item6_1,$gui_checked)
    $palette = "0x0000000000000003000000070000000B0000000F00000013000000170000001B0000001F00000023000000270000002B0000002F00000033000000370000003B0000003F00000043000000470000004B0000004F00000053000000570000005B0000005F00000063000000670000006B0000006F00000073000000770000007B0000007F00000083000000870000008B0000008F00000093000000970000009B0000009F000000A3000000A7000000AB000000AF000000B3000000B7000000BB000000BF000000C3000000C7000000CB000000CF000000D3000000D7000000DB000000DF000000E3000000E7000000EB000000EF000000F3000000F7000000FB000000FF000003FF000007FF00000BFF00000FFF000013FF000017FF00001BFF00001FFF000023FF000027FF00002BFF00002FFF000033FF000037FF00003BFF00003FFF000043FF000047FF00004BFF00004FFF000053FF000057FF00005BFF00005FFF000063FF000067FF00006BFF00006FFF000073FF000077FF00007BFF00007FFF000083FF000087FF00008BFF00008FFF000093FF000097FF00009BFF00009FFF0000A3FF0000A7FF0000ABFF0000AFFF0000B3FF0000B7FF0000BBFF0000BFFF0000C3FF0000C7FF0000CBFF0000CFFF0000D3FF0000D7FF0000DBFF0000DFFF0000E3FF0000E7FF0000EBFF0000EFFF0000F3FF0000F7FF0000FBFF0000FFFF0003FFFF0007FFFF000BFFFF000FFFFF0013FFFF0017FFFF001BFFFF001FFFFF0023FFFF0027FFFF002BFFFF002FFFFF0033FFFF0037FFFF003BFFFF003FFFFF0043FFFF0047FFFF004BFFFF004FFFFF0053FFFF0057FFFF005BFFFF005FFFFF0063FFFF0067FFFF006BFFFF006FFFFF0073FFFF0077FFFF007BFFFF007FFFFF0083FFFF0087FFFF008BFFFF008FFFFF0093FFFF0097FFFF009BFFFF009FFFFF00A3FFFF00A7FFFF00ABFFFF00AFFFFF00B3FFFF00B7FFFF00BBFFFF00BFFFFF00C3FFFF00C7FFFF00CBFFFF00CFFFFF00D3FFFF00D7FFFF00DBFFFF00DFFFFF00E3FFFF00E7FFFF00EBFFFF00EFFFFF00F3FFFF00F7FFFF00FBFFFF00FFFFFF00FBFBFB00F7F7F700F3F3F300EFEFEF00EBEBEB00E7E7E700E3E3E300DFDFDF00DBDBDB00D7D7D700D3D3D300CFCFCF00CBCBCB00C7C7C700C3C3C300BFBFBF00BBBBBB00B7B7B700B3B3B300AFAFAF00ABABAB00A7A7A700A3A3A3009F9F9F009B9B9B0097979700939393008F8F8F008B8B8B0087878700838383007F7F7F007B7B7B0077777700737373006F6F6F006B6B6B0067676700636363005F5F5F005B5B5B0057575700535353004F4F4F004B4B4B0047474700434343003F3F3F003B3B3B0037373700333333002F2F2F002B2B2B0027272700232323001F1F1F001B1B1B0017171700131313000F0F0F000B0B0B0007070700030303"
    DllStructSetData($data_palette, 1, $palette)
    $contextflag = 0
    ; GUICtrlSetState($item6_1,$gui_checked)
    _Asmcode_changecolor()
    _GUICtrlMenu_CheckRadioItem(GUICtrlGetHandle($item6),0,3,0)
    EndFunc ;==>_Palette1

    [/autoit] [autoit][/autoit] [autoit]

    Func _Palette2()
    $contextflag = 1
    $palette = "0x0000000000FEFB7E00FEF77D00FEF47B00FEF07A00FDED7900FDE97700FDE67600FDE27500FCDF7300FCDB7200FCD87000FCD46F00FBD16E00FBCD6C00FBCA6B00FBC66A00FBC36800FABF6700FABC6500FAB86400FAB56300F9B16100F9AE6000F9AA5F00F9A75D00F8A35C00F8A05A00F89C5900F8995800F7955600F7925500F78E5400F78A5200F7875100F6834F00F6804E00F67C4D00F6794B00F5754A00F5724900F56E4700F56B4600F4674400F4644300F4604200F45D4000F3593F00F3563E00F3523C00F34F3B00F34B3900F2483800F2443700F2413500F23D3400F13A3300F1363100F1333000F12F2E00F02C2D00F0282C00F0252A00F0212900F01E2800EE212B00EC252E00EA283200E92C3500E72F3800E5333C00E3363F00E23A4200E03D4600DE414900DC444C00DB485000D94B5300D74F5700D5525A00D4565D00D2596100D05D6400CE606700CD646B00CB676E00C96B7100C76E7500C6727800C4757B00C2797F00C07C8200BF808600BD838900BB878C00B98A9000B88E9300B6929600B4959A00B2999D00B19CA000AFA0A400ADA3A700ABA7AB00AAAAAE00A8AEB100A6B1B500A4B5B800A3B8BB00A1BCBF009FBFC2009DC3C5009CC6C9009ACACC0098CDCF0096D1D30095D4D60093D8DA0091DBDD008FDFE0008EE2E4008CE6E7008AE9EA0088EDEE0087F0F10085F4F40083F7F80081FBFB0080FFFF007EFDFF007CFBFF007AF9FF0078F7FF0076F5FF0074F3FF0072F1FF0070EFFF006EEDFF006CEBFF006AE9FF0068E7FF0066E5FF0064E3FF0062E1FF0060DFFF005EDDFF005CDBFF005AD9FF0058D7FF0056D5FF0054D3FF0052D1FF0050CFFF004ECDFF004CCBFF004AC9FF0048C7FF0046C5FF0044C3FF0042C1FF0040BFFF003EBDFF003CBBFF003AB9FF0038B7FF0036B5FF0034B3FF0032B1FF0030AFFF002EADFF002CABFF002AA9FF0028A7FF0026A5FF0024A3FF0022A1FF00209FFF001E9DFF001C9BFF001A99FF001897FF001695FF001493FF001291FF00108FFF000E8DFF000C8BFF000A89FF000887FF000685FF000483FF000281FF000080FF000381FD000783FB000B85F9000F87F7001389F500178BF3001B8DF1001F8FEF002391ED002793EB002B95E9002F97E7003399E500379BE3003B9DE1003F9FDF0043A1DD0047A3DB004BA5D9004FA7D70053A9D50057ABD3005BADD1005FAFCF0063B1CD0067B3CB006BB5C9006FB7C70073B9C50077BBC3007BBDC1007FBFBF0083C1BD0087C3BB008BC5B9008FC7B70093C9B50097CBB3009BCDB1009FCFAF00A3D1AD00A7D3AB00ABD5A900AFD7A700B3D9A500B7DBA300BBDDA100BFDF9F00C3E19D00C7E39B00CBE59900CFE79700D3E99500D7EB9300DBED9100DFEF8F00E3F18D00E7F38B00EBF58900EFF78700F3F98500F7FB8300FBFD81"
    DllStructSetData($data_palette, 1, $palette)
    $contextflag = 0
    ; GUICtrlSetState($item6_2,$gui_checked)
    _Asmcode_changecolor()
    _GUICtrlMenu_CheckRadioItem(GUICtrlGetHandle($item6),0,3,1)
    EndFunc ;==>_Palette2

    [/autoit] [autoit][/autoit] [autoit]

    Func _Palette3()
    $contextflag = 1
    $palette = "0x000000000000980000019601000293020003910300038E0300048C0400058A050006870600078507000782070008800800097D09000A7B0A000A790A000B760B000C740C000D710D000E6F0E000E6C0E000F6A0F0010681000116511001163110012601200135E1300145C140015591500155715001654160017521700184F1800194D1900194B19001A481A001B461B001C431C001C411C001D3E1D001E3C1E001F3A1F0020372000203520002132210022302200232E2300232B230024292400252625002624260027212700271F2700281D2800291A29002A182A002A152A002B132B002C102C002D0E2D002E0C2E002E092E002F072F00300430003102310032003200330031003500300036002F0038002E0039002E003B002D003C002C003E002B0040002A0041002A0043002900440028004600270047002700490026004B0025004C0024004E0023004F0023005100220052002100540020005500200057001F0059001E005A001D005C001C005D001C005F001B0060001A0062001900640019006500180067001700680016006A0015006B0015006D0014006E0013007000120072001100730011007500100076000F0078000E0079000E007B000D007D000C007E000B0080000A0081000A0083000900840008008600070087000700890006008B0005008C0004008E0003008F0003009100020092000100940000009B0000009C0303009E0707009F0B0B00A10F0F00A2131300A4171700A51B1B00A71F1F00A9232300AA272700AC2B2B00AD2F2F00AF333300B0373700B23B3B00B43F3F00B5434300B7474700B84B4B00BA4F4F00BB535300BD575700BE5B5B00C05F5F00C2636300C3676700C56B6B00C66F6F00C8737300C9777700CB7B7B00CD7F7F00CE838300D0878700D18B8B00D38F8F00D4939300D6979700D79B9B00D99F9F00DBA3A300DCA7A700DEABAB00DFAFAF00E1B3B300E2B7B700E4BBBB00E6BFBF00E7C3C300E9C7C700EACBCB00ECCFCF00EDD3D300EFD7D700F0DBDB00F2DFDF00F4E3E300F5E7E700F7EBEB00F8EFEF00FAF3F300FBF7F700FDFBFB00FFFFFF00FBFDFB00F7FBF700F3FAF300EFF8EF00EBF7EB00E7F5E700E3F4E300DFF2DF00DBF0DB00D7EFD700D3EDD300CFECCF00CBEACB00C7E9C700C3E7C300BFE6BF00BBE4BB00B7E2B700B3E1B300AFDFAF00ABDEAB00A7DCA700A3DBA3009FD99F009BD79B0097D6970093D493008FD38F008BD18B0087D0870083CE83007FCD7F007BCB7B0077C9770073C873006FC66F006BC56B0067C3670063C263005FC05F005BBE5B0057BD570053BB53004FBA4F004BB84B0047B7470043B543003FB43F003BB23B0037B0370033AF33002FAD2F002BAC2B0027AA270023A923001FA71F001BA51B0017A4170013A213000FA10F000B9F0B00079E0700039C03"
    DllStructSetData($data_palette, 1, $palette)
    $contextflag = 0
    ; GUICtrlSetState($item6_3,$gui_checked)
    _Asmcode_changecolor()
    _GUICtrlMenu_CheckRadioItem(GUICtrlGetHandle($item6),0,3,2)
    EndFunc ;==>_Palette3

    [/autoit] [autoit][/autoit] [autoit]

    Func _Palette4()
    $contextflag = 1
    $palette = "0x0000000000FEFB8100FEF78300FEF48500FEF08700FDED8800FDE98A00FDE68C00FDE28E00FCDF8F00FCDB9100FCD89300FCD49500FBD19600FBCD9800FBCA9A00FBC69C00FBC39D00FABF9F00FABCA100FAB8A300FAB5A400F9B1A600F9AEA800F9AAAA00F9A7AB00F8A3AD00F8A0AF00F89CB100F899B200F795B400F792B600F78EB800F78AB900F787BB00F683BD00F680BF00F67CC000F679C200F575C400F572C600F56EC700F56BC900F467CB00F464CD00F460CE00F45DD000F359D200F356D400F352D500F34FD700F34BD900F248DB00F244DC00F241DE00F23DE000F13AE200F136E300F133E500F12FE700F02CE900F028EA00F025EC00F021EE00F01EF000EF1FED00EF20EA00EF21E700EE23E400EE24E100EE25DE00ED26DB00ED28D800ED29D500EC2AD200EC2BCF00EC2DCC00EB2EC900EB2FC600EB30C300EB32C000EA33BD00EA34BA00EA35B700E937B400E938B100E939AE00E83AAB00E83CA800E83DA500E73EA200E73F9F00E7419C00E6429900E6439600E6449300E6469100E5478E00E5488B00E5498800E44B8500E44C8200E44D7F00E34E7C00E3507900E3517600E2527300E2537000E2556D00E1566A00E1576700E1586400E15A6100E05B5E00E05C5B00E05D5800DF5F5500DF605200DF614F00DE624C00DE644900DE654600DD664300DD674000DD693D00DC6A3A00DC6B3700DC6C3400DC6E3200D86E3500D56E3800D16E3B00CE6F3E00CA6F4200C76F4500C36F4800C0704B00BD704E00B9705200B6715500B2715800AF715B00AB715E00A8726200A5726500A17268009E736B009A736E009773720093737500907478008C747B0089747E0086758200827585007F7588007B758B0078768E0074769200717695006E7798006A779B0067779E006377A2006078A5005C78A8005978AB005578AE005279B2004F79B5004B79B800487ABB00447ABE00417AC2003D7AC5003A7BC800377BCB00337BCE00307CD2002C7CD500297CD800257CDB00227DDE001E7DE2001B7DE500187EE800147EEB00117EEE000D7EF2000A7FF500067FF800037FFB000080FF000381FD000783FB000B85F9000F87F7001389F500178BF3001B8DF1001F8FEF002391ED002793EB002B95E9002F97E7003399E500379BE3003B9DE1003F9FDF0043A1DD0047A3DB004BA5D9004FA7D70053A9D50057ABD3005BADD1005FAFCF0063B1CD0067B3CB006BB5C9006FB7C70073B9C50077BBC3007BBDC1007FBFBF0083C1BD0087C3BB008BC5B9008FC7B70093C9B50097CBB3009BCDB1009FCFAF00A3D1AD00A7D3AB00ABD5A900AFD7A700B3D9A500B7DBA300BBDDA100BFDF9F00C3E19D00C7E39B00CBE59900CFE79700D3E99500D7EB9300DBED9100DFEF8F00E3F18D00E7F38B00EBF58900EFF78700F3F98500F7FB8300FBFD81"
    DllStructSetData($data_palette, 1, $palette)
    $contextflag = 0
    ; GUICtrlSetState($item6_4,$gui_checked)
    _Asmcode_changecolor()
    _GUICtrlMenu_CheckRadioItem(GUICtrlGetHandle($item6),0,3,3)
    EndFunc ;==>_Palette4

    [/autoit] [autoit][/autoit] [autoit]

    Func _startnew()
    $exitflag=1
    $cx = -0.5 ;CenterX : Zentrum der Fläche in x-Richtung
    $cy = 0 ;Centery : Zentrum der Fläche in y-Richtung
    $breite = 4 ;die Ausdehnung der Fläche in x-Richtung, y wird proportional angepasst
    $tiefe = 5 ;Berechnungstiefe
    $maxiter = 200 ;maximale Anzahl der Iterationen, wird je nach zoomfaktor erhöht
    $zoom = 4 ;zoomfaktor bei mausclick
    _NewWindow()
    EndFunc ;==>_startnew

    [/autoit] [autoit][/autoit] [autoit]

    Func _Asmcode_changecolor() ;compares the colour of the source Bitmap with the colour of the palette and writes the palettecolour into the destinationbitmap
    FAsmReset($AsmObj)
    FasmAdd($AsmObj, " use32 ");
    FasmAdd($AsmObj, " mov esi,dword[ESP+04h] ");source bitmap
    FasmAdd($AsmObj, " mov edi,dword[ESP+08h] ");destination bitmap
    FasmAdd($AsmObj, " mov ecx,dword[esp+0ch] ");lenght bitmap
    FasmAdd($AsmObj, " mov ebx,0FFh ");EBX=255

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, "L0: ")
    FasmAdd($AsmObj, " mov eax,dword[esi] ");EAX=Colour of pixel in source Bitmap
    FasmAdd($AsmObj, " xor edx,edx ");EDX=0

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " div ebx ");in EAX steht nun die integerdivision, in EDX steht der Rest! =>edx=modulo(eax,ebx)
    FasmAdd($AsmObj, " mov eax,dword[esp+10h] ");anfang der palette
    FasmAdd($AsmObj, " shl edx,2 ");edx=edx*4 4 Byte pro Farbe in der palette
    FasmAdd($AsmObj, " add edx,eax ");Adresse der Farbe in der palette
    FasmAdd($AsmObj, " mov eax,dword[edx+01] ");Farbe in der palette
    FasmAdd($AsmObj, " add esi,4 ")
    FasmAdd($AsmObj, " mov dword[edi],eax ");Farbe aus der palette in die 2. Bitmap schreiben

    [/autoit] [autoit][/autoit] [autoit]

    FasmAdd($AsmObj, " add edi,4 ")
    FasmAdd($AsmObj, " dec ecx ")
    FasmAdd($AsmObj, " jnz L0 ")
    FasmAdd($AsmObj, " ret ")
    $t=timerinit()
    $ret=MemoryFuncCall("int:cdecl", FAsmGetFuncPtr($AsmObj), "ptr", dllstructgetdata($asmstack,"bmpdata"), "ptr", dllstructgetdata($asmstack,"bmppalette"), "uint", $winx*$winy, "ptr", dllstructgetptr($data_palette)) ;Assembler aufrufen und Code starten
    $m=timerdiff($t)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    ;_arraydisplay($ret)
    _showpic()
    endfunc

    [/autoit]

    autoit.de/wcf/attachment/8385/

    Vergleich mit AutoIt-Code:

    Spoiler anzeigen
    [autoit]

    #include <SliderConstants.au3>
    #include <GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)
    Opt("MouseCoordMode", 2)

    [/autoit] [autoit][/autoit] [autoit]

    Global $width, $height, $dc, $centerx, $centery, $apfelbreite, $btnstartpressed
    Global $cx, $cy, $centerx1, $centery1, $st, $st1, $apfelbreite1
    Global $step, $mousepressed, $maxiteration, $x0, $y0, $flag

    [/autoit] [autoit][/autoit] [autoit]

    $user32 = DllOpen("user32.dll")
    $gdi32 = DllOpen("gdi32.dll")

    [/autoit] [autoit][/autoit] [autoit]

    $width = 800
    $height = 600

    [/autoit] [autoit][/autoit] [autoit]

    ;Startparameter
    $maxiteration = 250 ; für 1. durchlauf, dann slider bis zu 1000
    $centerx = -.5
    $centery = 0
    $tiefe = 100
    $apfelbreite = 5
    $step = 1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Gui
    $Form1 = GUICreate("Apfelmännchen", $width + 100, $height)
    $Farbe = PixelGetColor(30, 30)
    $Label = GUICtrlCreateLabel("", 0, 0, $width + 10, $height)
    $dc = GetDC(WinGetHandle($Form1))
    GUICtrlCreateLabel("Steps: ", $width + 20, 15, 60)
    $stepslider = GUICtrlCreateSlider($width + 10, 30, 80, 40, BitOR($TBS_TOOLTIPS, $TBS_AUTOTICKS, $TBS_ENABLESELRANGE))
    GUICtrlSetLimit(-1, 5, 1)
    GUICtrlSetData($stepslider, $step)
    GUICtrlCreateLabel("Iterationen: ", $width + 20, 100, 60)
    $maxitslider = GUICtrlCreateSlider($width + 10, 115, 80, 40, BitOR($TBS_TOOLTIPS, $TBS_AUTOTICKS, $TBS_ENABLESELRANGE))
    GUICtrlSetLimit(-1, 1000, $maxiteration)
    GUICtrlSetData($maxitslider, 25)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_EXIT")
    GUISetOnEvent($GUI_EVENT_PRIMARYUP, "_mousepressed") ;beim UP der linken Maustaste die func aufrufen

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;$centerx=-0.125
    ;$centery=-0.733333333333333
    ;$apfelbreite=1.25
    ;$tiefe=130
    ;$maxiteration=350

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $mousepressed = 0
    $begin = TimerInit()
    ;Mandelbrot()
    ;$paintpixel=1 ;das bild ist am entstehen

    [/autoit] [autoit][/autoit] [autoit]

    WinSetTitle($Form1, "", $centerx & " " & $centery & " " & $apfelbreite & " Apfelmännchen :" & Int(TimerDiff($begin) / 1000 & " Sekunden ")) ;Zeit in der Titelleiste anzeigen
    $x0 = $centerx - $apfelbreite * .5

    [/autoit] [autoit][/autoit] [autoit]

    $stepx = $apfelbreite / $width * $step
    $y0 = $centery - $apfelbreite * .5

    [/autoit] [autoit][/autoit] [autoit]

    $stepy = $apfelbreite / $height * $step

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    For $py = 0 To $height Step $step
    $y0 = $y0 + $stepy
    $x0 = $centerx - $apfelbreite * .5
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $y0 = ' & $y0 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
    For $px = 0 To $width Step $step
    If $mousepressed = 1 Then ExitLoop ;Maustaste wurde gedrückt, marker setzen und Berechnung verlassen
    $x0 = $x0 + $stepx
    ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $x0 = ' & $x0 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $x = $x0
    $y = $y0
    $iteration = 0
    For $i = 1 To $tiefe
    $xtemp = $x * $x - $y * $y + $x0
    $y = 2 * $x * $y + $y0
    $x = $xtemp
    If (($x * $x + $y * $y) > $tiefe Or $iteration > $maxiteration) Then ExitLoop
    $iteration += 1
    Next
    $col = $iteration^4;0xffffff/ log(log($iteration)+1)
    setpixel($dc, $px, $py, $col) ;..

    [/autoit] [autoit][/autoit] [autoit]

    Next
    If $mousepressed = 1 Then ExitLoop ;Berechnung verlassen
    Next
    WinSetTitle($Form1, "", $centerx & " " & $centery & " " & $apfelbreite & " Apfelmännchen :" & Int(TimerDiff($begin) / 1000 & " Sekunden ")) ;Zeit in der Titelleiste anzeigen

    [/autoit] [autoit][/autoit] [autoit]

    If $mousepressed = 0 Then ;die Grafik wurde ohne Unterbrechung fertig
    ;$paintpixel=0
    While $mousepressed = 0 ;solange warten, bis linke mMustaste gedrückt
    Sleep(100)
    WEnd
    EndIf
    GUICtrlSetBkColor($Label, $Farbe)

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _mousepressed()
    $mousepressed = 0 ;
    $pos = MouseGetPos() ;Koordinaten der Maus
    tooltip(MouseGetPos(0)&" "&MouseGetPos(1))
    ;If $paintpixel=1 then ;Maustaste wurde innerhalb for/to gedrückt
    If $pos[0] < $width And $pos[1] < $height and $pos[0]>0 and $pos[1]>0 Then ;wenn mauspos innerhalb Grafik dann
    $flag = 1
    $mousepressed = 1 ;Flag setzen
    $centerx = $centerx - $apfelbreite * (0.5 - $pos[0] / $width) ;neuer Anfang der Berechnung an der Mausposition für x...
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $centerx = ' & $centerx & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $centery = $centery - $apfelbreite * (0.5 - $pos[1] / $height) ;...und y- Koordinate
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $centery = ' & $centery & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $apfelbreite = $apfelbreite / 4 ;neue Fenstergröße willkürlich auf 1/4 des ursprünglichen Bildes
    endif
    If $pos[0] < $width+100 And $pos[1] < $height and $pos[0]>$width and $pos[1]>0 Then ;wenn mauspos innerhalb Grafik dann
    $step = GUICtrlRead($stepslider) ;steps von Slider übernehmen
    $maxiteration = GUICtrlRead($maxitslider) ;und Maxiteration
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;msgbox(0,"start",$centerx&@crlf&$centery&@crlf&$apfelbreite)
    EndFunc ;==>_mousepressed

    [/autoit] [autoit][/autoit] [autoit]

    Func setpixel($dc, $x, $y, $color) ;pixel mit farbe an koordinaten setzen
    DllCall($gdi32, "long", "SetPixel", "long", $dc, "long", $x, "long", $y, "long", $color)
    EndFunc ;==>pix

    [/autoit] [autoit][/autoit] [autoit]

    Func GetDC($handle)
    $dc = DllCall($user32, "int", "GetDC", "hwnd", $handle)
    Return $dc[0]
    EndFunc ;==>GetDC

    [/autoit] [autoit][/autoit] [autoit]

    func _exit()
    Exit
    endfunc

    [/autoit]
  • Oh - mein - Gott.

    Ich bin einfach nur sprachlos.
    Ich dachte ja bereits das ASM Beispiel von Trancexx (?!) wäre krass, aber das hier ist wohl der abolute Hammer!
    Diese Geschwindigkeit ist unglaublich. Ich kann zum Code leider relativ wenig sagen (Frag mich in 5 Jahren nochmal :D)

    Wenn ich allerdings mal Bedarf habe sowas zu machen, ist dieses Script die erste Anlaufstelle.

    Top!

  • Endlich!
    Nach so etwas habe ich lange gesucht / selbst probiert!
    Danke!
    :)

    EDIT: Besteht die Möglichkeit, dass du es so umschreiben kannst, dass er die Bilder nicht anzeigt,
    sondern einfach als Bild - Datei in den Ordner Bilder packt, bei @ScriptDir?`
    Und die GUI soll einfach anzeigen bei welchem Bild er ist und bei wieviel 15% Berechnung.
    Denn man kann dann einen Film daraus machen :)

  • SSSSSSSSSSSSSSSUUUUUUUUUUUUUUUUUUUUUUUUUUUPPPPPPPPPPPPPPPPPPPPPPEEEEEEEEEEEEEEEEEEEEEERRRRRRRRRRRRRRRRRR :thumbup:

    Jetzt muss man nur noch ASM verstehen, um auch andere Dinge wie z.B. GDI+ Berechnungen zu beschleunigen!!!

    Mach' doch auch einen Thread im engl. Forum auf!


    Hut ab!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Zitat

    EDIT: Besteht die Möglichkeit, dass du es so umschreiben kannst, dass er die Bilder nicht anzeigt,
    sondern einfach als Bild - Datei in den Ordner Bilder packt, bei @ScriptDir?`

    Ja, absolut kein Thema, wie schon geschrieben ist auch eine beliebige Bildgröße einstellbar. In der "erweiterten" Fassung (die Menüpunkte sind ja schon vorhanden :D ) soll auch ein "Flug" bis zum aktuellen Bild (dann werden alle Zwischenbilder berechnet) darstellbar sein, als AVI oder einem anderen abspielbaren Container.

    Zitat

    Diese Geschwindigkeit ist unglaublich

    Naja, um den Code lesbar zu halten (soll ja für Anfänger verständlich sein) habe ich noch nicht optimiert, da Coprozessor und Prozessor parallel arbeiten, kann man die beiden auch verschränken. Aber eins weiß ich schon jetzt, so bekloppt wie damals, als ich nach Anzahl der ausgeführten TAKTE optimiert habe, bin ich heutzutage nicht :D
    Und Treiber werde ich auch keine mehr schreiben.

    Zitat

    Ich könnt Stunden damit verbringen immer weiter draufzuklicken

    irgendwann ist Schluß, dann ist die Rechengenauigkeit am Ende und es erscheinen nur noch Linien (und hoffentlich vorher eine Fehlermeldung ^^). Um mal einen Vergleich für die "Vergrößerung" an diesem Punkt zu bringen:
    Wenn man auf der Erde steht und den Mond fotografiert und immer weiter zoomt, dann ist dann die Rechengenauigkeit erreicht, wenn man ein ATOM auf der Mondoberfläche bildschirmfüllend durch das Objektiv der Kamera sähe.
    Es gibt Programme die so weit vergrößern können, daß das Verhältnis vom Durchmesser des Universums zu dem eines Protons erreicht wird.


    Nochmal ein Aufruf an die Paletten/Bildbearbeitungsprofis ! Nehmt das blaue Beispielbild und verändert es mit einer Palette so, daß es "richtig geil" aussieht. Diese Palette bzw die Berechnung wird dann eingebaut :thumbup: Wenn das JPG-Format dafür nicht geeignet sein sollte, dann mach ich schnell ne Bitmap.

  • Zitat

    Jetzt muss man nur noch ASM verstehen, um auch andere Dinge wie z.B. GDI+ Berechnungen zu beschleunigen!!!

    Naja, ehrlich gesagt, ist das die einfachste Sprache überhaupt^^. Sie kommt mit ca. 10-20 Befehlen aus. Und GDI+ ist auch kein Problem, da (wie im Script zu lesen) die erzeugte Bitmap mit GDI+-Befehlen bearbeitbar ist.

    Mal ein Pseudocodebeispiel zum Umwandeln einer Farbgrafik in Graustufen:

    • -Startlabel erstellen für die Schleife: Anfang:
      -Lade den Anfang der Bitmapgrafik in ein 32Bit-Register , z.B. EDI mov EDI,[Speicheradresse erstes Pixel der Bitmap]
      -schreibe 0 in das EAX-Register, mit EAX arbeiten wir mov EAX,0
      -lese das Farbbyte AABBGGRR der Grafik an dieser Position in einzelne 1-Byte Register z.B. ah ein: mov ah,[EDI+1] ;das 1. Byte an [EDI] ist der Alphakanal des Pixels AA, an [EDI+1] ist BB an EDI+2 GG und an EDI+3 steht RR
      -EAX ist aus den folgenden Registern aufgebaut. 4 Byte bilden das EAX-Register, die 16 niedrigen Bit sind das AX-Register , welches sich wiederum in ein Highbyte AH und ein Lowbyte AL unterteilt. Also 32Bit EAX= obere16 Bit+ 16Bit AX = obere 16Bit + 8Bit AH + 8 Bit AL , wenn man also ein mov al,3 schreiben würde, dann sähe das EAX-Register so aus 00000000000000000000000000000011 die letzten 2 Bits wären gesetzt, der Rest ist 0. Pixelbeispiel: mov EAX,[EDI] dann steht im Byte AL der Farbcode RR, in AH der Farbcode GG und im oberen Teil von EAX AABB. Aber wir lesen die Speicherstellen nacheinander aus (langsam aber nachvollziehbar^^) Durch mov al,[EDI+1] steht jetzt die Farbe für Blau im AL-Register
      -add ax,[EDI+2] ;dazu wird die Farbe Grün addiert
      -add ax,[EDI+3] ; und Rot auch noch
      -div ax,3 ;Integerdivision durch 3 => ax=int(ax/3) =arithmetisches Mittel aus den 3 Bytes
      -mov [EDI+1],ah ;das byte in den Speicher schreiben an die blaue, grüne und rote Position
      -mov [EDI+2],ah
      -mov [EDI+3],ah ;alle bytes sind geschrieben, haben RR, GG und BB die gleiche Farbe, dann ist das ein Grauton
      -add EDI,4 ;speicheradresse um 4 byte erhöhen, hier steht das nächste pixel
      -cmp EDI,[ende der Bitmap] ;vergleiche, ob das letzte Pixel erreicht wurde
      -jl @anfang ;jl=Jump if Lower , springe, wenn das letzte Pixel noch nicht erreicht ist, zum Anfang
      -ret ;ansonsten Ende des Programms

    Das ist natürlich ULTRALANGSAM durch die vielen Speicheranforderungen, aber um mal eine Hausnummer zu nennen:
    Wenn jeder der Befehle 10 Takte bräuchte und 10 Befehle gebraucht werden, dann dauert der Spass bei einer 2Ghz-CPU (2*10^9 Takte pro Sekunde) nur 0.5*10^-7 Sekunden pro Pixel, eine 1000x1000 Pixel große Bitmap wäre dann in 0,05 Sekunden umgewandelt!

  • geile sache das :thumbup:
    aber der script läuft bei mir nur auf Run x86 ( hab 64bit bs)
    die rechtsklick optionen bewirken bei mir nichts :?:

  • Zitat

    aber der script läuft bei mir nur auf Run x86 ( hab 64bit bs)

    Dem Bytecode sollte das egal sein, was allerdings sein kann, daß der "Assembler" in 64Bit-Umgebung nicht funktioniert.
    Teste mal das folgende Script pls

    [autoit]

    $tCodeBuffer = DllStructCreate("byte[20]") ;Speicher für den assemblercode belegen
    DllStructSetData($tCodeBuffer, 1, "0xC7C007000000C3")
    $ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "int", 0, "int", 0, "int", 0, "int", 0);bytecode aufrufen, rückgabe in a[0]
    msgbox(0,"Returncode",$ret[0])

    [/autoit]

    Es sollte normalerweise der Returncode 7 zurückgeben, funzt das auch unter 64Bit?

    Zitat

    die rechtsklick optionen bewirken bei mir nichts

    Die Zoomstufen funktionieren, und das Speichern auch, beim Rest wird "Coming soon :o)" angezeigt :D

  • Gleich mit GDI+ anfangen ist doch zu hoch gegriffen! Erstmal einfache Sachen machen, damit ich wieder das ASM Denken bekomme und die Befehle verstehe. ;) Wenn die Labels besser implementiert wären, wäre der Aufwand geringer! Vielleicht kommt das ja bald -> http://www.autoitscript.com/forum/index.php?showtopic=110794!

    Als Einsteig stelle ich mir die Erstellung der Primzahlen vor. Nun ja, schau ich mal, ob ich das hinbekomme... ?(

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Zitat

    Gleich mit GDI+ anfangen ist doch zu hoch gegriffen!

    Das sehe ich anders. Bei Grafiken bekommst du eine sofortige, optische Rückmeldung. Es macht meist nichts aus, ob du den Speicher nicht genau getroffen hast oder ob ein Register evtl. nicht den richtigen Farbcode übermittelt. Das schlimmste sind im Fehlerfall einige bunte Pixel. Wobei ein wirklicher "Absturz" in einem Fensterchen endet "AutoIt hat wg eines Fehlers das Programm beendet", aber der Rechner läuft weiterhin, kein Kaltstart ist erforderlich^^
    Durch die weggefallene Segmentierung des Speichers (man kann 2 Gig linear adressieren) ist vieles einfacher geworden. Man kann einfach lustig mit einer Bitmap rumexperimentieren, ohne daß etwas schwerwiegendes passiert.
    Wäre dieser Grmblfxx#%!§ mit den Vorwärtssprüngen nicht, ich wüsste nicht, was fehlen sollte^^

    Und wenn man bedenkt, daß AutoIt in mehr als 99,9% aller Fälle bei weitem schnell genug ist, ist dieser Assembler sowieso nur eine Spielerei für kurze, aber rechenaufwendige Sachen. Für größere Projekte nimmt man einen "richtigen" Assembler(incl IDE und Debugger) und fügt den Bytecode dann in AutoIt ein. Oder macht das gleiche mit C....oder was auch immer.

  • Zitat

    Es sollte normalerweise der Returncode 7 zurückgeben, funzt das auch unter 64Bit?

    klappt auch nur unter x86 aber returncode 7 wird angezeigt

  • Dem Bytecode sollte das egal sein, was allerdings sein kann, daß der "Assembler" in 64Bit-Umgebung nicht funktioniert.
    Teste mal das folgende Script pls

    [autoit]

    $tCodeBuffer = DllStructCreate("byte[20]") ;Speicher für den assemblercode belegen
    DllStructSetData($tCodeBuffer, 1, "0xC7C007000000C3")
    $ret = DllCall("user32.dll", "int", "CallWindowProcW", "ptr", DllStructGetPtr($tCodeBuffer), "int", 0, "int", 0, "int", 0, "int", 0);bytecode aufrufen, rückgabe in a[0]
    msgbox(0,"Returncode",$ret[0])

    [/autoit]

    Es sollte normalerweise der Returncode 7 zurückgeben, funzt das auch unter 64Bit?

    Die Zoomstufen funktionieren, und das Speichern auch, beim Rest wird "Coming soon :o)" angezeigt :D

    Unter x64 ist der Return Code genau dann 7, wenn der Code als x32 ausgeführt wird!

    Ansonsten:
    Problemsignatur:
    Problemereignisname: BEX64
    Anwendungsname: autoit3_x64.exe
    Anwendungsversion: 3.3.4.0
    Anwendungszeitstempel: 4b509369
    Fehlermodulname: StackHash_c82e
    Fehlermodulversion: 0.0.0.0
    Fehlermodulzeitstempel: 00000000
    Ausnahmeoffset: 0000000002240240
    Ausnahmecode: c0000005
    Ausnahmedaten: 0000000000000008
    Betriebsystemversion: 6.1.7600.2.0.0.256.1
    Gebietsschema-ID: 1031
    Zusatzinformation 1: c82e
    Zusatzinformation 2: c82e7933df2e59f70824ea0efe276023
    Zusatzinformation 3: 6fae
    Zusatzinformation 4: 6fae1bf06560f26c1ef29c48e79861c2

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • habe mal etwas gestöbert, entweder hängt es an den Pointern, denn in 64Bit-Windows sind diese immer 64Bit lang, oder ggf auch daran.(falsche dll?!)
    geht das?

    [autoit]

    $tCodeBuffer = DllStructCreate("byte[20]") ;Speicher für den assemblercode belegen
    DllStructSetData($tCodeBuffer, 1, "0xC7C007000000C3")
    $ret = DllCall("user32.dll", "int64", "CallWindowProcW", "int64", DllStructGetPtr($tCodeBuffer), "int64", 0, "int64", 0, "int64", 0, "int64", 0);bytecode aufrufen, rückgabe in a[0]
    msgbox(0,"Returncode",$ret[0])

    [/autoit]

    ggf sollte man mal jemanden fragen, der sich damit auskennt :o)

  • Update
    Farbpalette eingefügt, die Palette ist sehr einfach aufgebaut, ein Farbverlauf von rot nach gelb nach weiß nach schwarz . Die Farben sind als 32Bit-Hexcode einfach aneinandergehängt.
    Eine 2. Bitmap wurde eingefügt. In der orginalen Bitmap werden die Tiefeninformationen des Bildes gespeichert, in der 2. Bitmap dann die Farben aus der Palette entsprechend ersetzt. Geplant sind beim Umschalten der Paletten sofortige Änderung der Farben OHNE Neuberechnung.
    Werde jetzt einige Paletten basteln und per Menü umschaltbar machen. Rauszoomen wird noch eingebaut, und der "Flug" natürlich...
    Btw, hat jemand ein Script zum Packen der Bilder in einen Container, der per Videoplayer abspielbar ist?

  • habe mal etwas gestöbert, entweder hängt es an den Pointern, denn in 64Bit-Windows sind diese immer 64Bit lang, oder ggf auch daran.(falsche dll?!)
    geht das?

    [autoit]

    $tCodeBuffer = DllStructCreate("byte[20]") ;Speicher für den assemblercode belegen
    DllStructSetData($tCodeBuffer, 1, "0xC7C007000000C3")
    $ret = DllCall("user32.dll", "int64", "CallWindowProcW", "int64", DllStructGetPtr($tCodeBuffer), "int64", 0, "int64", 0, "int64", 0, "int64", 0);bytecode aufrufen, rückgabe in a[0]
    msgbox(0,"Returncode",$ret[0])

    [/autoit]

    ggf sollte man mal jemanden fragen, der sich damit auskennt :o)

    Nö, geht leider auch nicht! Unter Win7 x64 geht einiges mehr nicht, wenn es als x32 ausgeführt wird, z.B. stürzt es ab, wenn man das Fentser vergrößert! :(

    DIe Farben sehen jetzt richtig "schön" aus! :thumbup:

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯