📄 bezier.asm
字号:
;-----------------------------------------
; Bezier.asm -- Bezier Slines Demo
; based on Charles Petzold's Bezier.C
; Translated into assembly 7/4/99 by
; Ron Thomas Ron_Thom@Compuserve.com
;-----------------------------------------
.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
PolyBezier PROTO STDCALL hdc:DWORD, apt:DWORD, num:DWORD
DrawBezier PROTO STDCALL hdc:DWORD, apt:POINT
WHITE_PEN EQU 6
BLACK_PEN EQU 7
MK_LBUTTON EQU 1
MK_RBUTTON EQU 2
.data
ClassName db "SimpleWinClass",0
AppName db "Bezier Splines",0
BezPoints STRUCT ; 4 pairs of DWORD coordinates (x,y), (8 bytes/pair)
Spt POINT {} ; Line start point
Cp1 POINT {} ; Control point 1
Cp2 POINT {} ; Control point 2
Ept POINT {} ; Line end point
BezPoints ENDS
apt BezPoints {}
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
LOWORD MACRO ;; Retrieves the low word from double word lParam
mov eax,lParam
and eax,0FFFFh ;; Set cxClient to low word
ENDM
HIWORD MACRO ;; Retrieves the high word from double word lParam
mov ebx,lParam
shr ebx,16 ;; Shift 16 for high word to set cyClient to high word
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 hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
mov eax,uMsg
.IF eax==WM_SIZE ; lParam gives new window size in cxClient & cyClient
LOWORD ; Get low word from lParam in eax (cxClient)
HIWORD ; Get high " " " ebx (cyClient)
; Set the End points [apt(0) & apt(3)] and Control points [apt(1) &apt(2)]
; (Coord pairs are at offsets of 0,8,16 and 24 bytes in apt)
shr eax,2
mov apt.Spt.x,eax ; Set to cxClient/4 ;
shr ebx,1 ; 1st end Point
mov apt.Spt.y,ebx ; Set to cyClient/2 ;
mov apt.Ept.y,ebx ; y coord 2nd end point
shl eax,1
mov apt.Cp1.x,eax ; Set to cxClient/2 ; x coords for control points
mov apt.Cp2.x,eax ; ; 1 and 2
shr ebx,1
mov apt.Cp1.y,ebx ; Set to cyClient/4 ; y coord CP 1
add ebx,apt.Spt.y ; Add cyClient/2 to cyClient/4
mov apt.Cp2.y,ebx ; Set to 3*cyClient/4 ; y coord CP 2
mov eax,apt.Cp1.x
add eax,apt.Spt.x ; Add cxClient/2 to cxClient/4
mov apt.Ept.x,eax ; Set to 3*cxClient/4 ; y coord 2nd end point
.ELSEIF eax==WM_LBUTTONDOWN || eax==WM_RBUTTONDOWN || eax==WM_MOUSEMOVE
.IF (wParam & MK_LBUTTON) || (wParam & MK_RBUTTON)
invoke GetDC, hWnd
mov hdc,eax
invoke GetStockObject, WHITE_PEN
invoke SelectObject, hdc,eax
invoke DrawBezier, hdc, apt ; Paint out the bezier curve
.IF (wParam & MK_LBUTTON)
LOWORD ; With mouse functions, lParam returns
HIWORD ; the cursor coordinates in cxClient & cyClient
mov apt.Cp1.x,eax ; Reset Control Point 1
mov apt.Cp1.y,ebx ;
.ENDIF
.IF (wParam & MK_RBUTTON)
LOWORD
HIWORD
mov apt.Cp2.x,eax ; Reset Control Point 2
mov apt.Cp2.y,ebx ;
.ENDIF
invoke GetStockObject, BLACK_PEN
invoke SelectObject, hdc,eax
invoke DrawBezier, hdc, apt ; Draw the bezier curve
invoke ReleaseDC, hWnd,hdc
.ENDIF
.ELSEIF eax==WM_PAINT
invoke InvalidateRect, hWnd, NULL, TRUE
invoke BeginPaint, hWnd, ADDR ps
mov hdc,eax ; Obtain the handle to device context before
; selecting GDI object into it
invoke DrawBezier, hdc, apt
invoke EndPaint, hWnd, ADDR ps
.ELSEIF eax==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSE
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
DrawBezier PROC Hdc:DWORD, aapt:POINT
invoke PolyBezier, Hdc, ADDR aapt, 4
invoke MoveToEx, Hdc, apt.Spt.x, apt.Spt.y, NULL ; Set start point for line
invoke LineTo, Hdc, apt.Cp1.x, apt.Cp1.y ; from CP 1 to 1st end point
invoke MoveToEx, Hdc, apt.Cp2.x, apt.Cp2.y, NULL ; Set start point for line
invoke LineTo, Hdc, apt.Ept.x, apt.Ept.y ; from CP 2 to 2nd end point
ret
DrawBezier ENDP
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -