cube

A rotating 3D wireframe cube rendered in the terminal
git clone https://github.com/michaelneuper/cube.git
README | Files | Log | Refs | LICENSE

cube/src/ncdraw.c (1663B)


/**
 * @file    ncdraw.c
 * @author  Michael Neuper (michael@michaelneuper.com)
 *
 * Low-level ncurses drawing primitives: canvas initialisation,
 * single-pixel rendering, and Bresenham line drawing.
 */

#include <ctype.h>
#include <ncurses.h>
#include <stdlib.h>

#include "debug.h"
#include "ncdraw.h"

void init_canvas(void) {
    initscr();
    cbreak();
    noecho();
    curs_set(0);
    nodelay(stdscr, TRUE);
}

void draw_pixel(Pixel p) {
    char ch = '*';

    ASSERT(isprint(ch), "Must be a printable character.\n");
    ASSERT_LE(p.row, getmaxy(stdscr));
    ASSERT_LE(p.col, getmaxx(stdscr));

    mvprintw(p.row, p.col, "%c", ch);
}

void draw_line(Pixel p, Pixel q) {
    /** step direction */
    int sx = p.col < q.col ? 1 : -1;
    int sy = p.row < q.row ? 1 : -1;

    int dx = abs(p.col - q.col);
    int dy = abs(p.row - q.row);

    int x = p.col;
    int y = p.row;

    if (dx > dy) {
        int d = 2 * dy - dx;
        draw_pixel(p);

        while (x != q.col) {
            x += sx;

            if (d < 0) {
                d += 2 * dy;
            } else {
                y += sy;
                d += 2 * (dy - dx);
            }

            draw_pixel((Pixel){
                .row = y,
                .col = x,
            });
        }
    } else {
        int d = 2 * dx - dy;
        draw_pixel(p);

        while (y != q.row) {
            y += sy;

            if (d < 0) {
                d += 2 * dx;
            } else {
                x += sx;
                d += 2 * (dx - dy);
            }

            draw_pixel((Pixel){
                .row = y,
                .col = x,
            });
        }
    }
}