Diff for /np2/lio/gline.c between versions 1.4 and 1.15

version 1.4, 2004/02/20 15:20:30 version 1.15, 2005/05/20 13:59:47
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
 #include        "cpucore.h"  #include        "cpucore.h"
   #include        "pccore.h"
   #include        "iocore.h"
   #include        "gdc_sub.h"
 #include        "lio.h"  #include        "lio.h"
   
   
 typedef struct {  typedef struct {
         BYTE    x1[2];          UINT8   x1[2];
         BYTE    y1[2];          UINT8   y1[2];
         BYTE    x2[2];          UINT8   x2[2];
         BYTE    y2[2];          UINT8   y2[2];
         BYTE    pal;          UINT8   pal;
         BYTE    type;          UINT8   type;
         BYTE    sw;          UINT8   sw;
         BYTE    style_l;          UINT8   style[2];
         BYTE    style_h;          UINT8   patleng;
         BYTE    patleng;          UINT8   off[2];
         BYTE    off[2];          UINT8   seg[2];
         BYTE    seg[2];  
 } GLINE;  } GLINE;
   
   typedef struct {
           int             x1;
           int             y1;
           int             x2;
           int             y2;
           UINT8   pal;
   } LINEPT;
   
   
   static void gline(const _GLIO *lio, const LINEPT *lp, UINT16 pat) {
   
           int             x1;
           int             y1;
           int             x2;
           int             y2;
           int             swap;
           int             tmp;
           int             width;
           int             height;
           int             d1;
           int             d2;
           UINT32  csrw;
           GDCVECT vect;
   
           x1 = lp->x1;
           y1 = lp->y1;
           x2 = lp->x2;
           y2 = lp->y2;
   
           // びゅーぽいんと
           swap = 0;
           if (x1 > x2) {
                   tmp = x1;
                   x1 = x2;
                   x2 = tmp;
                   tmp = y1;
                   y1 = y2;
                   y2 = tmp;
                   swap = 1;
           }
           if ((x1 > lio->draw.x2) || (x2 < lio->draw.x1)) {
                   return;
           }
           width = x2 - x1;
           height = y2 - y1;
           d1 = lio->draw.x1 - x1;
           d2 = x2 - lio->draw.x2;
           if (d1 > 0) {
                   x1 = lio->draw.x1;
                   y1 += (((height * d1 * 2) / width) + 1) >> 1;
           }
           if (d2 > 0) {
                   x2 = lio->draw.x2;
                   y2 -= (((height * d2 * 2) / width) + 1) >> 1;
           }
           if (swap) {
                   tmp = x1;
                   x1 = x2;
                   x2 = tmp;
                   tmp = y1;
                   y1 = y2;
                   y2 = tmp;
           }
   
           swap = 0;
           if (y1 > y2) {
                   tmp = x1;
                   x1 = x2;
                   x2 = tmp;
                   tmp = y1;
                   y1 = y2;
                   y2 = tmp;
           }
           if ((y1 > lio->draw.y2) || (y2 < lio->draw.y1)) {
                   return;
           }
           width = x2 - x1;
           height = y2 - y1;
           d1 = lio->draw.y1 - y1;
           d2 = y2 - lio->draw.y2;
           if (d1 > 0) {
                   y1 = lio->draw.y1;
                   x1 += (((width * d1 * 2) / height) + 1) >> 1;
           }
           if (d2 > 0) {
                   y2 = lio->draw.y2;
                   x2 -= (((width * d2 * 2) / height) + 1) >> 1;
           }
           if (swap) {
                   tmp = x1;
                   x1 = x2;
                   x2 = tmp;
                   tmp = y1;
                   y1 = y2;
                   y2 = tmp;
           }
   
 static void nor_linebox(const _LIOWORK *lio, SINT16 x1, SINT16 y1,          // 進んだ距離計算
                                                                                         SINT16 x2, SINT16 y2, REG8 pal) {          d1 = x1 - lp->x1;
           if (d1 < 0) {
                   d1 = 0 - d1;
           }
           d2 = y1 - lp->y1;
           if (d2 < 0) {
                   d2 = 0 - d2;
           }
           d1 = max(d1, d2) & 15;
           pat = (UINT16)((pat >> d1) | (pat << (16 - d1)));
   
         lio_line(lio, x1, x2, y1, pal);          csrw = (y1 * 40) + (x1 >> 4) + ((x1 & 0xf) << 20);
         if (y1 != y2) {          if (lio->draw.flag & LIODRAW_UPPER) {
                 lio_line(lio, x1, x2, y2, pal);                  csrw += 16000 >> 1;
         }          }
         for (; y1<y2; y1++) {          gdcsub_setvectl(&vect, x1, y1, x2, y2);
                 lio_pset(lio, x1, y1, pal);          if (!(lio->draw.flag & LIODRAW_MONO)) {
                 lio_pset(lio, x2, y1, pal);                  gdcsub_vectl(csrw + 0x4000, &vect, pat,
                                                           (REG8)((lp->pal & 1)?GDCOPE_SET:GDCOPE_CLEAR));
                   gdcsub_vectl(csrw + 0x8000, &vect, pat,
                                                           (REG8)((lp->pal & 2)?GDCOPE_SET:GDCOPE_CLEAR));
                   gdcsub_vectl(csrw + 0xc000, &vect, pat,
                                                           (REG8)((lp->pal & 4)?GDCOPE_SET:GDCOPE_CLEAR));
                   if (lio->draw.flag & LIODRAW_4BPP) {
                           gdcsub_vectl(csrw, &vect, pat,
                                                           (REG8)((lp->pal & 8)?GDCOPE_SET:GDCOPE_CLEAR));
                   }
           }
           else {
                   csrw += ((lio->draw.flag + 1) & LIODRAW_PMASK) << 12;
                   gdcsub_vectl(csrw, &vect, pat,
                                                                   (REG8)((lp->pal)?GDCOPE_SET:GDCOPE_CLEAR));
         }          }
 }  }
   
 static void nor_lineboxfill(const _LIOWORK *lio, SINT16 x1, SINT16 y1,  static void glineb(const _GLIO *lio, const LINEPT *lp, UINT16 pat) {
                                                                                         SINT16 x2, SINT16 y2, REG8 pal) {  
           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 gbox(const _GLIO *lio, const LINEPT *lp, UINT8 *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;
           UINT8   *tterm;
           UINT    r;
   
           x1 = lp->x1;
           y1 = lp->y1;
           x2 = lp->x2;
           y2 = lp->y2;
   
           if (x1 > 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 = (UINT8)((r << tmp) | (r >> (8 - tmp)));
                   } while(++tile < tterm);
                   tile -= leng;
                   tmp = (y1 - lio->draw.y1) * planes;
                   tile += tmp % leng;
           }
   
         for (; y1<=y2; y1++) {          pat = 0xffff;
                 lio_line(lio, x1, x2, y1, pal);          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++;
         }          }
 }  }
   
   
   // ---- 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;          GLINE   dat;
         SINT16  x1;          LINEPT  lp;
         SINT16  y1;          UINT16  pat;
         SINT16  x2;          UINT    leng;
         SINT16  y2;  //      UINT    lengmin;
           UINT8   tile[256];
   
           lio_updatedraw(lio);
           MEMR_READS(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);
   
           TRACEOUT(("lio_gline %d,%d-%d,%d [%d]", lp.x1, lp.y1, lp.x2, lp.y2, dat.type));
   
         lio_updaterange(lio);  
         i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat));  
         if (dat.pal == 0xff) {          if (dat.pal == 0xff) {
                 dat.pal = lio->gcolor1.fgcolor;                  dat.pal = lio->work.fgcolor;
         }          }
         else if (dat.pal >= lio->gcolor1.palmax) {          if (dat.pal >= lio->draw.palmax) {
                 return(5);                  goto gline_err;
         }          }
         x1 = (SINT16)LOADINTELWORD(dat.x1);          pat = 0xffff;
         y1 = (SINT16)LOADINTELWORD(dat.y1);          if (dat.type < 2) {
         x2 = (SINT16)LOADINTELWORD(dat.x2);                  if (dat.sw) {
         y2 = (SINT16)LOADINTELWORD(dat.y2);                          pat = (GDCPATREVERSE(dat.style[0]) << 8) +
         switch(dat.type) {                                                                                          GDCPATREVERSE(dat.style[1]);
                 case 0:                  }
                         break;                  lp.pal = dat.pal;
                   if (dat.type == 0) {
                 case 1:                          gline(lio, &lp, pat);
                         nor_linebox(lio, x1, y1, x2, y2, dat.pal);                  }
                         break;                  else {
                           glineb(lio, &lp, pat);
                 case 2:                  }
                         nor_lineboxfill(lio, x1, y1, x2, y2, dat.pal);          }
                         break;          else if (dat.type == 2) {
                   leng = 0;
                 default:                  if (dat.sw == 2) {
                         return(5);                          leng = dat.patleng;
                           if (leng == 0) {
                                   goto gline_err;
                           }
                           MEMR_READS(LOADINTELWORD(dat.seg), LOADINTELWORD(dat.off),
                                                                                                                                   tile, leng);
                   }
                   if (dat.sw != 1) {
                           lp.pal = dat.pal;
                           gbox(lio, &lp, tile, leng);
                   }
                   else {
                           lp.pal = dat.style[0];
                           gbox(lio, &lp, tile, leng);
                           lp.pal = dat.pal;
                           glineb(lio, &lp, 0xffff);
                   }
         }          }
         return(0);          else {
                   goto gline_err;
           }
           return(LIO_SUCCESS);
   
   gline_err:
           return(LIO_ILLEGALFUNC);
 }  }
   

Removed from v.1.4  
changed lines
  Added in v.1.15


RetroPC.NET-CVS <cvs@retropc.net>