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

Anis-эффект

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

  1. Mikl___

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

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

    Anis-эффект


    Как скролить (вправо-влево, вверх-вниз), надеюсь, вы знаете. Что такое полярные координаты, наверно то же. Так вот этот эффект основан на скролинге, но в полярных координатах.
    Соответственно скролинг вдоль координаты [math]r[/math] - выглядит как втягивание-вытягивание, а изменение угла [math]\alpha[/math] - как повороты по часовой стрелке или против. Вот и вся теория. Теперь начнется практика.
    Пусть центр нашего anis`a находиться в центре экрана. Тектуру, которую мы хотим вращать, возьмем размером 256x256. Основное требование к этой текстуре - быть бесшовной, чтобы удобно было скроллить. Посмотрите на мою текстуру, чтобы понять о чем речь:

    в не имеющих названия единицах, которых в круге 256. Теперь сопоставим углу [math]\alpha[/math] - координату [math]x[/math] в нашей текстуре, а координате [math]r[/math] - [math]y[/math] нашей текстуры.

    Теперь, что бы втягивать-вытягивать и вращать текстуру, достаточно изменить начальные смещения по [math]x[/math] и [math]y[/math] в нашей текстуры.

    Реализуем наши соображения в алгоритме, он разделится на две части:

    1. Инициализация.
    Заведем два массива texture и anis. В первом храним нашу текстурку, а во втором (типа unsigned short, размер такой же как у экрана) будем хранить смещения текстуры. Далее в цикле проходим по всем точкам массива anis, преобразуем декартовы координаты текущей точки в полярные, по этим координатам вычисляем смещение от начала массива texture, и заносим его в текущую ячейку массива anis:
    Код (C):
    1.   long x,y,u,v,p=0;
    2.   double angle, radius;
    3.   for(y=-100;y<100;y++)
    4.     for(x=-160;x<160;x++)
    5.     {
    6.       radius=sqrt(x*x+y*y);
    7.       if(radius<1) radius=1;
    8.       angle=atan2(y,x)+PI;
    9.       v=radius;
    10.       u=angle*128/PI;
    11.       anis[p++]=(u&0xFF)+((v&0xFF)<<8);
    12.     }
    2. Рендеринг.
    Для каждого выводимого кадра решаем насколько нам надо повернуть, втянуть-вытянуть нашу текстуру, то есть находим сдвиг по координате [math]r[/math] и углу [math]\alpha[/math]. В цикле проходим по массиву anis, считываем из него смещение, прибавляем вычисленный ранее сдвиг, и по этому смещению считываем пиксель из массива texture. Записываем его по текущим координатам в буфер экрана:
    Код (C):
    1. long u=256*cos(time);
    2.   long v=512*sin(time);
    3.   long screen_ptr=(long)&screen;
    4.   long i=0;
    5.   for(long k=0;k<64000;k++)
    6.     *((char*)screen_ptr++)=texture[(anis[i++]+u+(v<<8))&0xFFFF];
    Взято здесь, текст программы немного переделан, в результате СОМ-файл уменьшился с 668 байт до 428 байт
    Код (ASM):
    1. ; masm dos com #
    2. .286
    3. .model tiny
    4. .code
    5. .386
    6. org 100h
    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    ;регистр статуса ввода 0
    12. VGA_SEGMENT equ 0A000h
    13.  
    14. u       equ dword ptr [bp-4]
    15. v       equ dword ptr [bp-8]
    16. x       equ dword ptr [bp-12]
    17. y       equ dword ptr [bp-16]
    18. x2      equ dword ptr [bp-20];x2=x*x
    19. radius      equ dword ptr [bp-24]
    20. anis        equ word ptr [bp-26]
    21. texture     equ word ptr [bp-28]
    22. screen      equ word ptr [bp-30]
    23.  
    24. start:  mov sp,0FB0h
    25.     mov ah,4Ah ; ADJUST MEMORY BLOCK SIZE (SETBLOCK)
    26.     mov bx,0FBh; BX = new size  in paragraphs
    27.     int 21h; ES = segment address of block to change              
    28.     enter 30,0
    29.     mov bx,MEMBLOCKSIZE
    30.     mov ah,48h ; ALLOCATE MEMORY
    31.     int 21h ; BX = number of 16-byte paragraphs desired
    32.     mov screen,ax
    33.     mov bx,1000h
    34.     mov ah,48h ; ALLOCATE MEMORY
    35.     int 21h ; BX = number of 16-byte paragraphs desired
    36.     mov texture,ax
    37.     mov bx,MEMBLOCKSIZE*2
    38.     mov ah,48h ; ALLOCATE MEMORY
    39.     int 21h ; BX = number of 16-byte paragraphs desired
    40.     mov fs,ax;
    41.     mov anis,ax
    42.     mov ax,13h
    43.     int 10h     ; - VIDEO - SET VIDEO MODE
    44. ;read bmp-file--------------------------------------------------------------
    45.     mov dx,offset filename; DS:DX-> ASCIZ filename "texture.bmp"
    46.     mov ax,3D00h     ; OPEN FILE FOR READ
    47.     int 21h          
    48.     mov bx,ax
    49.     xor cx,cx
    50.     mov dx,54;Первые 54 байта - заголовок, в котором  хранится разнообразная информация о картинке.
    51.     mov ax,4200h; MOVE FILE READ/WRITE POINTER (LSEEK)
    52.     int 21h ; AL = method: offset from beginning of file
    53. ;Эта информация нам не нужна, так как мы и так знаем какую картинку считываем.
    54. ;Если наша картинка 8-битная то следующие 1024 байта занимает палитра нашей картинки.                
    55.     mov dx,offset pal
    56.     mov cx,1024
    57.     mov ah,3Fh         ; READ FROM FILE
    58.     int 21h     ; BX = file handle, CX = number of bytes to read
    59.     mov di,1023
    60. @@: shr pal[di],2
    61.     dec di
    62.     jns @b
    63.     push ds
    64.     mov ds,texture; word ptr ds:39Eh
    65.     mov dx,0FF00h
    66. @@:     mov cx,256  ;dx=y*256
    67.     mov ah,3Fh  ; READ FROM FILE
    68.     int 21h ; BX = file handle, CX = number of bytes to read
    69.     sub dh,1
    70.     jnc @b
    71.     pop ds
    72.     mov ah,3Eh ; CLOSE A FILE WITH HANDLE
    73.     int 21h    ; BX = file handle
    74. ;init_anis-----------------------------------------------
    75. ;Заведем два массива texture и anis. В первом храним нашу текстурку, а во втором
    76. ;(типа unsigned short, размер такой же как у экрана) будем хранить смещения текс
    77. ;туры. Далее в цикле проходим по всем точкам массива anis, преобразуем декартовы
    78. ;координаты текущей точки в полярные, по этим координатам вычисляем смещение от
    79. ;начала массива texture, и заносим его в текущую ячейку массива anis
    80.     xor di, di
    81.     mov es,anis
    82.     mov y,-HEIGHT_SCREEN/2
    83. a0: mov x,-WIDTH_SREEN/2
    84. a1: mov eax,x
    85.     imul eax
    86.     mov x2,eax;x2=x*x
    87.     mov eax,y
    88.     imul eax
    89.     add eax,x2
    90.     mov radius,eax;radius=y*y+x2
    91.     fild radius
    92.     fsqrt
    93.     fistp radius;radius=sqrt(x*x+y*y)
    94.     cmp radius,1;if (radius < 1) radius = 1;
    95.     jge @f
    96.     mov radius,1
    97. @@: fild x
    98.     fild y
    99.     fpatan
    100.     fldpi
    101.     faddp st(1), st   ;angle=atan2(y,x)+PI;
    102.     fmul const_128_pi
    103.     fistp x2          ;u=angle*128/PI;
    104.     mov ah,byte ptr radius
    105.     mov al,byte ptr x2
    106.     stosw;anis[p++]=(u&0xFF)+((v&0xFF)<<8);
    107.     test di,di
    108.     jnz @f
    109.     mov ax,es
    110.     add ax,1000h
    111.     mov es,ax
    112. @@: inc x
    113.     cmp x,WIDTH_SREEN/2
    114.     jl a1
    115.     inc y
    116.     cmp y,HEIGHT_SCREEN/2
    117.     jl a0
    118. ;set color table----------------------------------
    119.     xor bx,bx;mov bx,255*4
    120.     xor ax,ax
    121.     mov cx,256
    122. ;set rgb palette
    123.     mov dx,3C8h
    124.     out dx,al
    125.     inc dx
    126. @@: mov al,pal[bx+2];красный
    127.     out dx,al
    128.     mov al,pal[bx+1];зеленый
    129.     out dx,al
    130.     mov al,pal[bx];синий
    131.     out dx,al
    132.     add bx,4
    133.     loop @b
    134. ;-------------------------------------------------
    135. ;Рендеринг
    136. ;Для  каждого выводимого кадра решаем насколько нам надо повернуть, втянуть-
    137. ;вытянуть нашу текстуру, то есть находим сдвиг по координате r и углу alpha. В
    138. ;цикле проходимся по массиву anis, считываем из него смещение, прибавляем
    139. ;вычисленный ранее сдвиг, и по этому смещению считываем пиксель из массива
    140. ;texture. Записываем его по текущим координатам в буфер экрана:
    141.         fldz; time=0
    142. @@: fld st
    143.     fsincos
    144.     fmul    const_512
    145.     fistp   v        ;long v=512*sin(time);
    146.     fmul    const_256
    147.     fistp   u        ;long u=256*cos(time);
    148.     shl v,8      ;long screen_ptr=(long)&screen;
    149.     xor bx,bx ;long i=0;
    150.     mov es,screen;for(long k=0;k<64000;k++)
    151.     mov fs,anis  ;*((char*)screen_ptr++)=texture[(anis[i++]+u+(v<<8))&0xFFFF];
    152.     mov gs,texture
    153.     mov cx,SCREENSIZE
    154.     xor di,di
    155. a2: mov si,fs:[bx]
    156.     add si,word ptr u
    157.     add si,word ptr v
    158.     movs byte ptr es:[di],gs:[si]
    159.     inc bx
    160.     inc bx
    161.     jnz a3
    162.     mov ax,fs
    163.     add ax,1000h
    164.     mov fs,ax
    165. a3: loop a2
    166. ;copy virtual screen
    167.     mov dx,IMPUT_STATUS_0
    168. WaitVerticalSync:in al,dx
    169.     test al,8
    170.     jz WaitVerticalSync
    171. WaitNotVerticalSync:in al,dx
    172.     test al,8
    173.     jnz WaitNotVerticalSync
    174.     push VGA_SEGMENT
    175.     pop es
    176.     xor di,di
    177.     xor si,si
    178.     fadd const_001;time+=0.01
    179.     push ds
    180.     mov ds,screen
    181.     mov cx,SCREENSIZE/4
    182.     rep movsd
    183.     push 0
    184.     pop ds
    185.     mov ax,ds:[41Ah]
    186.     sub ax,ds:[41Ch]
    187.     pop ds
    188.     jz @b
    189. @@: mov ax,3
    190.     int 10h     ; - VIDEO - SET VIDEO MODE
    191.     int 20h
    192. const_001   dd 0.01
    193. const_128_pi    dd 40.743665431525205956834243423364;128/3.14
    194. const_256   dd 256.0
    195. const_512   dd 512.0
    196. filename    db 'texture.bmp'
    197. pal     db 0
    198. end start
    Берем файл texture.bmp
    [​IMG]
    в результате получаем следующий эффект
    [​IMG]
     

    Вложения:

    • anis.jpg
      anis.jpg
      Размер файла:
      41,7 КБ
      Просмотров:
      618
    • TEXTURE.zip
      Размер файла:
      28,5 КБ
      Просмотров:
      144
    • texture.jpg
      texture.jpg
      Размер файла:
      12,8 КБ
      Просмотров:
      594
    Последнее редактирование: 24 дек 2016