/* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */ #include "uuterm.h" #include "dblbuf.h" #if 0 static void blitline8_crap(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw) { int cs = (cw+7)>>3; int skip = (-cw)&7; int x, i, j; signed char b; for (x=0; x>7); *dest++ = (*colors&15&(b>>7)) | (*colors>>4&~(b>>7)); if (i >= cs) break; b=*src++; j=0; } colors++; } } static void blitline8_2(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw) { int cs = (cw+7)>>3; int skip = (-cw)&7; int x, i, j; signed char b; unsigned char fg, bg; for (x=0; x> 4; for (i=0; ; i++) { for (; j<8; j++, b<<=1) *dest++ = (fg&(b>>7)) | (bg&~(b>>7)); if (i >= cs) break; b=*src++; j=0; } } } #endif #ifdef HAVE_I386_ASM #define BLIT_PIXEL_8 \ "add %%al,%%al \n\t" \ "sbb %%dl,%%dl \n\t" \ "and %%bh,%%dl \n\t" \ "mov %%bl,%%dh \n\t" \ "add %%dl,%%dh \n\t" \ "mov %%dh,(%%edi) \n\t" \ "inc %%edi \n\t" \ static void blitline8(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw) { __asm__ __volatile__( "push %%ebp \n\t" "mov %%ebx, %%ebp \n\t" "\n1: \n\t" "mov (%%esi), %%al \n\t" "inc %%esi \n\t" "mov (%%ecx), %%bl \n\t" "inc %%ecx \n\t" "mov %%bl, %%bh \n\t" "shr $4, %%bl \n\t" "and $15, %%bh \n\t" "sub %%bl, %%bh \n\t" BLIT_PIXEL_8 BLIT_PIXEL_8 BLIT_PIXEL_8 BLIT_PIXEL_8 BLIT_PIXEL_8 BLIT_PIXEL_8 BLIT_PIXEL_8 BLIT_PIXEL_8 "dec %%ebp \n\t" "jnz 1b \n\t" "pop %%ebp \n\t" : "=S"(src), "=D"(dest), "=c"(colors), "=b"(w) : "S"(src), "D"(dest), "c"(colors), "b"(w) : "memory" ); } #else static void blitline8(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw) { int x; unsigned char b; unsigned char c[2]; for (x=0; x> 4; dest[0] = c[b>>7]; b<<=1; dest[1] = c[b>>7]; b<<=1; dest[2] = c[b>>7]; b<<=1; dest[3] = c[b>>7]; b<<=1; dest[4] = c[b>>7]; b<<=1; dest[5] = c[b>>7]; b<<=1; dest[6] = c[b>>7]; b<<=1; dest[7] = c[b>>7]; b<<=1; dest += 8; } } #endif 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 char *colors = b->slices[idx].colors + x1; for (i=0; icell_h; i++) { blitline8(dest, src, colors, w, d->cell_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 + x1, 0, x2-x1+1); 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[x] = color; 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[t->x] ^= 0xff; blit_slice(d, idx, t->x, t->x); b->slices[idx].colors[t->x] ^= 0xff; } 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