Bresenham will nicht



  • Ich habe versucht eine Bresenham linienzeichen funktion in Assembler zu schreiben, doch es kommt nur müll an.

    bresenham.inc

    ;+-------------------------------------------+
    ;|Desciptrion: Draws a line from xy1 to xy2  |
    ;|Parameter: x1,x2,y1,y2,color               |
    ;+-------------------------------------------+
    line proc far
        push bp
        mov bp,sp
        add sp,6
    
        mov ax,[bp+16]
        mov bx,[bp+18]
        sub ax,bx
        mov [bp-2],ax
        mov ax,[bp+12]
        mov bx,[bp+14]
        sub ax,bx
        mov [bp-4],ax
    
        mov ax,[bp+18]
        mov bx,[bp+14]
        push ax
        push bx
        push [bp+8]
        call putpixel
        mov di,[bp-2]
        mov si,[bp-4]
        mov dx,di
        shr dx,1
        mov cx,[bp+16]
    l1:
        inc ax
        sub dx,si
        cmp dx,0
        jge noerror
    
        inc bx
        add dx,ax
    
    noerror:
        push ax
        push bx
        push [bp+8]
        loop l1
    
        sub sp,6
        pop bp
        ret 10
    line endp
    

    test.asm

    .model tiny
    .186
    
    .code
    include mode.inc
    start:
        init
        push word 50
        push word 50
        push word 100
        push word 100
        push 5
        call line
    keypressed:
        in al,60h
        cmp al,1
        jne keypressed
        deinit
        mov ax,4c00h
        int 21h
    end start
    


  • ok, mal versuchen, das durchzugehen...

    ;+-------------------------------------------+
    ;|Desciptrion: Draws a line from xy1 to xy2  |
    ;|Parameter: x1,x2,y1,y2,color               |
    ;+-------------------------------------------+
    line proc far
        push bp
        mov bp,sp
        add sp,6            ; => sp zeigt auf Parameter color. War wohl nicht, was du wolltest? (Stack waechst nach unten!)
    
        mov ax,[bp+16]      ; ??? undefinierte Daten
        mov bx,[bp+18]      ; ???
    ; nehmen wir aber einfach mal an, das waeren x2 und x1, um den Rest zu pruefen.
        sub ax,bx           ; delta x
        mov [bp-2],ax       ; So schreibst du hier in einen nicht reservierten Stackbereich - spaetestens beim naechsten IRQ ist hier alles weg.
    ; gemeint war das aber wahrscheinlich als 1. von 3 auf dem Stack reservierten words, also weiter...
        mov ax,[bp+12]      ; zeigt nun auf x2
        mov bx,[bp+14]      ; " x1
    ; sollen wohl y2 und y1 sein...
        sub ax,bx           ; delta y
        mov [bp-4],ax       ; so.
    
        mov ax,[bp+18]      ; angenommen: x1
        mov bx,[bp+14]      ; ": y1
        push ax             ; hiermit zerschiesst du dir jetzt deine Ruecksprungadresse, wegen sp+6 oben.
        push bx
        push [bp+8]         ; zeigt auf y2 - ich nehme mal an, das soll color sein
        call putpixel       ; angenommen 1(!) Pixel bei x1,y1
    ;ab hier wird es nun erst richtig verworren...
        mov di,[bp-2]       ; angenommen delta x
        mov si,[bp-4]       ; angenommen delta y
        mov dx,di
        shr dx,1            ; /2
        mov cx,[bp+16]      ; zeigt auf ???; angenommen x2
    l1:
        inc ax              ; Wert von ax ist undefiniert; ++?
        sub dx,si           ; delta x / 2 - y ?
        cmp dx,0            ; ???
        jge noerror
    
        inc bx              ; Wert von bx ist undefiniert; ++?
        add dx,ax           ; delta x / 2 - y + summ?
    
    noerror:
        push ax             ; eine effiziente Methode den Stack zuzumuellen
        push bx             ; mehr passiert hier nicht.
        push [bp+8]         ; und zwar x2 mal ?
        loop l1
    
        sub sp,6            ; wenigstens konsequent
        pop bp
        ret 10              ; ab ins Nirvana.
    line endp
    

    test.asm

    .model tiny
    .186
    
    .code
    include mode.inc
    start:
        init
        push word 50
        push word 50
        push word 100
        push word 100
        push 5
        call line
    keypressed:
        in al,60h             ; sowohl DOS als auch das BIOS bieten fuer diesen Zweck
        cmp al,1              ; sehr schoene Funktionen an. Sowas macht kaum Sinn...
        jne keypressed
        deinit
        mov ax,4c00h
        int 21h
    end start
    


  • also überschreiben meine lokalen Variablen die echten Parameter und da wo ich denke, wo meine Parameter sind, ist nur Müll, weil ich add sp,4 statt sub sp,4 gemacht habe?

    Ist den wenigstens mein Ansatz, lokale Variablen zu erzeugen funktionsfähig?

    also anzahl bytes aller lokalen von sp subtrahieren und lokale variablen mit [bp-x] (wobei x irgendeine Zahl ist) anzusprechen?



  • Ja, um Platz auf dem Stack zu reservieren, ziehst du die gewuenschte anzahl Bytes von sp ab (im 16Bit-Modus, in dem dein Programm laeuft, muss sp dabei immer durch 2 teilbar bleiben - im 32Bit-Modus laesst man sp idR. durch 4 teilbar).
    Wie du bp setzt und damit adressierst, bleibt dir ueberlassen. So wie du es gemacht hast, sollte es im Grunde auch funktionieren. Schau dir das alles halt nochmal genau an ... wenn das mit dem Stack klappt auch deinen Bresenham und die Schleife dafuer.



  • nächstes problem, meine Linie mit dem Algorithmus wird krumm gezeichnet und nicht wie eine linie, woran könnte das liegen?

    Habe mal den Code ein wenig "verschönert", damit man ihn besser lesen kann

    [code]
    ;+-------------------------------------------+
    ;|Desciptrion: Draws a line from xy1 to xy2  |
    ;|Parameter: x1,x2,y1,y2,color               |
    ;+-------------------------------------------+
    x1_line		equ [bp+14]
    x2_line		equ [bp+12]
    y1_line		equ [bp+10]
    y2_line		equ [bp+8]
    color_line	equ [bp+6]
    
    deltax_line equ [bp-2]
    deltay_line equ [bp-4]
    line proc far
        push bp
        mov bp,sp
        sub sp,6
    
        mov ax,x2_line
        mov bx,x1_line
        sub ax,bx
        mov deltax_line,ax
        mov ax,y2_line
        mov bx,y1_line
        sub ax,bx
        mov deltay_line,ax
    
        mov ax,x1_line
        mov bx,y1_line
        push ax
        push bx
        push color_line
        call putpixel
        mov di,deltax_line
        mov si,deltay_line
        mov dx,di
        shr dx,1
        mov cx,x2_line
    l1:
        inc ax
        sub dx,si
        cmp dx,0
        jge noerror
    
        inc bx
        add dx,ax
    
    noerror:
        push ax
        push bx
        push color_line
        call putpixel
        loop l1
    
        add sp,6
        pop bp
        ret 10
    line endp
    [/code]
    


  • ALso ich hab den fehler gefunden. Der Fehler war, dass ich auf fehler den x wert addiert habe, anstatt den dx wert. Jetzt muss ich den bresenham nurnoch so umschreiben, dass er in alle Richtungen geht.


Anmelden zum Antworten