diff options
author | Vincent Hamm | 2007-11-05 20:24:20 +0000 |
---|---|---|
committer | Vincent Hamm | 2007-11-05 20:24:20 +0000 |
commit | e2260d8afdbd28a74436c4f2001791f8fc816c3f (patch) | |
tree | 070f90917e7cd3c283c65fd0b84dda9938399c1e /engines | |
parent | f7c6189c1ee2e9c19ce879b1a6d357b370190c39 (diff) | |
download | scummvm-rg350-e2260d8afdbd28a74436c4f2001791f8fc816c3f.tar.gz scummvm-rg350-e2260d8afdbd28a74436c4f2001791f8fc816c3f.tar.bz2 scummvm-rg350-e2260d8afdbd28a74436c4f2001791f8fc816c3f.zip |
Implement polygon and sprite masking
svn-id: r29422
Diffstat (limited to 'engines')
-rw-r--r-- | engines/cruise/backgroundIncrust.cpp | 11 | ||||
-rw-r--r-- | engines/cruise/cell.cpp | 118 | ||||
-rw-r--r-- | engines/cruise/cruise_main.cpp | 41 | ||||
-rw-r--r-- | engines/cruise/cruise_main.h | 1 | ||||
-rw-r--r-- | engines/cruise/dataLoader.cpp | 88 | ||||
-rw-r--r-- | engines/cruise/mainDraw.cpp | 170 | ||||
-rw-r--r-- | engines/cruise/mainDraw.h | 2 | ||||
-rw-r--r-- | engines/cruise/object.h | 1 | ||||
-rw-r--r-- | engines/cruise/saveload.cpp | 4 | ||||
-rw-r--r-- | engines/cruise/vars.h | 2 |
10 files changed, 259 insertions, 179 deletions
diff --git a/engines/cruise/backgroundIncrust.cpp b/engines/cruise/backgroundIncrust.cpp index 0bcdbe12db..942b4d0e0d 100644 --- a/engines/cruise/backgroundIncrust.cpp +++ b/engines/cruise/backgroundIncrust.cpp @@ -44,9 +44,7 @@ void addBackgroundIncrustSub1(int fileIdx, int X, int Y, char *ptr2, buildPolyModel(X, Y, scale, ptr2, destBuffer, dataPtr); } -backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx, - int16 objectIdx, backgroundIncrustStruct *pHead, int16 scriptNumber, - int16 scriptOverlay, int16 backgroundIdx, int16 param4) { +backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx, int16 objectIdx, backgroundIncrustStruct *pHead, int16 scriptNumber, int16 scriptOverlay, int16 backgroundIdx, int16 param4) { uint8 *backgroundPtr; uint8 *ptr; objectParamsQuery params; @@ -117,12 +115,7 @@ backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx, int width = filesDatabase[params.fileIdx].width; int height = filesDatabase[params.fileIdx].height; - currentTransparent = - filesDatabase[params.fileIdx].subData.transparency; - mainDrawSub4(width, height, NULL, - (char *)filesDatabase[params.fileIdx].subData.ptr, - newElement->Y, newElement->X, (char *)backgroundPtr, - (char *)filesDatabase[params.fileIdx].subData.ptr); + drawSprite(width, height, NULL, (char *)filesDatabase[params.fileIdx].subData.ptr, newElement->Y, newElement->X, (char *)backgroundPtr, (char *)filesDatabase[params.fileIdx].subData.ptrMask); // ASSERT(0); } else { // poly /* if (param4 == 1) diff --git a/engines/cruise/cell.cpp b/engines/cruise/cell.cpp index 79b07f5c60..6cf84b44f7 100644 --- a/engines/cruise/cell.cpp +++ b/engines/cruise/cell.cpp @@ -274,90 +274,76 @@ void freezeCell(cellStruct * pObject, int overlayIdx, int objIdx, int objType, i } void sortCells(int16 param1, int16 param2, cellStruct *objPtr) { -/*int16 var; - cellStruct *var8_; - cellStruct *var40; - cellStruct *var3E; - cellStruct *currentObjPtrPrevious; - cellStruct *currentObjPtr2; - cellStruct *match; - - getSingleObjectParam(param1, param2, 2, &var); - - currentObjPtrPrevious = objPtr; - currentObjPtr2 = objPtr->next; - - match = NULL; - var40 = NULL; - var3E = NULL; - var8_ = objPtr; - - while (currentObjPtr2) { - if ((currentObjPtr2->overlay == param1) && (currentObjPtr2->idx == param2)) {// found - currentObjPtrPrevious->next = currentObjPtr2->next; - - if (currentObjPtr2->next) { - currentObjPtr2->next->prev = - currentObjPtr2->prev; + cellStruct *pl,*pl2,*pl3,*pl4,*plz,*pllast; + cellStruct prov; + int16 newz, objz, sobjz; + + pl4 = NULL; + + getSingleObjectParam(param1, param2, 2, &sobjz); + pl = objPtr; + prov.next = NULL; + prov.prev = NULL; + + pl2 = pl->next; + pllast = NULL; + plz = objPtr; + + while (pl2) { + pl3 = pl2->next; + if ((pl2->overlay == param1) && (pl2->idx == param2)) {// found + pl->next = pl3; + + if (pl3) { + pl3->prev = pl2->prev; } else { - objPtr->prev = currentObjPtr2->prev; + objPtr->prev = pl2->prev; } - if (var40) { - var40->prev = currentObjPtr2; + if (pl4) { + pl4->prev = pl2; } else { - var3E = currentObjPtr2; + prov.prev = pl2; } - currentObjPtr2->prev = NULL; + pl2->prev = NULL; + pl2->next = prov.next; + prov.next = pl2; - currentObjPtr2->next = var40; - - var40 = currentObjPtr2; - - if (match == NULL) { - match = currentObjPtr2; + if (pllast == NULL) { + pllast = pl2; } } else { - if (currentObjPtr2->type == 5) { - var2 = 32000; + if (pl2->type == 5) { + newz = 32000; } else { - int16 varC; - - getSingleObjectParam(currentObjPtr2->overlay, - currentObjPtr2->idx, 2, &varC); - - var2 = varC; + getSingleObjectParam(pl2->overlay, pl2->idx, 2, &objz); + newz = objz; } - if (var > var2) { - var8_ = currentObjPtr2; + if (newz < sobjz) { + plz = pl2; } - currentObjPtrPrevious = currentObjPtrPrevious->next; + pl = pl->next; } - currentObjPtr2 = currentObjPtr2->next; + pl2 = pl3; } - if (match) { - cellStruct *temp; - - temp = var8_->next; - - var8_->next = var40; - match->next = temp; - - if (objPtr != var8_) { - var40->prev = var8_; - } - - if (!temp) { - temp = match; - } - - temp->prev = match; - }*/ + if (pllast) { + pl2 = prov.next; + pl4 = plz->next; + plz->next = pl2; + pllast->next = pl4; + + if(plz != objPtr) + pl2->prev = plz; + if(!pl4) + objPtr->prev = pllast; + else + pl4->prev = pllast; + } } } // End of namespace Cruise diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp index 418976d5ef..48e2f435a7 100644 --- a/engines/cruise/cruise_main.cpp +++ b/engines/cruise/cruise_main.cpp @@ -186,7 +186,7 @@ void initBigVar3() { } filesDatabase[i].subData.ptr = NULL; - filesDatabase[i].subData.ptr2 = NULL; + filesDatabase[i].subData.ptrMask = NULL; filesDatabase[i].subData.index = -1; filesDatabase[i].subData.resourceType = 0; @@ -418,7 +418,7 @@ void resetFileEntry(int32 entryNumber) { free(filesDatabase[entryNumber].subData.ptr); filesDatabase[entryNumber].subData.ptr = NULL; - filesDatabase[entryNumber].subData.ptr2 = NULL; + filesDatabase[entryNumber].subData.ptrMask = NULL; filesDatabase[entryNumber].widthInColumn = 0; filesDatabase[entryNumber].width = 0; filesDatabase[entryNumber].resType = 0; @@ -465,7 +465,7 @@ int initAllData(void) { for (i = 0; i < 257; i++) { filesDatabase[i].subData.ptr = NULL; - filesDatabase[i].subData.ptr2 = NULL; + filesDatabase[i].subData.ptrMask = NULL; } initBigVar3(); @@ -605,6 +605,17 @@ int removeFinishedScripts(scriptInstanceStruct *ptrHandle) { return (0); } +bool testMask(int x, int y, unsigned char* pData, int stride) +{ + unsigned char* ptr = y * stride + x/8 + pData; + + unsigned char bitToTest = 0x80 >> (x & 7); + + if((*ptr) & bitToTest) + return true; + return false; +} + int buttonDown; int selectDown = 0; int menuDown = 0; @@ -697,30 +708,18 @@ int findObject(int mouseX, int mouseY, int *outObjOvl, int *outObjIdx) { int nWidth; int nHeight; - if (numBitPlanes == 1) { - nWidth = filesDatabase[j].widthInColumn / 2; - } else { - nWidth = filesDatabase[j].width; - } - + nWidth = filesDatabase[j].width; nHeight = filesDatabase[j].height; int offsetX = mouseX - x; int offsetY = mouseY - y; - if ((offsetX >= 0) && (offsetX < nWidth * 16) && (offsetY >= 0) && (nWidth <= nHeight) && filesDatabase[j].subData.ptr) { - if (numBitPlanes == 1) { - } else { + if ((offsetX >= 0) && (offsetX < nWidth) && (offsetY >= 0) && (offsetY <= nHeight) && filesDatabase[j].subData.ptr) { + if(testMask(offsetX, offsetY, filesDatabase[j].subData.ptrMask, filesDatabase[j].width/8)) { + *outObjOvl = objOvl; + *outObjIdx = objIdx; + return currentObject->type; } - - printf("should compare to mask in findObject...\n"); - - *outObjOvl = objOvl; - *outObjIdx = objIdx; - - printf("Selected: %s\n", objectName); - - return currentObject->type; } } } else if (currentObject->type == OBJ_TYPE_VIRTUEL) { diff --git a/engines/cruise/cruise_main.h b/engines/cruise/cruise_main.h index d2de09f08c..f00d247bff 100644 --- a/engines/cruise/cruise_main.h +++ b/engines/cruise/cruise_main.h @@ -110,6 +110,7 @@ void freeStuff2(void); char *getObjectName(int index, uint8 * string); void mainLoop(void); void getMouseStatus(int16 *pMouseVar, int16 *pMouseX, int16 *pMouseButton, int16 *pMouseY); +bool testMask(int x, int y, unsigned char* pData, int stride); } // End of namespace Cruise diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp index 54a0e97732..26984bce15 100644 --- a/engines/cruise/dataLoader.cpp +++ b/engines/cruise/dataLoader.cpp @@ -47,7 +47,7 @@ void decodeGfxFormat1(dataFileEntry *pCurrentFileEntry) { uint8 *dataPtr = pCurrentFileEntry->subData.ptr; int spriteSize = - pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 8; + pCurrentFileEntry->height * pCurrentFileEntry->width; int x = 0; buffer = (uint8 *) malloc(spriteSize); @@ -77,8 +77,7 @@ void decodeGfxFormat4(dataFileEntry *pCurrentFileEntry) { uint8 *buffer; uint8 *dataPtr = pCurrentFileEntry->subData.ptr; - int spriteSize = - pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 2; + int spriteSize = pCurrentFileEntry->height * pCurrentFileEntry->width; int x = 0; buffer = (uint8 *) malloc(spriteSize); @@ -98,8 +97,7 @@ void decodeGfxFormat4(dataFileEntry *pCurrentFileEntry) { /* decode planes */ for (c = 0; c < 16; c++) { buffer[x + c] = - ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & - 4) | ((p3 >> 12) & 8); + ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & 4) | ((p3 >> 12) & 8); p0 <<= 1; p1 <<= 1; @@ -143,8 +141,7 @@ void decodeGfxFormat5(dataFileEntry *pCurrentFileEntry) { /* decode planes */ for (c = 0; c < 16; c++) { buffer[x + c] = - ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & - 4) | ((p3 >> 12) & 8) | ((p4 >> 11) & 16); + ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & 4) | ((p3 >> 12) & 8) | ((p4 >> 11) & 16); p0 <<= 1; p1 <<= 1; @@ -163,28 +160,26 @@ void decodeGfxFormat5(dataFileEntry *pCurrentFileEntry) { int updateResFileEntry(int height, int width, int entryNumber, int resType) { int div = 0; - int size; resetFileEntry(entryNumber); filesDatabase[entryNumber].subData.field_1C = 0; - size = height * width; // for sprites: width * height + int maskSize = height * width; // for sprites: width * height if (resType == 4) { - div = size / 4; + div = maskSize / 4; } else if (resType == 5) { width = (width * 8) / 5; } - filesDatabase[entryNumber].subData.ptr = - (uint8 *) mallocAndZero(size + div); + filesDatabase[entryNumber].subData.ptr = (uint8 *) mallocAndZero(maskSize + div); if (!filesDatabase[entryNumber].subData.ptr) return (-2); filesDatabase[entryNumber].widthInColumn = width; - filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr + size; + filesDatabase[entryNumber].subData.ptrMask = (uint8 *) mallocAndZero(maskSize); filesDatabase[entryNumber].width = width / 8; filesDatabase[entryNumber].resType = resType; filesDatabase[entryNumber].height = height; @@ -230,7 +225,7 @@ int createResFileEntry(int width, int height, int resType) { } filesDatabase[entryNumber].widthInColumn = width; - filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr + size; + filesDatabase[entryNumber].subData.ptrMask = filesDatabase[entryNumber].subData.ptr + size; filesDatabase[entryNumber].width = width / 8; filesDatabase[entryNumber].resType = resType; filesDatabase[entryNumber].height = height; @@ -435,14 +430,9 @@ void loadSetEntry(uint8 *name, uint8 *ptr, int currentEntryIdx, resourceSize = localBuffer.width * localBuffer.height; if (currentDestEntry == -1) { - fileIndex = - createResFileEntry(localBuffer.width, - localBuffer.height, localBuffer.type); + fileIndex = createResFileEntry(localBuffer.width, localBuffer.height, localBuffer.type); } else { - fileIndex = - updateResFileEntry(localBuffer.height, - localBuffer.width, currentDestEntry, - localBuffer.type); + fileIndex = updateResFileEntry(localBuffer.height, localBuffer.width, currentDestEntry, localBuffer.type); } if (fileIndex < 0) { @@ -451,29 +441,26 @@ void loadSetEntry(uint8 *name, uint8 *ptr, int currentEntryIdx, ptr5 = ptr3 + localBuffer.field_0 + numIdx * 16; - memcpy(filesDatabase[fileIndex].subData.ptr, ptr5, - resourceSize); + memcpy(filesDatabase[fileIndex].subData.ptr, ptr5, resourceSize); ptr5 += resourceSize; switch (localBuffer.type) { case 0: { - filesDatabase[fileIndex].subData.resourceType = - 8; + filesDatabase[fileIndex].subData.resourceType = 8; break; } case 1: { - filesDatabase[fileIndex].subData.resourceType = - 2; + filesDatabase[fileIndex].width = filesDatabase[fileIndex].widthInColumn * 8; + filesDatabase[fileIndex].subData.resourceType = 2; decodeGfxFormat1(&filesDatabase[fileIndex]); break; } case 4: { - filesDatabase[fileIndex].width *= 2; - filesDatabase[fileIndex].subData.resourceType = - 4; + filesDatabase[fileIndex].width = filesDatabase[fileIndex].widthInColumn * 2; + filesDatabase[fileIndex].subData.resourceType = 4; decodeGfxFormat4(&filesDatabase[fileIndex]); break; } @@ -481,31 +468,60 @@ void loadSetEntry(uint8 *name, uint8 *ptr, int currentEntryIdx, { if (sec == 0) { // TODO sec type 5 needs special conversion. cut out 2 bytes at every width/5 position. + ASSERT(0); return; } - filesDatabase[fileIndex].subData.resourceType = - 4; + filesDatabase[fileIndex].subData.resourceType = 4; decodeGfxFormat5(&filesDatabase[fileIndex]); break; } case 8: { + ASSERT(0); filesDatabase[fileIndex].subData.resourceType = 4; // dummy ! break; } default: { - printf("Unsuported gfx loading type: %d\n", - localBuffer.type); + printf("Unsuported gfx loading type: %d\n", localBuffer.type); break; } } filesDatabase[fileIndex].subData.index = currentDestEntry; - filesDatabase[fileIndex].subData.transparency = - localBuffer.transparency; /*% 0x10 */ ; + filesDatabase[fileIndex].subData.transparency = localBuffer.transparency % 0x10; strcpyuint8(filesDatabase[fileIndex].subData.name, name); + + // create the mask + switch(localBuffer.type) + { + case 1: + case 4: + case 5: + case 8: + { + int maskX; + int maskY; + + memset(filesDatabase[fileIndex].subData.ptrMask, 0, filesDatabase[fileIndex].width/8 * filesDatabase[fileIndex].height); + + for(maskY=0; maskY<filesDatabase[fileIndex].height; maskY++) + { + for(maskX=0; maskX<filesDatabase[fileIndex].width; maskX++) + { + if(*(filesDatabase[fileIndex].subData.ptr + filesDatabase[fileIndex].width * maskY + maskX) != filesDatabase[fileIndex].subData.transparency) + { + *(filesDatabase[fileIndex].subData.ptrMask + filesDatabase[fileIndex].width/8 * maskY + maskX / 8) |= 0x80 >> (maskX&7); + } + } + } + break; + } + default: + { + } + } } // TODO: free diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp index 79e8b50ef3..a2c3cd6d62 100644 --- a/engines/cruise/mainDraw.cpp +++ b/engines/cruise/mainDraw.cpp @@ -29,8 +29,6 @@ namespace Cruise { -int currentTransparent; - struct autoCellStruct { struct autoCellStruct *next; short int ovlIdx; @@ -228,8 +226,23 @@ void getPolySize(int positionX, int positionY, int scale, int sizeTable[4], unsi int nbseg; int16 nbligne; -void blitPolyMode1(char *dest, char *ptr, int16 * buffer, char color) { - ASSERT(0); +void blitPolyMode1(char *dest, char *pMask, int16 * buffer, char color) { + 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(int x=XMIN; x<=XMAX; x++) + { + if(testMask(x, currentY, (unsigned char*)pMask, 40)) + { + *(dest + currentY * 320 + x) = color; + } + } + //line(XMIN, currentY, XMAX, currentY, color); + } } void blitPolyMode2(char *dest, int16 * buffer, char color) { @@ -240,15 +253,11 @@ void blitPolyMode2(char *dest, int16 * buffer, char color) { int XMIN = XMIN_XMAX[1+i*2]; int XMAX = XMIN_XMAX[1+i*2+1]; - line(XMIN, currentY, XMAX, currentY, color); + for(int x=XMIN; x<=XMAX; x++) + { + *(dest + currentY * 320 + x) = 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, nbseg, color); */ } int polyXMin; @@ -950,7 +959,7 @@ bool findPoly(char* dataPtr, int positionX, int positionY, int scale, int mouseX int polygonYMin = XMIN_XMAX[0]; int polygonYMax = polygonYMin + nbligne; - if ((mouseY >= polygonYMin) && (mouseY <= polygonYMax)) { + if ((mouseY >= polygonYMin) && (mouseY < polygonYMax)) { int polygonLineNumber = mouseY - polygonYMin; int XMIN = XMIN_XMAX[1+polygonLineNumber*2]; @@ -972,8 +981,38 @@ bool findPoly(char* dataPtr, int positionX, int positionY, int scale, int mouseX return false; } +void clearMaskBit(int x, int y, unsigned char* pData, int stride) +{ + unsigned char* ptr = y * stride + x/8 + pData; + + unsigned char bitToTest = 0x80 >> (x & 7); + + *(ptr) &= ~bitToTest; +} + + +void drawMask(unsigned char* workBuffer, int wbWidth, int wbHeight, unsigned char* pMask, int maskWidth, int maskHeight, int maskX, int maskY, int passIdx) +{ + for(int y=0; y<maskHeight; y++) + { + for(int x=0; x<maskWidth*8; x++) + { + if(testMask(x,y, pMask, maskWidth)) + { + int destX = maskX + x; + int destY = maskY + y; + + if((destX >= 0) && (destX < wbWidth*8) && (destY >= 0) && (destY < wbHeight)) + clearMaskBit(destX, destY, workBuffer, wbWidth); + } + } + } +} + +unsigned char polygonMask[(320*200)/8]; + // draw poly sprite (OLD: mainDrawSub1) -void mainDrawPolygons(int fileIndex, cellStruct *pObject, int X, int scale, int Y, char *destBuffer, char *dataPtr) { +void mainDrawPolygons(int fileIndex, cellStruct *plWork, int X, int scale, int Y, char *destBuffer, char *dataPtr) { int newX; int newY; int newScale; @@ -1021,27 +1060,44 @@ void mainDrawPolygons(int fileIndex, cellStruct *pObject, int X, int scale, int if (spriteY1 == spriteY2) return; - char *pMask = NULL; var_8 = 0; - if (pObject) { - cellStruct *pCurrentObject = pObject; + memset(polygonMask, 0xFF, (320*200)/8); - do { - if (pCurrentObject->type == OBJ_TYPE_BGMK) { -// ASSERT(0); + int numPasses = 0; + + while(plWork) + { + if(plWork->type == OBJ_TYPE_BGMK && plWork->freeze == 0) + { + objectParamsQuery params; + + getMultipleObjectParam(plWork->overlay, plWork->idx, ¶ms); + + int maskX = params.X; + int maskY = params.Y; + int maskFrame = params.fileIdx; + + if(filesDatabase[maskFrame].subData.resourceType == OBJ_TYPE_BGMK && filesDatabase[maskFrame].subData.ptrMask) + { + drawMask(polygonMask, 40, 200, filesDatabase[maskFrame].subData.ptrMask, filesDatabase[maskFrame].width/8, filesDatabase[maskFrame].height, maskX, maskY, numPasses++); + } + else + if(filesDatabase[maskFrame].subData.resourceType == OBJ_TYPE_SPRITE && filesDatabase[maskFrame].subData.ptrMask) + { + drawMask(polygonMask, 40, 200, filesDatabase[maskFrame].subData.ptrMask, filesDatabase[maskFrame].width/8, filesDatabase[maskFrame].height, maskX, maskY, numPasses++); } - pCurrentObject = pCurrentObject->next; - } while (pCurrentObject); + } + + plWork = plWork->next; } // this function builds the poly model and then calls the draw functions (OLD: mainDrawSub1Sub5) - buildPolyModel(newX, newY, newScale, pMask, destBuffer, newFrame); + buildPolyModel(newX, newY, newScale, (char*)polygonMask, destBuffer, newFrame); } -void mainSprite(int globalX, int globalY, gfxEntryStruct *pGfxPtr, - uint8 *ouputPtr, int newColor, int idx) { +void mainSprite(int globalX, int globalY, gfxEntryStruct *pGfxPtr, uint8 *ouputPtr, int newColor, int idx) { // this is used for font only if (pGfxPtr) { @@ -1080,8 +1136,7 @@ void mainSprite(int globalX, int globalY, gfxEntryStruct *pGfxPtr, if (color == 1) { *output = (uint8) 0; } else { - *output = - (uint8) newColor; + *output = (uint8) newColor; } } } @@ -1091,25 +1146,59 @@ void mainSprite(int globalX, int globalY, gfxEntryStruct *pGfxPtr, } } -void mainDrawSub4(int objX1, int var_6, cellStruct *currentObjPtr, - char *data1, int objY2, int objX2, char *output, char *data2) { +void drawSprite(int objX1, int var_6, cellStruct *currentObjPtr, char *data1, int objY2, int objX2, char *output, char *data2) { int x = 0; int y = 0; + cellStruct* plWork = currentObjPtr; + int workBufferSize = var_6 * (objX1/8); + + unsigned char* workBuffer = (unsigned char*)malloc(workBufferSize); + memcpy(workBuffer, data2, workBufferSize); + + int numPasses = 0; + + while(plWork) + { + if(plWork->type == OBJ_TYPE_BGMK && plWork->freeze == 0) + { + objectParamsQuery params; + + getMultipleObjectParam(plWork->overlay, plWork->idx, ¶ms); + + int maskX = params.X; + int maskY = params.Y; + int maskFrame = params.fileIdx; + + if(filesDatabase[maskFrame].subData.resourceType == OBJ_TYPE_BGMK && filesDatabase[maskFrame].subData.ptrMask) + { + drawMask(workBuffer, objX1/8, var_6, filesDatabase[maskFrame].subData.ptrMask, filesDatabase[maskFrame].width/8, filesDatabase[maskFrame].height, maskX - objX2, maskY - objY2, numPasses++); + } + else + if(filesDatabase[maskFrame].subData.resourceType == OBJ_TYPE_SPRITE && filesDatabase[maskFrame].subData.ptrMask) + { + drawMask(workBuffer, objX1/8, var_6, filesDatabase[maskFrame].subData.ptrMask, filesDatabase[maskFrame].width/8, filesDatabase[maskFrame].height, maskX - objX2, maskY - objY2, numPasses++); + } + + } + + plWork = plWork->next; + } + for (y = 0; y < var_6; y++) { - for (x = 0; x < (objX1 * 8); x++) { + for (x = 0; x < (objX1); x++) { uint8 color = (data1[0]); data1++; - if ((x + objX2) >= 0 && (x + objX2) < 320 - && (y + objY2) >= 0 && (y + objY2) < 200) { - if (color != currentTransparent) { - output[320 * (y + objY2) + x + objX2] = - color; + if ((x + objX2) >= 0 && (x + objX2) < 320 && (y + objY2) >= 0 && (y + objY2) < 200) { + if(testMask(x, y, workBuffer, objX1/8)) { + output[320 * (y + objY2) + x + objX2] = color; } } } } + + free(workBuffer); } #ifdef _DEBUG @@ -1299,7 +1388,7 @@ void mainDraw(int16 param) { //-------------------------------------------------- PROCESS SPRITES -----------------------------------------// while (currentObjPtr) { - if ((currentActiveBackgroundPlane == currentObjPtr->backgroundPlane) && (currentObjPtr->freeze == 0) && (currentObjPtr->type == OBJ_SPRITE)) { + if ((currentActiveBackgroundPlane == currentObjPtr->backgroundPlane) && (currentObjPtr->freeze == 0) && (currentObjPtr->type == OBJ_TYPE_SPRITE)) { objectParamsQuery params; currentObjIdx = currentObjPtr->idx; @@ -1319,8 +1408,7 @@ void mainDraw(int16 param) { objZ1 = 0; } - getMultipleObjectParam(currentObjPtr->overlay, - currentObjIdx, ¶ms); + getMultipleObjectParam(currentObjPtr->overlay, currentObjIdx, ¶ms); objX2 = objX1 + params.X; objY2 = objY1 + params.Y; @@ -1340,9 +1428,7 @@ void mainDraw(int16 param) { spriteHeight = filesDatabase[objZ2].height; // height if (filesDatabase[objZ2].subData.ptr) { - currentTransparent = filesDatabase[objZ2].subData.transparency; - - mainDrawSub4(objX1, spriteHeight, currentObjPtr, (char *)filesDatabase[objZ2].subData.ptr, objY2, objX2,(char *)gfxModuleData.pPage10,(char *)filesDatabase[objZ2].subData.ptr); + drawSprite(objX1, spriteHeight, currentObjPtr, (char *)filesDatabase[objZ2].subData.ptr, objY2, objX2,(char *)gfxModuleData.pPage10,(char *)filesDatabase[objZ2].subData.ptrMask); } } } @@ -1437,7 +1523,7 @@ void mainDraw(int16 param) { currentObjPtr = cellHead.next; while (currentObjPtr) { - if (currentObjPtr->type == 5 && currentObjPtr->freeze == 0) { + if (currentObjPtr->type == OBJ_TYPE_MSG && currentObjPtr->freeze == 0) { mainSprite(currentObjPtr->x, currentObjPtr->field_C, currentObjPtr->gfxPtr, gfxModuleData.pPage10, currentObjPtr->color, currentObjPtr->spriteIdx); var20 = 1; } diff --git a/engines/cruise/mainDraw.h b/engines/cruise/mainDraw.h index cd935bd2d8..940a485895 100644 --- a/engines/cruise/mainDraw.h +++ b/engines/cruise/mainDraw.h @@ -40,7 +40,7 @@ void mainDraw(int16 param); void flipScreen(void); void buildPolyModel(int X, int Y, int scale, char *ptr2, char *destBuffer, char *dataPtr); -void mainDrawSub4(int objX1, int var_6, cellStruct * currentObjPtr, +void drawSprite(int objX1, int var_6, cellStruct * currentObjPtr, char *data1, int objY2, int objX2, char *output, char *data2); bool findPoly(char* dataPtr, int x, int y, int zoom, int mouseX, int mouseY); diff --git a/engines/cruise/object.h b/engines/cruise/object.h index 546d2bc440..8d2a432b2e 100644 --- a/engines/cruise/object.h +++ b/engines/cruise/object.h @@ -36,7 +36,6 @@ struct gfxEntryStruct { int width; // for font: max right border; for sprite: just width }; -#define OBJ_SPRITE 4 struct objectParamsQuery { int16 X; diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp index 7078d547de..581ed3a9fc 100644 --- a/engines/cruise/saveload.cpp +++ b/engines/cruise/saveload.cpp @@ -339,11 +339,11 @@ int loadSavegameData(int saveGameIdx) { } for (k = j; k < i; k++) { - if (filesDatabase[k].subData.ptr2) + if (filesDatabase[k].subData.ptrMask) initVar1 = 0; filesDatabase[k].subData.ptr = NULL; - filesDatabase[k].subData.ptr2 = NULL; + filesDatabase[k].subData.ptrMask = NULL; } if (i < 2) { diff --git a/engines/cruise/vars.h b/engines/cruise/vars.h index 31a00ecec8..5f89a4f841 100644 --- a/engines/cruise/vars.h +++ b/engines/cruise/vars.h @@ -125,7 +125,7 @@ struct dataFileEntrySub { int16 index; // sprite index char name[14]; int16 transparency; // sprite transparency - uint8 *ptr2; + uint8 *ptrMask; uint8 resourceType; // sprite and image type 2,4,8 , fnt = 7, spl = 6 uint8 field_1B; int16 field_1C; |