Page 1 of 1

Рисование линий

PostPosted: Thu, 10.03.2016 13:31:40
by WBC
"по многочисленным просьбам трудящихся..." :)
В общем, по просьбе breeze решил выложить исходник DDA-рисовалки линии. Сразу скажу, что привычных координат x\y здесь нет - есть стартовый адрес, fixedpoint 0:8 приращение для одной из осей и количество шагов для противоположной, короче, вспоминайте матан :D

Вот сами процiдурки отдельно:
Code: Select all
; вход для x_line и y_line:
; DE - стартовый адрес на экране, переменная ScrPage где-то в памяти - номер текущей банки
; B - длина линии по одной из осей, C - fixedpoint 0:8 приращения для другой
; H - цвет линии; L = 0!

x_line   
    ; tryin' to write it :)
    ld    a, l
    add   c
    ld    l, a
    jr    nc, x_no_inc
    inc   d
    inc   d
    jr    nz, x_no_switch
    exx
    ld    a, (ScrPage)
    inc   a
    ld    (ScrPage), a
    ld    bc, PAGE3
    out   (c), a
    exx
    ld    d, #C0
x_no_switch
x_no_inc
    ld    a, h
    ld    (de), a
    inc   e                  ; inc\dec e for direction change
    djnz  x_line
    ret
 
y_line
    ; tryin' to write it :)
    ld    a, l
    add   c
    ld    l, a
    jr    nc, y_no_inc
    inc   e                  ; inc\dec e for direction change
y_no_inc
    ld    a, h
    ld    (de), a
    inc   d
    inc   d
    jr    nz, y_no_switch
    exx
    ld    a, (ScrPage)
    inc   a
    ld    (ScrPage), a
    ld    bc, PAGE3
    out   (c), a
    exx
    ld    d, #C0
y_no_switch
    djnz  y_line
    ret

Re: Рисование линий

PostPosted: Thu, 10.03.2016 13:33:37
by LessNick
Спасибо огромное!

Re: Рисование линий

PostPosted: Thu, 10.03.2016 13:37:51
by VBI
типо брезен_хам, утянуто и адаптировано.
юзается в инвитре zxe для вылета надписей. Cохраняет адреса точек, так как юзалась для GX/GY Ofsset:

Code: Select all
      ld de,(224/2)*256+(233/2)
      call line   ; DE (начало) и BC (конец)


/*
   Процедура  LINE  выводит  прямую линию
через 2 точки, координаты которых заданы в
регистрах   DE   (начало)  и  BC  (конец).
Процедура    PIXEL    выводит    точку   с
координатами в рег. DE (D-Y, E-X).

Недостатком  данной процедуры является то,
что  max  длина рассчитываемой линии - 127 точек. 
*/

LM1     LD H,E
        JR PM1
LM2     LD L,C
        JR PM2
LM3     LD H,A        ;dY=0, т.е. прямые
        LD (ST_XY),HL ;сегменты горизон-
        EXX           ;тальные
        LD C,L        ;большее расстояние
        LD L,H        ;в рег.C, меньшее в
        JR PM3        ;рег. L


line
   ; DE (начало) и BC (конец)
   ld (line_db_adress+1),hl   ; adress of stored XY data

   EXX
        LD DE,#1514   ;коды DEC D и INC D
        LD BC,#1D1C   ;коды DEC E и INC E
        EXX
        LD A,B
        SUB D         ;проверка Yк > Yн ?
        EXX           ;если да, то берем
        JR NC,LM1     ;код INC D, иначе
        NEG           ;берем модуль расс-
        LD H,D        ;тояния и код DEC D
PM1     EXX
        LD H,A        ;получили ?Yк-Yн?
        LD A,C
        SUB E         ;проверка Xк > Xн ?
        EXX           ;если да, то берем
        JR NC,LM2     ;код INC E, иначе
        NEG           ;берем модуль расс-
        LD L,B        ;тояния и код DEC E
PM2     LD (DI_XY),HL ;запись кодов
        EXX
        LD L,A        ;получили ?Xк-Xн?
        SUB H         ;определяем тип
        EXX           ;прямых сегментов
        LD A,0
        JR NC,LM3
        LD L,A        ;dX=0, т.е. прямые
