#include "compiler.h"
#include "cpucore.h"
#include "pccore.h"
#include "iocore.h"
#include "gdc_sub.h"
#include "lio.h"
typedef struct {
BYTE x1[2];
BYTE y1[2];
BYTE x2[2];
BYTE y2[2];
BYTE pal;
BYTE type;
BYTE sw;
BYTE style[2];
BYTE patleng;
BYTE off[2];
BYTE seg[2];
} GLINE;
typedef struct {
int x1;
int y1;
int x2;
int y2;
UINT16 pat;
UINT8 pal;
} LINEPT;
static void gline(const _LIOWORK *lio, const LINEPT *lp) {
int x1;
int y1;
int x2;
int y2;
int swap;
int tmp;
int width;
int height;
int d1;
int d2;
UINT16 pat;
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;
}
// 進んだ距離計算
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)((lp->pat >> d1) | (lp->pat << (16 - d1)));
csrw = (y1 * 40) + (x1 >> 4) + ((x1 & 0xf) << 20);
gdcsub_setvectl(&vect, x1, y1, x2, y2);
if (!(lio->draw.flag & LIODRAW_MONO)) {
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_linebox(const _LIOWORK *lio, SINT16 x1, SINT16 y1,
SINT16 x2, SINT16 y2, REG8 pal) {
lio_line(lio, x1, x2, y1, pal);
if (y1 != y2) {
lio_line(lio, x1, x2, y2, pal);
}
for (; y1<y2; y1++) {
lio_pset(lio, x1, y1, pal);
lio_pset(lio, x2, y1, pal);
}
}
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);
}
}
// ----
REG8 lio_gline(LIOWORK lio) {
GLINE dat;
LINEPT lp;
SINT16 x1;
SINT16 y1;
SINT16 x2;
SINT16 y2;
lio_updatedraw(lio);
i286_memstr_read(CPU_DS, CPU_BX, &dat, sizeof(dat));
if (dat.pal == 0xff) {
lp.pal = lio->mem.fgcolor;
}
else {
lp.pal = dat.pal;
}
if (lp.pal >= lio->draw.palmax) {
return(LIO_ILLEGALFUNC);
}
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) +
GDCPATREVERSE(dat.style[1]);
}
else {
lp.pat = 0xffff;
}
if (dat.pal == 0xff) {
dat.pal = lio->mem.fgcolor;
}
else if (dat.pal >= lio->draw.palmax) {
return(5);
}
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;
default:
return(5);
}
return(0);
}
RetroPC.NET-CVS <cvs@retropc.net>