📄 lover.asm
字号:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Programmed by 罗云彬, bigluo@telekbird.com.cn
; Website: http://asm.yeah.net
; LuoYunBin's Win32 ASM page (罗云彬的编程乐园)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 版本信息
; 月下情人简单动画 Ver 1.0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat, stdcall
option casemap :none ; case sensitive
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc
include comdlg32.inc
include shell32.inc
include gdi32.inc
include advapi32.inc
includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib
includelib shell32.lib
includelib gdi32.lib
includelib advapi32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
IDI_MAIN equ 1000 ;icon
BMP_GROUND equ 2000
BMP_MOON equ 2001
BMP_PIG equ 2002
BMP_STAR1 equ 2003
BMP_STAR2 equ 2004
BMP_STAR3 equ 2005
DLG_SETUP equ 3000
IDC_STAR1 equ 3001
IDC_STAR2 equ 3002
IDC_STAR3 equ 3003
IDC_TIME1 equ 3004
IDC_TIME2 equ 3005
IDC_ABOUT equ 3006
IDM_MAIN equ 4000
IDM_SETUP equ 4001
IDM_ABOUT equ 4002
IDM_EXIT equ 4003
DW_PIG_ADJY equ 45
TIMER_MOON equ 1
TIMER_BACK equ 2
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hIcon dd ?
hInstance dd ?
hWinMain dd ?
hMenu dd ?
;********************************************************************
; DC 句柄
;********************************************************************
hDcBack dd ?
hDcPicture dd ?
hDcGround dd ?
hDcGroundMask dd ?
hDcMoon dd ?
hDcMoonMask dd ?
hDcPig dd ?
hDcPigMask dd ?
;********************************************************************
; Bmp 句柄
;********************************************************************
hBmpBack dd ?
hBmpPicture dd ?
hBmpGround dd ?
hBmpGroundMask dd ?
hBmpMoon dd ?
hBmpMoonMask dd ?
hBmpPig dd ?
hBmpPigMask dd ?
;********************************************************************
; 图片及窗口大小
;********************************************************************
dwWidth dd ? ;窗口大小
dwHeight dd ?
dwPigWidth dd ? ;图片大小
dwPigHeight dd ?
dwGroundWidth dd ?
dwGroundHeight dd ?
dwMoonWidth dd ?
dwMoonHeight dd ?
;********************************************************************
; 图片各部分的坐标
;********************************************************************
dwPigOffsetX dd ?
dwPigOffsetY dd ? ;图片Y方向开始坐标
dwGroundOffsetY dd ?
dwMoonOffsetY dd ?
;********************************************************************
; 随时间变化的值
;********************************************************************
dwMoonOffsetX dd ?
dwBackOffsetX dd ?
dwTimerMoonNow dd ? ;现在月亮位置
dwTimerBackNow dd ? ;现在星空位置
dwRandom dd ?
;********************************************************************
dwTimerMoonMax dd ? ;循环时间
dwTimerBackMax dd ?
dwStar1 dd ? ;大星星
dwStar2 dd ? ;中星星
dwStar3 dd ? ;小星星
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
szClassName db "LoverMovie",0
szCaptionMain db '月下情人 - http://asm.yeah.net',0
szKeyName db 'Software\Lyb Software\LoverScreenSaver',0
szKeyStar1 db 'Big Stars',0
szKeyStar2 db 'Stars',0
szKeyStar3 db 'Small Stars',0
szKeyTime1 db 'Moon circle Time',0
szKeyTime2 db 'Star circle Time',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
include Win.asm
include Graphic.asm
include Reg.asm
include About.asm
;********************************************************************
; 随机数发生器
; 输入:eax = 随机数最大值
; 返回:eax = 随机数
;********************************************************************
_Random proc uses ebx ecx edx
push eax
mov cl,32
xor eax,eax
mov bl,byte ptr dwRandom
and bl,1
Gen_bit: ; make n bit numbers
shl eax,1
mov edx,dwRandom ; Copy seed
shr edx,9
xor bl,dl
shr edx,5
xor bl,dl
bt ebx,1 ; Copy bit 1 to carry flag
rcr dwRandom,1 ; Rotate seed right 1 bit
setc bl ; Set bl TRUE if carry is set
or al,bl
dec cl
jnz Gen_bit
pop ecx
mul ecx
mov eax,edx
ret
_Random endp
;********************************************************************
SetupDialogProc proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
local @dwTemp
mov eax,wMsg
;********************************************************************
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
;********************************************************************
.elseif eax == WM_INITDIALOG
invoke _CenterWindow,hWnd
call _GetConfig
;********************************************************************
invoke SendDlgItemMessage,hWnd,IDC_STAR1,EM_LIMITTEXT,2,NULL
invoke SendDlgItemMessage,hWnd,IDC_STAR2,EM_LIMITTEXT,2,NULL
invoke SendDlgItemMessage,hWnd,IDC_STAR3,EM_LIMITTEXT,2,NULL
invoke SendDlgItemMessage,hWnd,IDC_TIME1,EM_LIMITTEXT,2,NULL
invoke SendDlgItemMessage,hWnd,IDC_TIME2,EM_LIMITTEXT,2,NULL
;********************************************************************
invoke SetDlgItemInt,hWnd,IDC_STAR1,dwStar1,FALSE
invoke SetDlgItemInt,hWnd,IDC_STAR2,dwStar2,FALSE
invoke SetDlgItemInt,hWnd,IDC_STAR3,dwStar3,FALSE
mov eax,dwTimerMoonMax
xor edx,edx
mov ecx,600
div ecx
invoke SetDlgItemInt,hWnd,IDC_TIME1,eax,FALSE
mov eax,dwTimerBackMax
xor edx,edx
mov ecx,600
div ecx
invoke SetDlgItemInt,hWnd,IDC_TIME2,eax,FALSE
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if eax == IDOK
;********************************************************************
invoke GetDlgItemInt,hWnd,IDC_STAR1,addr @dwTemp,FALSE
.if eax < 1
mov eax,1
.endif
.if eax > 50
mov eax,50
.endif
mov dwStar1,eax
;********************************************************************
invoke GetDlgItemInt,hWnd,IDC_STAR2,addr @dwTemp,FALSE
.if eax < 1
mov eax,1
.endif
.if eax > 99
mov eax,99
.endif
mov dwStar2,eax
;********************************************************************
invoke GetDlgItemInt,hWnd,IDC_STAR3,addr @dwTemp,FALSE
.if eax < 1
mov eax,1
.endif
.if eax > 99
mov eax,99
.endif
mov dwStar3,eax
;********************************************************************
invoke GetDlgItemInt,hWnd,IDC_TIME1,addr @dwTemp,FALSE
.if eax < 1
mov eax,1
.endif
.if eax > 60
mov eax,60
.endif
mov ecx,600
mul ecx
mov dwTimerMoonMax,eax
;********************************************************************
invoke GetDlgItemInt,hWnd,IDC_TIME2,addr @dwTemp,FALSE
.if eax < 5
mov eax,5
.endif
.if eax > 60
mov eax,60
.endif
mov ecx,600
mul ecx
mov dwTimerBackMax,eax
;********************************************************************
call _SaveConfig
invoke EndDialog,hWnd,NULL
call _InitValue
call _CreatePic
;********************************************************************
.elseif eax == IDCANCEL
invoke EndDialog,hWnd,NULL
;********************************************************************
.elseif eax == IDC_ABOUT
invoke DialogBoxParam,hInstance,DLG_ABOUT,hWnd,offset AboutDialogProc,DLG_ABOUT
.endif
.else
;********************************************************************
; 注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息
; 要返回 FALSE
;********************************************************************
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
SetupDialogProc endp
;********************************************************************
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 程序开始
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
call _WinMain
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 主窗口程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain proc
local @stWcMain:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke LoadIcon,hInstance,IDI_MAIN
mov hIcon,eax
invoke LoadMenu,hInstance,IDM_MAIN
mov hMenu,eax
;*************** 注册窗口类 *****************************************
invoke LoadCursor,0,IDC_ARROW
mov @stWcMain.hCursor,eax
mov @stWcMain.cbSize,sizeof WNDCLASSEX
mov @stWcMain.hIconSm,0
mov @stWcMain.style,CS_HREDRAW or CS_VREDRAW
mov @stWcMain.lpfnWndProc,offset WndMainProc
mov @stWcMain.cbClsExtra,0
mov @stWcMain.cbWndExtra,0
mov eax,hInstance
mov @stWcMain.hInstance,eax
mov @stWcMain.hIcon,0
mov @stWcMain.hbrBackground,COLOR_BACKGROUND
mov @stWcMain.lpszClassName,offset szClassName
mov @stWcMain.lpszMenuName,0
invoke RegisterClassEx,addr @stWcMain
;*************** 建立输出窗口 ***************************************
invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
offset szClassName,offset szCaptionMain,\
WS_OVERLAPPEDWINDOW,\
0,0,640,480,\
NULL,hMenu,hInstance,NULL
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
;*************** 消息循环 *******************************************
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WndMainProc proc uses ebx edi esi, \
hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
local @stPs:PAINTSTRUCT,@hDc
mov eax,uMsg
.if eax == WM_CREATE
mov eax,hWnd
mov hWinMain,eax
call _Init
;********************************************************************
.elseif eax == WM_TIMER
call _CreatePic
invoke InvalidateRect,hWinMain,NULL,FALSE ;刷新屏幕
;********************************************************************
.elseif eax == WM_CLOSE
call _Quit
;********************************************************************
.elseif eax == WM_COMMAND
mov eax,wParam
.if eax == IDM_EXIT
call _Quit
.elseif eax == IDM_ABOUT
invoke DialogBoxParam,hInstance,DLG_ABOUT,hWnd,offset AboutDialogProc,DLG_ABOUT
.elseif eax == IDM_SETUP
invoke DialogBoxParam,hInstance,DLG_SETUP,hWnd,offset SetupDialogProc,DLG_SETUP
.endif
;********************************************************************
.elseif eax == WM_SIZE
invoke DeleteObject,hBmpBack
invoke DeleteObject,hBmpPicture
invoke DeleteDC,hDcBack
invoke DeleteDC,hDcPicture
call _InitValue
call _CreatePic
invoke InvalidateRect,hWinMain,NULL,FALSE ;刷新屏幕
;********************************************************************
.elseif eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPs
mov @hDc,eax
mov eax,@stPs.rcPaint.right
sub eax,@stPs.rcPaint.left
mov ecx,@stPs.rcPaint.bottom
sub ecx,@stPs.rcPaint.top
invoke BitBlt,@hDc,@stPs.rcPaint.left,@stPs.rcPaint.top,eax,ecx,\
hDcPicture,@stPs.rcPaint.left,@stPs.rcPaint.top,SRCCOPY
invoke EndPaint,hWnd,addr @stPs
;********************************************************************
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
;********************************************************************
; 注意:WndProc 处理 Windows 消息后,必须在 Eax 中返回 0
; 但是由 DefWindowProc 处理后的返回值不能改变,否则窗口
; 将无法显示!
;********************************************************************
xor eax,eax
ret
WndMainProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 主窗口控制子程序
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_Init proc
local @hDc,@dwWidth,@dwHeight
local @stBmp:BITMAP
invoke GetTickCount
mov dwRandom,eax
invoke SendMessage,hWinMain,WM_SETICON,ICON_SMALL,hIcon
invoke _CenterWindow,hWinMain
call _GetConfig
;********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -