1. Если вы только начинаете программировать на ассемблере и не знаете с чего начать, тогда попробуйте среду разработки ASM Visual IDE
    (c) на правах рекламы
    Скрыть объявление

след от водомерки на поверхности воды

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

  1. Mikl___

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

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

    След от водомерки на поверхности воды

    Этап первый

    Код (ASM):
    1. ; masm dos com #
    2. .model tiny
    3. .code
    4. .386
    5. org 100h
    6. PALSIZE equ 300h
    7. WIDTH_SCREEN    equ 320
    8. HEIGHT_SCREEN   equ 200
    9. SCREENSIZE  equ WIDTH_SCREEN*HEIGHT_SCREEN
    10. IMPUT_STATUS_0  equ 3DAh    ;регистр статуса ввода 0
    11. VGA_SEGMENT equ 0A000h
    12.  
    13. start:          mov ax, 13h;установили необходимый режим 320х200х256
    14.         int 10h
    15.         mov ax, 4309h;создать палитру
    16.         mov dx, 3D4h
    17.         out dx, ax
    18.  
    19.         xor bx, bx
    20.         mov dl, 0C8h
    21.         mov al, 0
    22.         out dx, al
    23.         inc dx
    24.  
    25. @0:     mov al, 0
    26.         cmp bl, 128
    27.         jnb @f
    28.         mov al, 127
    29.         sub al, bl
    30.         shr al, 1
    31.  
    32. @@:     out dx, al
    33.         out dx, al
    34.         mov cl, bl
    35.         shr cl, 1
    36.         mov al, 127
    37.         sub al, cl
    38.         shr al, 1
    39.         out dx, al
    40.         inc bl
    41.         jnz @0
    42. ;-----------------------------------------
    43.     mov ax,cs
    44.     add ax,1000h
    45.     mov fs,ax   ; watertable1=AX
    46.     mov es,ax
    47.     add ax,2000
    48.     mov gs,ax   ; watertable2=AX+WATERTABLE PARAGRAPH SIZE
    49. ;очистить буфер
    50.     xor di,di
    51.     mov cx, SCREENSIZE/4    ; CX=WATERTABLESIZE
    52.     xor eax, eax
    53.     rep stosd       ; initialize wt1 and wt2
    54.     push    VGA_SEGMENT
    55.     pop es
    56. main_loop:mov dx,IMPUT_STATUS_0
    57. WaitVerticalSync:in al,dx; притормозить вывод на экран до следующего кадра
    58.     test al,8
    59.     jz WaitVerticalSync
    60. WaitNotVerticalSync:in al,dx
    61.     test al,8
    62.     jnz WaitNotVerticalSync
    63. ;Вывод на экран из буфера
    64.     xor di, di
    65.     mov cx, SCREENSIZE/4
    66. @@: mov ax, fs:[di]
    67.     sub ax, fs:[di-2]
    68.     sar ax, 3; AX=(FS:[DI]-FS:[DI-2])/8
    69.     add al, HEIGHT_SCREEN/2
    70.     stosb
    71.     stosb
    72.     loop    @b
    73. ;Эффект воды
    74.     mov di,WIDTH_SCREEN+2
    75.     mov cx,SCREENSIZE/4 - WIDTH_SCREEN
    76. @@: mov ax,fs:[di-WIDTH_SCREEN]
    77.     add ax,fs:[di-2]
    78.     add ax,fs:[di+2]
    79.     add ax,fs:[di+WIDTH_SCREEN]
    80.     sar ax,1; AX=(FS:[DI-320]+FS:[DI-2]+FS:[DI+2]+FS:[DI+320])/2
    81.     sub ax,gs:[di]  ; AX-=GS:[DI]
    82.     mov bx,ax
    83.     sar bx,3
    84.     sub ax,bx
    85.     mov gs:[di],ax
    86.     add     di,2
    87.     loop    @b
    88.     push    gs
    89.     push    fs
    90.     pop gs
    91.     pop fs  ; watertable2 <-> watertable1
    92. ;перемещение объекта
    93.     mov bx,offset locobj
    94.     cmp word ptr [bx+4],WIDTH_SCREEN*2
    95.     sbb dx,dx
    96.     or  dl,1; IF( DS:[BX+4] > 640 ) DS:[BX]--
    97.     sub     [bx],dx; ELSE DSWORD[BX]++
    98.     cmp word ptr [bx+6],HEIGHT_SCREEN*2
    99.     sbb dx,dx   ; IF( DS:[BX+6] > 400 ) DS:[BX+2]--
    100.     or  dl,1
    101.     sub     [bx+2],dx; ELSE DS:[BX+2]++
    102.     mov ax,[bx]
    103.     add [bx+4],ax   ; DS:[BX+4]+=DS:[BX]
    104.     mov ax,[bx+2]
    105.     add [bx+6],ax   ; DS:[BX+6]+=DS:[BX+2]
    106.     mov di,[bx+4]
    107.     shr di,3        ; di=x-координата
    108.     mov ax,[bx+6]
    109.     shr ax,3
    110.     imul    ax,WIDTH_SCREEN/2;ax=y-координата
    111.     add di,ax       ; di=x+y
    112.     add di,di       ; DI*= 2
    113.  
    114.     mov dword ptr gs:[di],3840384h; GS=watertable1
    115.     mov dword ptr fs:[di],1C401C4h; FS=watertable2
    116.     add di,4
    117.     mov ah,1
    118.     int 16h     ;нажали на любую клавишу?
    119.     jz  main_loop
    120.     mov ax, 3           ;восстанавливаем текстовый режим
    121.     int 10h
    122.     retn                    ;завершаем программу
    123. locobj dw 5,0,80,40
    124. end start
    Размер COM-файла 265 байт.

    Этап второй

    Усложняем программу. Теперь у нас водомерка на поверхности воды и след от рыбы, которая пытается поймать водомерку
    Код (ASM):
    1. ; masm dos com #
    2. .model tiny
    3. .code
    4. .386
    5. org 100h
    6. PALSIZE equ 300h
    7. WIDTH_SCREEN    equ 320
    8. HEIGHT_SCREEN   equ 200
    9. SCREENSIZE  equ WIDTH_SCREEN*HEIGHT_SCREEN
    10. IMPUT_STATUS_0  equ 3DAh    ;регистр статуса ввода 0
    11. VGA_SEGMENT equ 0A000h
    12. palette equ byte ptr ende
    13.  
    14. start:          mov ax, 13h;установили необходимый режим 320х200х256
    15.         int 10h
    16.         mov ax, 4309h;создать палитру
    17.         mov dx, 3D4h
    18.         out dx, ax
    19.  
    20.         xor bx, bx
    21.         mov di,offset palette
    22.         push    ds
    23.         pop es
    24.  
    25. @0:     xor ax, ax
    26.         cmp bl, 128
    27.         jnb @f
    28.         mov al, 127
    29.         sub al, bl
    30.         shr al, 1
    31.         mov ah, al
    32. @@:     stosw
    33.         mov cl, bl
    34.         shr cl, 1
    35.         mov al, 127
    36.         sub al, cl
    37.         shr al, 1
    38.         stosb
    39.         inc bl
    40.         jnz @0
    41.         xor ax, ax
    42.         mov cx, PALSIZE
    43.         mov si, offset palette+3
    44.         mov dx, 3C8h
    45.         out dx, al
    46.         inc dx
    47.         rep outsb
    48.         push    ds
    49.         pop ax
    50.         add ah, 10h
    51.         mov fs,ax   ; watertable1=AX
    52.         mov es,ax
    53.         add ax,2000
    54.         mov gs,ax   ; watertable2=AX+WATERTABLEPARAGRAPHSIZE
    55.         xor di,di
    56.         mov cx, SCREENSIZE/4    ; CX=WATERTABLESIZE
    57.         xor eax, eax
    58.         rep stosd       ; initialize wt1 and wt2
    59.  
    60.     xor si, si
    61. main_loop:mov dx,IMPUT_STATUS_0
    62. WaitVerticalSync:in al,dx         ; притормозить
    63.     test al,8
    64.     jz WaitVerticalSync
    65. WaitNotVerticalSync:in al,dx
    66.     test al,8
    67.     jnz WaitNotVerticalSync
    68. ;ShowWater
    69.     push    VGA_SEGMENT
    70.     pop es
    71.     xor di, di
    72.     mov cx, SCREENSIZE/4
    73. @@: mov ax, fs:[di]
    74.     sub ax, fs:[di-2]
    75.     sar ax, 3; AX=(FS:[DI]-FS:[DI-2])/8
    76.     add al, HEIGHT_SCREEN/2
    77.     stosb
    78.     stosb
    79.     loop    @b
    80. ;CalcWaterEffect
    81.     mov di,WIDTH_SCREEN+2
    82.     mov cx,(HEIGHT_SCREEN-4)*WIDTH_SCREEN/4
    83. @@: mov ax,fs:[di-WIDTH_SCREEN]
    84.     add ax,fs:[di-2]
    85.     add ax,fs:[di+2]
    86.     add ax,fs:[di+WIDTH_SCREEN]
    87.     sar ax,1; AX=(FS:[DI-320]+FS:[DI-2]+FS:[DI+2]+FS:[DI+320])/2
    88.     sub ax,gs:[di]  ; AX-=GS:[DI]
    89.     mov bx,ax
    90.     sar bx,3
    91.     sub ax,bx
    92.     mov gs:[di],ax
    93.     add     di,2
    94.     loop    @b
    95.     push    gs
    96.     push    fs
    97.     pop gs
    98.     pop fs  ; watertable2 <-> watertable1
    99.  
    100.     mov bx,offset small
    101.     call    CALCADR
    102.     mov dword ptr gs:[di],3840384h; GS=watertable1
    103.     mov dword ptr fs:[di],1C401C4h; FS=watertable2
    104.     add di,4
    105.     test    si,100h ; IF(SI&256)
    106.     jz  @5
    107.     mov bx, offset big
    108.     call    CALCADR
    109.     mov cx, 5
    110. @4: mov bx, 5
    111. @@: mov word ptr gs:[di],384h; GS=watertable1
    112.     mov word ptr fs:[di],1C4h; FS=watertable2
    113.     add     di,2
    114.     dec bx
    115.     jnz @b
    116.     add di,WIDTH_SCREEN-10
    117.     loop    @4
    118. @5: add     si,2
    119.     mov ah,1
    120.     int 16h     ; KEYBOARD - CHECK BUFFER, DO NOT CLEAR
    121.     jz  main_loop
    122.     mov ax, 3
    123.     int 10h     ; - VIDEO - SET VIDEO MODE
    124.     retn
    125.  
    126. CALCADR proc
    127.     cmp word ptr [bx+4],WIDTH_SCREEN*2
    128.     sbb dx,dx
    129.     or  dl,1; IF(DSWORD[BX+4] > XSIZE*4) DSWORD[BX]--
    130.     sub     [bx],dx; ELSE DSWORD[BX]++
    131.     cmp word ptr [bx+6],HEIGHT_SCREEN*2
    132.     sbb dx,dx   ; IF(DSWORD[BX+6] > YSIZE*4) DSWORD[BX+2]--
    133.     or  dl,1
    134.     sub     [bx+2],dx; ELSE DSWORD[BX+2]++
    135.     mov ax,[bx]
    136.     add [bx+4],ax   ; DSWORD[BX+4]+=DSWORD[BX]
    137.     mov ax,[bx+2]
    138.     add [bx+6],ax   ; DSWORD[BX+6]+=DSWORD[BX+2]
    139.     mov di,[bx+4]
    140.     shr di,3        ; DI=DSWORD[BX+4]>>3
    141.     mov ax,[bx+6]
    142.     shr ax,3
    143.     imul    ax,WIDTH_SCREEN/2
    144.     add di,ax       ; DI+=AX
    145.     add di,di       ; DI+=DI
    146.     retn
    147. CALCADR endp
    148.  
    149. small dw 5,0,80,40
    150. big   dw -3,0,304,120
    151. ende:
    152. end start
    Размер COM-файла 342 байт.
    [​IMG]

    Заключительный этап


    Довольно загадочный, для непосвященных, но простой, эффект. В основе лежит, все тот же Blur. Я выбрал 8-пиксельный блюр, так как он дает более красивую картинку.

    Установим палитру так:
    Номер цвета0[​IMG] 255
    ЦветСинийБелый
    Заведем два буфера: buf1 и buf2, и указатели на них: buf1_ptr и buf2_ptr. Важно понять, что, хоть указатель называется buf1_ptr, но он может указывать совсем не на buf1, а на buf2. Аналогично для buf2_ptr. Далее по тексту, если массив будет называться buf1_ptr, то имеется в виду тот массив, на который, в данный момент, ссылается buf1_ptr. Тоже самое подразумевается под массивом buf2_ptr.

    Далее описывается последовательность, которую надо проделать, для расчета очередного кадра:
    1. Если buf1_ptr, действительно указывает на buf1, то заносим в buf1_ptr точки возмущения.
    2. Проходим по всем точкам массива buf1_ptr и buf2_ptr вот таким алгоритмом:
      2.1. Складываем значения точек окружающих текущую, в массиве buf1_ptr.
      2.2. Делим эту сумму на 4.
      2.3 Вычитаем из этой суммы значение текущей точки массива buf2_ptr.
      2.4 Если результат меньше 0, то результат равен 0.
      2.5 Записываем результат в текущую точку массива buf2_ptr.
    3. Теперь меняем местами buf1 и buf2 (собственно для этого нам и были нужны указатели):
      Код (C):
      1.   long temp_ptr=buf1_ptr;
      2.   buf1_ptr=buf2_ptr;
      3.   buf2_ptr=temp_ptr;
    4. Выводим на экран buf2_ptr.
    В результате получим эффект поверхности воды с всплывающими и лопающимися пузырьками и бегающими водомерками.
    [​IMG]
     

    Вложения:

    • water.jpg
      water.jpg
      Размер файла:
      38,1 КБ
      Просмотров:
      615
    • water1.jpg
      water1.jpg
      Размер файла:
      87,5 КБ
      Просмотров:
      608
    Последнее редактирование: 24 дек 2016
    >Quiet Snow< нравится это.
  2. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.776
    Код (ASM):
    1. ; masm dos com #
    2. .model tiny
    3. .code
    4. .686
    5. org 100h
    6. VGA_SEGMENT equ 0A000h
    7. IMPUT_STATUS_0  equ 3DAh
    8. SCREEN_WIDTH    equ 320
    9. SCREEN_HEIGHT   equ 200
    10. SCREENSIZE  equ SCREEN_HEIGHT*SCREEN_WIDTH
    11. MEMBLOCKSIZE    equ SCREENSIZE/16
    12. yd      equ dword ptr [bp-4]
    13. xd      equ dword ptr [bp-8]
    14. buf1        equ word ptr [bp-10]
    15. buf2        equ word ptr [bp-12]
    16. buf1_ptr    equ word ptr [bp-14]
    17. buf2_ptr    equ word ptr [bp-16]
    18. temp1       equ word ptr [bp-18]
    19. temp2       equ word ptr [bp-20]
    20.  
    21. start:      mov sp, 1260h
    22.         mov ah, 4Ah; ADJUST MEMORY BLOCK SIZE (SETBLOCK)
    23.         mov bx, 126h; ES = segment address of block to change
    24.         int 21h; BX = new size  in paragraphs
    25.         enter   20,0
    26.         mov bx, MEMBLOCKSIZE
    27.         mov ah, 48h; ALLOCATE MEMORY
    28.         int 21h; BX = number of 16-byte paragraphs desired
    29.         mov buf1, ax
    30.         mov buf1_ptr, ax
    31.         mov es,ax
    32.         xor eax,eax
    33.         xor di, di
    34.         mov cx,SCREENSIZE/4
    35.         rep stosd
    36.         rdtsc
    37.         mov dword ptr temp1, eax
    38.         mov bx, MEMBLOCKSIZE
    39.         mov ah, 48h; ALLOCATE MEMORY
    40.         int 21h; BX = number of 16-byte paragraphs desired
    41.         mov buf2, ax
    42.         mov buf2_ptr, ax
    43.         mov es,ax
    44.         xor eax,eax
    45.         xor di,di
    46.         mov cx,SCREENSIZE/4
    47.         rep stosd
    48.         mov ax,13h
    49.         int 10h     ; - VIDEO - SET VIDEO MODE
    50. ;setcolortable--------------------------------
    51.         mov cx,255
    52. @@:     mov dx, 3C8h
    53.         mov al,cl;color
    54.         mov ah,cl
    55.         sar ah,2;red
    56.         out dx, ax
    57.         inc dx
    58.         mov al,ah;gren=red
    59.         out dx, al
    60.         mov al,63;blue
    61.         out dx, al
    62.         dec cx
    63.         jns @b
    64.         fldz
    65. ;-------------------------------------------
    66. main:           mov ax, buf1
    67.         cmp buf1_ptr, ax
    68.         jnz @f
    69.         mov es, ax;buf1
    70.         mov ax, temp2
    71.         mov cx, temp1
    72.         shld    ax,cx,8
    73.         shl cx,8
    74.         rcr ax, 1
    75.         rcr cx, 1
    76.         add temp1, cx
    77.         adc ax, temp2
    78.         add word ptr temp1,25321
    79.         adc ax,13849
    80.         mov temp2, ax
    81.         movsx   eax, ax
    82.         add eax, eax
    83.         xor edx, edx
    84.         mov ecx,62000
    85.         div ecx
    86.         mov si, dx ;RAND()<<1%62000
    87.         add si, SCREEN_WIDTH
    88.         mov dword ptr es:[si], 7FFFFF7Fh
    89.         mov dword ptr es:[si+SCREEN_WIDTH],0FFFFFFFFh
    90.         mov dword ptr es:[si+SCREEN_WIDTH*2],0FFFFFFFFh
    91.         mov dword ptr es:[si+SCREEN_WIDTH*3],7FFFFF7Fh
    92.         fld st;time
    93.         fld st
    94.         fld     st
    95.         fld     st
    96.         fmul    const2_5
    97.         fadd    const1_5
    98.         fsin
    99.         fmul    const120
    100.         fistp   xd
    101.         add xd,160;xd=sin(time*2.5+1.5)*120+160
    102.         ;fld    time
    103.         fmul    const1_5
    104.         fadd    const2_5
    105.         fcos
    106.         fmul    const60
    107.         fistp   yd
    108.         add yd,100;yd=cos(time*1.5+2.5)*60+100
    109.         imul    si,word ptr yd,SCREEN_WIDTH
    110.         add si, word ptr xd
    111.         mov word ptr es:[si+SCREEN_WIDTH], 0FFFFh
    112.         mov word ptr es:[si+SCREEN_WIDTH*2], 0FFFFh
    113.         ;fld    time
    114.         fmul    const1_5
    115.         fadd    const2_5
    116.         fsin
    117.         fmul    const120
    118.         fistp   xd
    119.         add xd,160;xd=160+120*sin(time*1.5+2.5)
    120.         fmul    const2_5
    121.         fadd    const1_5
    122.         fcos
    123.         fmul    const60
    124.         fistp   yd
    125.         add yd,100;yd=100+60*cos(time*2.5+1.5)
    126.         imul    si,word ptr yd,SCREEN_WIDTH
    127.         add si, word ptr xd
    128.         mov word ptr es:[si+SCREEN_WIDTH], 0FFFFh
    129.         mov word ptr es:[si+SCREEN_WIDTH*2], 0FFFFh
    130.         fadd    const003;time=+0.03
    131. ;waterscreen--------------------------------
    132. @@:     mov fs, buf1_ptr
    133.         mov es, buf2_ptr
    134.         mov di, SCREEN_WIDTH+1
    135.         mov cx,0F8BFh-SCREEN_WIDTH-1
    136. loc_103BE:  movzx   ax, byte ptr fs:[di-SCREEN_WIDTH-1]
    137.         add al, byte ptr fs:[di-SCREEN_WIDTH]
    138.         adc ah, 0
    139.         add al, byte ptr fs:[di-SCREEN_WIDTH+1]
    140.         adc ah, 0
    141.         add al, byte ptr fs:[di-1]
    142.         adc ah, 0
    143.         add al, byte ptr fs:[di+1]
    144.         adc ah, 0
    145.         add al, byte ptr fs:[di+SCREEN_WIDTH-1]
    146.         adc ah, 0
    147.         add al, byte ptr fs:[di+SCREEN_WIDTH]
    148.         adc ah, 0
    149.         add al, byte ptr fs:[di+SCREEN_WIDTH+1]
    150.         adc ah, 0
    151.         shr ax, 2
    152.         sub al, byte ptr es:[di]
    153.         sbb ah, 0
    154.         test    ax, ax
    155.         jns @f
    156.         xor ax, ax
    157. @@:     stosb
    158.                 loop loc_103BE
    159.         mov ax, buf1_ptr
    160.         xchg    ax, buf2_ptr
    161.         mov buf1_ptr, ax
    162.         push    ds
    163.         mov ds,ax;buf1_ptr
    164. ;copyvirtualscreen--------------------------
    165.         mov dx,IMPUT_STATUS_0 ;=3DAh
    166. WaitVerticalSync:in al, dx
    167.         test al, 8
    168.         jz WaitVerticalSync
    169. WaitNotVerticalSync:in al, dx
    170.         test al, 8
    171.         jnz WaitNotVerticalSync
    172.         mov cx,SCREENSIZE/4
    173.         xor si,si
    174.         xor di,di
    175.         push    VGA_SEGMENT
    176.         pop es
    177.         rep movsd
    178.         mov ds,cx;ds=0
    179.         mov ax, ds:[41Ah]; было ли нажатие на клавиатуру?
    180.         sub ax, ds:[41Ch]
    181.         pop ds
    182.         jz  main
    183. exit:       mov ax, 3
    184.         int 10h     ; - VIDEO - SET VIDEO MODE
    185.         int 20h
    186. ;---------------------------------
    187. const1_5    dd 1.5
    188. const2_5    dd 2.5
    189. const60     dd 60.0
    190. const120    dd 120.0
    191. const003    dd 0.03
    192. end start
    Неплохо бы было добавить background какую-нибудь картинку, например такую
    [​IMG]
    да еще чтоб волны искажали его. Что ж нет ничего невозможного...
    Добавим два буфера: pics и screen_end. В pics будем хранить картинку, которую используем в качестве background`а. А screen_end мы будем выводить на экран. Палитру надо взять из считываемой картинки.
    Как же нам добиться эффекта искажения, из-за преломления лучей света на границе двух разнородных сред? Сейчас подумаем.
    Берем в руки учебник физики, ищем раздел "Оптика" и находим формулу расчета угла преломленного луча. Применив знания, полученные на уроках геометрии, выведем формулу, с помощью которой будем находить смещение, относительно текущего пикселя, по которому находиться пиксель, который и надо вывести на экран вместо текущего:
    [math]D=h\cdot tg(arcsin(0.75\cdot sin(\alpha)))[/math]
    [math]D[/math]-искомое смещение, [math]h[/math] - высота слоя воды (высота волны), [math]\alpha[/math] - угол между нормалью к поверхности воды в данной точке и вектором наблюдения.
    Нужно искать тангенс арксинуса синуса, да еще расчет нормали к поверхности, плюс это надо разложить на нахождение смещения по [math]X[/math] и [math]Y[/math], сложновато... [​IMG]
    Конечно, можно воспользоваться табличным разложением, но таблица получиться слишком уж большой. Как же быть? Взглянем еще раз на нашу формулу и подумаем, нельзя ее как нибудь сократить.
    Допустим, что наш тангенс арксинуса синуса, есть величина величина постоянная и равная, например 0.25. (Воспользуемся калькулятором). Опыт показал, что такое допущение вполне возможно, если ширина волны небольшая. Тогда формула значительно упроститься и будет выглядеть так:[math]D=\frac{h}{4}[/math] Теперь, чтобы найти координаты нужного пикселя, надо прибавить к текущим, [math]D[/math]:
    [math]x'=x+D[/math]
    [math]y'=y+D[/math]
    В наш алгоритм добавиться пункт 2.5.
    2.5. Делим результат на 4, полученное значение прибавляем к текущим X и Y. Если X, больше максимально допустимого значения, то X приравняем максимальному допустимому значению. Аналогичную проверку надо сделать и для Y. Считываем по этим координатам из массива pics, число и записываем по текущим координатам в screen_end.
    Теперь модифицируем этот алгоритм чтобы получить более реалистичное изображение.
    Недостаток описанного выше метода - смещение не зависит от наклона нормали к поверхности воды. Как исправить этот недостаток, не усложняя алгоритм? Довольно просто. Достаточно знать куда наклонена нормаль, тогда сможем смещать координаты в соответствии с этим направлением. Для того чтобы найти смещения по x и y, используем следующие формулы:
    Код (C):
    1. Dx=(buf1_ptr[x+1][y]-buf1_ptr[x-1][y])>>2;
    2. Dy=(buf1_ptr[x][y+1]-buf1_ptr[x][y-1])>>2;
    Как надо изменить пункт 2.6., вы наверняка догадаетесь сами.
     

    Вложения:

    • aqua.jpg
      aqua.jpg
      Размер файла:
      11 КБ
      Просмотров:
      608
    Последнее редактирование: 24 дек 2016
  3. Mikl___

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

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    2.776
    Код (ASM):
    1. ; masm dos com #
    2. .model tiny
    3. .code
    4. .686
    5. org 100h
    6. IMPUT_STATUS_0  equ 3DAh
    7. VGA_SEGMENT equ 0A000h
    8. SCREEN_HEIGHT   equ 200
    9. SCREEN_WIDTH    equ 320
    10. SCREENSIZE  equ SCREEN_WIDTH*SCREEN_HEIGHT
    11. MEMBLOCKSIZE    equ SCREENSIZE/16
    12. yd      equ dword ptr [bp-4]
    13. xd      equ dword ptr [bp-8]
    14. buf1        equ word ptr [bp-10]
    15. buf2        equ word ptr [bp-12]
    16. screen_end  equ word ptr [bp-14]
    17. pics        equ word ptr [bp-16]
    18. buf1_ptr    equ word ptr [bp-18]
    19. buf2_ptr    equ word ptr [bp-20]
    20. temp1       equ word ptr [bp-22]
    21. temp2       equ word ptr [bp-24]
    22. pal     equ byte ptr [bp-1048]
    23.  
    24.  
    25. start:      mov sp, 1260h
    26.         mov ah, 4Ah; ADJUST MEMORY BLOCK SIZE (SETBLOCK)
    27.         mov bx, 126h; ES = segment address of block to change
    28.         int 21h; BX = new size in paragraphs
    29.  
    30.         enter 1048, 0
    31.         rdtsc
    32.         mov dword ptr temp1,eax
    33.         mov bx,MEMBLOCKSIZE
    34.         mov ah,48h; ALLOCATE MEMORY
    35.         int 21h; BX = number of 16-byte paragraphs desired
    36.         mov buf1, ax
    37.         mov buf1_ptr, ax
    38.         mov es,ax
    39.         xor eax,eax
    40.         xor di,di
    41.         mov cx,SCREENSIZE/4
    42.         rep stosd
    43.         mov bx,MEMBLOCKSIZE
    44.         mov ah,48h; ALLOCATE MEMORY
    45.         int 21h; BX = number of 16-byte paragraphs desired
    46.         mov buf2, ax
    47.         mov buf2_ptr, ax
    48.         mov es,ax
    49.         xor eax,eax
    50.         xor di, di
    51.         mov cx,SCREENSIZE/4
    52.         rep stosd
    53.         mov bx,MEMBLOCKSIZE
    54.         mov ah,48h; ALLOCATE MEMORY
    55.         int 21h; BX = number of 16-byte paragraphs desired
    56.         mov screen_end,ax
    57.         mov es,ax
    58.         xor eax,eax
    59.         xor di,di
    60.         mov cx,SCREENSIZE/4
    61.         rep stosd
    62.         mov bx,MEMBLOCKSIZE
    63.         mov ah,48h; ALLOCATE MEMORY
    64.         int 21h; BX = number of 16-byte paragraphs desired
    65.         mov pics,ax
    66.         mov ax,13h
    67.         int 10h     ; - VIDEO - SET VIDEO MODE
    68. ;readbmp---------------------------------------------------------
    69.         mov dx,offset filename; OPEN DISK FILE WITH HANDLE
    70.         mov ax,3D00h       ; DS:DX  -> ASCIZ filename
    71.         int 21h     ; AL = access mode 0 - read
    72.         mov bx,ax;bx=handle
    73.         xor cx,cx
    74.         mov dx,54;размер заголовка BMP-файла
    75.         mov ax,4200h; MOVE FILE READ/WRITE POINTER (LSEEK)
    76.         int 21h; AL = method: offset from beginning of file
    77.         lea dx,pal
    78.         mov cx,1024
    79.         mov ah,3Fh; READ FROM FILE WITH HANDLE
    80.         int 21h; BX = file handle, CX = number of bytes to read
    81.                 ; DS:DX -> buffer
    82.         mov di,1023
    83. @@:     shr byte ptr pal[di],2
    84.         dec di
    85.         jns @b
    86.         push ds
    87.         mov ds,pics
    88.         mov di,SCREEN_HEIGHT-1
    89. @@:     imul dx,di,SCREEN_WIDTH
    90.         mov cx,SCREEN_WIDTH
    91.         mov ah,3Fh; READ FROM FILE WITH HANDLE
    92.         int 21h; BX = file handle, CX = number of bytes to read
    93.                 ; DS:DX -> buffer
    94.         dec di
    95.         jns @b
    96.         pop ds
    97.         mov ah,3Eh; CLOSE A FILE WITH HANDLE
    98.         int 21h ; BX = file handle
    99. ;--------------------------------------------------
    100.         mov cx,255
    101. @@:     mov di,cx
    102.         shl di,2
    103.         mov dx,3C8h
    104.         mov al,cl;color
    105.         mov     ah,pal[di+2];red
    106.         out dx,ax
    107.         inc dx
    108.         mov al,pal[di+1];green
    109.         out dx,al
    110.         mov al,pal[di];blue
    111.         out dx,al
    112.         dec cx
    113.         jns @b
    114. ;-----------------------------------------------------
    115.         fldz    ;time=0
    116. main:       mov ax,buf1
    117.         cmp buf1_ptr,ax
    118.         jnz @f
    119.         mov es,ax;buf1
    120.         mov ax,temp2
    121.         mov cx,temp1
    122.         shld ax,cx,8
    123.         shl cx,8
    124.         rcr ax,1
    125.         rcr cx,1
    126.         add temp1,cx
    127.         adc ax,temp2
    128.         add word ptr temp1,25321
    129.         adc ax,13849
    130.         mov temp2,ax
    131.         movsx eax,ax
    132.         add eax,eax
    133.         xor edx,edx
    134.         mov ecx,62000
    135.         div ecx
    136.         mov si,dx
    137.         add si,SCREEN_WIDTH
    138.         mov dword ptr es:[si],7FFFFF7Fh
    139.         mov dword ptr es:[si+SCREEN_WIDTH],0FFFFFFFFh
    140.         mov dword ptr es:[si+SCREEN_WIDTH*2],0FFFFFFFFh
    141.         mov dword ptr es:[si+SCREEN_WIDTH*3],7FFFFF7Fh
    142.         fld st;time
    143.         fld st
    144.         fld st
    145.         fld st
    146.         fmul const2_5
    147.         fadd const1_5
    148.         fsin
    149.         fmul const120
    150.         fistp xd      
    151.         add xd,160;xd=sin(time*2.5+1.5)*120+160
    152.         fmul const1_5
    153.         fadd const2_5
    154.         fcos
    155.         fmul const60
    156.         fistp yd      
    157.         add yd,100;yd=cos(time*1.5+2.5)*60+100
    158.         imul si,word ptr yd,SCREEN_WIDTH
    159.         add si,word ptr xd
    160.         mov word ptr es:[si+SCREEN_WIDTH], 0FFFFh
    161.         mov word ptr es:[si+SCREEN_WIDTH*2], 0FFFFh
    162.         fmul    const1_5
    163.         fadd    const2_5
    164.         fsin
    165.         fmul    const120
    166.         fistp   xd    
    167.         add xd, 160;xd=sin(time*1.5+2.5)*120+160
    168.         fmul    const2_5
    169.         fadd    const1_5
    170.         fcos
    171.         fmul    const60
    172.         fistp   yd    
    173.         add yd,100;yd=cos(time*2.5+1.5)*60+100
    174.         imul    si,word ptr yd,SCREEN_WIDTH
    175.         add si,word ptr xd
    176.         mov word ptr es:[si+SCREEN_WIDTH], 0FFFFh
    177.         mov word ptr es:[si+SCREEN_WIDTH*2], 0FFFFh
    178.         fadd    const003;time=+0.03
    179. ;waterscreen---------------------------------------------------
    180. @@:     mov gs,buf1_ptr
    181.         mov fs,buf2_ptr
    182.         mov di, SCREEN_WIDTH+1
    183.         mov cx,64000-321
    184. loc_10440:  movzx   ax, byte ptr gs:[di-SCREEN_WIDTH-1]
    185.         add al, byte ptr gs:[di-SCREEN_WIDTH]
    186.         adc ah, 0
    187.         add al, byte ptr gs:[di-SCREEN_WIDTH+1]
    188.         adc ah, 0
    189.         add al, byte ptr gs:[di-1]
    190.         adc ah, 0
    191.         add al, byte ptr gs:[di+1]
    192.         add ah, 0
    193.         add al, byte ptr gs:[di+SCREEN_WIDTH-1]
    194.         adc ah, 0
    195.         add al, byte ptr gs:[di+SCREEN_WIDTH]
    196.         adc ah, 0
    197.         add al, byte ptr gs:[di+SCREEN_WIDTH+1]
    198.         adc ah, 0
    199.         shr ax, 2
    200.         sub al, byte ptr fs:[di]
    201.         sbb ah, 0
    202.         test    ax, ax
    203.         jns @f
    204.         xor ax, ax
    205. @@:     mov fs:[di], al
    206.         shr ax,2
    207.         imul    si,ax,SCREEN_WIDTH+1
    208.         add si, di;si=ax*321+di
    209.         cmp si,SCREENSIZE-1
    210.         jbe @f
    211.         mov si,SCREENSIZE-1
    212. @@:     mov es,pics
    213.         lods byte ptr es:[si]
    214.         mov es,screen_end
    215.         stosb
    216.         loop loc_10440
    217.         mov ax, buf1_ptr
    218.         xchg    ax, buf2_ptr
    219.         mov buf1_ptr, ax
    220. ;copyvirtualscreen------------------------------------
    221.         mov dx,IMPUT_STATUS_0
    222. WaitVerticalSync:in al, dx
    223.         test al, 8
    224.         jz WaitVerticalSync
    225. WaitNotVerticalSync:in al, dx
    226.         test al, 8
    227.         jnz WaitNotVerticalSync
    228.         mov cx,SCREENSIZE/4
    229.         xor si,si
    230.         push ds
    231.         push es
    232.         pop ds;ds=screen_end
    233.         xor di,di
    234.         push VGA_SEGMENT
    235.         pop es
    236.         rep movsd
    237.         mov ds,cx;ds=0
    238.         mov ax,ds:[41Ah]
    239.         sub ax,ds:[41Ch]
    240.         pop ds
    241.         jz main
    242. exit:       mov ax,3
    243.         int 10h     ; - VIDEO - SET VIDEO MODE
    244.         int 20h
    245.  
    246. filename    db 'aqua11.bmp',0
    247. const1_5    dd 1.5
    248. const2_5    dd 2.5
    249. const60     dd 60.0
    250. const120    dd 120.0
    251. const003    dd 0.03
    252. end start

    Результат


    [​IMG]
     
    >Quiet Snow< нравится это.