Ранее видел этот заумный способ рисовании линии на сайте , занялся переделкой на разные языки
Purebasic
Procedure dra(x1.l,y1.l,x2.l,y2.l)midx.l=(x1+x2)/2
midy.l=(y1+y2)/2
If midx<>x1 And midy<>y1
dra(midx,midy,x1,y1)
dra(x2,y2,midx,midy)
Box(midx,midy,1,1,$FFFFFF)
EndIf
EndProcedure
If InitSprite() And OpenWindow(0,0,0,640,480,"Recursive draw",#PB_Window_SystemMenu) And OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)
StartDrawing(ScreenOutput())
dra(0,0,640,480)
StopDrawing()
FlipBuffers()
Repeat
Until WindowEvent()=#PB_Event_CloseWindow
EndIf
Z80(оригинал, sjasmplus)
;http://retro666.rssing.com/browser.php?indx=7149388&item=40
;While attempting to write a game in 256 bytes I needed a routine to draw lines, but Bresenham's line algorithm weighs in at approx ~120 bytes. The only suitable alternative I'm aware of is recursive divide and conquer: divide a line into two smaller lines and call the draw routine with each in turn:;
;/* Draw a line from (ax,ay) to (bx,by) */
;
;int draw ( ax, ay, bx, by )
;{
; int midx, midy;
; midx = ( ax+bx ) / 2;
; midy = ( ay+by ) / 2;
; if ( midx != ax && midy != ay )
; {
; draw( midx, midy, ax, ay );
; draw( bx, by, midx, midy );
; plot( midx, midy );
; }
;}
;This is significantly smaller thank Bresenham's, 32 byte of Z80. However, there are a couple of compromises: it's slower and the lines aren't perfect because the rounding errors accumulate.
device zxspectrum128
ORG #6000
begin
ld hl,0,de,$FFBF
call DRAW
jr $
; draw lines using recursive divide and conquer
; from de = end1 (d = x-axis, e = y-axis)
; to hl = end2 (h = x-axis, l = y-axis)
DRAW:
call PLOT
push hl
; calculate hl = centre pixel
ld a,l
add a,e
rra
ld l,a
ld a,h
add a,d
rra
ld h,a
; if de (end1) = hl (centre) then we're done
or a
sbc hl,de
jr z,EXIT
add hl,de
ex de,hl
call DRAW ; de = centre, hl = end1
ex (sp),hl
ex de,hl
call DRAW ; de = end2, hl = centre
ex de,hl
pop de
ret
EXIT:
pop hl
ret
; ---------------------------
; plot d = x-axis, e = y-axis
PLOT:
push hl
ld a,d
and 7
ld b,a
inc b
ld a,e
rra
scf
rra
or a
rra
ld l,a
xor e
and 248
xor e
ld h,a
ld a,l
xor d
and 7
xor d
rrca
rrca
rrca
ld l,a
ld a,1
PLOTBIT:
rrca
djnz PLOTBIT
or (hl)
ld (hl),a
pop hl
ret
end
display /d,end-begin
savesna "!void.sna",begin
x86(Flat assembler), 98bytes
org 100huse16
mov al,13h
int 10h
xor cx,cx
xor dx,dx
mov bp,319
mov di,199
call drw
ret
;/* Draw a line from (ax,ay) to (bx,by) */
;int draw ( ax, ay, bx, by )
drw: ; ax=CX,ay=DX,bx=BP,by=DI
;{
; int midx, midy;
; midx = ( ax+bx ) / 2;
mov ax,cx
add ax,bp
shr ax,1
; midy = ( ay+by ) / 2;
mov si,di
add si,dx
shr si,1
; if ( midx != ax && midy != ay )
cmp ax,cx
je eif
cmp si,dx
je eif
; {
; draw( midx, midy, ax, ay );
push ax
push cx
push dx
push bp
push di
push si
mov bp,cx
mov di,dx
mov cx,ax
mov dx,si
call drw
pop si
pop di
pop bp
pop dx
pop cx
pop ax
; draw( bx, by, midx, midy );
push ax
push cx
push dx
push bp
push di
push si
mov cx,bp
mov dx,di
mov bp,ax
mov di,si
call drw
pop si
pop di
pop bp
pop dx
pop cx
pop ax
pusha
; plot( midx, midy );
mov cx,ax
mov dx,si
xor bh,bh
mov ax,0C0Fh
int 10h
popa
; }
eif:
ret
;INT 10h, 0Ch (12) Write Pixel
;
; Writes a pixel dot of a specified color at a specified screen
; coordinate.
;
; On entry: AH 0Ch
; AL Pixel color
; CX Horizontal position of pixel
; DX Vertical position of pixel
; BH Display page number (graphics modes with more
; than 1 page)
;
; Returns: None
;
; Registers destroyed: AX, SP, BP, SI, DI
Только качество хромает. Попробую разобраться. Исходники тут
Комментарии
Отправить комментарий