Logo Search packages:      
Sourcecode: scummvm version File versions

backgroundIncrust.cpp

/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-1/engines/cruise/backgroundIncrust.cpp $
 * $Id: backgroundIncrust.cpp 35870 2009-01-16 02:43:41Z fingolfin $
 *
 */

#include "cruise/cruise_main.h"

namespace Cruise {

backgroundIncrustStruct backgroundIncrustHead;

void resetBackgroundIncrustList(backgroundIncrustStruct *pHead) {
      pHead->next = NULL;
      pHead->prev = NULL;
}

// blit background to another one
void addBackgroundIncrustSub1(int fileIdx, int X, int Y, char *ptr2, int16 scale, char *destBuffer, char *dataPtr) {
      if (*dataPtr == 0) {
            ASSERT(0);
      }

      buildPolyModel(X, Y, scale, ptr2, destBuffer, dataPtr);
}

void backupBackground(backgroundIncrustStruct *pIncrust, int X, int Y, int width, int height, uint8* pBackground) {
      pIncrust->saveWidth = width;
      pIncrust->saveHeight = height;
      pIncrust->saveSize = width * height;
      pIncrust->savedX = X;
      pIncrust->savedY = Y;

      pIncrust->ptr = (uint8*)malloc(width * height);
      for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                  pIncrust->ptr[i*width+j] = pBackground[(i+Y)*320+j+X];
            }
      }
}

void restoreBackground(backgroundIncrustStruct *pIncrust) {
      if (pIncrust->type != 1)
            return;
      if (pIncrust->ptr == NULL)
            return;

      uint8* pBackground = backgroundPtrtable[pIncrust->backgroundIdx];
      if (pBackground == NULL)
            return;

      int X = pIncrust->savedX;
      int Y = pIncrust->savedY;
      int width = pIncrust->saveWidth;
      int height = pIncrust->saveHeight;

      for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                  pBackground[(i+Y)*320+j+X] = pIncrust->ptr[i*width+j];
            }
      }
}

backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx,   int16 objectIdx, backgroundIncrustStruct *pHead, int16 scriptNumber, int16 scriptOverlay, int16 backgroundIdx, int16 saveBuffer) {
      uint8 *backgroundPtr;
      uint8 *ptr;
      objectParamsQuery params;
      backgroundIncrustStruct *newElement;
      backgroundIncrustStruct *currentHead;
      backgroundIncrustStruct *currentHead2;

      getMultipleObjectParam(overlayIdx, objectIdx, &params);

      ptr = filesDatabase[params.fileIdx].subData.ptr;

      if (!ptr) {
            return NULL;
      }

      if (filesDatabase[params.fileIdx].subData.resourceType != 4 && filesDatabase[params.fileIdx].subData.resourceType != 8) {
            return NULL;
      }

      backgroundPtr = backgroundPtrtable[backgroundIdx];

      if (!backgroundPtr) {
            ASSERT(0);
            return NULL;
      }

      currentHead = pHead;
      currentHead2 = currentHead->next;

      while (currentHead2) {
            currentHead = currentHead2;
            currentHead2 = currentHead->next;
      }

      newElement = (backgroundIncrustStruct *)mallocAndZero(sizeof(backgroundIncrustStruct));

      if (!newElement)
            return NULL;

      newElement->next = currentHead->next;
      currentHead->next = newElement;

      if (!currentHead2) {
            currentHead2 = pHead;
      }

      newElement->prev = currentHead2->prev;
      currentHead2->prev = newElement;

      newElement->objectIdx = objectIdx;
      newElement->type = saveBuffer;
      newElement->backgroundIdx = backgroundIdx;
      newElement->overlayIdx = overlayIdx;
      newElement->scriptNumber = scriptNumber;
      newElement->scriptOverlayIdx = scriptOverlay;
      newElement->X = params.X;
      newElement->Y = params.Y;
      newElement->scale = params.scale;
      newElement->field_E = params.fileIdx;
      newElement->spriteId = filesDatabase[params.fileIdx].subData.index;
      newElement->ptr = NULL;
      strcpy(newElement->name, filesDatabase[params.fileIdx].subData.name);

      if (filesDatabase[params.fileIdx].subData.resourceType == 4) {    // sprite
            int width = filesDatabase[params.fileIdx].width;
            int height = filesDatabase[params.fileIdx].height;

            if (saveBuffer == 1) {
                  backupBackground(newElement, newElement->X, newElement->Y, width, height, backgroundPtr);
            }

            drawSprite(width, height, NULL, (char *)filesDatabase[params.fileIdx].subData.ptr, newElement->Y, newElement->X, (char *)backgroundPtr, (char *)filesDatabase[params.fileIdx].subData.ptrMask);
      } else {                // poly
            if (saveBuffer == 1) {
                  int newX;
                  int newY;
                  int newScale;
                  char *newFrame;

                  int sizeTable[4]; // 0 = left, 1 = right, 2 = bottom, 3 = top

                  // this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1)
                  flipPoly(params.fileIdx, (int16*)filesDatabase[params.fileIdx].subData.ptr, params.scale, &newFrame, newElement->X, newElement->Y, &newX, &newY, &newScale);

                  // this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
                  getPolySize(newX, newY, newScale, sizeTable, (unsigned char*)newFrame);

                  int width = (sizeTable[1] + 2) - (sizeTable[0] - 2) + 1;
                  int height = sizeTable[3] - sizeTable[2] + 1;

                  backupBackground(newElement, sizeTable[0] - 2, sizeTable[2], width, height, backgroundPtr);
            }

            addBackgroundIncrustSub1(params.fileIdx, newElement->X, newElement->Y, NULL, params.scale, (char *)backgroundPtr, (char *)filesDatabase[params.fileIdx].subData.ptr);
      }

      return newElement;
}

