Эффект пламени

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

  1. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    , на этот раз в виде газовой горелки.

    Древнючий мой исходник лета 2000-го, код без комментариев. Но так даже полезней-интересней, т.к. все стандартно и описано в интернетах, так что придется немного погуглить.

    Компилировать:

    tasm /m2 phire.asm
    tlink /t phire.obj

    Код (ASM):
    1. model tiny
    2. codeseg
    3. org 0100h
    4. @strt:
    5. ; vmode
    6. mov ax,0013h
    7. int 10h
    8. mov ax,0a000h
    9. mov ds,ax
    10. mov cx,0040h
    11. ; pal
    12. @lc00:
    13. dec cx
    14. mov dx,03c8h
    15. mov al,cl
    16. out dx,al
    17. inc dx
    18. mov al,00h
    19. out dx,al
    20. out dx,al
    21. mov al,cl
    22. out dx,al
    23. dec dx
    24. mov al,cl
    25. add al,40h
    26. out dx,al
    27. inc dx
    28. mov al,cl
    29. out dx,al
    30. out dx,al
    31. mov al,3fh
    32. out dx,al
    33. inc cx
    34. loop @lc00
    35. ; patrn
    36. @lc01:
    37. mov di,0f8c0h
    38. mov cx,0140h
    39. in ax,40h
    40. push di ;;
    41. @lc02:
    42. dec cx
    43. rol ax,01h
    44. add ah,al
    45. push ax ;;
    46. shr al,01h
    47. cmp al,20h
    48. jb @lc06
    49. mov [di],al
    50. @lc06:
    51. pop ax ;;
    52. inc di
    53. inc cx
    54. loop @lc02
    55. pop di ;;
    56. mov cx,0040h
    57. ; blurrr
    58. @lc03:
    59. push cx ;;
    60. mov cx,0140h
    61. @lc04:
    62. dec cx
    63. mov ax,[di]
    64. add al,ah
    65. shr al,01h
    66. jz @lc05
    67. dec al
    68. @lc05:
    69. push di
    70. sbb di,013fh
    71. mov [di],al
    72. pop di
    73. mov [di+01h],al
    74. inc di
    75. inc cx
    76. loop @lc04
    77. sub di,0280h
    78. pop cx ;;
    79. loop @lc03
    80. ; esc
    81. in al,60h
    82. dec al
    83. jnz @lc01
    84. mov ax,0003h
    85. int 10h
    86. retn
    87. end @strt
    88.  
    Во вложении скомпилированный COM.
     

    Вложения:

    • fire.jpg
      fire.jpg
      Размер файла:
      27,3 КБ
      Просмотров:
      998
    • PHIRE.zip
      Размер файла:
      279 байт
      Просмотров:
      635
  2. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792

    Немного теории

    В сущности, пламя, это тот же эффект Blur, изменений совсем немного.
    Допустим, мы хотим изобразить самый простой вариант: Пламя поднимается снизу экрана и постепенно гаснет. Наша формула true-blur`а изменится совсем чуть-чуть:
    Код (C):
    1.     buffer[x][y+1]=(screen[x-1][y+1]+screen[x-1][y]+
    2.                     screen[x-1][y-1]+screen[x][y+1]+
    3.                     screen[x][y-1]+screen[x+1][y+1]+
    4.                     screen[x+1][y]+screen[x+1][y-1])/8;
    Для того, чтобы пламя красиво гасло, установим палитру так:
    Номер цвета064128192255
    Цветчерный[math]\to[/math]красный[math]\to[/math]желтый[math]\to[/math]ярко-желтый[math]\to[/math]белый
    Пример:
    Код (C):
    1. for(short k=0;k<=63;k++)
    2.   {
    3.     setrgbpalette(k,k,0,0);
    4.     setrgbpalette(k+64,63,k,0);
    5.     setrgbpalette(k+128,63,63,k);
    6.     setrgbpalette(k+192,63,63,63);
    7.   }
    Если вам кажется, что пламя слишком медленно гаснет, то формулу можно переписать вот так:
    Код (C):
    1.     short color=(screen[x-1][y+1]+screen[x-1][y]+
    2.                  screen[x-1][y-1]+screen[x][y+1]+
    3.                  screen[x][y-1]+screen[x+1][y+1]+
    4.                  screen[x+1][y]+screen[x+1][y-1])/8;
    5.     if(color>number) color-=number; else color=0;
    6.     buffer[x][y+1]=color;
    Значение number выберите по своему вкусу, чем оно больше, тем быстрее будет гаснуть пламя.Да, и самое главное, чтобы пламя "горело", его надо постоянно "подпитывать": в самую нижнюю строчку в начале каждого кадра записывать пиксели со случайным цветом.Добавится вот такая строка:
    Код (C):
    1.   for(x=0;x<320;x+=4)
    2.   {
    3.     char color=rand()%256;
    4.     screen[x][199]=c;
    5.     screen[x+1][199]=c;
    6.     screen[x+2][199]=c;
    7.     screen[x+3][199]=c;
    8.   }
    Забивая сразу четыре пикселя случайным цветом, мы получаем более красивое пламя. Естественно, эту и несколько следующих строк на экран мы не выводим. Почему? Догадайтесь сами!
    Опять же, для ускорения можно использовать вариант блюра с четырьмя усредняемыми пикселями, немного его изменив:
    Код (C):
    1.   screen[x][y]=(screen[x-1][y-1]+screen[x][y-1]+
    2.                 screen[x][y-1]+screen[x+1][y-2])/4;
    Вот еще одна быстрая формула:
    Код (C):
    1. for(short y=0;y<197;y+=2)
    2.   for(short x=1;x<319;x++)
    3.   {
    4.     short high=screen[x-1][y-2]+screen[x][y-2]+screen[x+1][y-2];
    5.     char low=screen[x][y-4];
    6.     char pixel=(high+low)/4;
    7.     screen[x][y]=pixel;
    8.     screen[x][y-1]=(pixel+low)/2
    9.   }
    Взято здесь, текст программы немного переделан, в результате СОМ-файл уменьшился с 693 байт до 583 байт
    Код (ASM):
    1. ; masm dos com #
    2. .model tiny
    3. .code
    4. .386
    5. org 100h
    6. VGA_SEGMENT equ 0A000h
    7. IMPUT_STATUS_0  equ 3DAh    ;регистр статуса ввода 0
    8. WIDTH_SCREEN    equ 320
    9. HEIGHT_SCREEN   equ 200
    10. SCREENSIZE  equ WIDTH_SCREEN*HEIGHT_SCREEN
    11. MEMBLOCKSIZE    equ SCREENSIZE/16
    12.  
    13. screen  equ word ptr [bp-2]
    14. temp1   equ word ptr [bp-4]
    15. temp2   equ word ptr [bp-6]
    16.  
    17. start:      mov sp, 0BC0h
    18.         mov ah, 4Ah; ADJUST MEMORY BLOCK SIZE (SETBLOCK)
    19.         mov bx, 0BCh; ES = segment address of block to change
    20.         int 21h; BX = new size  in paragraphs
    21.         enter 6,0
    22. ;RANDOMIZE
    23.         push    0
    24.         pop es
    25. ;получаем системное время, накапливаемое в 4-х байтовой ячейке с адресом 46Ch
    26.         mov ax, es:[46Ch]
    27.         mov temp1, ax
    28.         mov ax, es:[46Eh]
    29.         mov temp2, ax
    30.         mov ax, 13h
    31.         int 10h
    32. ;setcolortable
    33.         mov cx,63
    34. @@:     push    cx
    35.         push    cx
    36.         push    0
    37.         push    0
    38.         call    setrgbpalette
    39.         mov al, cl
    40.         add al, 64
    41.         push    ax
    42.         push    63
    43.         push    cx
    44.         push    0
    45.         call    setrgbpalette
    46.         mov al, cl
    47.         add al, 128
    48.         push    ax
    49.         push    63
    50.         push    63
    51.         push    cx
    52.         call    setrgbpalette
    53.         mov al, cl
    54.         add al,192
    55.         push    ax
    56.         push    63
    57.         push    63
    58.         push    63
    59.         call    setrgbpalette
    60.         dec cx
    61.         jns @b
    62. ;setcolortable
    63.         mov bx, MEMBLOCKSIZE
    64.         mov ah, 48h; ALLOCATE MEMORY
    65.         int 21h; BX = number of 16-byte paragraphs desired
    66.         mov screen, ax
    67. ;clearblock
    68.         mov es, ax
    69.         xor eax, eax
    70.         xor di, di
    71.         mov cx,SCREENSIZE/4
    72.         rep stosd
    73.         mov bx, MEMBLOCKSIZE
    74.         mov ah, 48h; ALLOCATE MEMORY
    75.         int 21h; BX = number of 16-byte paragraphs desired
    76.         mov fs,ax;buffer
    77. ;clearblock
    78.         mov es, ax
    79.         xor eax, eax
    80.         xor di, di
    81.         mov cx,SCREENSIZE/4
    82.         rep stosd
    83. loc_10143:  xor ax, ax
    84.         mov es, ax
    85.         mov ax, es:[41Ah]
    86.         sub ax, es:[41Ch]
    87.         jnz loc_10158;нажали на клавиатуру?
    88.         call    incfire
    89. ;trueflamescreen
    90.         mov di,WIDTH_SCREEN
    91.         xor si, si
    92.         mov dx,HEIGHT_SCREEN-2
    93. loc_10218:  mov bx,13Fh
    94. loc_10220:  movzx   ax, byte ptr es:[di-WIDTH_SCREEN-1]
    95.         movzx   cx, byte ptr es:[di-WIDTH_SCREEN]
    96.         add ax, cx
    97.         movzx   cx, byte ptr es:[di-WIDTH_SCREEN+1]
    98.         add ax, cx
    99.         movzx   cx, byte ptr es:[di-1]
    100.         add ax, cx
    101.         movzx   cx, byte ptr es:[di+1]
    102.         add ax, cx
    103.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN-1]
    104.         add ax, cx
    105.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN]
    106.         add ax, cx
    107.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN+1]
    108.         add ax, cx
    109.         shr ax, 3
    110.         test al,al
    111.         je @f
    112.         dec al
    113. @@:     mov fs:[si], al
    114.         inc di
    115.         inc si
    116.         dec bx
    117.         jns loc_10220
    118.         dec dx
    119.         jnz loc_10218
    120. ;copybufferscreen
    121.         push    ds
    122.         push    fs
    123.         pop ds;buffer
    124.         xor si, si
    125.         xor di, di
    126.         mov cx,SCREENSIZE/4
    127.         rep movsd
    128.         pop ds
    129.         call    copyvirtualscreen
    130.         jmp loc_10143
    131. loc_10158:  mov ah, 0
    132.         int 16h     ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY
    133. loc_1015C:  xor ax, ax
    134.         mov es, ax
    135.         mov ax, es:[41Ah]
    136.         sub ax, es:[41Ch]
    137.         jnz loc_1016E
    138.         call    incfire
    139. ;fastflamescreen
    140.         xor di, di
    141.         mov si, HEIGHT_SCREEN-4
    142. loc_102B7:  mov bx, WIDTH_SCREEN-1
    143. loc_102BF:  movzx   ax, byte ptr es:[di+WIDTH_SCREEN-1]
    144.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN]
    145.         add ax, cx
    146.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN+1]
    147.         add ax, cx
    148.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN*2]
    149.         add ax, cx
    150.         shr ax, 2
    151.         test al,al
    152.         je @f
    153.         dec al
    154. @@:     stosb
    155.         dec bx
    156.         jns loc_102BF
    157.         dec si
    158.         jns loc_102B7
    159.  
    160.         call    copyvirtualscreen
    161.         jmp short loc_1015C
    162. loc_1016E:  mov ah, 0
    163.         int 16h     ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY
    164. loc_10172:  xor ax, ax
    165.         mov es, ax
    166.         mov ax, es:[41Ah]
    167.         sub ax, es:[41Ch]
    168.         jnz short loc_10184
    169.         call    incfire
    170. ;fastestflamescreen
    171.         xor di, di
    172.         mov bx, HEIGHT_SCREEN-4
    173. loc_10300:  mov si, WIDTH_SCREEN-1
    174. loc_10308:  movzx   ax, byte ptr es:[di+WIDTH_SCREEN*2-1]
    175.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN*2]
    176.         add ax, cx
    177.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN*2+1]
    178.         add ax, cx
    179.         xchg    ax, dx
    180.         movzx   cx, byte ptr es:[di+WIDTH_SCREEN*4]
    181.         mov ax, cx
    182.         add ax, dx
    183.         shr ax, 2
    184.         cmp al, 2
    185.         jbe short loc_1033A
    186.         sub al, 2
    187.         jmp short loc_1033C
    188. loc_1033A:  mov al, 0
    189. loc_1033C:  stosb
    190.         cbw
    191.         mov ch,0
    192.         add ax, cx
    193.         sar ax, 1
    194.         mov es:[di+WIDTH_SCREEN-1], al
    195.         dec si
    196.         jns loc_10308
    197.         add di,WIDTH_SCREEN
    198.         sub bx,2
    199.         jns loc_10300
    200. ;fastestflamescreen
    201.         call    copyvirtualscreen
    202.         jmp short loc_10172
    203. loc_10184:  mov ax, 3
    204.         int 10h     ; - VIDEO - SET VIDEO MODE
    205.         mov ah, 0
    206.         int 16h     ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY
    207.         int 20h
    208. setrgbpalette   proc near
    209.  
    210. blue        equ byte ptr  [bp+4]
    211. green       equ byte ptr  [bp+6]
    212. red     equ byte ptr  [bp+8]
    213. color       equ byte ptr  [bp+10]
    214.  
    215.         push    bp
    216.         mov bp, sp
    217.         mov dx, 3C8h
    218.         mov al, color
    219.         mov ah, red
    220.         out dx, ax
    221.         inc dx
    222.         mov al, green
    223.         out dx, al
    224.         mov al, blue
    225.         out dx, al
    226.         pop bp
    227.         retn    8
    228. setrgbpalette   endp
    229.  
    230. incfire proc
    231.         mov es, screen
    232.         mov di,WIDTH_SCREEN*(HEIGHT_SCREEN-2)
    233.         mov cx,80
    234. @@:             mov ax, temp2
    235.         mov dx, temp1
    236.         shld    ax,dx,8
    237.         shl dx,8
    238.         rcr ax, 1
    239.         rcr dx, 1
    240.         add temp1, dx
    241.         adc ax, temp2
    242.         add temp1,25321
    243.         adc ax,13849
    244.         mov temp2, ax
    245.         mov ah, al
    246.         push    ax
    247.         push    ax
    248.         pop eax
    249.         stosd
    250.         mov es:[di+WIDTH_SCREEN-4], eax
    251.         loop    @b
    252.         retn
    253. incfire endp
    254. copyvirtualscreen   proc
    255.         mov dx,IMPUT_STATUS_0
    256. WaitVerticalSync:in al,dx
    257.     test al,8
    258.     jz WaitVerticalSync
    259. WaitNotVerticalSync:in al,dx
    260.     test al,8
    261.     jnz WaitNotVerticalSync
    262.         mov cx,WIDTH_SCREEN*(HEIGHT_SCREEN-4)/4
    263.         xor si,si
    264.         push ds
    265.         mov ds,screen
    266.         xor di,di
    267.         push    VGA_SEGMENT
    268.         pop es
    269.         rep movsd
    270.         pop ds
    271.         retn
    272. copyvirtualscreen   endp
    273. end start
    [​IMG]
    P.S. Попробуйте найти ЧЕМ мой исходник отличается от исходника _edge
     

    Вложения:

    • flame.jpg
      flame.jpg
      Размер файла:
      34,8 КБ
      Просмотров:
      1.487
    _edge нравится это.
  3. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    Полыхает огонь в душе моей.
    Компилировать uasm32 -bin -Fo napalm.com napalm.asm
    ЗЫ
    Да, линкер для com файлов UASM'у ненужен!
     

    Вложения:

    • napalm.asm
      Размер файла:
      2 КБ
      Просмотров:
      482