/* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */ #include #include "uuterm.h" #include "dblbuf.h" static void blitline8(unsigned char *dest, unsigned char *src, unsigned long *colors, int w) { #define T(x) ~((x&8)*0xff>>3 | (x&4)*0xff<<6 | (x&2)*0xff<<15 | (x&1)*0xff<<24) static const uint32_t tab[16] = { T(0), T(1), T(2), T(3), T(4), T(5), T(6), T(7), T(8), T(9), T(10), T(11), T(12), T(13), T(14), T(15) }; #undef T uint32_t *dest4 = (uint32_t*)dest; for(; w--; dest4+=2, colors+=2) { int s = *src++; int t0 = tab[s>>4]; int t1 = tab[s&15]; dest4[0] = colors[0] ^ (colors[1] & t0); dest4[1] = colors[0] ^ (colors[1] & t1); } } static void blit_slice(struct uudisp *d, int idx, int x1, int x2) { struct dblbuf *b = (void *)&d->priv; int cs = (d->cell_w+7)>>3; int y = b->slices[idx].y; int w = x2 - x1 + 1; int s = d->w * cs; int i; unsigned char *dest = b->vidmem + y*b->row_stride + x1*d->cell_w*b->bytes_per_pixel; unsigned char *src = b->slices[idx].bitmap + x1*cs; unsigned long *colors = b->slices[idx].colors + 2*x1; for (i=0; icell_h; i++) { blitline8(dest, src, colors, w); dest += b->line_stride; src += s; } } void clear_cells(struct uudisp *d, int idx, int x1, int x2) { struct dblbuf *b = (void *)&d->priv; int i; int cs = d->cell_w+7 >> 3; int cnt = (x2 - x1 + 1) * cs; int stride = d->w * cs; unsigned char *dest = b->slices[idx].bitmap + x1 * cs; memset(b->slices[idx].colors + 2*x1, 0, (x2-x1+1)*2*sizeof(long)); for (i=d->cell_h; i; i--, dest += stride) memset(dest, 0, cnt); } void uudisp_draw_glyph(struct uudisp *d, int idx, int x, const void *glyph, int color) { struct dblbuf *b = (void *)&d->priv; int i; int cs = d->cell_w+7 >> 3; int stride = d->w * cs; unsigned char *src = (void *)glyph; unsigned char *dest = b->slices[idx].bitmap + cs * x; b->slices[idx].colors[2*x] = (color&15)*(unsigned long)0x0101010101010101; b->slices[idx].colors[2*x+1] = b->slices[idx].colors[2*x] ^ (color>>4)*(unsigned long)0x0101010101010101; for (i=d->cell_h; i; i--, dest += stride) *dest |= *src++; } void uudisp_refresh(struct uudisp *d, struct uuterm *t) { struct dblbuf *b = (void *)&d->priv; int h = t->h < d->h ? t->h : d->h; int y; /* Clean up cursor first.. */ blit_slice(d, t->rows[b->curs_y]->idx, b->curs_x, b->curs_x); //printf("--- %d\r\n", b->slices[t->rows[b->curs_y]->idx].y); for (y=0; yrows[y]->idx; int x1 = t->rows[y]->x1; int x2 = t->rows[y]->x2; if (x2 >= x1) { clear_cells(d, idx, x1, x2); uuterm_refresh_row(d, t->rows[y], x1, x2); t->rows[y]->x1 = t->w; t->rows[y]->x2 = -1; } if (b->slices[idx].y != y) { b->slices[idx].y = y; x1 = 0; x2 = d->w-1; } else if (x2 < x1) continue; blit_slice(d, idx, x1, x2); } if (d->blink & 1) { int idx = t->rows[t->y]->idx; b->slices[idx].colors[2*t->x] ^= (unsigned long)0x0f0f0f0f0f0f0f0f; blit_slice(d, idx, t->x, t->x); b->slices[idx].colors[2*t->x] ^= (unsigned long)0x0f0f0f0f0f0f0f0f; } b->curs_x = t->x; b->curs_y = t->y; //printf("+++ %d\r\n", b->slices[t->rows[b->curs_y]->idx].y); } struct slice *dblbuf_setup_buf(int w, int h, int cs, int ch, unsigned char *mem) { struct slice *slices = (void *)mem; int i; mem += sizeof(slices[0]) * h; for (i=0; i