2012年7月5日星期四

Mandelbrot.asm


;--------------------------------------------
; "The Mandelbrot Set"
;
;  Derived from an algorithm described in "Chaos & Fractals"
;  by  Peitgen, Jurgens & Suape
;
;  coded by Ron Thomas 17/5/99  Ron_Thom@Compuserve.com  
;---------------------------------------------
;The Mandelbrot Set

;This is "The" clasic fractal, which was discovered by Benoit Mandelbrot in 1979 and
;is a complex object in mathematical space. Many fractals have been discovered since.

;Enjoy

;Ron Thomas

;Ron_Thom@Compuserve.com

;www.rbthomas.freeserve.co.uk

;17/5/99
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;以上是原作者的说明,
;这是我从国外(俄国)的一个网站下载的。
;这个是关于分形的,这个代码很常见,有好几种代码。
;这个程序我存放半年多了,特放出来与需要的人共享。
;QQ:112426112
;Email:leguanyuan at 126 dot com
;Homepage:http://correy.webs.com
;以下是我改编的代码:
.386
.model flat,stdcall
option casemap:none

include windows.inc

include kernel32.inc
includelib kernel32.lib

include user32.inc
includelib user32.lib

include gdi32.inc 
includelib gdi32.lib 

.code
hInstance dd 0
hWinMain dd 0
szClassName db "made by correy",0
pwndclassex dd 48,3,offset liuchunli,0,0,0,0,0,6,0,offset szClassName,0
stMsg MSG <>

cxClient DD ?
cyClient DD ?
x  DD ?  ;Coordinates of point to be plotted
y  DD ?
x_offset  DD ?  ;Horizontal offset
y_offset  DD ?   ;Vertical offset
colour  DD ?  ;Plotting colour

k  DD 60 ;20  ;Larger #s for more detail. 5 is crude 20+ is reasonable 

outside  DD ?  ;Flag we are outside the set
w  DD ?  ;Sets size of the fractal
half_w  DD ?
temp  DD ?
  
r real4 2.0   ; encirclement radius (enlargement control)
s real4 ?
im real4 ?
im2 real4 ?
imc real4 ?   ;Imaginary part of "c"
re real4 ?
re2 real4 ?
rec real4 ?   ;Real part of "c"
recen real4 0.0   ;Set to change the focus of the algorithm 
imcen real4 0.0   ; " " " "
scaleX real4 0.0   ;Scaling factors
scaleY real4 0.0

RGB MACRO red, green, blue ;; Get composite number from red green and blue bytes 
  mov al,blue   ;; ,,,blue 
  shl eax,8   ;; ,,blue,

  add al,green  ;; ,,blue,green
  shl eax,8   ;; ,blue,green,
  add al,red   ;; ,blue,green,red
  and eax,0FFFFFFh  ;; Mask out top byte to complete COLORREF dword 
ENDM

testit proc uses ecx  ; Test for encirclement of the Mandelbrot Set  
  mov outside,TRUE  ; Start with flag set 

  fld rec
  fstp re

  fld imc
  fstp im

  mov ecx,k   ; Get param controlling the detail
  add ecx,2   ; Set loop index

  .WHILE  ecx > 0
    fld re
    fmul re   ; st=re^2
    fst re2

    fld im
    fmul im   ; st=im^2,st(1)=re^2
    fst im2
    fadd
    fistp temp
    cmp temp,256  ;Reject if over 256
    jb SHORT ok  
    ret

    ok: fld re   ;st=re
    fmul im   ;st=im*re
    fadd st,st   ;st=2*im*re
    fadd imc   ;st=2*im*re+imc
    fstp im   ;Update im

    fld re2
    fsub im2
    fadd rec   ;st=re2 - im2  + rec
    fstp re   ;Update re
    dec ecx
  .ENDW    ; Go round again

  mov  outside,FALSE  ; Flag its outside
  ret
testit endp