void saveIncrust(Common::OutSaveFile& currentSaveFile) {
      int count = 0;

      backgroundIncrustStruct *pl = backgroundIncrustHead.next;
      while (pl) {
            count++;
            pl = pl->next;
      }

      currentSaveFile.writeSint16LE(count);

      pl = backgroundIncrustHead.next;
      while (pl) {
            char dummy[4] = {0, 0, 0, 0};
            currentSaveFile.write(dummy, 2);
            currentSaveFile.write(dummy, 2);

            currentSaveFile.writeSint16LE(pl->objectIdx);
            currentSaveFile.writeSint16LE(pl->type);
            currentSaveFile.writeSint16LE(pl->overlayIdx);
            currentSaveFile.writeSint16LE(pl->X);
            currentSaveFile.writeSint16LE(pl->Y);
            currentSaveFile.writeSint16LE(pl->field_E);
            currentSaveFile.writeSint16LE(pl->scale);
            currentSaveFile.writeSint16LE(pl->backgroundIdx);
            currentSaveFile.writeSint16LE(pl->scriptNumber);
            currentSaveFile.writeSint16LE(pl->scriptOverlayIdx);
            currentSaveFile.write(dummy, 4);
            currentSaveFile.writeSint16LE(pl->saveWidth / 2);
            currentSaveFile.writeSint16LE(pl->saveHeight);
            currentSaveFile.writeSint16LE(pl->saveSize);
            currentSaveFile.writeSint16LE(pl->savedX);
            currentSaveFile.writeSint16LE(pl->savedY);
            currentSaveFile.write(pl->name, 13);
            currentSaveFile.write(dummy, 1);
            currentSaveFile.writeSint16LE(pl->spriteId);
            currentSaveFile.write(dummy, 2);

            if (pl->saveSize) {
                  char* buffer = (char*)malloc(pl->saveSize);
                  memset(buffer, 0, pl->saveSize);
                  currentSaveFile.write(buffer, pl->saveSize);
                  free(buffer);
            }

            pl = pl->next;
      }
}

void loadBackgroundIncrustFromSave(Common::InSaveFile& currentSaveFile) {
      int16 numEntry;
      int32 i;

      numEntry = currentSaveFile.readSint16LE();

      backgroundIncrustStruct *pl = &backgroundIncrustHead;
      backgroundIncrustStruct *pl1 = &backgroundIncrustHead;

      for (i = 0; i < numEntry; i++) {
            backgroundIncrustStruct *pl2 = (backgroundIncrustStruct *)mallocAndZero(sizeof(backgroundIncrustStruct));

            currentSaveFile.skip(2);
            currentSaveFile.skip(2);

            pl2->objectIdx = currentSaveFile.readSint16LE();
            pl2->type = currentSaveFile.readSint16LE();
            pl2->overlayIdx = currentSaveFile.readSint16LE();
            pl2->X = currentSaveFile.readSint16LE();
            pl2->Y = currentSaveFile.readSint16LE();
            pl2->field_E = currentSaveFile.readSint16LE();
            pl2->scale = currentSaveFile.readSint16LE();
            pl2->backgroundIdx = currentSaveFile.readSint16LE();
            pl2->scriptNumber = currentSaveFile.readSint16LE();
            pl2->scriptOverlayIdx = currentSaveFile.readSint16LE();
            currentSaveFile.skip(4);
            pl2->saveWidth = currentSaveFile.readSint16LE() * 2;
            pl2->saveHeight = currentSaveFile.readSint16LE();
            pl2->saveSize = currentSaveFile.readUint16LE();
            pl2->savedX = currentSaveFile.readSint16LE();
            pl2->savedY = currentSaveFile.readSint16LE();
            currentSaveFile.read(pl2->name, 13);
            currentSaveFile.skip(1);
            pl2->spriteId = currentSaveFile.readSint16LE();
            currentSaveFile.skip(2);

            if (pl2->saveSize) {
                  /*pl2->ptr = (uint8 *) mallocAndZero(pl2->size);
                  currentSaveFile.read(pl2->ptr, pl2->size);*/

                  currentSaveFile.skip(pl2->saveSize);

                  int width = pl2->saveWidth;
                  int height = pl2->saveHeight;
                  pl2->ptr = (uint8*)malloc(width * height);
                  memset(pl2->ptr, 0, width * height);

                  // TODO: convert graphic format here
            }

            pl2->next = NULL;
            pl->next = pl2;

            pl2->prev = pl1->prev;
            pl1->prev = pl2;

            pl = pl2;
      }
}

