View Single Post
Old 20 December 2019, 14:19   #16
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 551
I've cleaned up the code the best I can and also used it to make the artificial horizon on the instrument panel work.

Executable attached for anyone interested.

The code now looks like this, it's better than it was, but it still seems overly complicated:

Code:
void GroundAndSky_Draw(const Camera * camera) {
    WORD displayHeight = display.displayMode == SPLIT_SCREEN_DISPLAY_MODE ? SPLIT_SCREEN_MAIN_DISPLAY_HEIGHT :
                                                                            DISPLAY_HEIGHT;

    LONG a = ((Entity *) camera)->transformation.rotation.value[0][1];
    LONG b = ((Entity *) camera)->transformation.rotation.value[1][1];

    LONG cz = ((Entity *) camera)->transformation.rotation.value[2][1] << 8; // 2^8 = 256 = viewing distance

    LONG leftX = -DISPLAY_WIDTH / 2;
    LONG rightX = DISPLAY_WIDTH / 2;
    LONG topY = displayHeight / 2;
    LONG bottomY = -displayHeight / 2;

    BOOL topLeft = a * leftX + b * topY + cz < 0;
    BOOL topRight = a * rightX + b * topY + cz < 0;
    BOOL bottomLeft = a * leftX + b * bottomY + cz < 0;
    BOOL bottomRight = a * rightX + b * bottomY + cz < 0;

    UWORD intersections = 0;

    if (topLeft != bottomLeft)
        intersections |= LEFT;
    if (topRight != bottomRight)
        intersections |= RIGHT;
    if (topLeft != topRight)
        intersections |= TOP;
    if (bottomLeft != bottomRight)
        intersections |= BOTTOM;

    if (!intersections) {
        BlitterFill(topLeft);
        return;
    }

    Point2D upperPoint, lowerPoint;
    BOOL reverse;
    BOOL fci;
    Kludge kludge = { .required = FALSE };

    switch (intersections) {
        WORD x0, x1, y0, y1;

        case LEFT | RIGHT:
            y0 = topY + (cz - a * rightX) / b;
            y1 = topY + (cz + a * rightX) / b;

            if (y0 > y1) {
                upperPoint = (Point2D) {{ DISPLAY_WIDTH - 1, y1 }};
                lowerPoint = (Point2D) {{ 0, y0 }};

                if (topLeft) {
                    reverse = FALSE;
                    fci = FALSE;
                } else {
                    reverse = TRUE;
                    fci = TRUE;
                }

                kludge = (Kludge) { TRUE, 0, y1 - 1 };
            } else {
                upperPoint = (Point2D) {{ 0, y0 }};
                lowerPoint = (Point2D) {{ DISPLAY_WIDTH - 1, y1 }};

                if (topRight) {
                    reverse = FALSE;
                    fci = TRUE;
                } else {
                    reverse = TRUE;
                    fci = FALSE;
                }

                kludge = (Kludge) { TRUE, y1 + 1, DISPLAY_HEIGHT - 1 };
            }
            break;
        case LEFT | TOP:
            upperPoint = (Point2D) {{ rightX - (cz + b * topY) / a, 0 }};
            lowerPoint = (Point2D) {{ 0, topY + (cz - a * rightX) / b }};

            if (bottomRight) {
                reverse = TRUE;
                fci = TRUE;
            } else {
                reverse = FALSE;
                fci = FALSE;
            }
            break;
        case LEFT | BOTTOM:
            upperPoint = (Point2D) {{ 0, topY + (cz - a * rightX) / b }};
            lowerPoint = (Point2D) {{ rightX - (cz - b * topY) / a, displayHeight - 1 }};

            if (topRight) {
                reverse = FALSE;
                fci = TRUE;
            } else {
                reverse = TRUE;
                fci = FALSE;
            }
            break;
        case RIGHT | TOP:
            y1 = topY + (cz + a * rightX) / b;

            upperPoint = (Point2D) {{ rightX - (cz + b * topY) / a, 0 }};
            lowerPoint = (Point2D) {{ DISPLAY_WIDTH - 1, y1 }};

            if (bottomLeft) {
                reverse = TRUE;
                fci = FALSE;
            } else {
                reverse = FALSE;
                fci = TRUE;
            }
            kludge = (Kludge) { TRUE, y1 + 1, displayHeight - 1 };
            break;
        case RIGHT | BOTTOM:
            y1 = topY + (cz + a * rightX) / b;

            upperPoint = (Point2D) {{ DISPLAY_WIDTH - 1, y1 }};
            lowerPoint = (Point2D) {{ rightX - (cz - b * topY) / a, displayHeight - 1 }};

            if (topLeft) {
                reverse = FALSE;
                fci = FALSE;
            } else {
                reverse = TRUE;
                fci = TRUE;
            }
            kludge = (Kludge) { TRUE, 0, y1 - 1 };
            break;
        case TOP | BOTTOM:
            x0 = rightX - (cz + b * topY) / a;
            x1 = rightX - (cz - b * topY) / a;

            upperPoint = (Point2D) {{ x0, 0 }};
            lowerPoint = (Point2D) {{ x1, displayHeight - 1 }};

            if (x0 > x1) {
                if (topLeft) {
                    reverse = FALSE;
                    fci = FALSE;
                } else {
                    reverse = TRUE;
                    fci = TRUE;
                }
            } else {
                if (bottomLeft) {
                    reverse = TRUE;
                    fci = FALSE;
                } else {
                    reverse = FALSE;
                    fci = TRUE;
                }
            }
            break;
        default:
            return; // should never happen
    }

    Line2D line = reverse ? (Line2D) {{ lowerPoint, upperPoint }} : (Line2D) {{ upperPoint, lowerPoint }};

    BlitterLine(line, TRUE);
    if (kludge.required)
        DoKludgeLine(kludge.start, kludge.end, 0x0001);

    BlitterFill(fci);
    
    BlitterLine(line, FALSE);
    if (kludge.required) {
        DoKludgeLine(kludge.start, kludge.end, 0x0000);
        if (fci)
            RemoveKludgeLine(kludge.start, kludge.end);
    }
}
Attached Files
File Type: zip dec-20.zip (19.7 KB, 24 views)
deimos is offline  
 
Page generated in 0.04451 seconds with 12 queries