PM0     LD (ST_XY),HL ;сегменты верти-
        EXX           ;кальные
        LD C,H        ;см. прим. к LM3
PM3     LD B,A        ;A=0!
        LD H,A        ;A=0!
        ADD HL,HL     ;удваиваем меньшее
        LD (ST_CO+1),HL ;расстояние
        SBC HL,BC     ;вычисляем:
        OR A          ;2 x меньшее минус
        SBC HL,BC     ;2 x большее
        LD (DI_CO+1),HL
        ADD HL,BC     ;счетчик цикла в
        LD A,C        ;рег. A=большему
PIXEL   PUSH HL       ;расстояию
        BIT 7,H       ;HL-фактор вырав-

line_db_adress   ld hl,#7000
      ld (hl),e
      inc hl
      ld (hl),d
      inc hl
      ld (line_db_adress+1),hl

        POP HL
        JR Z,DI_XY    ;вывод прямых
ST_XY   DW 0          ;сегментов и
ST_CO   LD BC,0       ;пересчет фактора
        JR DECDIST    ;выравнивания
DI_XY   DW 0          ;вывод диагональных
DI_CO   LD BC,0       ;сегментов и
DECDIST ADD HL,BC     ;пересчет фактора
        DEC A
        JP nz,PIXEL    ;следующая точка
   ld hl,(line_db_adress+1)
   ld a,#ff
   ld (hl),a
   inc hl
   ld (hl),a
        RET

несмотря на обьёмность кода, основное здесь - это вычисление направления и прироста.
основной цикл вычислений маленький.

Re: Рисование линий

PostPosted: Thu, 10.03.2016 13:53:49
by g0blinish
Code: Select all
    exx
    ld    a, (ScrPage)
    inc   a
    ld    (ScrPage), a
    ld    bc, PAGE3
    out   (c), a
    exx

вот здесь лучше ускорить.
например, BC'=PAGE3,
E'=ScrPage

тогда
сразу
INC E
OUT(C),E

и с HL:

ld a, h
ld (de), a

тоже медленно. Увидеть бы оригинал исходник.

Re: Рисование линий

PostPosted: Thu, 10.03.2016 14:49:51
by WBC
g0blinish wrote:Увидеть бы оригинал исходник.

это и есть оригинал :) но да, ускорить там много чего можно

Re: Рисование линий

PostPosted: Thu, 10.03.2016 15:17:07
by g0blinish
кстати, еще непонятно, каков критерий выбора x_line/y_line?

Re: Рисование линий

PostPosted: Thu, 10.03.2016 16:52:56
by g0blinish
еще про просьбе breeze построение точек:

сначала формирование табличек - страничка и адрес линии.
Code: Select all
lutpl equ $6000;;bank, MSB addres=2*$100
 ld hl,lutpl
  push hl
  ld de,hl
  inc de
  ld (hl),0
  ld bc,511
  ldir
  pop hl
  ld de,$C020;bank #
lulp1:
 ld (hl),e;bank
 inc h
 ld (hl),d
 dec h

 inc d,d
 ld a,d:or a
 jr nz,nonextbank
 ld d,$c0
 inc e
nonextbank:
 inc l
 ld a,l
 cp 200:jr nz,lulp1


а теперь построение точки:
Code: Select all
 exx
;DE=Y.X, ixl-цвет точки
 ld h,lutpl/256
 ld l,d;Y and bank
 ld a,(hl)
 or a:jr z,nextp
 inc h
 LD   BC,RAMPage3
 OUT   (C),A
 ld h,(hl)
 ld l,e;suppose X
 ld a,ixl
colr: ld (hl),a
nextp:
 exx


Естественный недостаток - значения координат от 0 до 255, пока не придумал, как лучше сделать при построении точки 320х200. Вроде в Carousel было такое.

Re: Рисование линий

PostPosted: Thu, 10.03.2016 18:22:56
by LessNick
g0blinish wrote:про просьбе breeze построение


Большое спасибо! Главное посты не потерять теперь :vodka:

Re: Рисование линий

PostPosted: Thu, 10.03.2016 18:43:38
by g0blinish
breeze wrote:Большое спасибо! Главное посты не потерять теперь


Напомнишь, если чо:(