From a1766d2d378710f924391784d0ffc736d59678db Mon Sep 17 00:00:00 2001 From: james Date: Sun, 3 Feb 2008 23:31:25 +0000 Subject: [PATCH] *** empty log message *** --- src/ansi.c | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ansi.h | 38 +++++++ src/crt.c | 51 ++++++++++ src/crt.h | 58 +++++++++++ src/html.c | 93 +++++++++++++++++ src/render.c | 28 ++++++ 6 files changed, 543 insertions(+) create mode 100644 src/ansi.c create mode 100644 src/ansi.h create mode 100644 src/crt.c create mode 100644 src/crt.h create mode 100644 src/html.c create mode 100644 src/render.c diff --git a/src/ansi.c b/src/ansi.c new file mode 100644 index 0000000..5d6105e --- /dev/null +++ b/src/ansi.c @@ -0,0 +1,275 @@ +/* + * ansi.c: + * + * Copyright (c) 2008 James McKenzie , + * All rights reserved. + * + */ + +static char rcsid[] = "$Id$"; + +/* + * $Log$ + * Revision 1.1 2008/02/03 23:31:25 james + * *** empty log message *** + * + */ + +void +ansi_write (ANSI * a, char *buf, int n) +{ + write (a->fd, buf, n); +} + + + +void +ansi_move (ANSI * a, CRT_Pos p) +{ + char buf[16]; + int n; + int dx = a->pos.x - p.x; + int dy = a->pos.y - p.y; + + + if (a->pos.x != ANSI_INVAL) + { + + if ((!dx) && (!dy)) + return; + + if (!dy) + { + if (dx == 1) + { + ansi_write (a, "\033[C", 3); + } + else if (dx == -1) + { + ansi_write (a, "\033[D", 3); + } + else + { + n = snprintf (buf, sizeof (buf), "\033[%dG", p.x + 1); + ansi_write (a, buf, n); + } + } + else if (!dx) + { + if (dy == -1) + { + ansi_write (a, "\033[A", 3); + } + else if (dy == 1) + { + ansi_write (a, "\033[B", 3); + } + else if (dy < 0) + { + n = snprintf (buf, sizeof (buf), "\033[%dA", -dy); + ansi_write (a, buf, n); + } + else + { + n = snprintf (buf, sizeof (buf), "\033[%dB", dy); + ansi_write (a, buf, n); + } + } + else if (!p.x) + { + if (dy == 1) + { + ansi_write (a, "\033[E", 3); + } + else if (dy == -1) + { + ansi_write (a, "\033[F", 3); + } + else if (dy > 0) + { + n = snprintf (buf, sizeof (buf), "\033[%dE", -dy); + ansi_write (a, buf, n); + } + else + { + n = snprintf (buf, sizeof (buf), "\033[%dF", dy); + ansi_write (a, buf, n); + } + } + else + { + n = snprintf (buf, sizeof (buf), "\033[%d;%dHF", p.y + 1, p.x + 1); + ansi_write (a, buf, n); + } + } + else + { + n = snprintf (buf, sizeof (buf), "\033[%d;%dHF", p.y + 1, p.x + 1); + ansi_write (a, buf, n); + } + + a->pos = p; +} + + +void +ansi_showhide_cursor (ANSI * a, int hide) +{ + if (a->hide_cursor == hide) + return; + + if (hide) + { + ansi_write (a, "\033[?25h", 6); + } + else + { + ansi_write (a, "\033[?25l", 6); + } + + a->hide_cursor = hide; +} + + +void ansi_force_attr_normal(ANSI *a) +{ + ansi_write (a, "\033[0m", 4); + a->attr=CRT_ATTR_NORMAL; +} + +void +ansi_set_attr (ANSI * a, int attr) +{ + + dif = attr ^ a->attr; + + if (!dif) + return; + + if (attr == ATTR_NORMAL) + { + ansi_force_attr_normal(a); + return; + } + + if (dif & CRT_ATTR_UNDERLINE) + { + if (attr & CRT_ATTR_UNDERLINE) + { + ansi_write (a, "\033[4m", 4); + } + else + { + ansi_write (a, "\033[24m", 5); + } + } + if (dif & CRT_ATTR_REVERSE) + { + if (attr & CRT_ATTR_REVERSE) + { + ansi_write (a, "\033[7m", 4); + } + else + { + ansi_write (a, "\033[27m", 5); + } + } + if (dif & CRT_ATTR_BOLD) + { + if (attr & CRT_ATTR_REVERSE) + { + ansi_write (a, "\033[1m", 4); + } + else + { + ansi_write (a, "\033[22m", 5); + } + } +} + + +void +ansi_render (ANSI * a, CRT_CA ca) +{ + int dif; + + if (ca.chr < 32) + ca.chr = ' '; + if (ca.chr > 126) + ca.chr = ' '; + + ansi_set_attr (a, ca.attr); + + ansi_write (a, &ca.chr, 1); + + a->pos.x++; + +/*Can't easily wrap round here as don't know size of destination screen*/ +/*so invalidate the cached cursor position*/ + + if (a->pos.x >= CRT_COLS) + a->pos.x = ANSI_INVAL; + +} + +void +ansi_cls (ANSI * a) +{ + CRT_Pos p = { 0 }; + + crt_cls (&a->crt); + ansi_force_attr_normal(a); + ansi_move (a, p); + ansi_write (a, "\033[2J", 4); +/*different emulators leave cursor in different places after cls differently*/ + a->pos.x = ANSI_INVAL; +} + + +void +ansi_draw (ANSI * a, CRT * c) +{ + CRT_Pos p; + int o; + + ansi_showhide_cursor (a, 1); + + for (p.y = 0; p.y < CRT_ROWS; ++p.y) + { + if (p.y >= a->size.y) + continue; + o = CRT_ADDR (r, 0); + for (p.x = 0; p.x < CRT_COLS; ++p.x, ++o) + { + if (p.x >= a->size.x) + continue; + if (crt_ca_cmp (a->crt.screen[p], c->screen[p])) + { + a->crt.screen[p] = c->screen[p]; + + ansi_move (a, p); + ansi_render (a, a->crt.screen[p]); + } + } + } + + a->crt.pos = c->pos; + ansi_move (a, a->crt.pos); + + a->crt.hide_cursor = c->hide_cursor; + ansi_showhide_cursor (a, ci->crt.hide_cursor); +} + +void +ansi_reset (ANSI * a) +{ + ansi_write (a, "\033[c", 3); + + a->pos.x = ANSI_INVAL; + a->hide_cursor = ANSI_INVAL; + + crt_reset (&a->crt); + + ansi_cls (a); + ansi_draw (a, &a->crt); +} diff --git a/src/ansi.h b/src/ansi.h new file mode 100644 index 0000000..b687ac6 --- /dev/null +++ b/src/ansi.h @@ -0,0 +1,38 @@ +/* + * ansi.h: + * + * Copyright (c) 2008 James McKenzie , + * All rights reserved. + * + */ + +/* + * $Id$ + */ + +/* + * $Log$ + * Revision 1.1 2008/02/03 23:31:25 james + * *** empty log message *** + * + */ + +#ifndef __ANSI_H__ +#define __ANSI_H__ + +#define ANSI_INVAL -1 + +typedef struct { +int fd; + +CRT crt; +CRT_Pos pos; +CRT_Pos size; +int hide_cursor; + +int attr; + +} ANSI; + + +#endif /* __ANSI_H__ */ diff --git a/src/crt.c b/src/crt.c new file mode 100644 index 0000000..24c0f02 --- /dev/null +++ b/src/crt.c @@ -0,0 +1,51 @@ +/* + * crt.c: + * + * Copyright (c) 2008 James McKenzie , + * All rights reserved. + * + */ + +static char rcsid[] = "$Id$"; + +/* + * $Log$ + * Revision 1.1 2008/02/03 23:31:25 james + * *** empty log message *** + * + */ + +#include "project.h" + +void crt_cls(CRT *c) +{ +int i; + +for (i=0;iscreen[i].chr=' '; + c->screen[i].chr=CRT_ATTR_NORMAL; +} +} + +void crt_reset(CRT *c) +{ +crt_cls(c); + +crt->pos.x=0; +crt->pos.y=0; +crt->hide_cursor=1; +} + +void crt_insert(CRT *c,CRT_CA ca) +{ +if (c->pos.x<0) c->pos.x=0; +if (c->pos.x>=CRT_COLS) c->pos.x=CRT_COLS-1; +if (c->pos.y<0) c->pos.y=0; +if (c->pos.y>=CRT_ROWS) c->pos.y=CRT_ROWS-1; + +crt->screen[CRT_ADDR(c->pos.y,c->pos.x)]=ca; + + + +} + diff --git a/src/crt.h b/src/crt.h new file mode 100644 index 0000000..a46affa --- /dev/null +++ b/src/crt.h @@ -0,0 +1,58 @@ +/* + * crt.h: + * + * Copyright (c) 2008 James McKenzie , + * All rights reserved. + * + */ + +/* + * $Id$ + */ + +/* + * $Log$ + * Revision 1.1 2008/02/03 23:31:25 james + * *** empty log message *** + * + */ + +#ifndef __CRT_H__ +#define __CRT_H__ + +#define CRT_ROWS 25 +#define CRT_COLS 80 + +#define CRT_CELS (CRT_ROWS*CRT_COLS) +#define CRT_ADDR(r,c) (((r)*CRT_ROWS)+(c)) +#define CRT_ADDR_POS(p) ((((p)->y)*CRT_ROWS)+((p)->x)) + +#define CRT_ATTR_NORMAL 0x0 +#define CRT_ATTR_UNDERLINE 0x1 +#define CRT_ATTR_REVERSE 0x2 +#define CRT_ATTR_BLINK 0x4 +#define CRT_ATTR_BOLD 0x8 + +typedef struct { + uint8_t chr; + uint8_t attr; +} CRT_CA; + +typedef struct { + int x; + int y; +} CRT_Pos; + + +typedef struct { + CRT_CA screen[CRT_CELS]; + CRT_Pos pos; + int hide_cursor; +} CRT; + + +static inline crt_ca_cmp(CRT_CA a,CRT_CA b) { + return memcmp(&a,&b,sizeof(a)); +} + +#endif /* __CRT_H__ */ diff --git a/src/html.c b/src/html.c new file mode 100644 index 0000000..5f48fe3 --- /dev/null +++ b/src/html.c @@ -0,0 +1,93 @@ +/* + * html.c: + * + * Copyright (c) 2008 James McKenzie , + * All rights reserved. + * + */ + +static char rcsid[] = "$Id$"; + +/* + * $Log$ + * Revision 1.1 2008/02/03 23:31:25 james + * *** empty log message *** + * + */ + +void +html_entity (FILE * f, int c) +{ + switch (c) + { + case 32: + fprintf (f, " "); + break; + case 38: + fprintf (f, "&"); + break; + case 60: + fprintf (f, "<"); + break; + case 62: + fprintf (f, ">"); + break; + default: + fputc (c, f); + } +} + +void +html_render (FILE * f, CRT_CA c) +{ + if (c.attr & CRT_ATTR_REVERSE) + { + fprintf (f, ""); + } + else + { + fprintf (f, ""); + } + + if (c.attr & CRT_ATTR_UNDERLINE) + fprintf (f, "
    "); + if (c.attr & CRT_ATTR_BOLD) + fprintf (f, ""); + + if (c.chr < 32) + c.chr = 32; + if (c.chr > 126) + c.chr = 32; + + html_entity (f, c.chr); + + if (c.attr & CRT_ATTR_BOLD) + fprintf (f, ""); + if (c.attr & CRT_ATTR_UNDERLINE) + fprintf (f, "
"); + if (c.attr & CRT_ATTR_REVERSE) + { + fprintf (f, "
"); + } + fprintf (f, ""); +} + +void +html_draw (FILE * f, CRT * c) +{ + CRT_Pos p; + int o; + + fprintf (f, "\n"); + for (p.y = 0; p.y < CRT_ROWS; ++p.y) + { + o = CRT_ADDR (p.y, 0); + fprintf (f, ""); + for (p.x = 0; p.x < CRT_ROWS; ++p.x, ++o) + { + html_render (f, c->screen[o]); + } + fprintf (f, "\n"); + } + fprintf (f, "
\n"); +} diff --git a/src/render.c b/src/render.c new file mode 100644 index 0000000..6ef0e67 --- /dev/null +++ b/src/render.c @@ -0,0 +1,28 @@ +/* + * render.c: + * + * Copyright (c) 2008 James McKenzie , + * All rights reserved. + * + */ + +static char rcsid[] = "$Id$"; + +/* + * $Log$ + * Revision 1.1 2008/02/03 23:31:25 james + * *** empty log message *** + * + */ + + + + + + + + + +} + + -- 2.30.2