⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 invcircs.asm

📁 masm32 汇编源码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;-----------------------------------------------
;    Inversion of a rectangular array of circles
						
;	by	Ron Thomas
 	
;	Ron_Thom@Compuserve.com 15/7/99	
;-----------------------------------------------

.386				; 32 bit when .386 appears before .MODEL
.MODEL FLAT,STDCALL

include windows.inc

include user32.inc
include kernel32.inc
include gdi32.inc

includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib

WinMain		PROTO :DWORD, :DWORD, :DWORD, :SDWORD     	
	
.data

inverted    =   FALSE

numCols		EQU	16
numRows		EQU	11


Total_no_circles EQU numRows*numCols*2+1 ; 2 * # in rectangular matrix + 1 (inversion circle)
	
ClassName db "SimpleWinClass",0
AppName   db "Circle Inversion:   Press any key to see the transform",0

;	Set up a structure to hold data for all created circles
;	Floating point numbers are used so that precision is not lost by
;	rounding action as in the case of integer computation of radii etc
  
Circle$	STRUCT	4	; Align for fastest speed 
   
X_Coord	real4	?	; X and Y coordinates for the circle centre	 
Y_Coord real4	?	; 
Fradius	real4	?	; Radius 
Ccolour	DD	?	; Circle colour

Circle$	ENDS		; End of circle template

circles	Circle$	Total_no_circles DUP ({})	; Provide storage for circle data


circles_made	DW	0	; (No of circles made by inversion)*4

.data?

hInstance HINSTANCE ?
CommandLine LPSTR ?

delta_X		real4	?
delta_Y		real4	?	; Storage for computational constants
sin_beta	real4	?	;
cos_beta	real4	?	;
SL_prime	real4	?	;
SM_prime	real4	?	;
radius_cos_beta	real4	?	; radius*cos(beta)
radius_sin_beta	real4	?	; radius*sin(beta)

cxClient	DD	?
cyClient	DD	?
colour		DD	?
x1		DD	?
x2		DD	?
y1		DD	?
y2		DD	?
cDiam		DD	?
temp		DD	?
XC		DW	?	; Screen centre location
YC		DW	?
last		dw	?
tmp		dw	?
	
.const

two		real4	2.0
three		DW	3
first		DW	16	; Offset to 1st circle in the rectangular array

;MACRO's

LOWORD	MACRO 	bigword	;; Retrieves the low word from double word argument

	mov	eax,bigword
	and	eax,0FFFFh	;; Set to low word 
	ENDM

HIWORD	MACRO   bigword	;; Retrieves the high word from double word argument

	mov	ebx,bigword
	shr	ebx,16		;; Shift 16 for high word to set to high word
				
	ENDM

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

CIRCOLOUR MACRO	red, green, blue			;; Set the circle colours for any one row 
 
	  RGB	red, green, blue	 
	  invoke CreateSolidBrush, eax

	  mov	esi,0

	  .WHILE esi < numCols	

	  mov	 circles.Ccolour[ebx],eax
	  add	ebx,16
	  inc	esi

	  .ENDW

	  ENDM
;----------------------------------------------------------------------------
.code

start:
	invoke GetModuleHandle, NULL
	mov    hInstance,eax
	invoke GetCommandLine
        invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
	invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD

	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
        LOCAL hwnd:HWND
	mov   wc.cbSize,SIZEOF WNDCLASSEX
	mov   wc.style, CS_HREDRAW or CS_VREDRAW
	mov   wc.lpfnWndProc, OFFSET WndProc
	mov   wc.cbClsExtra,NULL
	mov   wc.cbWndExtra,NULL
        push  hInstance
        pop   wc.hInstance
	mov   wc.hbrBackground,COLOR_WINDOW+1 
	mov   wc.lpszMenuName,NULL
	mov   wc.lpszClassName,OFFSET ClassName
        invoke LoadIcon,NULL,IDI_APPLICATION
	mov   wc.hIcon,eax
        mov   wc.hIconSm,0
        invoke LoadCursor,NULL,IDC_ARROW
	mov   wc.hCursor,eax 
        invoke RegisterClassEx, addr wc
        INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
        mov   hwnd,eax
        INVOKE ShowWindow, hwnd,SW_SHOWNORMAL
        INVOKE UpdateWindow, hwnd
        .WHILE TRUE
                INVOKE GetMessage, ADDR msg,NULL,0,0
                .BREAK .IF (!eax)
                INVOKE TranslateMessage, ADDR msg
                INVOKE DispatchMessage, ADDR msg
        .ENDW
        mov     eax,msg.wParam
        ret
