' Line Drawing — Bresenham's line algorithm using character grid
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL grid(2500) AS LONG
    LOCAL width AS LONG
    LOCAL height AS LONG
    LOCAL x0 AS LONG
    LOCAL y0 AS LONG
    LOCAL x1 AS LONG
    LOCAL y1 AS LONG
    LOCAL x AS LONG
    LOCAL y AS LONG
    LOCAL dx AS LONG
    LOCAL dy AS LONG
    LOCAL sx AS LONG
    LOCAL sy AS LONG
    LOCAL err AS LONG
    LOCAL e2 AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL idx AS LONG
    LOCAL lineStr AS STRING
    LOCAL charVal AS STRING
    width = 40
    height = 20
    PRINT "============================================"
    PRINT "       LINE DRAWING (Bresenham Algorithm)"
    PRINT "============================================"
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    x0 = 2
    y0 = 2
    x1 = 37
    y1 = 17
    dx = x1 - x0
    IF dx < 0 THEN
        dx = 0 - dx
        sx = -1
    ELSE
        sx = 1
    END IF
    dy = y1 - y0
    IF dy < 0 THEN
        dy = 0 - dy
        sy = -1
    ELSE
        sy = 1
    END IF
    x = x0
    y = y0
    err = dx - dy
    DO WHILE x <> x1 OR y <> y1
        IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
            idx = y * width + x
            grid(idx) = 1
        END IF
        e2 = err * 2
        IF e2 > (0 - dy) THEN
            err = err - dy
            x = x + sx
        END IF
        IF e2 < dx THEN
            err = err + dx
            y = y + sy
        END IF
        IF x = x1 AND y = y1 THEN
            IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
                idx = y * width + x
                grid(idx) = 1
            END IF
            EXIT DO
        END IF
    LOOP
    PRINT "Line from (2,2) to (37,17):"
    PRINT ""
    FOR y = 0 TO height - 1
        lineStr = ""
        FOR x = 0 TO width - 1
            idx = y * width + x
            IF grid(idx) = 1 THEN
                lineStr = lineStr + "#"
            ELSE
                lineStr = lineStr + "."
            END IF
        NEXT x
        PRINT lineStr
    NEXT y
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    x0 = 5
    y0 = 10
    x1 = 35
    y1 = 10
    dx = x1 - x0
    IF dx < 0 THEN
        dx = 0 - dx
        sx = -1
    ELSE
        sx = 1
    END IF
    dy = y1 - y0
    IF dy < 0 THEN
        dy = 0 - dy
        sy = -1
    ELSE
        sy = 1
    END IF
    x = x0
    y = y0
    err = dx - dy
    DO WHILE x <> x1 OR y <> y1
        IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
            idx = y * width + x
            grid(idx) = 1
        END IF
        e2 = err * 2
        IF e2 > (0 - dy) THEN
            err = err - dy
            x = x + sx
        END IF
        IF e2 < dx THEN
            err = err + dx
            y = y + sy
        END IF
        IF x = x1 AND y = y1 THEN
            IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
                idx = y * width + x
                grid(idx) = 1
            END IF
            EXIT DO
        END IF
    LOOP
    PRINT "Horizontal line from (5,10) to (35,10):"
    PRINT ""
    FOR y = 0 TO height - 1
        lineStr = ""
        FOR x = 0 TO width - 1
            idx = y * width + x
            IF grid(idx) = 1 THEN
                lineStr = lineStr + "#"
            ELSE
                lineStr = lineStr + "."
            END IF
        NEXT x
        PRINT lineStr
    NEXT y
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    x0 = 20
    y0 = 2
    x1 = 20
    y1 = 17
    dx = x1 - x0
    IF dx < 0 THEN
        dx = 0 - dx
        sx = -1
    ELSE
        sx = 1
    END IF
    dy = y1 - y0
    IF dy < 0 THEN
        dy = 0 - dy
        sy = -1
    ELSE
        sy = 1
    END IF
    x = x0
    y = y0
    err = dx - dy
    DO WHILE x <> x1 OR y <> y1
        IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
            idx = y * width + x
            grid(idx) = 1
        END IF
        e2 = err * 2
        IF e2 > (0 - dy) THEN
            err = err - dy
            x = x + sx
        END IF
        IF e2 < dx THEN
            err = err + dx
            y = y + sy
        END IF
        IF x = x1 AND y = y1 THEN
            IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
                idx = y * width + x
                grid(idx) = 1
            END IF
            EXIT DO
        END IF
    LOOP
    PRINT "Vertical line from (20,2) to (20,17):"
    PRINT ""
    FOR y = 0 TO height - 1
        lineStr = ""
        FOR x = 0 TO width - 1
            idx = y * width + x
            IF grid(idx) = 1 THEN
                lineStr = lineStr + "#"
            ELSE
                lineStr = lineStr + "."
            END IF
        NEXT x
        PRINT lineStr
    NEXT y
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    x0 = 2
    y0 = 17
    x1 = 37
    y1 = 2
    dx = x1 - x0
    IF dx < 0 THEN
        dx = 0 - dx
        sx = -1
    ELSE
        sx = 1
    END IF
    dy = y1 - y0
    IF dy < 0 THEN
        dy = 0 - dy
        sy = -1
    ELSE
        sy = 1
    END IF
    x = x0
    y = y0
    err = dx - dy
    DO WHILE x <> x1 OR y <> y1
        IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
            idx = y * width + x
            grid(idx) = 1
        END IF
        e2 = err * 2
        IF e2 > (0 - dy) THEN
            err = err - dy
            x = x + sx
        END IF
        IF e2 < dx THEN
            err = err + dx
            y = y + sy
        END IF
        IF x = x1 AND y = y1 THEN
            IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
                idx = y * width + x
                grid(idx) = 1
            END IF
            EXIT DO
        END IF
    LOOP
    PRINT "Diagonal line from (2,17) to (37,2):"
    PRINT ""
    FOR y = 0 TO height - 1
        lineStr = ""
        FOR x = 0 TO width - 1
            idx = y * width + x
            IF grid(idx) = 1 THEN
                lineStr = lineStr + "#"
            ELSE
                lineStr = lineStr + "."
            END IF
        NEXT x
        PRINT lineStr
    NEXT y
    PRINT ""
    PRINT "Multi-line star pattern:"
    PRINT ""
    FOR i = 0 TO width * height - 1
        grid(i) = 0
    NEXT i
    x0 = 20
    y0 = 10
    FOR i = 0 TO 7
        x1 = 20 + (20 * COS(i * 3.14159 / 4))
        y1 = 10 + (10 * SIN(i * 3.14159 / 4))
        dx = x1 - x0
        IF dx < 0 THEN
            dx = 0 - dx
            sx = -1
        ELSE
            sx = 1
        END IF
        dy = y1 - y0
        IF dy < 0 THEN
            dy = 0 - dy
            sy = -1
        ELSE
            sy = 1
        END IF
        x = x0
        y = y0
        err = dx - dy
        DO WHILE x <> x1 OR y <> y1
            IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
                idx = y * width + x
                grid(idx) = 1
            END IF
            e2 = err * 2
            IF e2 > (0 - dy) THEN
                err = err - dy
                x = x + sx
            END IF
            IF e2 < dx THEN
                err = err + dx
                y = y + sy
            END IF
            IF x = x1 AND y = y1 THEN
                IF x >= 0 AND x < width AND y >= 0 AND y < height THEN
                    idx = y * width + x
                    grid(idx) = 1
                END IF
                EXIT DO
            END IF
        LOOP
    NEXT i
    grid(10 * width + 20) = 2
    grid(10 * width + 20) = 2
    FOR y = 0 TO height - 1
        lineStr = ""
        FOR x = 0 TO width - 1
            idx = y * width + x
            IF grid(idx) = 1 THEN
                lineStr = lineStr + "*"
            ELSE
                IF grid(idx) = 2 THEN
                    lineStr = lineStr + "O"
                ELSE
                    lineStr = lineStr + " "
                END IF
            END IF
        NEXT x
        PRINT lineStr
    NEXT y
    PRINT ""
    PRINT "Line drawing demo complete"
    FUNCTION = 0
END FUNCTION
