-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Library for drawing ascii shapes and controlling the cursor in the te…
…rminal with escape characters.
- Loading branch information
0 parents
commit 725812e
Showing
4 changed files
with
220 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*.o | ||
termdraw | ||
*.swp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# termdraw - terminal drawing program | ||
# Makefile taken from suckless style. | ||
|
||
include config.mk | ||
|
||
HEADERS = termdraw.h | ||
SRC = termdraw.c | ||
OBJ = ${SRC:.c=.o} | ||
|
||
all: options termdraw | ||
|
||
options: | ||
@echo determinant build options: | ||
@echo "CFLAGS = ${CFLAGS}" | ||
@echo "LDFLAGS = ${LDFLAGS}" | ||
@echo "CC = ${CC}" | ||
@echo "LD = ${LD}" | ||
|
||
%.o: %.c | ||
@echo CC $< | ||
@${CC} -c ${CFLAGS} $< | ||
|
||
${OBJ}: config.mk | ||
|
||
termdraw: ${OBJ} | ||
@echo LD $@ | ||
@${LD} -o $@ ${OBJ} ${LDFLAGS} | ||
|
||
clean: | ||
@echo cleaning | ||
@rm -f determinant ${OBJ} ${PROG_NAME}-${VERSION}.tar.gz | ||
|
||
dist: clean | ||
@echo creating dist tarball | ||
@mkdir -p ${PROG_NAME}-${VERSION} | ||
@cp -R Makefile LICENSE README.md config.mk ${SRC} ${HEADERS} ${PROG_NAME}-${VERSION} | ||
@tar -cf ${PROG_NAME}-${VERSION}.tar ${PROG_NAME}-${VERSION} | ||
@gzip ${PROG_NAME}-${VERSION}.tar | ||
@rm -rf ${PROG_NAME}-${VERSION} | ||
|
||
.PHONY: all options clean dist | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# program version | ||
VERSION = 0.0.1 | ||
# program name | ||
PROG_NAME = termdraw | ||
|
||
# Customize below to fit your needs. | ||
|
||
# paths | ||
|
||
# includes and libs | ||
INCS = | ||
LIBS = | ||
|
||
# flags | ||
CPPFLAGS = -DVERSION=\"${VERSION}\" | ||
CFLAGS = -g -std=c99 -pedantic -Wall -O3 ${INCS} ${CPPFLAGS} | ||
LDFLAGS = ${LIBS} | ||
|
||
# compiler and linker | ||
CC = gcc | ||
LD = ${CC} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
#include <sys/ioctl.h> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <ctype.h> | ||
|
||
#include <termios.h> | ||
|
||
struct screen_state_t { | ||
int cur_x; | ||
int cur_y; | ||
int cols; | ||
int rows; | ||
char *buf; | ||
}; | ||
|
||
int | ||
set_term_environ(void) | ||
{ | ||
struct termios old = {0}; | ||
if (tcgetattr(0, &old) < 0) { | ||
perror("tcgetattr()"); | ||
return -1; | ||
} | ||
old.c_lflag &= ~ICANON; | ||
old.c_lflag &= ~ECHO; | ||
old.c_cc[VMIN] = 1; | ||
old.c_cc[VTIME] = 0; | ||
if (tcsetattr(0, TCSANOW, &old) < 0) { | ||
perror("tcsetattr ICANON"); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
int | ||
cleanup(void) | ||
{ | ||
struct termios old = {0}; | ||
if (tcgetattr(0, &old) < 0) { | ||
perror("tcsetattr()"); | ||
return -1; | ||
} | ||
old.c_lflag |= ICANON; | ||
old.c_lflag |= ECHO; | ||
if (tcsetattr(0, TCSADRAIN, &old) < 0) { | ||
perror ("tcsetattr ~ICANON"); | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
int | ||
move_cursor(struct screen_state_t *screen, char direction, int n) | ||
{ | ||
switch (direction) { | ||
case 'u': | ||
if (screen->cur_y <= 1) break; | ||
printf("\033[%dA", n); | ||
screen->cur_y -= n; | ||
break; | ||
case 'd': | ||
if (screen->cur_y >= screen->rows) break; | ||
printf("\033[%dB", n); | ||
screen->cur_y += n; | ||
break; | ||
case 'l': | ||
if (screen->cur_x <= 1) break; | ||
printf("\033[%dD", n); | ||
screen->cur_x -= n; | ||
break; | ||
case 'r': | ||
if (screen->cur_x >= screen->cols) break; | ||
printf("\033[%dC", n); | ||
screen->cur_x += n; | ||
break; | ||
default: | ||
return -1; | ||
} | ||
fflush(stdout); | ||
return 0; | ||
} | ||
|
||
int | ||
getch() | ||
{ | ||
char buf = 0; | ||
if (read(0, &buf, 1) < 0) { | ||
perror ("read()"); | ||
return 0; | ||
} | ||
return buf; | ||
} | ||
|
||
void | ||
fill_screen(struct screen_state_t *screen, char c) | ||
{ | ||
struct winsize w; | ||
int i, j; | ||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); | ||
|
||
printf("\033[0;0H"); | ||
fflush(stdout); | ||
|
||
for (i = 0; i < screen->rows; i++) { | ||
for (j = 0; j < screen->cols; j++) { | ||
printf("%c", c); | ||
} | ||
printf("\n"); | ||
} | ||
|
||
//printf("\033[%d;%dH", w.ws_row / 2, w.ws_col / 2); | ||
printf("\033[%d;%dH", screen->cur_y, screen->cur_x); | ||
fflush(stdout); | ||
} | ||
|
||
int main (int argc, char **argv) | ||
{ | ||
int c; | ||
struct screen_state_t screen; | ||
/* Clear the entire screen intially */ | ||
printf("\033[2J"); | ||
set_term_environ(); | ||
screen.cols = 80; | ||
screen.rows = 40; | ||
screen.cur_x = 40; | ||
screen.cur_y = 20; | ||
fill_screen(&screen, '0'); | ||
|
||
while (1) { | ||
c = getch(); | ||
if (isspace(c)) | ||
continue; | ||
switch (c) { | ||
case 'h': | ||
move_cursor(&screen, 'l', 1); | ||
break; | ||
case 'j': | ||
move_cursor(&screen, 'd', 1); | ||
break; | ||
case 'k': | ||
move_cursor(&screen, 'u', 1); | ||
break; | ||
case 'l': | ||
move_cursor(&screen, 'r', 1); | ||
break; | ||
default: | ||
break; | ||
} | ||
fill_screen(&screen, (char)c); | ||
} | ||
|
||
cleanup(); | ||
return 0; | ||
} |