WinMain endp

WndProc proc uses ebx esi edi, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

        LOCAL hdc:HDC, ps:PAINTSTRUCT, msg:MSG, whiteBrush:HBRUSH, redBrush:HBRUSH
	      
	mov   eax,uMsg

	.IF	eax==WM_CREATE

  	  RGB	 255, 0, 0			; Colour red
	  invoke CreateSolidBrush, eax
	  mov	 redBrush,eax

;	Set colour for each row of circles

	  mov	 ebx,16				; Initialise to 1st circle on 1st row

	  CIRCOLOUR 255, 0, 0			; Red row
	  CIRCOLOUR 0, 255, 0			; Green
	  CIRCOLOUR 0, 0, 255			; Blue
	  CIRCOLOUR 255, 255, 0			; Yellow
	  CIRCOLOUR 0, 255, 255			; Cyan
	  CIRCOLOUR 255, 0, 255			; Magenta
	  CIRCOLOUR 255, 0, 125
	  CIRCOLOUR 128, 255, 128
	  CIRCOLOUR 255, 128, 128
	  CIRCOLOUR 128, 128, 255
	  CIRCOLOUR 255, 255, 128
	  
	.ELSEIF eax==WM_SIZE
	
	  LOWORD  lParam
	  mov	cxClient,eax
	  
	  shr	eax,4				; Set diameter to 1/16 of screen width 
	  mov	cDiam,eax
	  	  		  
	  HIWORD  lParam
	  mov	cyClient,ebx

	  mov	eax,cxClient			
	  shr	eax,1				; Set inversion circle at centre of screen
	  mov	XC,ax				; and save integer coordinates
	  shr	ebx,1				;
	  mov	YC,bx				; 

	  finit					; Initialise the coprocessor

	  fild	XC
	  fstp	circles.X_Coord			; Store FP values for base circle centre
	  fild	YC				; coordinates
	  fstp	circles.Y_Coord

	  mov	ax,YC			
	  shl	ax,1			; Sets R(b)=2/3 screen
	  xor	dx,dx			;
	  div	three			; 
	  mov	tmp,ax			; 
	  fild	tmp
	  
	  fstp	circles.Fradius		; Store radius of base circle as a real number

        .ELSEIF eax==WM_PAINT
 
	  invoke  InvalidateRect, hWnd, NULL, TRUE	; Request a full repaint	

	  invoke  BeginPaint,hWnd, ADDR ps
	  mov     hdc,eax

	  mov	y1,0
	  mov	y2,0

 	  mov	ebx,16			; set circle index to 1st colomn of row 1
	  mov	edi,0			; Row index

	.WHILE	edi  <= numRows-1

	  mov	x1,0			; Start on left hand side 

	  mov	eax,cDiam

	  .IF	edi==0
	    inc	eax
	  .ENDIF

	  add	y2,eax			; Set y2 boundary
	  
	  mov	esi,1			; Column index

	  .WHILE  esi <= numCols
	  		  
	    mov	eax,cDiam		; Get circle diameter
	    mov	edx,0
	    mul	esi

	    .IF	esi != numCols
	      inc	eax		; boundary to just touch  
	    .ENDIF

	    mov	x2,eax			; Set x2 boundary

 	    invoke  SelectObject, hdc, circles.Ccolour[ebx]
	    invoke  Ellipse, hdc, x1, y1, x2, y2

	    mov	  eax,x1
	    add	  eax,x2
	    mov	  temp,eax
	    fild  temp
	    fdiv  two
	    fstp  circles.X_Coord[ebx]	; circle-centre x-coord

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -