Рисование линии - Assembler

Узнай цену своей работы

Формулировка задачи:

Здравствуйте, прошу оказать помощь в выполнении задания. Требуется нарисовать линию: первая точка имеет координаты нажатия левой кнопки мыши, а вторая – правой. Нашел два кода для рисования линии, любой из них переделать бы (добавить вторую координату при нажатии правой кнопки мыши): 1) Здесь используется алгоритм Брезенхема, но здесь координата второй точки служит началом следующей линии.
.model tiny
.code
org 100h
.186
start:
      mov       ax, 12h ;X 12h+80h X ;включение видеорежима
      int       10h
      mov       ax, 0 ; проверка драйверов мыши
      int       33h
      mov       ax, 1 ;вывод курсора
      int       33h
 
      mov       ax, 000Ch ; создание обработчика события
      mov       cx, 0002h ; нажатие на левую кнопку мыши
      mov       dx, offset handler
      int       33h
 
      mov       ah, 0
      int       16h
      mov       ax, 000Ch ;удаляем 
      mov       cx, 0000h ;обработчик
      int       33h       ; событий
      mov       ax, 83h
      int       10h
      ret
; Обработчик событий от мыши
handler:
      push      0A000h
      pop       es
      push      cs
      pop       ds
      push      cx
      push      dx
 
      mov       ax, 2
      int       33h
 
      cmp       word ptr previous_X, -1
      je        first_point
 
      call      line_bresenham
exit_handler:
      pop    dx
      pop    cx
      mov    previous_X, cx
      mov    previous_Y, dx
 
      mov    ax, 1
      int    33h
 
      retf
 
first_point:
      call   putpixel1b
      jmp    short exit_handler
 
;Процедура рисования прямой линии
line_bresenham:
      mov      ax, cx
      sub      ax, previous_X
      jns      dx_pos
      neg      ax
      mov      word ptr X_increment, 1
      jmp      short dx_neg
dx_pos:
      mov      word ptr X_increment, -1
 
dx_neg:
      mov       bx, dx
      sub       bx, previous_Y
      jns       dy_pos
      neg       bx
      mov       word ptr Y_increment, 1
      jmp       short dy_neg
dy_pos:
      mov       word ptr Y_increment, -1
dy_neg:
      shl       ax, 1
      shl       bx, 1
 
      call      putpixel1b
 
      cmp       ax, bx
      jna       dx_le_dy
      mov       di, ax
      shr       di, 1
      neg       di
      add       di, bx
cycle:
      cmp       cx, word ptr previous_X
      je        exit_bres
      cmp       di, 0
      jl        fractlt0
      add       dx, word ptr Y_increment
      sub       di, ax
fractlt0:
      add       cx, word ptr X_increment
      add       di, bx
      call      putpixel1b
      jmp       short     cycle
 
dx_le_dy:
      mov       di, bx
      shr       di, 1
      neg       di
      add       di, ax
cycle2:
      cmp       dx, word ptr previous_Y
      je        exit_bres
      cmp       di, 0
      jl        fractlt02
      add       cx, word ptr X_increment
      sub       di, bx
fractlt02:
      add       dx, word ptr Y_increment
      add       di, ax
      call      putpixel1b
      jmp       short cycle2
exit_bres:
      ret
; Процедура вывода точки на экран
putpixel1b:
      pusha
      xor       bx, bx
      mov       ax, dx
      imul      ax, ax, 80
      push      cx
      shr       cx, 3
      add       ax, cx
      mov       di, ax
      mov       si, di
 
      pop       cx
      mov       bx, 0080h
      and       cx, 07h
 
      shr       bx, cl
      lods      es:byte ptr some_label
      or        ax, bx
      stosb
      popa
      ret
 
previous_X      dw      -1
previous_Y      dw      -1
Y_increment     dw      -1
X_increment     dw      -1
 
some_label:
 
           end  start
2) А здесь все линии начинаются с центра.
.model tiny
.486
.code
org 100h
start:
mov ax,13h
int 10h
 
xor ax,ax
int 33h
mov ax,1
int 33h
 
mov ax,12
mov cx,2
mov dx,offset handler
int 33h
 
xor ax,ax
int 16h
ret
 
handler:
  mov  ax,2
  int  33h
  push dx
  shr  cx,1
  push cx
  push 100
  push 160
  call line
  mov  ax,1
  int  33h
retf

line:
  push bp
  mov  bp,sp
  imul di,ss:[bp+6],320
  add  di,ss:[bp+4]
 
  mov  ax,ss:[bp+8]
  sub  ax,ss:[bp+4]
  sbb  bx,bx
  mov  dx,ss:[bp+10]
  sub  dx,ss:[bp+6]
  sbb  cx,cx
 
  mov  si,ax
  or   si,dx
  je   quit
 
  xor  ax,bx
  sub  ax,bx
  xor  dx,cx
  sub  dx,cx
 
  or   bx,1
  mov  si,cx
  xor  cx,320
  sub  cx,si
 
  cmp  ax,dx
  ja a
      xchg ax,dx
      xchg bx,cx
  a:
 
  push 0A000h
  pop  es
 
  mov  si,ax
  mov  bp,ax
  b:mov byte ptr es:[di],2
    sub si,dx
    jnl next
      add si,ax
      add di,cx
    next:
    add di,bx
    dec bp
  jne b
 
  quit:
  mov byte ptr es:[di],2
  pop bp
