Написано под влиянием программы manhunter Эффект водной поверхности на Ассемблере. За это manhunter'у огромный респект и уважуха! Переделано с диалекта FASM 32-разряда на 64-разрядный MASM. asm-файл Код (ASM): ; GUI # include win64a.inc ID_IMG = 101 ID_BMP = 102 IDC_DIALOG = 200 DIB_RGB_COLORS = 0 F_WO_ACTIVE = 1 F_WO_NEED_UPDATE= 2 F_WO_EFFECT = 4 F_WO_ELLIPSE = 8 RGBQUAD struct rgbBlue db ? rgbGreen db ? rgbRed db ? rgbReserved db ? RGBQUAD ends BITMAPINFO struct bmiHeader BITMAPINFOHEADER <> bmiColors RGBQUAD <> BITMAPINFO ends WAVE_OBJECT struct hWnd QWORD ? dwFlag DWORD ? hDcRender QWORD ? hBmpRender QWORD ? lpDIBitsSource QWORD ? lpDIBitsRender QWORD ? lpWave1 QWORD ? lpWave2 QWORD ? dwBmpWidth DWORD ? dwBmpHeight DWORD ? dwDIByteWidth DWORD ? dwWaveByteWidth DWORD ? dwRandom DWORD ? dwEffectType DWORD ? dwEffectParam1 DWORD ? dwEffectParam2 DWORD ? dwEffectParam3 DWORD ? dwEff2X DWORD ? dwEff2Y DWORD ? dwEff2XAdd DWORD ? dwEff2YAdd DWORD ? dwEff2Flip DWORD ? stBmpInfo BITMAPINFO <> WAVE_OBJECT ends .code WinMain PROC enter 30h,0 and qword ptr[rsp+20h],0 invoke DialogBoxParamA,IMAGE_BASE,IDC_DIALOG,HWND_DESKTOP,&DialogProc invoke RtlExitUserProcess,0 WinMain ENDP DialogProc proc hwnddlg:qword,msg:qword,wparam:qword,lparam:qword local hBitmap:QWORD mov hwnddlg,rcx mov wparam,r8 mov lparam,r9 for msg,<INITDIALOG,CLOSE,COMMAND,PAINT,LBUTTONDOWN,MOUSEMOVE> cmp edx,WM_&msg je wm&msg endm jmp processed wmINITDIALOG:invoke LoadBitmapA,IMAGE_BASE,ID_BMP; Загрузить битмап mov hBitmap,rax invoke GetDlgItem,hwnddlg,ID_IMG invoke _WaveInit,&stWaveObj,eax,hBitmap; Инициализация водной поверхности invoke DeleteObject,hBitmap mov qword ptr[rsp+20h],250 invoke _WaveEffect,&stWaveObj,1,5,4; Настроить эффекты jmp finish wmPAINT:invoke invoke GetDlgItem,hwnddlg,ID_IMG invoke GetDC,eax invoke _WaveUpdateFrame,&stWaveObj,eax,TRUE jmp processed wmLBUTTONDOWN:mov r8,r9;получить координаты клика левой кнопкой мышки movzx edx,r9w ; x shr r8,16 ; y mov qword ptr[rsp+20h],256 invoke _WaveDropStone,&stWaveObj,,,2 invoke ReleaseCapture; Перетаскивание окна за любое место invoke SendMessageA,hwnddlg,WM_SYSCOMMAND,SC_MOVE + HTCAPTION,0 jmp processed wmMOUSEMOVE:mov r8,r9;координаты курсора мыши при движении над изображением movzx edx,r8w ; x shr r8,16 ; y mov qword ptr[rsp+20h],256 invoke _WaveDropStone,&stWaveObj,,,2 jmp processed wmCOMMAND:cmp wparam,BN_CLICKED shl 16 + IDCANCEL jne processed wmCLOSE:invoke _WaveFree,&stWaveObj invoke EndDialog,hwnddlg,0 processed:xor eax,eax finish: leave retn DialogProc endp _WaveInit proc _lpWaveObject:QWORD,_hWnd:QWORD,_hBmp:QWORD local dummy[10]:qword local dwReturn:DWORD local stBmp:BITMAP local temp:qword mov _lpWaveObject,rcx mov _hWnd,rdx mov _hBmp,r8 xor eax,eax and dwReturn,eax mov rbx,rcx mov rdi,rcx mov ecx,(sizeof WAVE_OBJECT)/4 rep stosd mov [rbx].WAVE_OBJECT.hWnd,rdx;_hWnd invoke GetTickCount mov [rbx].WAVE_OBJECT.dwRandom,eax invoke GetObject,_hBmp,sizeof BITMAP,&stBmp or eax,eax jnz loc_endif_1 @@: inc dwReturn jmp .Ret loc_endif_1:mov eax,stBmp.bmHeight mov [rbx].WAVE_OBJECT.dwBmpHeight,eax cmp eax,3 jle @b mov eax,stBmp.bmWidth mov [rbx].WAVE_OBJECT.dwBmpWidth,eax cmp eax,3 jle @b push rax shl eax,2 mov [rbx].WAVE_OBJECT.dwWaveByteWidth,eax pop rax lea eax,[rax+rax*2+3] and eax,not 0011b mov [rbx].WAVE_OBJECT.dwDIByteWidth,eax invoke GetDC,_hWnd mov esi,eax invoke CreateCompatibleDC,eax mov [rbx].WAVE_OBJECT.hDcRender,rax invoke CreateCompatibleBitmap,esi,[rbx].WAVE_OBJECT.dwBmpWidth,\ [rbx].WAVE_OBJECT.dwBmpHeight mov [rbx].WAVE_OBJECT.hBmpRender,rax invoke SelectObject,[rbx].WAVE_OBJECT.hDcRender,rax mov eax,[rbx].WAVE_OBJECT.dwWaveByteWidth mul [rbx].WAVE_OBJECT.dwBmpHeight mov edi,eax invoke GlobalAlloc,GPTR,edi mov [rbx].WAVE_OBJECT.lpWave1,rax invoke GlobalAlloc,GPTR,edi mov [rbx].WAVE_OBJECT.lpWave2,rax mov eax,[rbx].WAVE_OBJECT.dwDIByteWidth mul [rbx].WAVE_OBJECT.dwBmpHeight mov edi,eax invoke GlobalAlloc,GPTR,edi mov [rbx].WAVE_OBJECT.lpDIBitsSource,rax invoke GlobalAlloc,GPTR,edi mov [rbx].WAVE_OBJECT.lpDIBitsRender,rax mov [rbx].WAVE_OBJECT.stBmpInfo.bmiHeader.biSize,sizeof BITMAPINFOHEADER mov eax,[rbx].WAVE_OBJECT.dwBmpWidth mov [rbx].WAVE_OBJECT.stBmpInfo.bmiHeader.biWidth,eax mov eax,[rbx].WAVE_OBJECT.dwBmpHeight neg eax mov [rbx].WAVE_OBJECT.stBmpInfo.bmiHeader.biHeight,eax inc [rbx].WAVE_OBJECT.stBmpInfo.bmiHeader.biPlanes mov [rbx].WAVE_OBJECT.stBmpInfo.bmiHeader.biBitCount,24 mov [rbx].WAVE_OBJECT.stBmpInfo.bmiHeader.biCompression,BI_RGB and [rbx].WAVE_OBJECT.stBmpInfo.bmiHeader.biSizeImage,0 invoke CreateCompatibleDC,esi mov temp,rax invoke SelectObject,eax,_hBmp invoke ReleaseDC,_hWnd,esi mov rax,temp mov esi,eax and qword ptr[rsp+30h],DIB_RGB_COLORS lea eax,[rbx].WAVE_OBJECT.stBmpInfo mov [rsp+28h],rax mov rax,[rbx].WAVE_OBJECT.lpDIBitsSource mov [rsp+20h],rax invoke GetDIBits,esi,_hBmp,0,[rbx].WAVE_OBJECT.dwBmpHeight and qword ptr[rsp+30h],DIB_RGB_COLORS lea eax,[rbx].WAVE_OBJECT.stBmpInfo mov [rsp+28h],rax mov rax,[rbx].WAVE_OBJECT.lpDIBitsRender mov [rsp+20h],rax invoke GetDIBits,esi,_hBmp,0,[rbx].WAVE_OBJECT.dwBmpHeight invoke DeleteDC,esi cmp [rbx].WAVE_OBJECT.lpWave1,0 je @f cmp [rbx].WAVE_OBJECT.lpWave2,0 je @f cmp [rbx].WAVE_OBJECT.lpDIBitsSource,0 je @f cmp [rbx].WAVE_OBJECT.lpDIBitsRender,0 je @f cmp [rbx].WAVE_OBJECT.hDcRender,0 jnz loc_endif_2 @@: invoke _WaveFree,ebx inc dwReturn loc_endif_2:invoke SetTimer,_hWnd,ebx,30,&_WaveTimerProc or [rbx].WAVE_OBJECT.dwFlag,F_WO_ACTIVE or F_WO_NEED_UPDATE invoke _WaveRender,ebx invoke GetDC,[rbx].WAVE_OBJECT.hWnd invoke _WaveUpdateFrame,ebx,eax,TRUE invoke ReleaseDC,[rbx].WAVE_OBJECT.hWnd,eax .Ret: leave mov eax,dwReturn ret _WaveInit endp ; Установка или изменение типа и параметров эффекта ; _dwType = тип эффекта: ; 0 - нет никаких эффектов ; 1 - мелкий дождик ; 2 - глайдер ; 3 - проливной дождь ; _dwParam1 = скорость применения эффекта ; _dwParam2 = сила падения капель ; _dwParam3 = количество одновременных кругов на воде _WaveEffect proc _lpWaveObject:QWORD,_dwType:QWORD,_dwParam1:DWORD,_dwParam2:DWORD,_dwParam3:DWORD local dwMaxY:DWORD local dwMaxX:DWORD mov _dwType,rdx mov _dwParam1,r8d mov _dwParam2,r9d mov rbx,rcx mov rax,_dwType cmp eax,0 jne loc_else_1 and [rbx].WAVE_OBJECT.dwFlag,not F_WO_EFFECT mov [rbx].WAVE_OBJECT.dwEffectType,eax jmp loc_endif loc_else_1:cmp eax,2 jne loc_else_2 mov eax,_dwParam1 mov [rbx].WAVE_OBJECT.dwEff2XAdd,eax mov [rbx].WAVE_OBJECT.dwEff2YAdd,eax mov edx,[rbx].WAVE_OBJECT.dwBmpWidth sub edx,2 invoke _WaveRandom,rbx inc eax mov [rbx].WAVE_OBJECT.dwEff2X,eax mov edx,[rbx].WAVE_OBJECT.dwBmpHeight sub edx,2 invoke _WaveRandom,ebx inc eax mov [rbx].WAVE_OBJECT.dwEff2Y,eax loc_else_2:mov rax,_dwType mov [rbx].WAVE_OBJECT.dwEffectType,eax mov eax,_dwParam1 mov [rbx].WAVE_OBJECT.dwEffectParam1,eax mov eax,_dwParam2 mov [rbx].WAVE_OBJECT.dwEffectParam2,eax mov eax,_dwParam3 mov [rbx].WAVE_OBJECT.dwEffectParam3,eax or [rbx].WAVE_OBJECT.dwFlag,F_WO_EFFECT loc_endif:leave ret _WaveEffect endp ; Генераторы случайных чисел _WaveRandom16 proc _lpWaveObject:DWORD mov rbx,rcx push rdx mov eax,[rbx].WAVE_OBJECT.dwRandom mov ecx,32768-1 ; 2^15-1 mul ecx add eax,2048-1 ; 2^11-1 adc edx,0 mov ecx,2147483647 ; 2^31-1 div ecx mov eax,[rbx].WAVE_OBJECT.dwRandom mov [rbx].WAVE_OBJECT.dwRandom,edx and eax,0FFFFh pop rdx leave ret _WaveRandom16 endp _WaveRandom proc _lpWaveObject:QWORD, _dwMax:DWORD local temp:dword mov rbx,rcx mov _dwMax,edx push rcx push rdx invoke _WaveRandom16,rbx mov temp,eax invoke _WaveRandom16,rbx shl eax,16 or eax,temp mov ecx,_dwMax or ecx,ecx jz @f xor edx,edx div ecx mov eax,edx @@: pop rcx pop rdx leave ret _WaveRandom endp ; Перемешивание волн ; Wave2(x,y) = (Wave1(x+1,y)+Wave1(x-1,y)+Wave1(x,y+1)+Wave1(x,y-1))/2-Wave2(x,y) ; Wave2(x,y) = Wave2(x,y) - Wave2(x,y) >> 5 ; xchg Wave1,Wave2 _WaveSpread proc _lpWaveObject:QWORD mov rbx,rcx;_lpWaveObject test [rbx].WAVE_OBJECT.dwFlag,F_WO_ACTIVE jz .Ret mov rsi,[rbx].WAVE_OBJECT.lpWave1 mov rdi,[rbx].WAVE_OBJECT.lpWave2 mov ecx,[rbx].WAVE_OBJECT.dwBmpWidth mov eax,[rbx].WAVE_OBJECT.dwBmpHeight dec eax mul ecx jmp loc_while_chk loc_while:push rax test [rbx].WAVE_OBJECT.dwFlag,F_WO_ELLIPSE jz loc_else mov edx,[rsi+rcx*4-1*4] add edx,[rsi+rcx*4+1*4] add edx,[rsi+rcx*4-2*4] add edx,[rsi+rcx*4+2*4] lea edx,[rdx+rdx*2] add edx,[rsi+rcx*4-3*4] add edx,[rsi+rcx*4-3*4] add edx,[rsi+rcx*4+3*4] add edx,[rsi+rcx*4+3*4] lea eax,[rsi+rcx*4] sub eax,[rbx].WAVE_OBJECT.dwWaveByteWidth mov eax,[rax] shl eax,3 add edx,eax lea eax,[rsi+rcx*4] add eax,[rbx].WAVE_OBJECT.dwWaveByteWidth mov eax,[rax] shl eax,3 add edx,eax sar edx,4 sub edx,[rdi+rcx*4] mov eax,edx sar eax,5 sub edx,eax mov [rdi+rcx*4],edx jmp loc_endif loc_else:mov edx,[rsi+rcx*4-1*4] add edx,[rsi+rcx*4+1*4] lea eax,[rsi+rcx*4] sub eax,[rbx].WAVE_OBJECT.dwWaveByteWidth add edx,[rax] lea eax,[rsi+rcx*4] add eax,[rbx].WAVE_OBJECT.dwWaveByteWidth add edx,[rax] sar edx,1 sub edx,[rdi+rcx*4] mov eax,edx sar eax,5 sub edx,eax mov [rdi+rcx*4],edx loc_endif:pop rax inc ecx loc_while_chk:cmp ecx,eax jb loc_while mov [rbx].WAVE_OBJECT.lpWave1,rdi mov [rbx].WAVE_OBJECT.lpWave2,rsi .Ret: leave ret _WaveSpread endp ; Отрисовка волн ; posx = Wave1(x-1,y)-Wave1(x+1,y)+x ; posy = Wave1(x,y-1)-Wave1(x,y+1)+y ; SourceBmp(x,y) = DestBmp(posx,posy) _WaveRender proc _lpWaveObject:DWORD local dwFlag:DWORD local dwPtrSource:DWORD local dwPosY:DWORD local dwPosX:DWORD local temp:QWORD mov rbx,rcx and dwFlag,0 test [rbx].WAVE_OBJECT.dwFlag,F_WO_ACTIVE jz .Ret or [rbx].WAVE_OBJECT.dwFlag,F_WO_NEED_UPDATE mov rsi,[rbx].WAVE_OBJECT.lpWave1 mov edi,[rbx].WAVE_OBJECT.dwWaveByteWidth mov ecx,1 .Loop1: xor edx,edx .Loop2: mov temp,rdx mov eax,edi sub eax,[rbx].WAVE_OBJECT.dwWaveByteWidth mov eax,[rsi+rax] mov dwPosY,eax mov eax,[rbx].WAVE_OBJECT.dwWaveByteWidth lea eax,[rdi+rax] mov eax,[rsi+rax] sub dwPosY,eax add dwPosY,ecx mov eax,[rsi+rdi-4] sub eax,[rsi+rdi+4] add eax,edx ;@dwPosX = eax mov dwPosX,eax cmp eax,0 jl .Continue cmp eax,[rbx].WAVE_OBJECT.dwBmpWidth jge .Continue mov eax,dwPosY cmp eax,0 jl .Continue cmp eax,[rbx].WAVE_OBJECT.dwBmpHeight jge .Continue ; ptrSource = dwPosY * dwDIByteWidth + dwPosX * 3 ; ptrDest = i * dwDIByteWidth + j * 3 mov eax,dwPosX lea eax,[rax+rax*2] mov dwPosX,eax push rdx mov eax,dwPosY mul [rbx].WAVE_OBJECT.dwDIByteWidth add eax,dwPosX mov dwPtrSource,eax mov eax,ecx mul [rbx].WAVE_OBJECT.dwDIByteWidth pop rdx lea edx,[rdx+rdx*2] add eax,edx ;@dwPtrDest = eax push rcx push rdi push rsi mov ecx,dwPtrSource mov rsi,[rbx].WAVE_OBJECT.lpDIBitsSource mov rdi,[rbx].WAVE_OBJECT.lpDIBitsRender lea esi,[rsi+rcx] lea edi,[rdi+rax] cmp ecx,eax jz .loc_else or dwFlag,1 mov ecx,[rbx].WAVE_OBJECT.dwDIByteWidth .loc_else:movsd .loc_endif:pop rsi pop rdi pop rcx .Continue:mov rdx,temp inc edx add edi,4 cmp edx,[rbx].WAVE_OBJECT.dwBmpWidth jb .Loop2 inc ecx mov eax,[rbx].WAVE_OBJECT.dwBmpHeight dec eax cmp ecx,eax jb .Loop1 and qword ptr[rsp+30h],DIB_RGB_COLORS lea eax,[rbx].WAVE_OBJECT.stBmpInfo mov [rsp+28h],rax mov rax,[rbx].WAVE_OBJECT.lpDIBitsRender mov [rsp+20h],rax invoke SetDIBits,[rbx].WAVE_OBJECT.hDcRender,[rbx].WAVE_OBJECT.hBmpRender,\ 0,[rbx].WAVE_OBJECT.dwBmpHeight cmp dwFlag,0 jnz .Ret and [rbx].WAVE_OBJECT.dwFlag,not F_WO_ACTIVE .Ret: leave ret _WaveRender endp ; Обновление изображения _WaveUpdateFrame proc _lpWaveObject:QWORD,_hDc:QWORD,_bIfForce:QWORD local dummy[2]:qword mov rbx,rcx mov _hDc,rdx mov _bIfForce,r8 cmp _bIfForce,0 jnz @f test [rbx].WAVE_OBJECT.dwFlag, F_WO_NEED_UPDATE jz loc_endif @@: mov qword ptr[rsp+40h],SRCCOPY xor edx,edx mov [rsp+38h],rdx mov [rsp+30h],rdx mov rax,[rbx].WAVE_OBJECT.hDcRender mov [rsp+28h],rax mov eax,[rbx].WAVE_OBJECT.dwBmpHeight mov [rsp+20h],rax invoke BitBlt,_hDc,,0,[rbx].WAVE_OBJECT.dwBmpWidth and [rbx].WAVE_OBJECT.dwFlag,not F_WO_NEED_UPDATE loc_endif:leave ret _WaveUpdateFrame endp ; Отработка падения капли, например, по таймеру или при движении курсора _WaveDropStone proc _lpWaveObject:QWORD,_dwX:QWORD,_dwY:QWORD,_dwSize:QWORD,_dwWeight:QWORD local dwMaxY:DWORD local dwMaxX:DWORD mov rbx,rcx;_lpWaveObject mov _dwX,rdx mov _dwY,r8 mov _dwSize,r9 mov rdx,r9;_dwSize shr edx,1 mov rax,_dwX mov rsi,_dwY mov ecx,eax mov edi,esi add eax,edx ; x + size sub ecx,edx ; x - size push rdx test [rbx].WAVE_OBJECT.dwFlag,F_WO_ELLIPSE jz @f shr edx,1 @@: add esi,edx ; y + size sub edi,edx ; y - size pop rdx shl edx,1 or edx,edx jnz @f inc edx @@: mov _dwSize,rdx inc eax cmp eax,[rbx].WAVE_OBJECT.dwBmpWidth jge .Ret cmp ecx,1 jl .Ret inc esi cmp esi,[rbx].WAVE_OBJECT.dwBmpHeight jge .Ret cmp edi,1 jl .Ret dec eax dec esi mov dwMaxX,eax mov dwMaxY,esi jmp .loc_endw_1 .loc_while_1:push rdi jmp .loc_endw_2 .loc_while_2:mov eax,ecx sub rax,_dwX imul eax push rax mov eax,edi sub rax,_dwY imul eax pop rdx add eax,edx push rax mov rax,_dwSize imul eax pop rdx cmp edx,eax ja @f mov eax,edi mul [rbx].WAVE_OBJECT.dwBmpWidth add eax,ecx shl eax,2 add rax,[rbx].WAVE_OBJECT.lpWave1 push _dwWeight pop qword ptr [rax] @@: inc edi .loc_endw_2:cmp edi,dwMaxY jbe .loc_while_2 pop rdi inc ecx .loc_endw_1:cmp ecx,dwMaxX jbe .loc_while_1 or [rbx].WAVE_OBJECT.dwFlag,F_WO_ACTIVE .Ret: leave ret _WaveDropStone endp ; Вызов эффекта по таймеру _WaveTimerProc proc _hWnd:QWORD,_uMsg:QWORD,_idEvent:QWORD,_dwTime:QWORD local temp1:qword local temp2:qword local dummy[10]:qword mov _hWnd,rcx mov _uMsg,rdx mov _idEvent,r8 mov _dwTime,r9 mov rbx,r8;_idEvent invoke _WaveSpread,ebx invoke _WaveRender,ebx test [rbx].WAVE_OBJECT.dwFlag,F_WO_NEED_UPDATE jz @f invoke GetDC,[rbx].WAVE_OBJECT.hWnd invoke _WaveUpdateFrame,ebx,eax,FALSE invoke ReleaseDC,[rbx].WAVE_OBJECT.hWnd,eax @@: test [rbx].WAVE_OBJECT.dwFlag,F_WO_EFFECT jz .Ret mov eax,[rbx].WAVE_OBJECT.dwEffectType ; Type1 - мелкий дождь ; Param1 - скорость ; Param2 - сила падения капель ; Param3 - количество кругов на воде cmp eax,1 jne .loc_else_1 mov edx,[rbx].WAVE_OBJECT.dwEffectParam1 or edx,edx jz @f invoke _WaveRandom,ebx or eax,eax jnz .Ret @@: mov edx,[rbx].WAVE_OBJECT.dwBmpWidth sub edx,2 invoke _WaveRandom,ebx inc eax mov temp2,rax mov edx,[rbx].WAVE_OBJECT.dwBmpHeight sub edx,2 invoke _WaveRandom,ebx inc eax mov temp1,rax invoke _WaveRandom,ebx,[rbx].WAVE_OBJECT.dwEffectParam2 inc eax mov esi,eax invoke _WaveRandom,ebx,[rbx].WAVE_OBJECT.dwEffectParam3 add eax,50 mov [rsp+20h],rax invoke _WaveDropStone,ebx,temp2,temp1,esi jmp .loc_endif_1 ; Type2 - глайдер ; Param1 - скорость движения глайдера ; Param2 - сила волны ; Param3 - количество кругов на воде .loc_else_1:cmp eax,2 jne .loc_else_2 inc [rbx].WAVE_OBJECT.dwEff2Flip test [rbx].WAVE_OBJECT.dwEff2Flip,1 jnz .Ret mov ecx,[rbx].WAVE_OBJECT.dwEff2X mov edx,[rbx].WAVE_OBJECT.dwEff2Y add ecx,[rbx].WAVE_OBJECT.dwEff2XAdd add edx,[rbx].WAVE_OBJECT.dwEff2YAdd cmp ecx,1 jge @f sub ecx,1 neg ecx neg [rbx].WAVE_OBJECT.dwEff2XAdd @@: cmp edx,1 jge @f sub edx,1 neg edx neg [rbx].WAVE_OBJECT.dwEff2YAdd @@: mov eax,[rbx].WAVE_OBJECT.dwBmpWidth dec eax cmp ecx,eax jl @f sub ecx,eax xchg eax,ecx sub ecx,eax neg [rbx].WAVE_OBJECT.dwEff2XAdd @@: mov eax,[rbx].WAVE_OBJECT.dwBmpHeight dec eax cmp edx,eax jl @f sub edx,eax xchg eax,edx sub edx,eax neg [rbx].WAVE_OBJECT.dwEff2YAdd @@: mov [rbx].WAVE_OBJECT.dwEff2X,ecx mov temp1,rcx mov [rbx].WAVE_OBJECT.dwEff2Y,edx mov temp2,rdx mov eax,[rbx].WAVE_OBJECT.dwEffectParam3 mov [rsp+20h],rax invoke _WaveDropStone,ebx,temp1,temp2,[rbx].WAVE_OBJECT.dwEffectParam2 jmp .loc_endif_1 ; Type3 - проливной дождь ; Param1 - скорость ; Param2 - сила падения капель ; Param3 - количество кругов на воде .loc_else_2:cmp eax,3 jne .loc_endif_1 xor edi,edi jmp .loc_endw .loc_while:mov edx,[rbx].WAVE_OBJECT.dwBmpWidth sub edx,2 invoke _WaveRandom,ebx inc eax mov temp2,rax mov edx,[rbx].WAVE_OBJECT.dwBmpHeight sub edx,2 invoke _WaveRandom,ebx inc eax mov temp1,rax invoke _WaveRandom,ebx,[rbx].WAVE_OBJECT.dwEffectParam2 inc eax mov esi,eax invoke _WaveRandom,ebx,[rbx].WAVE_OBJECT.dwEffectParam3 mov [rsp+20h],rax invoke _WaveDropStone,ebx,temp2,temp1,esi inc edi .loc_endw:cmp edi,[rbx].WAVE_OBJECT.dwEffectParam1 jbe .loc_while .loc_endif_1: .Ret: leave ret _WaveTimerProc endp ; Освобождение ресурсов _WaveFree proc _lpWaveObject:DWORD mov rbx,rcx cmp [rcx].WAVE_OBJECT.hDcRender,0 je @f invoke DeleteDC,[rcx].WAVE_OBJECT.hDcRender @@: cmp [rbx].WAVE_OBJECT.hBmpRender,0 je @f invoke DeleteObject,[rbx].WAVE_OBJECT.hBmpRender @@: cmp [rbx].WAVE_OBJECT.lpDIBitsSource,0 je @f invoke GlobalFree,[rbx].WAVE_OBJECT.lpDIBitsSource @@: cmp [rbx].WAVE_OBJECT.lpDIBitsRender,0 je @f invoke GlobalFree,[rbx].WAVE_OBJECT.lpDIBitsRender @@: cmp [rbx].WAVE_OBJECT.lpWave1,0 je @f invoke GlobalFree,[rbx].WAVE_OBJECT.lpWave1 @@: cmp [rbx].WAVE_OBJECT.lpWave2,0 je @f invoke GlobalFree,[rbx].WAVE_OBJECT.lpWave2 @@: invoke KillTimer,[rbx].WAVE_OBJECT.hWnd,ebx xor eax,eax mov edi,ebx mov ecx,sizeof WAVE_OBJECT rep stosd leave ret _WaveFree endp .data stWaveObj WAVE_OBJECT <> end rc-файл Код (C++): #include "Resource.h" #define ID_IMG 101 #define ID_BMP 102 #define IDCANCEL 2 #define IDC_DIALOG 200 ID_BMP BITMAP "water.bmp" IDC_DIALOG DIALOG 0, 0, 346, 250 STYLE DS_CENTER | WS_POPUP | WS_MAXIMIZE | WS_DLGFRAME | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_DLGMODALFRAME CAPTION "Эффект дождя" FONT 10, "Arial" BEGIN CONTROL ID_BMP,ID_IMG,"STATIC", SS_BITMAP | WS_CHILD | WS_VISIBLE, 1, 1, 300, 223 CONTROL "Exit",IDCANCEL,"BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 120, 235, 90, 12 END во вложении asm-/rc-/exe-/bmp-файлы