--- np2/lio/gline.c 2004/02/21 04:48:35 1.6 +++ np2/lio/gline.c 2004/02/22 00:52:55 1.11 @@ -25,12 +25,11 @@ typedef struct { int y1; int x2; int y2; - UINT16 pat; UINT8 pal; } LINEPT; -static void gline(const _LIOWORK *lio, const LINEPT *lp) { +static void gline(const _GLIO *lio, const LINEPT *lp, UINT16 pat) { int x1; int y1; @@ -42,7 +41,6 @@ static void gline(const _LIOWORK *lio, c int height; int d1; int d2; - UINT16 pat; UINT32 csrw; GDCVECT vect; @@ -129,9 +127,12 @@ static void gline(const _LIOWORK *lio, c d2 = 0 - d2; } d1 = max(d1, d2) & 15; - pat = (UINT16)((lp->pat >> d1) | (lp->pat << (16 - d1))); + pat = (UINT16)((pat >> d1) | (pat << (16 - d1))); csrw = (y1 * 40) + (x1 >> 4) + ((x1 & 0xf) << 20); + if (lio->draw.flag & LIODRAW_UPPER) { + csrw += 16000 >> 1; + } gdcsub_setvectl(&vect, x1, y1, x2, y2); if (!(lio->draw.flag & LIODRAW_MONO)) { gdcsub_vectl(csrw + 0x4000, &vect, pat, @@ -140,7 +141,7 @@ static void gline(const _LIOWORK *lio, c (REG8)((lp->pal & 2)?GDCOPE_SET:GDCOPE_CLEAR)); gdcsub_vectl(csrw + 0xc000, &vect, pat, (REG8)((lp->pal & 4)?GDCOPE_SET:GDCOPE_CLEAR)); - if (lio->palmode == 2) { + if (lio->draw.flag & LIODRAW_4BPP) { gdcsub_vectl(csrw, &vect, pat, (REG8)((lp->pal & 8)?GDCOPE_SET:GDCOPE_CLEAR)); } @@ -152,92 +153,201 @@ static void gline(const _LIOWORK *lio, c } } +static void glineb(const _GLIO *lio, const LINEPT *lp, UINT16 pat) { + + LINEPT lpt; + + lpt = *lp; + lpt.y2 = lp->y1; + gline(lio, &lpt, pat); + lpt.y2 = lp->y2; + + lpt.x2 = lp->x1; + gline(lio, &lpt, pat); + lpt.x2 = lp->x2; + + lpt.x1 = lp->x2; + gline(lio, &lpt, pat); + lpt.x1 = lp->x1; + + lpt.y1 = lp->y2; + gline(lio, &lpt, pat); + lpt.y1 = lp->y1; +} + // ---- -static void nor_linebox(const _LIOWORK *lio, SINT16 x1, SINT16 y1, - SINT16 x2, SINT16 y2, REG8 pal) { +static void gbox(const _GLIO *lio, const LINEPT *lp, BYTE *tile, UINT leng) { + + int x1; + int y1; + int x2; + int y2; + int tmp; + UINT32 csrw; + GDCVECT vect; + UINT planes; + UINT adrs[4]; + UINT8 ope[4]; + UINT16 pat; + BYTE *tterm; + UINT r; + + x1 = lp->x1; + y1 = lp->y1; + x2 = lp->x2; + y2 = lp->y2; - lio_line(lio, x1, x2, y1, pal); - if (y1 != y2) { - lio_line(lio, x1, x2, y2, pal); - } - for (; y1 x2) { + tmp = x1; + x1 = x2; + x2 = tmp; + } + if (y1 > y2) { + tmp = y1; + y1 = y2; + y2 = tmp; + } + if ((x1 > lio->draw.x2) || (x2 < lio->draw.x1) || + (y1 > lio->draw.y2) || (y2 < lio->draw.y1)) { + return; + } + x1 = max(x1, lio->draw.x1); + y1 = max(y1, lio->draw.y1); + x2 = min(x2, lio->draw.x2); + y2 = min(y2, lio->draw.y2); + + csrw = 0; + if (lio->draw.flag & LIODRAW_UPPER) { + csrw += 16000 >> 1; + } + if (!(lio->draw.flag & LIODRAW_MONO)) { + planes = (lio->draw.flag & LIODRAW_4BPP)?4:3; + adrs[0] = csrw + 0x4000; + adrs[1] = csrw + 0x8000; + adrs[2] = csrw + 0xc000; + adrs[3] = csrw + 0x0000; + ope[0] = (lp->pal & 1)?GDCOPE_SET:GDCOPE_CLEAR; + ope[1] = (lp->pal & 2)?GDCOPE_SET:GDCOPE_CLEAR; + ope[2] = (lp->pal & 4)?GDCOPE_SET:GDCOPE_CLEAR; + ope[3] = (lp->pal & 8)?GDCOPE_SET:GDCOPE_CLEAR; + } + else { + planes = 1; + adrs[0] = csrw + (((lio->draw.flag + 1) & LIODRAW_PMASK) << 12); + ope[0] = (lp->pal)?GDCOPE_SET:GDCOPE_CLEAR; + } + + if (leng == 0) { + tile = NULL; + tterm = NULL; + } + else { + tterm = tile + leng; + tmp = (x1 - lio->draw.x1) & 7; + do { + r = GDCPATREVERSE(*tile); + *tile = (BYTE)((r << tmp) | (r >> (8 - tmp))); + } while(++tile < tterm); + tile -= leng; + tmp = (y1 - lio->draw.y1) * planes; + tile += tmp % leng; + } + + pat = 0xffff; + while(y1 <= y2) { + gdcsub_setvectl(&vect, x1, y1, x2, y1); + csrw = (y1 * 40) + (x1 >> 4) + ((x1 & 0xf) << 20); + r = 0; + do { + if (tile) { + pat = (*tile << 8) | *tile; + if (++tile >= tterm) { + tile -= leng; + } + } + gdcsub_vectl(csrw + adrs[r], &vect, pat, ope[r]); + } while(++r < planes); + y1++; } } -static void nor_lineboxfill(const _LIOWORK *lio, SINT16 x1, SINT16 y1, - SINT16 x2, SINT16 y2, REG8 pal) { - for (; y1<=y2; y1++) { - lio_line(lio, x1, x2, y1, pal); - } +// ---- CLS + +REG8 lio_gcls(GLIO lio) { + + LINEPT lp; + + lio_updatedraw(lio); + lp.x1 = lio->draw.x1; + lp.y1 = lio->draw.y1; + lp.x2 = lio->draw.x2; + lp.y2 = lio->draw.y2; + lp.pal = lio->work.bgcolor; + gbox(lio, &lp, NULL, 0); + return(LIO_SUCCESS); } // ---- -REG8 lio_gline(LIOWORK lio) { +REG8 lio_gline(GLIO lio) { GLINE dat; LINEPT lp; - SINT16 x1; - SINT16 y1; - SINT16 x2; - SINT16 y2; + UINT16 pat; + UINT leng; +// UINT lengmin; + BYTE tile[256]; lio_updatedraw(lio); i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat)); + lp.x1 = (SINT16)LOADINTELWORD(dat.x1); + lp.y1 = (SINT16)LOADINTELWORD(dat.y1); + lp.x2 = (SINT16)LOADINTELWORD(dat.x2); + lp.y2 = (SINT16)LOADINTELWORD(dat.y2); if (dat.pal == 0xff) { - lp.pal = lio->mem.fgcolor; + lp.pal = lio->work.fgcolor; } else { lp.pal = dat.pal; } if (lp.pal >= lio->draw.palmax) { - return(LIO_ILLEGALFUNC); + goto gline_err; } - lp.x1 = (SINT16)LOADINTELWORD(dat.x1); - lp.y1 = (SINT16)LOADINTELWORD(dat.y1); - lp.x2 = (SINT16)LOADINTELWORD(dat.x2); - lp.y2 = (SINT16)LOADINTELWORD(dat.y2); - if (dat.sw) { - lp.pat = (GDCPATREVERSE(dat.style[0]) << 8) + + pat = 0xffff; + if (dat.type < 2) { + if (dat.sw) { + pat = (GDCPATREVERSE(dat.style[0]) << 8) + GDCPATREVERSE(dat.style[1]); + } + if (dat.type == 0) { + gline(lio, &lp, pat); + } + else { + glineb(lio, &lp, pat); + } } - else { - lp.pat = 0xffff; - } - - - if (dat.pal == 0xff) { - dat.pal = lio->mem.fgcolor; + else if (dat.type == 2) { + leng = 0; + if (dat.sw == 2) { + leng = dat.patleng; + if (leng == 0) { + goto gline_err; + } + i286_memstr_read(LOADINTELWORD(dat.seg), LOADINTELWORD(dat.off), + tile, leng); + } + gbox(lio, &lp, tile, leng); } - else if (dat.pal >= lio->draw.palmax) { - return(5); + else { + goto gline_err; } - x1 = (SINT16)LOADINTELWORD(dat.x1); - y1 = (SINT16)LOADINTELWORD(dat.y1); - x2 = (SINT16)LOADINTELWORD(dat.x2); - y2 = (SINT16)LOADINTELWORD(dat.y2); - switch(dat.type) { - case 0: - gline(lio, &lp); - break; - - case 1: - nor_linebox(lio, x1, y1, x2, y2, dat.pal); - break; - - case 2: - nor_lineboxfill(lio, x1, y1, x2, y2, dat.pal); - break; + return(LIO_SUCCESS); - default: - return(5); - } - return(0); +gline_err: + return(LIO_ILLEGALFUNC); }