Заставка для Windows 7 64 bits выполнена с использованием того же эффекта. На самом деле этот эффект называется blow ("раздувание"). Установим палитру так: 0 [math]\to[/math] 63 от черного цвета к зеленому оттенку. Наши светлячки - обыкновенные спрайты, точнее, один спрайт размером 256x256. Назовем массив, в котором будет храниться этот спрайт, blow. Формула по которой мы будем рисовать выглядит так: [math]color=\frac{max\;radius^{2}}{radius^{2}+max\;radius}[/math], где [math]max\;radius[/math] - это требуемый радиус огонька, [math]radius[/math] - радиус текущей точки. Сущность этой формулы: смягченная обратная зависимость яркости от радиуса, квадраты радиусов используются из-за того, что вычислить квадрат радиуса текущей точки намного легче, чем просто радиус (не надо извлекать корень). Максимальное значение цвета ограниченно числом 63. Процедура инициализации будет выглядеть так: Код (C): void initblow() { long c; for(long y=0;y<256;y++) for(long x=0;x<256;x++) { c=(16384/((x-128)*(x-128)+(y-128)*(y-128)+128)); if(c>63) c=63; blow[x+(y<<8)]=c; } } Выводя спрайт на экран, мы обязательно столкнемся с необходимостью clliping`a, то есть, отсечения кусков спрайта, вылезающих за границы экрана. Эта проблема решается довольно просто. Допустим, что мы начинаем выводить спрайт на экран с точки, координаты которой dx,dy. Тогда процедура вывода спрайта будет выглядеть так: Код (C): void drawblow(long dx,long dy) { long c,s; long minx=0; if(dx<0) minx=-dx; long miny=0; if(dy<0) miny=-dy; long maxx=320-dx; if(maxx>255) maxx=255; long maxy=200-dy; if(maxy>255) maxy=255; for(long y=miny;y<maxy;y++) for(long x=minx;x<maxx;x++) { s=(x+dx)+((y+dy)<<6)+((y+dy)<<8); c=screen[s]+blow[x+(y<<8)]; if(c>63) c=63; screen[s]=c; } } Идея эффекта заключается в том, что при выводе точки спрайта на экран мы суммируем цвет точки экрана и спрайта, и результат записываем в экранную точку. Естественно, если сумма > 63, то результат должен быть равен 63, иначе мы вылезем за границу используемой части палитры. Собственно сам эффект получается автоматически, самое сложным было выдумать формулу. Взято здесь, текст программы немного переделан, в результате СОМ-файл уменьшился с 912 байт до 740 байт Код (ASM): ; masm dos com # .286 .model tiny .code .686p .mmx WIDTH_SREEN equ 320 HEIGHT_SCREEN equ 200 SCREENSIZE equ WIDTH_SREEN*HEIGHT_SCREEN MEMBLOCKSIZE equ SCREENSIZE/16 IMPUT_STATUS_0 equ 3DAh VGA_SEGMENT equ 0A000h org 100h start: x1 equ word ptr [bp-16] y1 equ word ptr [bp-14] x equ dword ptr [bp-12] y equ dword ptr [bp-8] time equ dword ptr [bp-4] mov sp, 0CA0h mov ah, 4Ah; ADJUST MEMORY BLOCK SIZE (SETBLOCK) mov bx, 0CAh; ES = segment address of block to change int 21h; BX = new size in paragraphs enter 10h, 0 ;initblow---------------------------------------- mov bx, 0FA0h mov ah, 48h; ALLOCATE MEMORY int 21h; BX = number of 16-byte paragraphs desired mov screen, ax mov bx, 1000h mov ah, 48h; ALLOCATE MEMORY int 21h; BX = number of 16-byte paragraphs desired mov fs,ax; адрес буфера спрайта mov es, ax mov y1,-128 a0: mov di,y1 imul di,di mov x1,-128 a1: mov bx, x1 imul bx,bx lea bx,[bx+di+256] mov ax,16384 ;4000h xor dx, dx div bx cmp al,63 jbe @f mov al,63 @@: mov si, y1 add si, 128 shl si, 8 add si, x1 mov es:[si+128], al inc x1 cmp x1,128 jl a1 inc y1 cmp y1,128 jl a0 ;initblow---------------------------------------- mov ax, 13h int 10h ; - VIDEO - SET VIDEO MODE ;setcolortable-------------------------------------------------------- mov cx,64;3 xor ax,ax xor bx,bx mov dx,3C8h out dx,al;color inc dx @@: mov al,0 ;red out dx,al mov al,bl;green out dx,al mov al,0;blue out dx,al inc bx loop @b ;setcolortable-------------------------------------------------------- fldz;time=0 begin:;clearvirtualscreen-------------------------------------- mov es,screen mov cx,SCREENSIZE/4;16000 xor eax, eax xor di, di rep stosd ;main----------------------------------- fld st fmul const05 fadd const1 fsin fmul const92 fistp x add x,32;x=32+92*sin(time*0.5+1.0); fld time fmul const1_5 fadd const2 fcos fmul const58 fistp y sub y,28;y=-28+58*cos(time*1.5+2.0); push word ptr x push word ptr y call drawblow fld time fadd const1_5 fsin fmul const92 fistp x add x, 32;x=32+92*sin(time+1.5); fld time fmul const2 fadd const2_5 fcos fmul const58 fistp y sub y,28;y=-28+58*cos(time*2.0+2.5); push word ptr x push word ptr y call drawblow fld time fmul const1_5 fadd const2 fsin fmul const92 fistp x add x, 32;x=32+92*sin(time*1.5+2.0); fld time fmul const2_5 fadd const3 fcos fmul const58 fistp y sub y,28;y=-28+58*cos(time*2.5+3.0); push word ptr x push word ptr y call drawblow fld time fmul const2 fadd const2_5 fsin fmul const92 fistp x add x, 32;x=32+92*sin(time*2.0+2.5); fld time fmul const3 fadd const05 fcos fmul const58 fistp y sub y,28;y=-28+58*cos(time*3.0+0.5); push word ptr x push word ptr y call drawblow fld time fmul const2_5 fadd const3 fsin fmul const92 fistp x add x,32;x=32+92*sin(time*2.5+3.0); fld time fmul const05 fadd const1 fcos fmul const58 fistp y sub y,28;y=-28+58*cos(time*0.5+1.0); push word ptr x push word ptr y call drawblow fld time fmul const3 fadd const05 fsin fmul const92 fistp x add x,32;x=32+92*sin(time*3.0+0.5); fld time fadd const1_5 fcos fmul const58 fistp y sub y,28;y=-28+58*cos(time*1.0+1.5); push word ptr x push word ptr y call drawblow fadd const002 fst time ;copyvirtualscreen----------------------------------------- mov dx,IMPUT_STATUS_0 WaitVerticalSync:in al,dx test al,8 jz WaitVerticalSync WaitNotVerticalSync:in al,dx test al,8 jnz WaitNotVerticalSync mov cx,SCREENSIZE/4 xor si,si push ds mov ds,screen xor di,di push VGA_SEGMENT pop es rep movsd xor ax,ax mov ds,ax mov ax,ds:[41Ah] sub ax,ds:[41Ch] pop ds jz begin exit: mov ax,3 int 10h ; - VIDEO - SET VIDEO MODE int 20h drawblow proc x2 equ word ptr [bp-8] y2 equ word ptr [bp-6] maxX equ word ptr [bp-4] maxY equ word ptr [bp-2] inY equ word ptr [bp+4] inX equ word ptr [bp+6] enter 8,0 mov x2,0 mov y2,0 mov ax,inX ;IF(dx<0)x=-dx; test ax,ax jns @f neg ax mov x2,ax @@: mov ax,inY ;IF(dy<0)y=-dy; test ax,ax jns @f neg ax mov y2,ax @@: mov ax,WIDTH_SREEN sub ax,inX ;AX=320-dx cmp ax,255 jbe @f mov ax,255 ;IF(AX>255)AX=255; @@: mov maxX,ax ;maxx=AX; mov ax,HEIGHT_SCREEN sub ax,inY ;AX=200-dy; cmp ax,255 jbe @f mov ax,255 ;IF(AX>255)AX=255; @@: mov maxY,ax ;maxy=AX; mov es,screen a2: mov bx,y2 ;BX=(y+dy)*320; add bx,inY imul bx,WIDTH_SREEN mov si,x2 ;FOR(DI=x;DI<maxx;DI++){ a3: lea di,[si+bx] add di,inX push di mov al,es:[di] imul di,y2,256 add di,si add al,fs:[di] cmp al,63 jbe @f mov al,63 @@: pop di stosb inc si cmp maxX,si jg a3 inc y2 mov ax, maxY cmp y2, ax jb a2 leave retn 4 drawblow endp const002 dd 0.02 screen dw ?; адрес буфера экрана const05 dd 0.5 const1 dd 1.0 const1_5 dd 1.5 const2 dd 2.0 const2_5 dd 2.5 const3 dd 3.0 const58 dd 58.0 const92 dd 92.0 end start