aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Hamm2007-11-03 12:30:02 +0000
committerVincent Hamm2007-11-03 12:30:02 +0000
commit3e3cfca83e7f11425349a61567dc0e672726cafe (patch)
treefe5dda405919537f14401bdf555ee73589bb6365
parent01de17b063926071ea05886e950279da4d9fbdb7 (diff)
downloadscummvm-rg350-3e3cfca83e7f11425349a61567dc0e672726cafe.tar.gz
scummvm-rg350-3e3cfca83e7f11425349a61567dc0e672726cafe.tar.bz2
scummvm-rg350-3e3cfca83e7f11425349a61567dc0e672726cafe.zip
Early polygon rewrite
svn-id: r29383
-rw-r--r--engines/cruise/mainDraw.cpp439
1 files changed, 397 insertions, 42 deletions
diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp
index d5372be84e..106be81782 100644
--- a/engines/cruise/mainDraw.cpp
+++ b/engines/cruise/mainDraw.cpp
@@ -230,7 +230,8 @@ void getPolySize(int positionX, int positionY, int scale, int sizeTable[4], unsi
sizeTable[3] = upperBorder; // top
}
-int polyVar1;
+int nbseg;
+int16 nbligne;
void blitPolyMode1(char *dest, char *ptr, int16 * buffer, char color)
{
@@ -239,65 +240,417 @@ void blitPolyMode1(char *dest, char *ptr, int16 * buffer, char color)
void blitPolyMode2(char *dest, int16 * buffer, char color)
{
- int i;
+ int Y = XMIN_XMAX[0];
+
+ for(int i=0; i<nbligne; i++)
+ {
+ int currentY = Y+i;
+ int XMIN = XMIN_XMAX[1+i*2];
+ int XMAX = XMIN_XMAX[1+i*2+1];
- for (i = 0; i < polyVar1; i++) {
+ if(XMAX > 0)
+ line(XMIN, currentY, XMAX, currentY, color);
+ }
+/* int i;
+
+ for (i = 0; i < nbseg; i++) {
line(buffer[i * 2], buffer[i * 2 + 1], buffer[(i + 1) * 2], buffer[(i + 1) * 2 + 1], color);
}
- fillpoly(buffer, polyVar1, color);
+ fillpoly(buffer, nbseg, color); */
}
-int polySize1;
-int polySize2;
-int polySize3;
-int polySize4;
+int polyXMin;
+int polyXMax;
+int polyYMax;
+int polyYMin;
+
+int16 *A2ptr;
+
+
+
+void buildSegment(void)
+{
+ int16* pOut = XMIN_XMAX;
+
+ if((polyXMin >= 320) || (polyXMax < 0) || (polyYMax < 0) || (polyYMin >= 200))
+ {
+ XMIN_XMAX[0] = -1;
+ nbligne = -1;
+ return;
+ }
+
+ if(polyYMin == polyYMax) // line
+ {
+ *(pOut++) = polyYMin; // store initial Y
+
+ int cx = nbseg-1;
+ int16* pIn = A2ptr;
+
+ int XLeft;
+ int XRight;
+
+ XLeft = XRight = *pIn; // init to first X
+ pIn+=2;
+
+ do
+ {
+ int X = *pIn;
+ if(XLeft > X)
+ XLeft = X;
+ if(XRight < X)
+ XRight = X;
+ pIn+=2;
+ }while(--cx);
+
+ // now store left and right coordinates in XMIN_XMAX
+
+ int XMin = XLeft;
+ int XMax = XRight;
+
+ if(XLeft < 0)
+ XMin = 0;
+
+ if(XRight >= 320)
+ XMax = 319;
+
+ *(pOut++) = XMin;
+ *(pOut++) = XMax;
+ *(pOut++) = -1;
+
+ nbligne = -1;
+ return;
+ }
+
+ // true polygon
+
+ int ydep;
+
+ if(polyYMin < 0)
+ ydep = 0;
+ else
+ ydep = polyYMin;
+
+ int yfin;
+
+ if(polyYMax > 199)
+ yfin = 199;
+ else
+ yfin = polyYMax;
+
+ nbligne = yfin - ydep + 1;
+
+ int16* ptrMini = XMIN_XMAX + 1;
+ XMIN_XMAX[0] = ydep;
+
+ int16* ptrMax = XMIN_XMAX + ((yfin - ydep) * 2) + 1;
+ ptrMax[2] = -1; // mark the end
+
+ // init table with default values
+ int16* si = XMIN_XMAX + 1;
+ int tempCount = nbligne;
+ do
+ {
+ si[0] = 5000;
+ si[1] = -5000;
+ si+=2;
+ }while(--tempCount);
+
+ int16* di = A2ptr;
+ int segCount = nbseg;
+
+ do
+ {
+ int X2 = di[2];
+ int X1 = di[0];
+ int Y2 = di[3];
+ int Y1 = di[1];
+
+
+ int tempAX = Y1;
+ int tempDX = Y2;
+ if(tempAX > tempDX)
+ {
+ // swap
+ tempAX = Y2;
+ tempDX = Y1;
+ }
+
+ // is segment on screen ?
+ if(!((tempAX > 199) || (tempDX < 0)))
+ {
+ int dx = Y1;
+ int cx = X2 - X1;
+ if(cx == 0)
+ {
+ // vertical line
+ int CX = X2;
+ if(CX < 0)
+ CX = 0;
+
+ int DX = X2;
+ if(DX > 319)
+ DX = 319;
+
+ int16* BX = XMIN_XMAX + (Y2 - ydep) * 2 +1;
+ int16* DI = XMIN_XMAX + (Y1 - ydep) * 2 +1;
+
+ if(Y2 >= Y1)
+ {
+ int16* temp;
+
+ temp=BX;
+ BX = DI;
+ DI = temp;
+ }
-int16 *polyVar2;
+ do
+ {
+ if((BX < ptrMax) && (BX > ptrMini)) // are we in screen ?
+ {
+ if(CX < BX[0])
+ BX[0] = CX;
+
+ if(DX > BX[1])
+ BX[1] = DX;
+ }
+
+ BX+=2;
+ }while(BX <= DI);
+ }
+ else
+ {
+ if( cx < 0 )
+ {
+ cx = -cx;
+ dx = Y2;
+
+ int temp;
+ temp = X1;
+ X1 = X2;
+ X2 = temp;
+
+ temp = Y1;
+ Y1 = Y2;
+ Y2 = temp;
+ }
+ // swap again ?
+ int temp;
+ temp = X1;
+ X1 = X2;
+ X2 = temp;
+
+ int patchAdd = 2;
+
+ int dy = Y2 - Y1;
+
+ if( dy == 0 )
+ {
+ // hline
+ int16* ptr = (Y1 - ydep) * 2 + XMIN_XMAX + 1;
+
+ if((ptr <= ptrMax) && (ptr >= ptrMini)) // are we in screen ?
+ {
+ int CX = X1;
+ if(CX < 0)
+ CX = 0;
+
+ int SI = X2;
+ if(SI > 319)
+ SI = 319;
+
+ if(CX < ptr[0])
+ ptr[0] = CX;
+
+ if(SI > ptr[1])
+ ptr[1] = SI;
+ }
+ }
+ else
+ {
+ if( dy < 0 )
+ {
+ dy = -dy;
+ patchAdd = -2;
+ }
+
+ int stepType = 0; // small DY <= DX
+
+ if(dy > cx)
+ {
+ stepType = 1; // DX < DY
+
+ int temp;
+ temp = dy;
+ dy = cx;
+ cx = dy;
+ }
+ int patchinc1 = 2*dy;
+
+ int d = 2 * dy - cx;
+ int bx = 2 * (dy - cx);
+
+ int patchinc2 = bx;
+
+ cx++; // cx is the number of pixels to trace
+
+ int16* ptr = (Y1 - ydep)*2 + XMIN_XMAX + 1;
+
+ if(stepType == 0)
+ {
+ // small step
+ int BP = X2;
+
+ int SI = BP;
+ if(SI < 0)
+ SI = 0;
+ int DX = BP;
+ if(DX > 319)
+ DX = 319;
+
+ do
+ {
+ if((ptr <= ptrMax) && (ptr >= ptrMini)) // are we in screen ?
+ {
+ if(SI < ptr[0])
+ ptr[0] = SI;
+
+ if(DX > ptr[1])
+ ptr[1] = DX;
+ }
+
+ BP ++;
+
+ // test limits
+ SI = BP;
+ if(SI < 0)
+ SI = 0;
+ DX = BP;
+ if(DX > 319)
+ DX = 319;
+
+ if(d < 0)
+ {
+ d += patchinc1;
+ if( cx == 1 ) // last ?
+ {
+ if((ptr <= ptrMax) && (ptr >= ptrMini)) // are we in screen ?
+ {
+ if(SI < ptr[0])
+ ptr[0] = SI;
+
+ if(DX > ptr[1])
+ ptr[1] = DX;
+ }
+ }
+ }
+ else
+ {
+ d += patchinc2;
+ ptr+=patchAdd;
+ }
+ }while(--cx);
+ }
+ else
+ {
+ // big step
+ int BP = X2;
+
+ int SI = BP;
+ if(SI < 0)
+ SI = 0;
+ int DX = BP;
+ if(DX > 319)
+ DX = 319;
+
+ do
+ {
+ if((ptr <= ptrMax) && (ptr >= ptrMini)) // are we in screen ?
+ {
+ if(SI < ptr[0])
+ ptr[0] = SI;
+
+ if(DX > ptr[1])
+ ptr[1] = DX;
+ }
+
+ ptr += patchAdd; // next line
+
+ if(d < 0)
+ {
+ d += patchinc1;
+ }
+ else
+ {
+ d += patchinc2;
+ BP ++;
+
+ // test limits
+ SI = BP;
+ if(SI < 0)
+ SI = 0;
+ DX = BP;
+ if(DX > 319)
+ DX = 319;
+ }
+ }while(--cx);
+ }
+
+ }
+ }
+ }
+
+ di+=2;
+ }while(--segCount);
+}
char *drawPolyMode1(char *dataPointer, int linesToDraw) {
int index;
int16 *pBufferDest;
- polyVar1 = linesToDraw;
- pBufferDest = &polyBuffer4[polyVar1 * 2];
+ nbseg = linesToDraw;
+ pBufferDest = &polyBuffer4[nbseg * 2];
index = *(dataPointer++);
- polySize1 = polySize2 = pBufferDest[-2] = pBufferDest[-2 + linesToDraw * 2] = polyBuffer2[index * 2];
- polySize1 = polySize2 = pBufferDest[-1] = pBufferDest[-1 + linesToDraw * 2] = polyBuffer2[(index * 2) + 1];
+ polyXMin = polyXMax = pBufferDest[-2] = pBufferDest[-2 + linesToDraw * 2] = polyBuffer2[index * 2];
+ polyYMin = polyYMax = pBufferDest[-1] = pBufferDest[-1 + linesToDraw * 2] = polyBuffer2[(index * 2) + 1];
linesToDraw--;
pBufferDest -= 2;
- polyVar2 = pBufferDest;
+ A2ptr = pBufferDest;
do {
- int value;
-
index = *(dataPointer++);
- value = pBufferDest[-2] = pBufferDest[-2 + polyVar1 * 2] = polyBuffer2[index * 2];
+ int X = polyBuffer2[index * 2];
+
+ pBufferDest[-2] = pBufferDest[-2 + nbseg * 2] = X;
- if (value < polySize1) {
- polySize1 = value;
+ if (X < polyXMin) {
+ polyXMin = X;
}
- if (value > polySize2) {
- polySize2 = value;
+ if (X > polyXMax) {
+ polyXMax = X;
}
- value = pBufferDest[-1] = pBufferDest[-1 + polyVar1 * 2] = polyBuffer2[(index * 2) + 1];
+ int Y = polyBuffer2[(index * 2) + 1];
- if (value > polySize4) {
- polySize4 = value;
+ pBufferDest[-1] = pBufferDest[-1 + nbseg * 2] = Y;
+
+ if (Y < polyYMin) {
+ polyYMin = Y;
}
- if (value < polySize3) {
- polySize3 = value;
- polyVar2 = pBufferDest - 4;
+ if (Y > polyYMax) {
+ polyYMax = Y;
+ A2ptr = pBufferDest - 4;
}
pBufferDest -= 2;
} while (--linesToDraw);
+ buildSegment();
+
return dataPointer;
}
@@ -307,12 +660,12 @@ char *drawPolyMode2(char *dataPointer, int linesToDraw)
int16 *pBufferDest;
pBufferDest = polyBuffer4;
- polyVar1 = linesToDraw;
- polyVar2 = polyBuffer4;
+ nbseg = linesToDraw;
+ A2ptr = polyBuffer4;
index = *(dataPointer++);
- polySize1 = polySize2 = pBufferDest[0] = pBufferDest[linesToDraw * 2] = polyBuffer2[index * 2];
- polySize1 = polySize2 = pBufferDest[1] = pBufferDest[linesToDraw * 2 + 1] = polyBuffer2[(index * 2) + 1];
+ polyXMin = polyXMax = pBufferDest[0] = pBufferDest[linesToDraw * 2] = polyBuffer2[index * 2];
+ polyYMin = polyYMax = pBufferDest[1] = pBufferDest[linesToDraw * 2 + 1] = polyBuffer2[(index * 2) + 1];
linesToDraw--;
@@ -322,29 +675,31 @@ char *drawPolyMode2(char *dataPointer, int linesToDraw)
int value;
index = *(dataPointer++);
- value = pBufferDest[0] = pBufferDest[polyVar1 * 2] = polyBuffer2[index * 2];
+ value = pBufferDest[0] = pBufferDest[nbseg * 2] = polyBuffer2[index * 2];
- if (value < polySize1) {
- polySize1 = value;
+ if (value < polyXMin) {
+ polyXMin = value;
}
- if (value > polySize2) {
- polySize2 = value;
+ if (value > polyXMax) {
+ polyXMax = value;
}
- value = pBufferDest[1] = pBufferDest[polyVar1 * 2 + 1] = polyBuffer2[(index * 2) + 1];
+ value = pBufferDest[1] = pBufferDest[nbseg * 2 + 1] = polyBuffer2[(index * 2) + 1];
- if (value > polySize4) {
- polySize4 = value;
+ if (value < polyYMin) {
+ polyYMin = value;
}
- if (value < polySize3) {
- polySize3 = value;
- polyVar2 = pBufferDest;
+ if (value > polyYMax) {
+ polyYMax = value;
+ A2ptr = pBufferDest;
}
pBufferDest += 2;
} while (--linesToDraw);
+ buildSegment();
+
return dataPointer;
}