Beispiel Verwendung von Floatingpoint-Registern und ein Versuch, ein AutoIt-Script 1:1 in Assembler umzusetzen
Für Berechnungen mit Fließkommazahlen (bis zu 80 Bit Genauigkeit) verwende ich den "Coprozessor" mit seinem eigenen Registerstack (ST0 bis ST7)
alle Coprozessorbefehle fangen mit F an, also FADD, FMUL, FDIV usw.
Zunächst muss der Copro mit FINIT initialisiert werden.
Die Coprozessorbefehle arbeiten (fast) alle mit dem internen Stack. Um nun 2 Zahlen zu multiplizieren, lädt man beide Zahlen per FLD auf den Stack und multipliziert dann:
FINIT
FLD dword[float1] ;ST0=float1
FLD [float2] ;ST0=float2 ST1=float1 ;wenn der Befehl anhand des Namens den Typ feststellen kann, braucht man den Typ nicht anzugeben
FMUL st0,st1 ;ST0=float2+float1 ST1=float1
;dritte Zahl addieren, intgr ist aber ein Integer, macht nix, man kann auch Integer (erlkennt man an dem I im Namen des Befehls) laden
FIADD [float3] ;sogar direkt auf die Speicherstelle zugreifen ist möglich ST0=intgr+float2+float1 ST1=float1
FST [float1] ;Inhalt von ST0 wird an die Speicherstelle [föoat1] geschrieben ST0=intgr+float2+float1 ST1=float1
FSTP [float1] ;Inhalt von ST0 wird an die Speicherstelle [föoat1] geschrieben, und dann st0 vom Stack gepopt danach ist ST0=float1
float1 dd 0.004 ;Fliesskommazahlen immer mit Komma!
float2 dd 58.0 ;Fliesskommazahlen immer mit Komma!
intgr dd 66 ;Das ist ein INT! 66.0 wäre float
Alles anzeigen
ACHTUNG! Ab jetzt wird ST0 in EAX zurückgegeben, um also schnell mal das aktuelle Register auf dem Coprozessorstack (ST0) im Programm zu checken, einfach ein RET hinter den entsprechenden Befehl setzen, dabei im Dll-Call den Rückgabetyp entweder auf float oder double setzen.
Das Programm "Tunnelflug" habe ich freundlicherweise von UEZ bekommen, der es wiederum von einem JavaScript abgekupfert hat^^
AutoIt-Version: (jaja, sieht wüst aus, aber so habe ich es bekommen^^)
Spoiler anzeigen
;Idea taken from http://js1k.com/demo/462
;Ported to AutoIt by UEZ Build 2010-08-20
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
#AutoIt3Wrapper_Run_After=del /f /q "Star Burst_Obfuscated.au3"
#AutoIt3Wrapper_Run_After=upx.exe --ultra-brute "%out%"
;~ #AutoIt3Wrapper_Run_After=upx.exe --best "%out%"
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
;Opt("MustDeclareVars", 1)
Opt("GUIOnEventMode", 1)
Local $hGUI, $hGraphics, $hBackbuffer, $hBitmap
Local $H = 132, $W = 132
; Initialize GDI+
_GDIPlus_Startup()
$hGUI = GUICreate("GDI+ Test", $W, $H)
GUISetState()
$hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($W, $H, $hGraphics)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
; Using antialiasing
;~ _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 0)
; Create a Brush object
Local $hBrush = _GDIPlus_BrushCreateSolid()
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
[/autoit] [autoit][/autoit] [autoit]adlibregister("_fps",1000)
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]global $pi = ACos(-1), $pi2 = 2 * $pi, $pi05 = ACos(-1) * 0.5, $fps
Local $HW = $H * 0.5, $HH = $W * 0.5
Local $A0 = 0, $A1 = 0, $A2 = 0, $A3 = 0
Local $ox = 0, $oy = 0, $0z = 0
Local $tu = 0, $tv = 0
Local $speed = 2
Local $i, $j, $x, $y, $o
Local $cc, $ss, $z, $col
Local $dx, $dy, $dz, $rd, $A, $B, $C, $R, $t1, $tu, $tv, $q, $g, $l
Local $d[$W + 1]
While 1;Sleep(10)
_GDIPlus_GraphicsClear($hBackbuffer, 0xFF000000)
$o = 0
For $i = 0 To $H Step $speed
For $j = 0 To $W Step $speed
$dx=($j-$HW)/$W;
$dy=($i-$HH)/$H;
$dz=-1;
$l=Sqrt($dx*$dx+$dy*$dy+$dz*$dz);
$dx/=$l;
$dy/=$l;
$dz/=$l;
$X=$dx;
$Y=$dy;
;//rotate(A0-A2);
$dy=$Y;
$Y=$dz;
$dx=$X;
$X=$dy;
;//rotate(A3);
$dy=$X;
$dz=$Y;
$R=100;
$A=$dx*$dx+$dy*$dy;
$B=2*($dx*$ox+$dy*$oy);
$C=$ox*$ox+$oy*$oy-$R*$R;
$rd=Sqrt($B*$B-4*$A*$C);
$q=-.5*($B-$rd);
$t1=$C/$q;
$tu=5*ATan2($dy,$dx)/$Pi2;
$tv=$dz*$t1/256;
$tv+=$A1;
$g = Hex(bitand(Bitxor(int($tu * 256), int($tv * 256)), 0xFF), 2)
$col = "0xFF" & $g & $g & $g
_GDIPlus_BrushSetSolidColor($hBrush, $col)
_GDIPlus_GraphicsFillRect($hBackbuffer, $j, $i, $speed, $speed, $hBrush)
; $o += 1
Next
; $A0 += 0.015
;~ $A2 += 0.041
;~ $A3 += 0.009
Next
$A1 += 0.07
_GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $W, $H)
$fps+=1
; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $A1 = ' & $A1 & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console
WEnd
func _FPS()
winsettitle($hgui,"",$FPS)
$FPS=0
endfunc
Func Rotate($t)
$cc = Cos($t)
$ss = Sin($t)
$z = $x * $cc - $y * $ss
$y = $x * $ss + $y * $cc
$x = $z
EndFunc
func atan2($y,$x)
return (2*atan($y/($x+sqrt($x*$x+$y*$y))))
endfunc
Func ATan2_UEZ($y,$x)
Switch $x
Case ($x > 0)
Return ATan($y / $x)
Case ($x < 0 And $y >= 0)
Return ATan($y / $x + $pi)
Case ($x < 0 And $y < 0)
Return ATan($y / $x - $pi)
Case ($x = 0 And $y > 0)
Return $pi05
Case ($x = 0 And $y < 0)
Return -$pi05
Case ($x = 0 And $y = 0)
Return 0
EndSwitch
EndFunc
Func _Exit()
; Clean up
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hBackbuffer)
_GDIPlus_GraphicsDispose($hGraphics)
; Uninitialize GDI+
_GDIPlus_Shutdown()
Exit
EndFunc
Umsetzung in Assembler, ich habe versucht, die Rechenschritte im AutoIt-Programm direkt in Assemblerbefehle umzusetzen^^
Die eigentliche Stärke des Coprozessors, OHNE Zugreifen auf Prozessorregister (EAX, EBX usw) und Speicher, sondern nur mit den eigenen 8 ST-Registern zu arbeiten (parallel zum Prozessor! ) habe ich hier NICHT ausgespielt!
Im Apfelmännchen habe ich das wesentlich besser gelöst, aber das war mir dann für ein TUT doch etwas heavy^^
Weiterhin werden extrem viele Speicherschreib- und Lesebefehle durchgeführt. Da die Cachelines jedes mal mit "falschen" Daten gefüllt sind, ist das ein sehr schönes Beispiel, wie man auch mit Assembler SEHR langsame Programme erstellen kann! aber es ist wesentlich schneller als das AutoIt-Script^^ (wobei mein Opera mit dem compilierten Javacode fast ähnlich schnell ist! )
Spoiler anzeigen
#include <FASM.au3>
#include <MemoryDll.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>
#include <GDIConstants.au3>
#include <array.au3>
#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)
[/autoit] [autoit][/autoit] [autoit]$b=520
$h=520
global $Fasm = FasmInit(), $FPS
_createbytecode() ;assemblercode erstellen
;backbuffer erstellen für die Bitmap
local $ptr_bitmap,$hbmp_bitmap ;byref
$hDC_bitmap=_CreateNewBmp32($b, $h, $ptr_bitmap,$hbmp_bitmap) ;DC, Pointer auf die Bitmapdaten und ein Handle für GDI+....eine eierlegende Wollmilchsau
$hgui=guicreate("",$b,$h,1,1)
$hdc_gui=_WinAPI_GetDC($hgui)
guisetstate()
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
adlibregister("_fps",1000) ;FramesPerSecond
$step=0.07 ;das ist die Schrittweite, um die der Tunnelflug ein Frame weiter gezeichnet wird
[/autoit] [autoit][/autoit] [autoit]$struct_a=dllstructcreate("float") ;
dllstructsetdata($struct_a,1,$step) ;zähler, wird nach jedem Frame um $step erhöht
while 1;sleep(20)
$Ret = MemoryFuncCall("int", FasmGetFuncPtr($Fasm), "int", $b,"int",$h,"float",dllstructgetdata($struct_a,1),"ptr", $ptr_bitmap)
_winapi_bitblt($hdc_gui,0,0,$b,$h,$hDC_bitmap,0,0,$srccopy) ;bitmap in die GUI blitten
$fps+=1
dllstructsetdata($struct_a,1,dllstructgetdata($struct_a,1)+$step) ;zähler erhöhen
wend
func _fps()
winsettitle($hgui,"",$fps)
$fps=0
endfunc
Func _Exit()
Exit
EndFunc
func _createbytecode()
[/autoit] [autoit][/autoit] [autoit]FasmReset($Fasm)
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "use32")
FasmAdd($Fasm, "org " & FasmGetBasePtr($Fasm))
FasmAdd($Fasm, "mov eax,[esp+4]") ;breite
FasmAdd($Fasm, "mov [breite],eax") ;
FasmAdd($Fasm, "mov eax,[esp+8]") ;hoehe
FasmAdd($Fasm, "mov [hoehe],eax") ;
FasmAdd($Fasm, "mov eax,[esp+12]") ;A1
FasmAdd($Fasm, "mov [va1],eax") ;
FasmAdd($Fasm, "mov edi,[esp+16]") ;Ptr auf bitmapdaten
;FasmAdd($Fasm, "mov [bitmap],eax") ;
FasmAdd($Fasm, "FINIT") ;copro init
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "mov dword[vo],0") ; init
FasmAdd($Fasm, "mov dword[vi],0") ;schleifenzähler
FasmAdd($Fasm, "mov dword[vj],0") ;
FasmAdd($Fasm, "mov eax,dword[breite]") ;HW=BREITE/2
FasmAdd($Fasm, "shr eax,1") ;
FasmAdd($Fasm, "mov [vhw],eax") ;
FasmAdd($Fasm, "mov eax,dword[hoehe]") ;HH=HOEHE/2
FasmAdd($Fasm, "shr eax,1") ;
FasmAdd($Fasm, "mov [vhh],eax") ;
;schleifen
FasmAdd($Fasm, "mov edx,[hoehe]") ;
FasmAdd($Fasm, "i_schleife:") ; for i=0 to h
FasmAdd($Fasm, "mov ecx,[breite]") ; schleifenzähler breite
FasmAdd($Fasm, "j_schleife:") ; for j=0 to w
;~ ;$dx=($j-$HW)/$W;
FasmAdd($Fasm, "fild dword[vj]") ;st(0)=j
FasmAdd($Fasm, "fisub dword[vhw]") ;st(0)=j-hw
FasmAdd($Fasm, "fidiv dword[breite]");st(0)=(j-hw)/w
FasmAdd($Fasm, "fst dword[vdx]") ;dx speichern
FasmAdd($Fasm, "fmul st0,st0") ;st(0)=dx^2 ;26
;$dy=($i-$HH)/$H
FasmAdd($Fasm, "fild [vi]") ;st(0)=i
FasmAdd($Fasm, "fisub [vhh]") ;st(0)=i-hh
FasmAdd($Fasm, "fidiv [hoehe]") ;st(0)=(j-hw)/h
FasmAdd($Fasm, "fst dword[vdy]") ;dy speichern
;dz=-1
FasmAdd($Fasm, "mov [vdz],-1") ;dz=-1
;$l=Sqrt($dx*$dx+$dy*$dy+$dz*$dz);
FasmAdd($Fasm, "fmul st0,st0") ;st(0)=dy^2 st(1)= dx^2
FasmAdd($Fasm, "fadd st0,st1") ;st(0) =dx^2+dy^2
FasmAdd($Fasm, "fld1") ;st(0) =1
FasmAdd($Fasm, "fadd st0,st1") ;st(0) =dx^2+dy^2+1
FasmAdd($Fasm, "fsqrt") ;st(0)= sqrt(dx^2+dy^2+1)
;dx=dx/l
FasmAdd($Fasm, "fld [vdx]") ;st0=dx st1=l
FasmAdd($Fasm, "fdiv st0,st1") ;st0=dx/l
FasmAdd($Fasm, "fstp dword[vdx]") ;dx=dx/l
;dy=dy/l
FasmAdd($Fasm, "fld [vdy]") ;st0=dy st1=l
FasmAdd($Fasm, "fdiv st0,st1") ;st0=dy/l
FasmAdd($Fasm, "fstp dword[vdy]") ;dy=dy/l
;dz=dz/l
FasmAdd($Fasm, "fild [vdz]") ;st0=dz st1=l
FasmAdd($Fasm, "fdiv st0,st1") ;st0=dz/l
FasmAdd($Fasm, "fstp dword[vdz]") ;dz=dz/l
;x=dx
FasmAdd($Fasm, "mov eax,[vdx]") ;
FasmAdd($Fasm, "mov [vx],eax") ;
;y=dy
FasmAdd($Fasm, "mov eax,[vdy]") ;
FasmAdd($Fasm, "mov [vy],eax") ;
;dy=y
FasmAdd($Fasm, "mov eax,[vy]") ;
FasmAdd($Fasm, "mov [vdy],eax") ;
;y=dz
FasmAdd($Fasm, "mov eax,[vdz]") ;
FasmAdd($Fasm, "mov [vy],eax") ;
;dx=x
FasmAdd($Fasm, "mov eax,[vx]") ;
FasmAdd($Fasm, "mov [vdx],eax") ;
;x=dy
FasmAdd($Fasm, "mov eax,[vdy]") ;
FasmAdd($Fasm, "mov [vx],eax") ;
;dy=x
FasmAdd($Fasm, "mov eax,[vx]") ;
FasmAdd($Fasm, "mov [vdy],eax") ;
;dz=y
FasmAdd($Fasm, "mov eax,[vy]") ;
FasmAdd($Fasm, "mov [vdz],eax") ;
;r=10000 ist konstante
;$A=$dx*$dx+$dy*$dy;
FasmAdd($Fasm, "fld [vdx]") ;st0=dx
FasmAdd($Fasm, "fmul st0,st0") ;st0=dx^2
FasmAdd($Fasm, "fld [vdy]") ;st0=dy
FasmAdd($Fasm, "fmul st0,st0") ;st0=dy^2 st1=dx^2
FasmAdd($Fasm, "fadd st0,st1") ;st0 =dx^2+dy^2
FasmAdd($Fasm, "fstp dword[va]") ;a=dx^2+dy^2
;$B=2*($dx*$ox+$dy*$oy) = 0;
;$c=-10000 =konstante
;$rd=Sqrt($B*$B-4*$A*$C);
FasmAdd($Fasm, "fld [minusvier]") ;st0=-4 69
FasmAdd($Fasm, "fmul [va]") ;st0=-4*a
FasmAdd($Fasm, "fmul [vc]") ;st0=-4*a*c
FasmAdd($Fasm, "fsqrt") ;st0=-4*a*c
; $q=-.5*($B-$rd)
FasmAdd($Fasm, "fldz ") ;st0=b=0 st1==rd
FasmAdd($Fasm, "fsub st0,st1") ;st0=(b-rd) st1=rd
FasmAdd($Fasm, "fmul [minuseinhalb]") ;st0=-0.5*(B-rd)=q
FasmAdd($Fasm, "fstp dword[vq]") ;
;~ ; $tu=5*ATan2($dy,$dx)/$Pi2;
FasmAdd($Fasm, "fld [vdx]") ;st0 =vdx
FasmAdd($Fasm, "fld [vdy]") ;
FasmAdd($Fasm, "fpatan") ;
FasmAdd($Fasm, "fmul [fuenf]") ;
FasmAdd($Fasm, "fldpi") ;
FasmAdd($Fasm, "fdivp st1,st0") ;
FasmAdd($Fasm, "fdiv [zwei]") ;st0=tu
FasmAdd($Fasm, "fistp [vtu]") ;tu
; $tv=$dz*$c/q/256;
FasmAdd($Fasm, "fld [vdz]") ;st0=dz
FasmAdd($Fasm, "fmul [vc]") ;
FasmAdd($Fasm, "fdiv [vq]") ;
FasmAdd($Fasm, "fdiv [v256]") ;
FasmAdd($Fasm, "fadd [va1]") ;tv
FasmAdd($Fasm, "fst [vtv]") ;tv=tv+a1
FasmAdd($Fasm, "fmul [v256]") ;tv
FasmAdd($Fasm, "fistp [vtv1]") ;tv
;stack cleanen
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "fstp st0") ;pop
FasmAdd($Fasm, "mov eax,[vtv1]") ;
FasmAdd($Fasm, "xor eax,[vtu]") ;
FasmAdd($Fasm, "and eax,0xFF") ;farbe von RR, GG und BB
;FasmAdd($Fasm, "ret 16");Funktionsende
;pixelfarbe (grauton) erstellen
FasmAdd($Fasm, "mov ebx,0xFF") ;alpha AA
FasmAdd($Fasm, "shl ebx,8") ;AA00
FasmAdd($Fasm, "or ebx,eax") ;AABB
FasmAdd($Fasm, "shl ebx,8") ;AABB00
FasmAdd($Fasm, "or ebx,eax") ;AABBGG
FasmAdd($Fasm, "shl ebx,8") ;AABBGG00
FasmAdd($Fasm, "or eax,ebx") ;AABBGGRR
;FasmAdd($Fasm, "ret 16");Funktionsende
;FasmAdd($Fasm, "mov eax,0xFF00FF00") ;AABBGGRR
FasmAdd($Fasm, "stosd") ;mov [edi],eax pixel in die bitmap schreiben
FasmAdd($Fasm, "dec ecx" ) ;schleifenzähler breite
FasmAdd($Fasm, "mov [vj],ecx" ) ;schleifenzähler breite
FasmAdd($Fasm, "jnz j_schleife") ;so lange bis 0
FasmAdd($Fasm, "dec edx") ;schleifenzähler hoehe
FasmAdd($Fasm, "mov [vi],edx" ) ;schleifenzähler breite
FasmAdd($Fasm, "jnz i_schleife") ;so lange bis 0
FasmAdd($Fasm, "ret 16");Programmende
[/autoit] [autoit][/autoit] [autoit];variablen, einige werden nicht gebraucht, habe aber versucht, das AutoItscript zu übernehmen
[/autoit] [autoit][/autoit] [autoit]FasmAdd($Fasm, "v256 dd 256.0") ;eigentlich konstanten....
FasmAdd($Fasm, "zwei dd 2.0")
FasmAdd($Fasm, "minusvier dd -4.0")
FasmAdd($Fasm, "fuenf dd 1280.0")
FasmAdd($Fasm, "minuseinhalb dd -0.5")
FasmAdd($Fasm, "bitmap dd 0")
FasmAdd($Fasm, "breite dd 0")
FasmAdd($Fasm, "hoehe dd 0")
FasmAdd($Fasm, "vhw dd 0")
FasmAdd($Fasm, "vhh dd 0")
FasmAdd($Fasm, "vo dd 0.0")
FasmAdd($Fasm, "vi dd 0.0")
FasmAdd($Fasm, "vj dd 0.0")
FasmAdd($Fasm, "vl dd 0.0")
FasmAdd($Fasm, "vdx dd 0.0")
FasmAdd($Fasm, "vdy dd 0.0")
FasmAdd($Fasm, "vdz dd 0.0")
FasmAdd($Fasm, "vx dd 0.0")
FasmAdd($Fasm, "vy dd 0.0")
FasmAdd($Fasm, "vr dd 10000.0")
FasmAdd($Fasm, "va dd 0.0")
FasmAdd($Fasm, "vb dd 0.0")
FasmAdd($Fasm, "vc dd -10000.0")
FasmAdd($Fasm, "vrd dd 0.0")
FasmAdd($Fasm, "vq dd 0.0")
FasmAdd($Fasm, "vt1 dd 0.0")
FasmAdd($Fasm, "vtu dd 0")
FasmAdd($Fasm, "vtv dd 0")
FasmAdd($Fasm, "vtv1 dd 0")
FasmAdd($Fasm, "va1 dd 0.00005")
$Binary = FasmGetBinary($Fasm) ;syntaxerror im Assembler abfangen abfangen
;~ If @Extended Then ;syntax-error aufgetreten
;~ $Error = FasmGetLastError()
;~ ConsoleWrite("Error Code:" & $Error[0] & @CRLF & "Error Message:" & $Error[1] & @CRLF & "Error Line:" & $Error[2] & @CRLF)
;~ Else ;syntax ok
ConsoleWrite(String(FasmGetBinary($Fasm)) & @CRLF)
filedelete("test.bin") ;assembly für externen debugger
filewrite("test.bin",binarytostring(String(FasmGetBinary($Fasm))))
endfunc
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]Func _CreateNewBmp32($iwidth, $iheight, ByRef $ptr, ByRef $hbmp) ;erstellt leere 32-bit-Bitmap; Rückgabe DC und ptr und handle auf die Bitmapdaten
;by Andy
Local $hcdc = _WinAPI_CreateCompatibleDC(0) ;Desktop-Kompatiblen DeviceContext erstellen lassen
Local $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
Local $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
übrigens habe ich auf einem AMD4850@2,5Ghz bei einer Fenstergröße von 320x320 ca 55FPS und bei 800x800 nur noch 5-6 FPS^^
und der JS-Code
Spoiler anzeigen
<!doctype html>
<html>
<head>
<title>JS1k, 1k demo submission [165]</title>
<meta charset="utf-8" />
</head>
<body>
<canvas id="c"></canvas>
<script>
/*possan.se*2010*/
M=Math;
Sin=M.sin;
Cos=M.cos;
Sqrt=M.sqrt;
ATan2=M.atan2
Pi=M.PI;
Pi2=M.PI*2;
d=document;
d.body.style.backgroundColor="#222";
c=d.getElementById('c');
G=c.getContext('2d');
W=320;
H=320;
c.width=W;
c.height=H;
HW=W/2;
HH=H/2;
A0=A1=A2=A3=0;
ox=oy=oz=0;
tu=tv=0;
// rotate=function(t)
// {
// cc=Cos(t);
// ss=Sin(t);
// Z=X*cc-Y*ss;
// Y=X*ss+Y*cc;
// X=Z;
// };
setInterval(function()
{
b=G.getImageData(0,0,W,H);
d=b.data;
o=0;
for(i=0;i<H;i++)
for(j=0;j<W;j++)
{
dx=(j-HW)/W;
dy=(i-HH)/H;
dz=-1;
l=Sqrt(dx*dx+dy*dy+dz*dz);
dx/=l;
dy/=l;
dz/=l;
X=dx;
Y=dy;
//rotate(A0-A2);
dy=Y;
Y=dz;
dx=X;
X=dy;
//rotate(A3);
dy=X;
dz=Y;
R=100;
A=dx*dx+dy*dy;
B=2*(dx*ox+dy*oy);
C=ox*ox+oy*oy-R*R;
rd=Sqrt(B*B-4*A*C);
q=-.5*(B-rd);
t1=C/q;
tu=5*ATan2(dy,dx)/Pi2;
tv=dz*t1/256;
tv+=A1;
//tu*=5;
g=((tu*256)^(tv*256))&255;
//g&=255;
d[o++]=g;
d[o++]=g;
d[o++]=g;
d[o++]=255;
};
G.putImageData(b,0,0);
//A0+=0.015;
A1+=0.026;
//A2+=0.041;
//A3+=0.009;
},30);
</script>
</body>
</html>
Alles anzeigen
einfach als HTML speichern und aufrufen