liuchunli proc uses ebx edi esi,hWnd,uMsg,wParam,lParam
LOCAL hdc:HDC, ps:PAINTSTRUCT, msg:MSG
.if uMsg == WM_CLOSE;放置后面会反应更快点。
  invoke DestroyWindow,hWinMain
  invoke PostQuitMessage,0
.elseif uMsg == WM_SIZE
  finit    ; Initialise coprocessor
  mov eax,lParam
  and eax,0FFFFh

  mov cxClient,eax  ; Compute X offset
  shr eax,3   ;
  mov x_offset,eax  ; 

  invoke  GetSystemMetrics, SM_CXSCREEN ; Get screen width

  mov temp,eax  ;  
  fild cxClient  ; Compute scaling factor
  fidiv temp   ;
  fstp scaleX   ;

  mov ebx,lParam
  shr ebx,16 

  mov cyClient,ebx  ; Compute Y offset 
  shr ebx,3   ;  
  mov y_offset,ebx  ; 

  invoke  GetSystemMetrics, SM_CYSCREEN ; Get screen height

  mov temp,eax  ; Compute scaling factor
  fild cyClient
  fidiv temp
  fstp scaleY

  .IF eax <= 480   ; Set magnification according to resolution
    mov w, 640
  .ELSEIF  eax > 480 && eax <= 600
    mov w, 800
  .ELSE 
    mov w, 1000
  .ENDIF

  RGB 0,0,255   ;Set colour blue
  mov colour,eax 
.elseif uMsg == WM_PAINT  
  invoke BeginPaint,hWnd, ADDR ps
  mov    hdc,eax

  finit    ;Initialise the coprocessor

  mov eax,w
  shr eax,1
  mov half_w,eax

  fld r
  fidiv w
  fadd st,st   ;Compute s as 2*r/w
  fstp s

  mov y,0   ;Set outer loop index
  mov esi,w
  .WHILE esi > 0
    mov x,0   ;Set inner loop index
    mov edi,w
    .WHILE edi > 0 
      fld s
      mov temp,edi
      fild temp   ;Get inner loop index (x)
      fisub half_w   ;Subtract w/2
      fmul    
      fadd recen   ;st=s*(x-w/2) + recen
      fstp rec

      fld s
      mov temp,esi
      fild temp   ;Get outer loop index (y)
      fisub half_w
      fmul
      fadd imcen   ;st = s*(y-w/2) + imcen
      fstp imc
  
      invoke testit   ;Test if outside the set (TRUE)  
      .IF !outside  ; and plot inside points only Set X,Y coordinates for plotting 
        mov x,edi
        fild x
        fmul  scaleX
        fiadd x_offset  ;X coordinate = (x + x_offset)
        fistp x

        mov y,esi
        fild y
        fmul  scaleY   ;Y coordinate = (y - y_offset
        fisub y_offset
        fistp y

        invoke  SetPixel, hdc, x, y, colour ;Draw the fractal  
      .ENDIF
      dec edi
    .ENDW
    dec esi
  .ENDW    
  invoke EndPaint,hWnd, ADDR ps
.else
  invoke DefWindowProc,hWnd,uMsg,wParam,lParam
  ret;不能去掉。
.endif
xor eax,eax;这两行可以去掉?
ret
liuchunli endp

start: invoke GetModuleHandle,0
mov hInstance,eax
mov pwndclassex+20,eax

invoke LoadCursor,0,32512;加载箭头鼠标。
mov pwndclassex+28,eax

invoke RegisterClassEx,addr pwndclassex
invoke CreateWindowEx,200h,offset szClassName,offset szClassName,0Cf0000h,80000000h,80000000h,80000000h,80000000h,0,0,hInstance,0;0Ca0000h
mov hWinMain,eax

invoke ShowWindow,hWinMain,1;若不想显示,此行也可以去掉。
again:invoke GetMessage,addr stMsg,0,0,0
  cmp eax,0
  je exit
  invoke DispatchMessage,addr stMsg
jmp again

exit:invoke ExitProcess,0
end start
;made at 2011.09.24 

没有评论:

发表评论