Светлячки

Тема в разделе "WASM.DOS/BIOS/Vesa/ports", создана пользователем Mikl___, 24 дек 2016.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.709
    Заставка для Windows 7 64 bits выполнена с использованием того же эффекта.
    [​IMG]
    На самом деле этот эффект называется 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):
    1. void initblow()
    2. {
    3.   long c;
    4.   for(long y=0;y<256;y++)
    5.     for(long x=0;x<256;x++)
    6.     {
    7.       c=(16384/((x-128)*(x-128)+(y-128)*(y-128)+128));
    8.       if(c>63) c=63;
    9.       blow[x+(y<<8)]=c;
    10.     }
    11. }
    Выводя спрайт на экран, мы обязательно столкнемся с необходимостью clliping`a, то есть, отсечения кусков спрайта, вылезающих за границы экрана. Эта проблема решается довольно просто. Допустим, что мы начинаем выводить спрайт на экран с точки, координаты которой dx,dy.
    Тогда процедура вывода спрайта будет выглядеть так:
    Код (C):
    1. void drawblow(long dx,long dy)
    2. {
    3.   long c,s;
    4.   long minx=0;
    5.   if(dx<0) minx=-dx;
    6.   long miny=0;
    7.   if(dy<0) miny=-dy;
    8.   long maxx=320-dx;
    9.   if(maxx>255) maxx=255;
    10.   long maxy=200-dy;
    11.   if(maxy>255) maxy=255;
    12.   for(long y=miny;y<maxy;y++)
    13.     for(long x=minx;x<maxx;x++)
    14.     {
    15.       s=(x+dx)+((y+dy)<<6)+((y+dy)<<8);
    16.       c=screen[s]+blow[x+(y<<8)];
    17.       if(c>63) c=63;
    18.       screen[s]=c;
    19.     }
    20. }
    Идея эффекта заключается в том, что при выводе точки спрайта на экран мы суммируем цвет точки экрана и спрайта, и результат записываем в экранную точку. Естественно, если сумма > 63, то результат должен быть равен 63, иначе мы вылезем за границу используемой части палитры. Собственно сам эффект получается автоматически, самое сложным было выдумать формулу.
    Взято здесь, текст программы немного переделан, в результате СОМ-файл уменьшился с 912 байт до 740 байт
    Код (ASM):
    1. ; masm dos com #
    2. .286
    3. .model tiny
    4. .code
    5. .686p
    6. .mmx
    7. WIDTH_SREEN equ 320
    8. HEIGHT_SCREEN   equ 200
    9. SCREENSIZE  equ WIDTH_SREEN*HEIGHT_SCREEN
    10. MEMBLOCKSIZE    equ SCREENSIZE/16
    11. IMPUT_STATUS_0  equ 3DAh
    12. VGA_SEGMENT equ 0A000h
    13. org 100h
    14. start:
    15. x1      equ word ptr [bp-16]
    16. y1      equ word ptr [bp-14]
    17. x       equ dword ptr [bp-12]
    18. y       equ dword ptr [bp-8]
    19. time        equ dword ptr [bp-4]
    20.  
    21.         mov sp, 0CA0h
    22.         mov ah, 4Ah; ADJUST MEMORY BLOCK SIZE (SETBLOCK)
    23.         mov bx, 0CAh; ES = segment address of block to change
    24.         int 21h; BX = new size in paragraphs                  
    25.         enter   10h, 0
    26. ;initblow----------------------------------------
    27.         mov bx, 0FA0h
    28.         mov ah, 48h; ALLOCATE MEMORY
    29.         int 21h; BX = number of 16-byte paragraphs desired
    30.         mov screen, ax
    31.         mov bx, 1000h
    32.         mov ah, 48h; ALLOCATE MEMORY
    33.         int 21h; BX = number of 16-byte paragraphs desired
    34.         mov fs,ax; адрес буфера спрайта
    35.         mov es, ax
    36.         mov y1,-128
    37. a0:     mov di,y1
    38.         imul    di,di
    39.         mov x1,-128
    40. a1:     mov bx, x1
    41.         imul    bx,bx
    42.         lea bx,[bx+di+256]
    43.         mov ax,16384 ;4000h
    44.         xor dx, dx
    45.         div bx
    46.         cmp al,63
    47.         jbe @f
    48.         mov al,63
    49. @@:     mov si, y1
    50.         add si, 128
    51.         shl si, 8
    52.         add si, x1
    53.         mov es:[si+128], al
    54.         inc x1
    55.                 cmp x1,128
    56.         jl  a1
    57.         inc y1
    58.         cmp y1,128
    59.         jl  a0
    60. ;initblow----------------------------------------
    61.         mov ax, 13h
    62.         int 10h     ; - VIDEO - SET VIDEO MODE
    63. ;setcolortable--------------------------------------------------------
    64.         mov cx,64;3
    65.         xor ax,ax
    66.         xor bx,bx
    67.         mov dx,3C8h
    68.         out dx,al;color
    69.         inc dx
    70. @@:             mov al,0 ;red
    71.         out dx,al
    72.         mov al,bl;green
    73.         out dx,al
    74.         mov al,0;blue
    75.         out dx,al
    76.         inc bx
    77.         loop @b
    78. ;setcolortable--------------------------------------------------------
    79.         fldz;time=0
    80. begin:;clearvirtualscreen--------------------------------------
    81.         mov es,screen
    82.         mov cx,SCREENSIZE/4;16000
    83.         xor eax, eax
    84.         xor di, di
    85.         rep stosd
    86. ;main-----------------------------------
    87.         fld st
    88.         fmul    const05
    89.         fadd    const1
    90.         fsin
    91.         fmul    const92
    92.         fistp   x
    93.         add x,32;x=32+92*sin(time*0.5+1.0);
    94.         fld time
    95.         fmul    const1_5
    96.         fadd    const2
    97.         fcos
    98.         fmul    const58
    99.         fistp   y
    100.         sub y,28;y=-28+58*cos(time*1.5+2.0);
    101.         push    word ptr x
    102.         push    word ptr y
    103.         call    drawblow
    104.         fld time
    105.         fadd    const1_5
    106.         fsin
    107.         fmul    const92
    108.         fistp   x
    109.         add x, 32;x=32+92*sin(time+1.5);
    110.         fld time
    111.         fmul    const2
    112.         fadd    const2_5
    113.         fcos
    114.         fmul    const58
    115.         fistp   y
    116.         sub y,28;y=-28+58*cos(time*2.0+2.5);
    117.         push    word ptr x
    118.         push    word ptr y
    119.         call    drawblow
    120.         fld time
    121.         fmul    const1_5
    122.         fadd    const2
    123.         fsin
    124.         fmul    const92
    125.         fistp   x
    126.         add x, 32;x=32+92*sin(time*1.5+2.0);
    127.         fld time
    128.         fmul    const2_5
    129.         fadd    const3
    130.         fcos
    131.         fmul    const58
    132.         fistp   y
    133.         sub y,28;y=-28+58*cos(time*2.5+3.0);
    134.         push    word ptr x
    135.         push    word ptr y
    136.         call    drawblow
    137.         fld time
    138.         fmul    const2
    139.         fadd    const2_5
    140.         fsin
    141.         fmul    const92
    142.         fistp   x
    143.         add x, 32;x=32+92*sin(time*2.0+2.5);
    144.         fld time
    145.         fmul    const3
    146.         fadd    const05
    147.         fcos
    148.         fmul    const58
    149.         fistp   y
    150.         sub y,28;y=-28+58*cos(time*3.0+0.5);
    151.         push    word ptr x
    152.         push    word ptr y
    153.         call    drawblow
    154.         fld time
    155.         fmul    const2_5
    156.         fadd    const3
    157.         fsin
    158.         fmul    const92
    159.         fistp   x
    160.         add x,32;x=32+92*sin(time*2.5+3.0);
    161.         fld time
    162.         fmul    const05
    163.         fadd    const1
    164.         fcos
    165.         fmul    const58
    166.         fistp   y
    167.         sub y,28;y=-28+58*cos(time*0.5+1.0);
    168.         push    word ptr x
    169.         push    word ptr y
    170.         call    drawblow
    171.         fld time
    172.         fmul    const3
    173.         fadd    const05
    174.         fsin
    175.         fmul    const92
    176.         fistp   x
    177.         add x,32;x=32+92*sin(time*3.0+0.5);
    178.         fld time
    179.         fadd    const1_5
    180.         fcos
    181.         fmul    const58
    182.         fistp   y
    183.         sub y,28;y=-28+58*cos(time*1.0+1.5);
    184.         push word ptr x
    185.         push word ptr y
    186.         call    drawblow
    187.         fadd    const002
    188.         fst time
    189. ;copyvirtualscreen-----------------------------------------
    190.         mov dx,IMPUT_STATUS_0
    191. WaitVerticalSync:in al,dx
    192.             test al,8
    193.             jz WaitVerticalSync
    194. WaitNotVerticalSync:in al,dx
    195.             test al,8
    196.             jnz WaitNotVerticalSync
    197.         mov cx,SCREENSIZE/4
    198.         xor si,si
    199.         push ds
    200.         mov ds,screen
    201.         xor di,di
    202.         push VGA_SEGMENT
    203.         pop es
    204.         rep movsd
    205.                 xor ax,ax
    206.         mov ds,ax
    207.         mov ax,ds:[41Ah]
    208.         sub ax,ds:[41Ch]
    209.         pop ds
    210.         jz begin
    211. exit:       mov ax,3
    212.         int 10h ; - VIDEO - SET VIDEO MODE
    213.         int 20h
    214.  
    215. drawblow    proc
    216.  
    217. x2      equ word ptr [bp-8]
    218. y2      equ word ptr [bp-6]
    219. maxX        equ word ptr [bp-4]
    220. maxY        equ word ptr [bp-2]
    221. inY     equ word ptr [bp+4]
    222. inX     equ word ptr [bp+6]
    223.  
    224.         enter 8,0
    225.         mov x2,0
    226.         mov y2,0
    227.         mov ax,inX     ;IF(dx<0)x=-dx;
    228.         test ax,ax
    229.         jns @f
    230.         neg ax
    231.         mov x2,ax
    232. @@:     mov ax,inY     ;IF(dy<0)y=-dy;
    233.         test ax,ax
    234.         jns @f
    235.         neg ax
    236.         mov y2,ax
    237. @@:     mov ax,WIDTH_SREEN
    238.         sub ax,inX     ;AX=320-dx
    239.         cmp ax,255
    240.         jbe @f
    241.         mov ax,255           ;IF(AX>255)AX=255;
    242. @@:     mov maxX,ax    ;maxx=AX;
    243.         mov ax,HEIGHT_SCREEN
    244.         sub ax,inY     ;AX=200-dy;
    245.         cmp ax,255
    246.         jbe @f
    247.         mov ax,255           ;IF(AX>255)AX=255;
    248. @@:     mov maxY,ax     ;maxy=AX;
    249.         mov es,screen
    250. a2:     mov bx,y2       ;BX=(y+dy)*320;
    251.         add bx,inY
    252.         imul bx,WIDTH_SREEN
    253.         mov si,x2       ;FOR(DI=x;DI<maxx;DI++){
    254. a3:     lea di,[si+bx]
    255.         add di,inX
    256.         push di
    257.         mov al,es:[di]
    258.         imul di,y2,256
    259.         add di,si
    260.         add al,fs:[di]
    261.         cmp al,63
    262.         jbe @f
    263.         mov al,63
    264. @@:     pop di
    265.         stosb
    266.         inc si
    267.         cmp maxX,si
    268.         jg a3
    269.         inc y2
    270.         mov ax, maxY
    271.         cmp y2, ax
    272.         jb a2
    273.         leave
    274.         retn 4
    275. drawblow    endp
    276.  
    277. const002    dd 0.02
    278. screen dw ?; адрес буфера экрана
    279. const05 dd 0.5
    280. const1  dd 1.0
    281. const1_5 dd 1.5
    282. const2  dd 2.0
    283. const2_5 dd 2.5
    284. const3  dd 3.0
    285. const58 dd 58.0
    286. const92 dd 92.0
    287. end start
    288.  
     

    Вложения:

    • blows.jpg
      blows.jpg
      Размер файла:
      25,6 КБ
      Просмотров:
      1.288
    Последнее редактирование: 24 дек 2016
    >Quiet Snow< и comrade нравится это.