The MASM Forum

Miscellaneous => 16 bit DOS Programming => Topic started by: tda0626 on May 19, 2024, 06:22:25 AM

Title: Line Drawing
Post by: tda0626 on May 19, 2024, 06:22:25 AM
I got a basic line drawing routine but I want it to stop it from wrapping around like in the image below if the slope value starts increasing.
(https://i.postimg.cc/87xLSxPq/Capture.jpg) (https://postimg.cc/87xLSxPq)

.model small


Stack SEGMENT STACK
DW 256 DUP(?)
Stack ENDS

.data

red db 028h
x DW ?
DW ?
slope DW ?

.code

_main proc

mov ax, @data
mov ds, ax

mov ax, 0A000h ;video memory
mov es, ax
xor di, di

mov ah, 0 ; 320 x 200
mov al, 013h
int 10h

mov x, 0 ; Starting Coordinates
mov y, 0
mov cx, 100 ; 100 pixel line
mov slope, 3 ; Slope of the line

DrawLine:

mov ax, y ; Calculate offset in video memory
mov bx, 320 ; Y * 320 + X
mul bx
add ax, x

mov di, ax ; Set DI to our offset value
mov al, red
mov es:[di], al ; Write a red pixel to memory


cmp cx, 0
je EndLine

mov ax, y ; Add the slope to the line
add ax, slope
mov y, ax
inc x

dec cx
jmp DrawLine

EndLine:

mov ah, 0 ; wait for key press
int 16h

mov ax, 04c00h ; exit
int 21h

_main endp
end _main
Title: Re: Line Drawing
Post by: zedd151 on May 19, 2024, 06:28:37 AM
Once you have clearly defined boundaries, you must tell the program what to do once a boundary is met.
Change direction, stop, start at a new x,y position, etc.
I don't know how to do it in 16 bit and as you have coded it, but it shouldn't be very difficult to implement.
You should be able to draw the lines as if it were a bouncing ping pong ball (staying within the boundaries), is that what you had in mind? (Where the lines appear to be bouncing off the 'walls'?).

After looking at the code again...
        dec cx
        jmp DrawLine
that jump should be jnz maybe, rather than jmp???
Then you wouldnt need the
cmp cx, 0
je EndLine
further up in the code.

Title: Re: Line Drawing
Post by: NoCforMe on May 19, 2024, 06:57:57 AM
Your "slope" isn't really the slope of the line (your actual slope is negative), but let's not worry about that for the moment: it's really the offset to the next y-position down for the next drawn pixel.

Your problem is not that the "slope" is increasing (it's not, it stays constant at 3) but that you're hitting the bottom line and wrapping around in the video buffer. So if you want to stop drawing at the bottom of the screen, then check to see if your y-position is at or past the bottom line, then exit your loop. (I'll leave it up to you to figure out how to determine that.)

Hint: at least two ways to do that:
1. Set your loop counter to a value that you know will only draw pixels to the bottom of the screen and stop.
2. Check the value of y each time through the loop to see if it's at the bottom of the screen.
Title: Re: Line Drawing
Post by: tda0626 on May 19, 2024, 08:20:51 AM
Quote from: NoCforMe on May 19, 2024, 06:57:57 AMHint: at least two ways to do that:
2. Check the value of y each time through the loop to see if it's at the bottom of the screen.


Thanks, I got it to work. I was overthinking it for some reason when it was simple. I also added checks for the other screen borders.

How would I implement a slope? I want to eventually input start and end coordinates.

Title: Re: Line Drawing
Post by: NoCforMe on May 19, 2024, 08:32:10 AM
Remember high-school algebra?

Given 2 points, (x1,y1) & (x2, y2):

m = y2 - y1 / x2 - x1

m is the slope.
Title: Re: Line Drawing
Post by: tda0626 on May 19, 2024, 10:01:20 AM
Quote from: NoCforMe on May 19, 2024, 08:32:10 AMRemember high-school algebra?

Given 2 points, (x1,y1) & (x2, y2):

m = y2 - y1 / x2 - x1

m is the slope.

I know that. Usually the Y values are going to be smaller than the x values so we end up with a fraction but thanks anyway. I will see if I can find something on the Internet that explains it better.

Title: Re: Line Drawing
Post by: NoCforMe on May 19, 2024, 10:28:23 AM
You do end up with fractions. That's one of the problems you have to solve. (See below for one possible solution.)

I think you meant the delta-Y values are going to be smaller than the delta-X values, but that's only true if the slope is less than 1 (45°).

Fractions: since you aren't using floating-point (I'm assuming: you could, but that's another whole ball o'wax), here's a way to deal with fractions: scaling up and scaling down.

Let's say you have a line with a slope of 0.5 (0,0)--> (6,3).
Use a scaling factor of let's say 100. Using the slope formula above, multiply delta-Y (the change in Y) by 100, then divide by delta-X:

(3-0) * 100 / (6-0) = 50

So our "slope" (scaled) is 50.
To plot a point, use the formula above, use 50 as the slope, then divide the result by the scaling factor (100) to calculate the actual coordinates.

Title: Re: Line Drawing
Post by: NoCforMe on May 19, 2024, 10:53:41 AM
Your question is a non-trivial one. I just revisited some of my old line-drawing code which I hadn't looked at in years.

I did use scaling like I explained above. Thing is, since you're dealing with fractional values here, you need to keep an accumulator going to draw a line. Otherwise, let's say the slope is 0.5, you're never going to get any change in Y if you just go pixel-by-pixel since the incremental delta-Y value is less than one, therefore zero in integer arithmetic.

The basic idea is you start at your starting point, let's call it (x0, y0). Since you want a solid line and not a dotted one like you drew, we'll set our delta-X at 1, meaning we'll always move 1 pixel to the right.

The problem then becomes one of determining what our Y-position is for each pixel (we know what our X-position is because it increases by 1 each step). That's a matter of using scaling as shown above and calculating each next Y-position.

I'll leave it as an exercise for you. I'd suggest getting out paper and pencil and drawing lines to figure it out. Works for me, anyhow.

Hopefully this makes sense to you.
Title: Re: Line Drawing
Post by: NoCforMe on May 19, 2024, 11:05:07 AM
Here's my line-drawing routine. Not necessarily suggesting you copy and use it (you could if you wanted to), but it does work, so it might tell you something.

It even fills in "sparse" lines (lines with gaps between pixels) to make them look smoother.

The structure passed in in BX contains the starting and ending coordinates.

$slopeFactor EQU 100

DrawLine LABEL NEAR
; Draws a line from (x0, y0) to (x1, y1)
;
; On entry,
; ES:BX--> $LineStruct structure

; Get rise, run:
MOV AX, ES:[BX.$$gl_x1]
SUB AX, ES:[BX.$$gl_x0]
MOV Xdistance, AX
MOV AX, ES:[BX.$$gl_y1]
SUB AX, ES:[BX.$$gl_y0]
MOV CX, AX

; Determine if slope positive or negative:
TEST AX, 8000h
JZ dl_pos
MOV AX, -1 ;Slope negative.
MOV NegFlag, 1
NEG CX
JMP SHORT drw2

dl_pos: MOV AX, 1
MOV NegFlag, 0
drw2: MOV DeltaYsign, AX
MOV AX, CX ;Get Ydistance back.

; Calculate slope (y1-y0/x1-x0):
MOV DX, $slopeFactor
IMUL DX
IDIV Xdistance
MOV DeltaY, AX ;This is amount (fractional) to add to Y each time.
; Draw line:
drw5: MOV Y_accum, 0
MOV CX, Xdistance

MOV AX, ES:[BX.$$gl_x0]
MOV CurrX, AX
MOV AX, ES:[BX.$$gl_y0]
MOV CurrY, AX

MOV AL, ES:[BX.$$gl_Color]
MOV CurrColor, AL
dl_loop:
CALL DrawPixel
MOV AX, CurrY
MOV LastY, AX
; Move 1 notch on x-axis, determine new y-position:
INC CurrX ;Next X increment.
MOV AX, DeltaY
ADD Y_accum, AX ;Add increment to accumulator.
MOV AX, Y_accum
XOR DX, DX
IDIV SlopeFactor
CMP NegFlag, 1
JNE drw20
SUB CurrY, AX
JMP SHORT drw22
drw20: ADD CurrY, AX

; Adjust accumulator:
drw22: IMUL SlopeFactor
SUB Y_accum, AX ;Take out whole-number part.

; Fill in "sparse" lines:
drw30: MOV AX, CurrY
SUB AX, LastY
JNC drw33
NEG AX
drw33:
CMP AX, 1
JBE drw40 ;If increment <= 1, no need to fill in.
MOV AX, LastY
ADD AX, DeltaYsign ;Add or subtract 1, depending on slope sign.
MOV LastY, AX
PUSH CurrY
MOV CurrY, AX
DEC CurrX ;Fill in behind where we are now.
CALL DrawPixel ;Fill in line.
POP CurrY
INC CurrX
JMP drw30

drw40: LOOP dl_loop
drw99: RET
Title: Re: Line Drawing
Post by: daydreamer on May 19, 2024, 03:37:33 PM
@sudoku
You are only limited to use 16 bit registers indirect addressing ,you can use 32 bit registers too
Rol eax,16 to get two different ax regs
Fractions without fpu ,check Raymond's fixed point tutorial
Been Curious if use fpu for line drawing produces smallest code ?

When Using es pointing to a000h ,shortest code to write a pixel
Stosb
Dec di
Use di as indirect register is simplest




Title: Re: Line Drawing
Post by: tda0626 on May 20, 2024, 12:56:11 AM
After some studying up on the subject, I came across Bresenham's line drawing algorithm so my program uses that to draw the line. However, at this point, it can only do values x1 < x2 & y1 < y2 but I intend to add more functionality to it in the near future.

After I got the code in my source file, it wasn't working. Took me a bit to figure it out but it looked like it wasn't treating PCorrect as a negative number when its value should sometimes be negative. Added a check to see if the most significant bit is set and now it seems to work. If someone would like to look over the code and point out other possible bugs, please do. Thanks!


.model small


Stack    SEGMENT STACK
    DW 256 DUP(?)
Stack    ENDS

.data

red    db    028h
x        DW    ?        ; used to keep track of x position for draw routine
y          DW    ?        ; used to keep track of y position for draw routine
x1        DW    ?        ; x1 and x2 are used to calculate deltax value
x2        DW    ?
y1        DW    ?        ; y1 and y2 are used to calculate deltay value
y2        DW    ?
deltax    DW    ?        ; deltax and deltay are used to calculate initial value of PCorrect
deltay    DW    ?        ; also they are used in draw routine for pixel correction calculation
PCorrect    DW    ?    ; Pixel Correction

.code

_main proc

mov ax, @data
    mov ds, ax
   
    mov ax, 0A000h        ;video memory
    mov es, ax
    xor di, di
   
    mov ah, 0            ; 320 x 200 mode
    mov al, 013h
    int 10h
   
    mov x1, 2            ; Coordinates of our line (x1,y1) & (x2,y2)
    mov x2, 300
    mov y1, 2
    mov y2, 20
    mov ax, x1
    mov x, ax            ; set our starting x and y values for draw routine
    mov ax, y1
    mov y, ax
   
    mov ax, x2            ; Calculate X2-X1 and store in delta x
    sub ax, x1
    mov deltax,  ax
   
    mov ax, y2            ; Calculate Y2-Y1 and store in delta y
    sub ax, y1
    mov deltay, ax
   
    mov ax, deltay        ; Set our Pixel Correction Value
    mov bx, 2            ; PCorrect = 2 * delta y - delta x
    imul bx                ; Pixel Correction checks to see which Pixel
    mov bx, deltax        ; is closer out of two pixels when the line intersects two pixels
    sub ax, bx
    mov PCorrect,  ax
   
   
   

   
    DrawLine:
               
        mov ax, x        ; If x==x2 we are done drawing the line
        cmp ax, x2
        je EndLine
   
        mov ax, y        ; Calculate offset in video memory
        mov bx, 320        ; Y * 320 + X
        mul bx
        add ax, x

        mov di, ax        ; Set DI to our offset value
        mov al, red
        mov es:[di], al    ; Write a red pixel to memory
       
        inc x                    ; increment x to draw next position
        mov ax, PCorrect            ; Check to see if Pixel Correction is a negative number
        test ax, 08000h
        js Lessthan
       
       
            mov ax,deltay        ; Pixel Correction = PCorrect + 2 * deltay - 2 * deltax
            mov bx, deltax        ; If line is closer to the pixel in the next row, inc y
            sub ax, bx
            mov bx, 2
            imul bx
            add PCorrect, ax
            mov ax, deltay
            inc y
            jmp DrawLine
        Lessthan:
            mov ax, deltay        ; If the line is closer to the adjacent pixel closest to our current position
            mov bx, 2            ; Pixel Correction = PCorrect + 2 * deltay
            imul bx
            add PCorrect, ax
            jmp DrawLine
       
    Endline:   
   
    mov ah, 0            ; wait for key press
    int 16h
   
    mov ax, 04c00h        ; exit
    int 21h
   
_main endp
end _main


Output:

(https://i.postimg.cc/SJM60k8p/Capture.jpg) (https://postimg.cc/SJM60k8p)
Title: Re: Line Drawing
Post by: daydreamer on May 20, 2024, 01:39:31 AM
Seen in Bresenham line algo code before it starts with cmp x1,x2 and cmp y1,y2 and exchange coordinates if x1>x2  and y1>y2
Title: Re: Line Drawing
Post by: NoCforMe on May 20, 2024, 03:31:06 AM
Quote from: tda0626 on May 20, 2024, 12:56:11 AMAfter some studying up on the subject, I came across Bresenham's line drawing algorithm so my program uses that to draw the line.
Congrats; that's some pretty fancy stuff.

One tiny improvement: you might want to get into the habit of minimizing instructions when doing things like multiplication and division. Instead of your
        mov ax, y        ; Calculate offset in video memory
        mov bx, 320        ; Y * 320 + X
        mul bx
you can get rid of an instruction:
        mov ax, 320
        mul y
since mul multiplies whatever is in AX by the multiplier (y in this case).
Title: Re: Line Drawing
Post by: NoCforMe on May 20, 2024, 03:36:27 AM
BTW, I'm sure you've realized that you need to deal with the problem of coordinate systems here. If you ask your user for line coordinates they're going to expect them to be in Cartesian space, where y-values increase going up, whereas your actual coordinates in memory increase going down. (Fortunately x-values are the same in both cases.)
Title: Re: Line Drawing
Post by: tda0626 on May 20, 2024, 07:18:05 AM
Quote from: NoCforMe on May 20, 2024, 03:36:27 AMBTW, I'm sure you've realized that you need to deal with the problem of coordinate systems here. If you ask your user for line coordinates they're going to expect them to be in Cartesian space, where y-values increase going up, whereas your actual coordinates in memory increase going down. (Fortunately x-values are the same in both cases.)


Maybe. It might be a case of inverting the the y by subtracting the y given from the y max value but don't know if I want to go that far. We will see.

In any case, I think my next step is to treat each quadrant in its own routine and to get that working. Unfortunately, due to work, I won't be able to work on it till the end of the week. Out of town...

Tim
Title: Re: Line Drawing
Post by: NoCforMe on May 20, 2024, 09:20:36 AM
Quote from: tda0626 on May 20, 2024, 07:18:05 AMIt might be a case of inverting the the y by subtracting the y given from the y max value but don't know if I want to go that far. We will see.
If you do, the formula would be really simple:
Yactual = -YCartesian + Ymax

Title: Re: Line Drawing
Post by: FORTRANS on May 20, 2024, 10:19:28 PM
Hi Tim,

Quote from: tda0626 on May 20, 2024, 07:18:05 AMIn any case, I think my next step is to treat each quadrant in its own routine and to get that working.

   The last time I tried coding a general purpose line drawing routine,
I wrote code for the four quadrants, horizontal lines, vertical lines,
and the two diagonal lines.  Those last four could be coded up rather
easily, and could be faster than a general purpose line drawing routine.

Regards,

Steve

Edit:   With the four special case lines, it should be eight octants, not
four quadrants.

SRN
Title: Re: Line Drawing
Post by: daydreamer on May 21, 2024, 05:33:59 AM
Steve try port your old code to 32 bit using ddraw or SDL interface to access Max hires screen memory in win32 coding ?
I tried bresenham circle algo and pixelshader approach to use sqrt( x^2+y^2 )
Title: Re: Line Drawing
Post by: NoCforMe on May 21, 2024, 01:27:31 PM
Quote from: FORTRANS on May 20, 2024, 10:19:28 PMThe last time I tried coding a general purpose line drawing routine,
I wrote code for the four quadrants, horizontal lines, vertical lines,
and the two diagonal lines.
I understand everything except why you deal differently with "diagonal" lines (I assume by this you mean lines where the slope is exactly 1 or -1, right?) Why would you need to do that?

I checked with my old DIY line-drawing routine and it works fine with "diagonal" lines.
Title: Re: Line Drawing
Post by: FORTRANS on May 22, 2024, 12:16:31 AM
Hi,

Quote from: NoCforMe on May 21, 2024, 01:27:31 PMI understand everything except why you deal differently with "diagonal" lines (I assume by this you mean lines where the slope is exactly 1 or -1, right?) Why would you need to do that?

   It has been a while since I last looked at it, but it was either
for increased speed or reduced "bookkeeping".  For either it allows
for not updating variables and testing for when to update things.
Just run a loop to its end.

Regards,

Steve N.
Title: Re: Line Drawing
Post by: FORTRANS on May 22, 2024, 03:55:08 AM
Hi,

   Looked at some old notes, not any actual code.  I was
trying to get the fastest code possible.  Mostly in mode
6 screen format (640x200x1).  Also mode 13 and some VESA
modes.  It looks as if I spent way too much time and effort
for what I finally ended up using.

   I looked at line drawing code by Abrash, Wilton, and the
Waite Group.  And tried out some different algorithms with
my own code.  Including drawing from both ends to meet in
the middle.

   The slow mode 6 code that started the whole exercise was
more flexible and useful in the end.  Speeded it up a little
bit, but not as much as I had wanted.  Basically, I needed
a routine that allowed for differing pixel types for drawing
things like fat lines or XORed lines.  All the faster line
drawing routines had only one type of pixel, direct writing
to the screen.

Cheers,

Steve N.

Cheers,

Steve N.
Title: Re: Line Drawing
Post by: NoCforMe on May 22, 2024, 02:25:02 PM
Quote from: FORTRANS on May 22, 2024, 03:55:08 AMLooked at some old notes, not any actual code.  I was
trying to get the fastest code possible.  Mostly in mode
6 screen format (640x200x1).  Also mode 13 and some VESA
modes.  It looks as if I spent way too much time and effort
for what I finally ended up using.
Steve, have a look at what I posted on the subject in the Workshop (https://masm32.com/board/index.php?topic=11960.0).
I can't for the life of me figure why your code was so complicated. Mine has exactly 4 cases:
o Horizontal and vertical lines are drawn separately, since the general drawing code would fail on them;
o Lines where Y0 > Y1 are simply mirrored (the endpoints are swapped) and drawn "backwards";
o Otherwise, all line drawing is handled by the same code, regardless of quadrant/octant.

So instead of caring about quadrants/octants, I only care about what I guess you could call left or right vertical halves (regarding that Y0 > Y1 business).

Now I'm certainly not claiming any speed records, but it seems to be reasonably fast, and not overly complicated.
Title: Re: Line Drawing
Post by: FORTRANS on May 22, 2024, 10:45:16 PM
Hi,

Quote from: NoCforMe on May 22, 2024, 02:25:02 PMI can't for the life of me figure why your code was so complicated. Mine has exactly 4 cases:

   I was trying every and any thing.  It got complicated in an attempt
to speed things up by special casing things and trying to optimize the
specific routines separately.  Essentially lots of special code to
replace general purpose code.  If you try every thing, most will end up
being rather bad.  Throw the bad out and try using what's left over.

   It was interesting at the time.  And may have taught me something.
But not useful in general, I suppose.

Regards,

Steve N.
Title: Re: Line Drawing
Post by: NoCforMe on May 23, 2024, 03:52:23 AM
Well, don't feel too bad. Even our most abject failures tend to teach us something useful.
Title: Re: Line Drawing
Post by: tda0626 on May 23, 2024, 05:30:12 AM
I was going to implement this from the Bresenham Algo wiki. Looks like it checks for 4 cases. What other cases would there be?



plotLine(x0, y0, x1, y1)
    if abs(y1 - y0) < abs(x1 - x0)
        if x0 > x1
            plotLineLow(x1, y1, x0, y0)
        else
            plotLineLow(x0, y0, x1, y1)
        end if
    else
        if y0 > y1
            plotLineHigh(x1, y1, x0, y0)
        else
            plotLineHigh(x0, y0, x1, y1)
        end if
    end if

Title: Re: Line Drawing
Post by: NoCforMe on May 23, 2024, 05:59:29 AM
Can your plotLineXXX() routines handle horizontal and vertical lines? Those would be the other two cases to check for, I would think. (If the plot routine can handle horiz. & vert., no need to check for them.)

Remember: horizontal: slope = 0. Vertical: slope =
Title: Re: Line Drawing
Post by: tda0626 on May 23, 2024, 08:05:31 AM
Don't think it will be an issue.
Title: Re: Line Drawing
Post by: tda0626 on May 28, 2024, 06:32:33 AM
I have been at this for awhile now and can't figure this problem out so I am asking for some help.

I am trying to get this new line drawing program to work where it draws the different types of lines except vertical and horizontal ones, which will be taken care of later. When drawing from top-right to bottom-left or vice versa, it does not draw correctly, see the picture attached and the source code to this post . This has me stumped! If someone could look over my code and let me know if they see what the issue is, it would be appreciated. Thanks!


(https://i.postimg.cc/WFw0xR55/Capture.jpg) (https://postimg.cc/WFw0xR55)
Title: Re: Line Drawing
Post by: _japheth on May 28, 2024, 11:34:28 AM
Quote from: tda0626 on May 28, 2024, 06:32:33 AMI am trying to get this new line drawing program to work where it draws the different types of lines except vertical and horizontal ones, which will be taken care of later. When drawing from top-right to bottom-left or vice versa, it does not draw correctly, see the picture attached and the source code to this post . This has me stumped! If someone could look over my code and let me know if they see what the issue is, it would be appreciated. Thanks!

I also once implemented the Bresenham thing. Your algorithm for PCorrect was definitely wrong.

Attached is your modified sample. It should work. I also added an implementation of mine, which is now deactive, but may be activated.
Title: Re: Line Drawing
Post by: tda0626 on May 28, 2024, 08:51:21 PM
Quote from: _japheth on May 28, 2024, 11:34:28 AMI also once implemented the Bresenham thing. Your algorithm for PCorrect was definitely wrong.


Thank you for all you do!

Would you mind going into more detail why PCorrect is wrong? I got the PCorrect calculation from the Bresenham Line Algo page:

plotLineLow(x0, y0, x1, y1)

D = (2 * dy) - dx

plotLineHigh(x0, y0, x1, y1)

D = (2 * dx) - dy


Also, what is @f in the code? I have never seen that.


Tim
Title: Re: Line Drawing
Post by: zedd151 on May 28, 2024, 08:55:55 PM
Quote from: tda0626 on May 28, 2024, 08:51:21 PMAlso, what is
@f in the code? I have never seen that.

it means jump forward to the next (anonymous) label.
@@:  is an anonymous label --- Its kind of a shortcut. if you ever need a quick label and cant come up with a good name.

you can jump forward to it " jxx @f" or jump backward to it "jxx @b" with any of the jxxx jumps
The @f and @b can be either case, upper or lower. short example of usage:
jnz @f
some code here
@@: <---- anonymous label
some other code
jmp @b

Mistakes can happen if used multiple times, without taking care where the next anonymous label is located - resulting in jumping to wrong anonymous label, or worse getting stuck in endless loop. Best to use named labels if that happens to you too often.  (from experience
 :tongue:  )
Title: Re: Line Drawing
Post by: _japheth on May 28, 2024, 09:47:03 PM
Quote from: tda0626 on May 28, 2024, 08:51:21 PMWould you mind going into more detail why PCorrect is wrong? I got the PCorrect calculation from the Bresenham Line Algo page:

Ok, I cannot comment the "Bresenham Line Algo page" - what I coded is about 28 years old, but IMO it's pretty straitforward:

For a flat line ( dx > dy ), the "PCorrect" is initialized with "-dx". Then a loop is entered, where
- x is incremented
- dy is added to PCorrect
- if PCorrect "overflows" ( meaning the total of dy's exceeds dx ), y is incremented/decremented and dx is subtracted from PCorrect.

That seems intuitively correct to me and - as an aside - it works.
Title: Re: Line Drawing
Post by: tda0626 on May 29, 2024, 08:15:26 AM
@Sudoku Thanks for explanation.

@_japheth I will have to study your code when I get a chance. Thanks for offering it!


I found what was wrong with my code. I knew it was something to do with the PlotLineLow routine and the PCorrect calculation because that would be the routine it would be using. The negative deltay was not playing nicely with my PCorrect calculation so I added an ABS(deltay) in the code with the conditional statements when determining which branch it should take depending on the value of PCorrect. Now it seems to be drawing correctly from right-top to bottom-left and vice versa, see picture attached to this thread.


Tim
(https://i.postimg.cc/ZvWd1HMq/Capture.jpg) (https://postimg.cc/ZvWd1HMq)

Title: Re: Line Drawing
Post by: NoCforMe on May 29, 2024, 09:19:22 AM
Quote from: tda0626 on May 28, 2024, 08:51:21 PMAlso, what is
@f in the code? I have never seen that.
Easy one, I can answer that:
@@: creates an "anonymous" jump target label so you don't have to scratch your head to come up with a name.
@F (or @f, doesn't matter) used with a jump instruction jumps forward to the next @@: label. @B jumps back to the next previous label:
    CMP  AX, -1
    JE  @F
    . . .
@@: NEG  AX
    . . .
    CMP  AX, -1
    JE  @B

BTW, I second what sudoku said above. Anonymous jump labels are really useful but can easily get you into trouble. My general rule is to only use them when the jump instruction and the target are within just a few lines of each other. Otherwise use a named target.
Title: Re: Line Drawing
Post by: NoCforMe on May 29, 2024, 09:23:41 AM
Quote from: tda0626 on May 29, 2024, 08:15:26 AMNow it seems to be drawing correctly from right-top to bottom-left and vice versa, see picture attached to this thread.
(https://i.postimg.cc/ZvWd1HMq/Capture.jpg) (https://postimg.cc/ZvWd1HMq)
Now all you need is some anti-aliasing code ...
Title: Re: Line Drawing
Post by: tda0626 on May 29, 2024, 09:38:24 AM
Quote from: NoCforMe on May 29, 2024, 09:23:41 AM
Quote from: tda0626 on May 29, 2024, 08:15:26 AMNow it seems to be drawing correctly from right-top to bottom-left and vice versa, see picture attached to this thread.
(https://i.postimg.cc/ZvWd1HMq/Capture.jpg) (https://postimg.cc/ZvWd1HMq)
Now all you need is some anti-aliasing code ...

Surely you jest  :cool: . I don't even know where to start with that.  :joking: 

It draws vertical and horizontal lines as is so I didn't have to do a separate routine for those. However, I found another problem. For deltay > deltax, it will draw them from top to bottom fine but not the other way around. It should swap the values if the deltay is negative but for some reason that is not happening so there is something up in my PlotLineHigh routine or so I suspect.
Title: Re: Line Drawing
Post by: tda0626 on May 30, 2024, 08:14:23 AM
This is odd. I was having trouble with one case in my line drawing program that didn't make sense to me. If the deltay > deltax (steep slope) but the deltax was negative, it would not draw the line correctly. Right before the conditional code to determine which line to draw and to either swap the x and y values, I had NoCforMe's ABS() code that I used to convert the negative to a positive.

mov ax, deltax
cwd
xor ax, dx
sub ax, dx

Fired up DOS debug and got to that part of code that does that ABS() routine but it does not sign extend to DX after the CWD instruction. Anyone know why? As far as I know, that instruction is supported on 386 and higher. The DX register contents are zero after the instruction is executed.

In the meantime, I just used this bit of code to convert it and now it works but still curious to why CWD isn't working because that is a pretty good method if you ask me to get the ABS().

mov ax, deltax
.if ax  & 08000h
neg ax
.endif

Tim
Title: Re: Line Drawing
Post by: NoCforMe on May 30, 2024, 09:41:44 AM
CWD was supported way back from the beginning, on the 8086.

What was the value of AX before CWD? Are you sure it was negative?
Title: Re: Line Drawing
Post by: tda0626 on May 30, 2024, 10:35:54 AM
Quote from: NoCforMe on May 30, 2024, 09:41:44 AMCWD was supported way back from the beginning, on the 8086.

What was the value of AX before CWD? Are you sure it was negative?

Wish I took a screen shot of it. I can't remember unfortunately but my conditional statement code fixed it. I will add your bit of code back in there and test for that condition again but this time I will take screenshots of it and let you know.

Made a loop to test for all cases and it appears to draw everything correctly now, see picture.

(https://i.postimg.cc/gn1R8Fbs/Capture.jpg) (https://postimg.cc/gn1R8Fbs)
Title: Re: Line Drawing
Post by: NoCforMe on May 30, 2024, 11:06:58 AM
Kewl, psychedelic.