void regenerateBackgroundIncrust(backgroundIncrustStruct *pHead) {

      lastAni[0] = 0;

      backgroundIncrustStruct* pl = pHead->next;

      while (pl) {
            backgroundIncrustStruct* pl2 = pl->next;

            bool bLoad = false;
            int frame = pl->field_E;
            //int screen = pl->backgroundIdx;

            if ((filesDatabase[frame].subData.ptr == NULL) || (strcmp(pl->name, filesDatabase[frame].subData.name))) {
                  frame = 257 - 1;
                  if (loadFile(pl->name, frame, pl->spriteId) >= 0) {
                        bLoad = true;
                  } else {
                        frame = -1;
                  }
            }

            if (frame >= -1) {
                  if (filesDatabase[frame].subData.resourceType == 4) { // sprite
                        int width = filesDatabase[frame].width;
                        int height = filesDatabase[frame].height;

                        drawSprite(width, height, NULL, (char *)filesDatabase[frame].subData.ptr, pl->Y, pl->X, (char*)backgroundPtrtable[pl->backgroundIdx], (char *)filesDatabase[frame].subData.ptrMask);
                  } else {                // poly
                        addBackgroundIncrustSub1(frame, pl->X, pl->Y, NULL, pl->scale, (char*)backgroundPtrtable[pl->backgroundIdx], (char *)filesDatabase[frame].subData.ptr);
                  }
            }

            pl = pl2;
      }

      lastAni[0] = 0;
}

void freeBackgroundIncrustList(backgroundIncrustStruct *pHead) {
      backgroundIncrustStruct *pCurrent = pHead->next;

      while (pCurrent) {
            backgroundIncrustStruct *pNext = pCurrent->next;

            if (pCurrent->ptr) {
                  free(pCurrent->ptr);
            }

            free(pCurrent);

            pCurrent = pNext;
      }

      resetBackgroundIncrustList(pHead);
}

void removeBackgroundIncrust(int overlay, int idx, backgroundIncrustStruct * pHead) {
      objectParamsQuery params;
      int var_4;
      int var_6;

      backgroundIncrustStruct *pCurrent;
      backgroundIncrustStruct *pCurrentHead;

      getMultipleObjectParam(overlay, idx, &params);

      var_4 = params.X;
      var_6 = params.Y;

      pCurrent = pHead->next;

      while (pCurrent) {
            if ((pCurrent->overlayIdx == overlay || overlay == -1) && (pCurrent->objectIdx == idx || idx == -1) && (pCurrent->X == var_4) && (pCurrent->Y == var_6)) {
                  pCurrent->type = - 1;
            }

            pCurrent = pCurrent->next;
      }

      pCurrentHead = pHead;
      pCurrent = pHead->next;

      while (pCurrent) {
            if (pCurrent->type == - 1) {
                  backgroundIncrustStruct *pNext = pCurrent->next;
                  backgroundIncrustStruct *bx = pCurrentHead;
                  backgroundIncrustStruct *cx;

                  bx->next = pNext;
                  cx = pNext;

                  if (!pNext) {
                        cx = pHead;
                  }

                  bx = cx;
                  bx->prev = pCurrent->next;

                  if (pCurrent->ptr) {
                        free(pCurrent->ptr);
                  }

                  free(pCurrent);

                  pCurrent = pNext;
            } else {
                  pCurrentHead = pCurrent;
                  pCurrent = pCurrent->next;
            }
      }
}

void unmergeBackgroundIncrust(backgroundIncrustStruct * pHead, int ovl, int idx) {
      backgroundIncrustStruct *pl;
      backgroundIncrustStruct *pl2;

      objectParamsQuery params;
      getMultipleObjectParam(ovl, idx, &params);

      int x = params.X;
      int y = params.Y;

      pl = pHead;
      pl2 = pl;
      pl = pl2->next;

      while (pl) {
            pl2 = pl;
            if ((pl->overlayIdx == ovl) || (ovl == -1))
                  if ((pl->objectIdx == idx) || (idx == -1))
                        if ((pl->X == x) && (pl->Y == y))
                              restoreBackground(pl);

            pl = pl2->next;
      }

}

} // End of namespace Cruise

Generated by  Doxygen 1.6.0   Back to index