Переделанная для masm x64 программа ManHunter'a Чтобы пламя красиво гасло, установим палитру так: Номер цвета0→6364→127128→134135→189190→255Цветчерныйкрасныйжелтыйярко- желтыйбелыйarc-файл Код (C++): #include "resource.h" #define ID_DIALOG 100 ID_DIALOG DIALOG 0, 0, 200, 144 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Fire Effect Demo" FONT 8, "MS Sans Serif" { CONTROL "Exit", IDCANCEL, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 148, 126, 50, 15 } asm-файл Код (ASM): ; GUI # include win64a.inc ; Размеры окна WINDOW_WIDTH equ 300 WINDOW_HEIGHT equ 202 ID_DIALOG equ 100 .code WinMain proc dummy:qword and qword ptr[rsp+20h],0 invoke DialogBoxParam,IMAGE_BASE,ID_DIALOG,HWND_DESKTOP,&DialogProc invoke RtlExitUserProcess,NULL WinMain endp ;--------------------------------------------- DialogProc proc hwnddlg:qword,msg:qword,wparam:qword,lparam:qword local ps:PAINTSTRUCT local hCompDC:qword local hBitmap:dword local hOldBitmap:qword mov hwnddlg,rcx cmp edx,WM_INITDIALOG je wmINITDIALOG cmp edx,WM_COMMAND je wmCOMMAND cmp edx,WM_CLOSE je wmCLOSE cmp edx,WM_TIMER je wmTIMER cmp edx,WM_PAINT je wmPAINT cmp edx,WM_LBUTTONDOWN jne wmBYE drag_window: ;Перетаскивание окна за любое место invoke ReleaseCapture invoke SendMessage,hwnddlg,WM_SYSCOMMAND,SC_MOVE or HTCAPTION,0 jmp wmBYE wmINITDIALOG:; Инициализация ГПСЧ invoke GetTickCount mov random_seed,eax ; Шрифт текста pushaddr szFont push FIXED_PITCH or FF_DONTCARE push PROOF_QUALITY push CLIP_DEFAULT_PRECIS push OUT_RASTER_PRECIS push ANSI_CHARSET push FALSE push FALSE push FALSE push FW_BOLD sub esp,20h invoke CreateFont,80,25,0,0 mov hFont,rax invoke GlobalAlloc,GMEM_ZEROINIT or GMEM_FIXED,256*4 mov palette,rax ; Заполнить палитру mov edi,eax;palette mov ecx,64;от 0 до 63 @@: mov eax,64 sub eax,ecx shl eax,2 stosd;eax от 0 до 63*4=0FC0000h (от черного к красному) loop @b mov ecx,64;от 64 к 127 @@: mov eax,64 sub eax,ecx shl eax,10 or al,0FFh stosd;eax от 0FF0000h до 0FF0200h (от красного к темно-желтому) loop @b mov ecx,64;от 128 к 191 @@: mov eax,64 sub eax,ecx shl eax,10 bswap eax or ax,0FFFFh stosd;eax от 0FFFF00h до 0FFFF76h (от желтого к белому) loop @b mov ecx,65;от 192 к 255 mov eax,0FFFFFFh rep stosd;белый ; Чем меньше интервал таймера, тем быстрее горит огонь invoke SetTimer,hwnddlg,1,50,NULL invoke GlobalAlloc,GMEM_ZEROINIT or GMEM_FIXED,WINDOW_WIDTH*WINDOW_HEIGHT mov px_data,rax jmp wmBYE wmTIMER:; Интервал между появлением текста cmp text_interval,0 jne @f ; Вывести текст на форму call FireText ; Следующая строка mov text_interval,100 mov ecx,pointer invoke lstrlen inc eax add pointer,eax ; Строки закончились? mov ecx,pointer invoke lstrlen or eax,eax jnz @f ; Перемотать указатель на начало списка mov pointer,offset text @@: dec text_interval ; Заполнить нижнюю линию изображения invoke WIRandom,WINDOW_WIDTH-1 inc eax xor edx,edx mov ecx,WINDOW_WIDTH xchg eax,ecx div ecx mov edi,eax mov esi,WINDOW_WIDTH*(WINDOW_HEIGHT-1) add esi,eax loc_fill:invoke WIRandom,100 mov rdx,px_data or bl,255 cmp eax,11 jbe @f and bl,0 cmp eax,19 jbe @f mov bl,[rdx+rsi-1] cmp eax,59 jbe @f mov bl,[rdx+rsi+1] @@: mov [rdx+rsi],bl inc esi inc edi cmp edi,(WINDOW_WIDTH-1) jb loc_fill ; Смиксовать ближайшие точки mov esi,WINDOW_WIDTH*(WINDOW_HEIGHT-1)-1 mov rdx,px_data loc_mix:movzx eax,byte ptr[rdx+rsi] add al,[rdx+rsi+WINDOW_WIDTH] adc ah,0 add al,[rdx+rsi+WINDOW_WIDTH+1] adc ah,0 add al,[rdx+rsi+WINDOW_WIDTH-1] adc ah,0 dec eax jns @f xor eax,eax @@: shr eax,2 mov [rdx+rsi],al dec esi jnz loc_mix ; Обновить содержимое окна invoke InvalidateRect,hwnddlg,NULL,NULL jmp wmBYE wmPAINT:invoke BeginPaint,,&ps mov hDC,rax invoke CreateCompatibleDC,eax mov hCompDC,rax invoke CreateCompatibleBitmap,hDC,WINDOW_WIDTH,WINDOW_HEIGHT mov hBitmap,eax invoke SelectObject,hCompDC,eax mov hOldBitmap,rax ; Перенести точки на холст mov esi,WINDOW_WIDTH*WINDOW_HEIGHT mov rdi,palette @@: mov rdx,px_data movzx ebx,byte ptr[rdx+rsi] xor edx,edx mov eax,esi mov ecx,WINDOW_WIDTH div ecx mov r8d,eax mov r9d,[rdi+rbx*4] invoke SetPixel,hCompDC dec esi jnz @b invoke SetBkMode,hDC,OPAQUE cmp text_interval,90 ja @f ; Шрифт invoke SelectObject,hCompDC,hFont invoke SetBkMode,hCompDC,TRANSPARENT ; Вывести текст на форму invoke SetTextColor,hCompDC,0 add rc.right,6 add rc.top,6 mov qword ptr [rsp+20h],DT_VCENTER or DT_CENTER or DT_NOPREFIX or DT_SINGLELINE mov edx,pointer invoke DrawText,hCompDC,,-1,&rc sub rc.right,6 sub rc.top,6 invoke SetTextColor,hCompDC,0FFFFFFh mov qword ptr [rsp+20h],DT_VCENTER or DT_CENTER or DT_NOPREFIX or DT_SINGLELINE mov edx,pointer invoke DrawText,hCompDC,,-1,&rc @@: xor edx,edx push SRCCOPY push rdx push rdx push hCompDC push WINDOW_HEIGHT-2 sub esp,20h invoke BitBlt,hDC,,0,WINDOW_WIDTH ; Прибраться за собой invoke SelectObject,hCompDC,hOldBitmap mov ecx,hBitmap invoke DeleteObject invoke DeleteDC,hCompDC invoke EndPaint,hwnddlg,&ps jmp wmBYE wmCOMMAND:cmp r8d,BN_CLICKED shl 16 + IDCANCEL jne wmBYE wmCLOSE:invoke EndDialog,,0 invoke GlobalFree,px_data invoke GlobalFree,palette wmBYE: xor eax,eax leave retn DialogProc endp FireText proc local hzCompDC:qword local hzBitmap:qword local hzDC:qword local zps:PAINTSTRUCT ; Нанести надпись invoke CreateCompatibleDC,NULL mov hzCompDC,rax invoke CreateCompatibleBitmap,eax,WINDOW_WIDTH,WINDOW_HEIGHT mov hzBitmap,rax invoke SelectObject,hzCompDC,eax invoke FillRect,hzCompDC,&rc,0 ; Шрифт invoke SelectObject,hzCompDC,hFont invoke SetTextColor,hzCompDC,0FF00h mov qword ptr [rsp+20h],DT_VCENTER or DT_CENTER or DT_NOPREFIX or DT_SINGLELINE mov edx,pointer invoke DrawText,hzCompDC,,-1,&rc ; Перенести точки на холст mov esi,WINDOW_WIDTH*WINDOW_HEIGHT @@: xor edx,edx mov eax,esi mov ecx,WINDOW_WIDTH div ecx invoke GetPixel,hzCompDC,,eax dec esi jz @f or eax,eax jne @b mov rdx,px_data or byte ptr [rdx+rsi+1],255 jmp @b @@: invoke DeleteObject,hzBitmap invoke DeleteDC,hzCompDC leave ret FireText endp ;--------------------------------------------- ; Park Miller random number algorithm ; Получить случайное число в нужном интервале от 1 до max ; на выходе EAX - случайное число ;--------------------------------------------- WIRandom proc rmax:dword mov rmax,ecx mov eax,random_seed or eax,eax ; Модификация против зацикливания генератора ; на случай если в random_seed будет нулевое значение jnz @f rdtsc xor eax,edx mov random_seed,eax @@: xor edx,edx mov ecx,127773 div ecx mov ecx,eax mov eax,16807 mul edx mov edx,ecx mov ecx,eax mov eax,2836 mul edx sub ecx,eax xor edx,edx mov eax,ecx mov random_seed,ecx mov ecx,100000 div ecx mov eax,edx xor edx,edx div rmax lea eax,[rdx+1] leave ret WIRandom endp .data text db 'ManHunter',0,'presents',0,'FIRE DEMO',0,0 szFont db 'Arial',0 text_interval dd 29 pointer dd text rc RECT <0,0,WINDOW_WIDTH,WINDOW_HEIGHT> .data? px_data dq ? palette dq ? random_seed dd ? hDC dq ? hFont dq ? end Во вложении asm-/rc-/exe-файлы