ret 8
 
end start
Не актуально.

Решение задачи: «Рисование линии»

textual
Листинг программы
    draw.line:
        ;рисование точки
        ;stdcall draw.add_op (x1:DWORD, y1:DWORD, x2:DWORD, y2:DWORD)
        draw.line.x1 equ [ebp+4*4-4] 
        draw.line.y1 equ [ebp+4*4-8]
        draw.line.x2 equ [ebp+4*4-12] 
        draw.line.y2 equ [ebp+4*4-16]
        
        push ebp
        lea ebp,[esp+8]
        pusha
        
        mov eax,draw.line.x2
        cmp eax,draw.line.x1
        ;прямые, параллельные Ox или Oy
        jne draw.line.not_vert
            ;рисуем вертикальную линию
            mov edx,draw.XRes
            shl edx,2
            
            mov eax,draw.line.y1
            cmp eax,draw.line.y2
            jc @f
                xchg eax,draw.line.y2
                mov draw.line.y1,eax
            @@:
            mov edi,draw.XRes
            imul edi,draw.line.y1
            add edi,draw.line.x1
            shl edi,2
            add edi,[draw.buff]
            
            mov eax,[draw.color]
            mov ecx,draw.line.y2
            sub ecx,draw.line.y1
            test ecx,80000000h
            jz @f
                neg ecx
            @@:
                mov [edi],eax
                add edi,edx
                dec ecx
                jnz @b
            jmp draw.line.exit
        draw.line.not_vert:
        mov eax,draw.line.y2
        cmp eax,draw.line.y1
        jne draw.line.not_hor
            ;рисуем горизонтальную линию    
            mov eax,draw.line.x1
            cmp eax,draw.line.x2
            jc @f
                xchg eax,draw.line.x2
                mov draw.line.x1,eax
            @@:
            
            mov edi,draw.XRes
            imul edi,draw.line.y1
            add edi,draw.line.x1
            shl edi,2
            add edi,[draw.buff]
            
            mov eax,[draw.color]
            mov ecx,draw.line.x2
            sub ecx,draw.line.x1
            rep stosd
            jmp draw.line.exit
        draw.line.not_hor:  
        ;с наклоном 45 градусов
        sub eax,draw.line.y1
        test eax,80000000h
        jz @f
            neg eax
        @@:
        mov ebx,draw.line.x2
        sub ebx,draw.line.x1
        test ebx,80000000h
        jz @f
            neg ebx
        @@:
        cmp ebx,eax
        jne draw.line.not_45    
            mov eax,draw.line.x1
            cmp eax,draw.line.x2
            jc @f
                xchg eax,draw.line.x2
                mov draw.line.x1,eax
            @@:
            mov ecx,ebx
            mov eax,draw.line.y2
            sub eax,draw.line.y1
            mov edx,01h
            test eax,80000000h
            jz @f
                neg edx
            @@:
            imul edx,draw.XRes
            inc edx
            shl edx,2
            
            mov edi,draw.XRes
            imul edi,draw.line.y1
            add edi,draw.line.x1
            shl edi,2
            add edi,[draw.buff]
            mov eax,[draw.color]
            @@:
                mov [edi],eax
                add edi,edx
                dec ecx
                jnz @b
            
            jmp draw.line.exit      
        draw.line.not_45:
        ;все остальные      
        mov edi,draw.line.y1
        mov edx,draw.XRes*4
        mov ebx,draw.line.y2
        sub ebx,draw.line.y1
        jnc @f
            mov edx,-draw.XRes*4
            neg ebx
        @@: 
        imul edi,draw.XRes
        add edi,draw.line.x1
        shl edi,2
        add edi,[draw.buff]
        
        mov eax,draw.line.x2
        sub eax,draw.line.x1
        mov ebp,4
        jnc @f
            mov ebp,-4
            neg eax
        @@:     
        
        mov esi,[draw.color]
        
        mov [draw.line.counter],00h
        cmp eax,ebx
        jc draw.line.Y
        draw.line.X:
            mov ecx,eax
            draw.line.X.loop:
                mov [edi],esi
                add edi,ebp
                add [draw.line.counter],ebx
                cmp [draw.line.counter],eax
                jc @f
                    add edi,edx
                    sub [draw.line.counter],eax
                @@:
                dec ecx
                jnz draw.line.X.loop
            jmp draw.line.exit
        draw.line.Y:
            mov ecx,ebx
            draw.line.Y.loop:
                mov [edi],esi
                add edi,edx
                add [draw.line.counter],eax
                cmp [draw.line.counter],ebx
                jc @f
                    add edi,ebp
                    sub [draw.line.counter],ebx
                @@:
                dec ecx
                jnz draw.line.Y.loop
            jmp draw.line.exit
        draw.line.dx dd 0
        draw.line.dy dd 0
        draw.line.counter dd 0
        
        draw.line.exit:
        
        popa
        ;возват из процедуры
        pop ebp
        pop eax
        add esp,4*4 ;общий размер передаваемых операндов
        push eax
        mov eax,00h
        ret

Оцени полезность:

14   голосов , оценка 3.929 из 5
Похожие ответы