~aritra1911/ansi_anim

f4282951fc997877ddb38aaacb1b00764cbeccbd — Aritra Sarkar 2 years ago 42e8ed6
Generalize I/O
M Makefile => Makefile +3 -1
@@ 8,12 8,14 @@ CPPFLAGS =
LDFLAGS =

SRCS = src/main.c \
       ansilib/src/ansi/screen.c \
       src/io.c \
       ansilib/src/ansi/cursor.c \
       ansilib/src/ansi/screen.c \
       ansilib/src/graphics/common.c \
       ansilib/src/graphics/shapes.c

OBJS = obj/main.o \
       obj/io.o \
       obj/ansi/screen.o \
       obj/ansi/cursor.o \
       obj/graphics/common.o \

M ansilib/inc/graphics/shapes.h => ansilib/inc/graphics/shapes.h +4 -0
@@ 1,6 1,10 @@
#ifndef __GRAPHICS_SHAPES_H_
# define __GRAPHICS_SHAPES_H_

# include <stdint.h>

# include <graphics/common.h>

void draw_rectangle(point_t pos, uint32_t width, uint32_t height);

#endif  /* __GRAPHICS_SHAPES_H_ */

M ansilib/src/ansi/cursor.c => ansilib/src/ansi/cursor.c +9 -16
@@ 1,24 1,21 @@
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <string.h>

#include <io.h>
#include <ansi/common.h>
#include <ansi/cursor.h>

point_t get_cursor_pos(void)
{
    char buf[16];
    point_t ret = { 0 };
    uint32_t line, column;

    /* ESC[6n   request cursor position (reports as ESC[#;#R) */
    /* ESC[6n   request cursor position ( reports as ESC[#;#R ) */

    write(STDOUT_FILENO, CSI"6n", 4);
    if ( read(STDIN_FILENO, buf, 16) ) {

        uint32_t line, column;
        sscanf(buf, CSI"%"PRIu32";%"PRIu32"R", &line, &column);
    printmsg(CSI"6n");
    if ( scanmsg(CSI"%"PRIu32";%"PRIu32"R", &line, &column) ) {

        ret.x = column;
        ret.y = line;


@@ 29,22 26,19 @@ point_t get_cursor_pos(void)

void move_cursor(point_t pos)
{
    char buf[16];

    /*
     * ESC[{line};{column}H
     * or
     * ESC[{line};{column}f
     */

    sprintf(buf, CSI"%i;%iH", pos.y, pos.x);
    write(STDOUT_FILENO, (void *) buf, strlen(buf));
    printmsg(CSI"%i;%iH", pos.y, pos.x);
}

void nudge_cursor(dir_t direction, uint32_t step)
{
    /* TODO: `direction` is a bitmask */
    char buf[16], end_ch;
    char end_ch;

    /*
     * ESC[#A   moves cursor up # lines


@@ 60,6 54,5 @@ void nudge_cursor(dir_t direction, uint32_t step)
        case LEFT:  end_ch = 'D';
    }

    sprintf(buf, CSI"%i%c", step, end_ch);
    write(STDOUT_FILENO, (void *) buf, strlen(buf));
    printmsg(CSI"%i%c", step, end_ch);
}

M ansilib/src/ansi/screen.c => ansilib/src/ansi/screen.c +0 -2
@@ 1,5 1,3 @@
#include <unistd.h>

#include <ansi/cursor.h>

point_t get_screen_size(void)

M ansilib/src/graphics/shapes.c => ansilib/src/graphics/shapes.c +6 -6
@@ 1,15 1,15 @@
#include <unistd.h>

#include <ansi/cursor.h>
#include <graphics/shapes.h>

#include <io.h>

void draw_rectangle(point_t pos, uint32_t width, uint32_t height)
{
    move_cursor(pos);

    /* Top edge */
    for (uint32_t i = 0; i < width; i++) {
        write(STDOUT_FILENO, (void *) "#", 1);
        printmsg("#");
    }

    for (uint32_t i = 0; i < height - 2; i++) {


@@ 19,11 19,11 @@ void draw_rectangle(point_t pos, uint32_t width, uint32_t height)
        nudge_cursor(DOWN, 1);

        /* Left edges */
        write(STDOUT_FILENO, (void *) "#", 1);
        printmsg("#");

        /* Right edges */
        nudge_cursor(RIGHT, width - 2);
        write(STDOUT_FILENO, (void *) "#", 1);
        printmsg("#");
    }

    /* Get to the next line */


@@ 32,6 32,6 @@ void draw_rectangle(point_t pos, uint32_t width, uint32_t height)

    /* Bottom edge */
    for (uint32_t i = 0; i < width; i++) {
        write(STDOUT_FILENO, (void *) "#", 1);
        printmsg("#");
    }
}

A inc/io.h => inc/io.h +11 -0
@@ 0,0 1,11 @@
#ifndef __IO_H_
# define __IO_H_

# define SEND_BUF_SIZ 4096
# define RECV_BUF_SIZ 4096

int printmsg(const char *format, ...);
int printmsgln(const char *format, ...);
int scanmsg(const char *format, ...);

#endif  /* __IO_H_ */

A src/io.c => src/io.c +66 -0
@@ 0,0 1,66 @@
#include <unistd.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include <io.h>

int printmsg(const char *format, ...)
{
    char str[SEND_BUF_SIZ];
    va_list args;
    int bytes;

    /* extract the arg list using va apis */
    va_start(args, format);
    bytes = vsnprintf(str, SEND_BUF_SIZ, format, args);
    va_end(args);

    if ( bytes >= 0 ) {
        /* `vsnprintf()` didn't report an error */
        str[SEND_BUF_SIZ - 1] = '\0';
        write(STDOUT_FILENO, (void *) str, strlen(str));
    }

    return bytes;
}

int printmsgln(const char *format, ...)
{
    char str[SEND_BUF_SIZ];
    va_list args;
    int bytes;

    /* extract the arg list using va apis */
    va_start(args, format);
    bytes = vsnprintf(str, SEND_BUF_SIZ - 2, format, args);
    va_end(args);

    if ( bytes >= 0 ) {
        /* `vsnprintf()` didn't report an error */
        strcpy(str, "\r\n");
        str[SEND_BUF_SIZ - 1] = '\0';
        write(STDOUT_FILENO, (void *) str, strlen(str));
    }

    return bytes;
}


int scanmsg(const char *format, ...)
{
    char str[RECV_BUF_SIZ];
    va_list args;
    int items;

    /* `read()` will timeout after 100 ms */
    read(STDIN_FILENO, str, RECV_BUF_SIZ);
    str[RECV_BUF_SIZ - 1] = '\0';

    /* extract the arg list using va apis */
    va_start(args, format);
    items = vsscanf(str, format, args);
    va_end(args);

    return items;
}

M src/main.c => src/main.c +2 -1
@@ 4,6 4,7 @@
#include <termios.h>
#include <unistd.h>

#include <io.h>
#include <ansi/cursor.h>
#include <ansi/screen.h>
#include <graphics/common.h>


@@ 76,7 77,7 @@ int main(void)

    /* Draw a rectangle */
    point_t orig_cursor_pos = get_cursor_pos();
    draw_rectangle((point_t) { 20, 40 }, 32, 16);
    draw_rectangle((point_t) { 72, 12 }, 32, 16);
    move_cursor(orig_cursor_pos);

    while ( 1 ) {