示例#1
0
/**
 * Adds velocities and creates clipping rectangles for all the
 * objects that have moved on the specified object list.
 * @param pObjList			Playfield display list to draw
 * @param pWin				Playfield window top left position
 * @param pClip				Playfield clipping rectangle
 * @param bNoVelocity		When reset, objects pos is updated with velocity
 * @param bScrolled)		When set, playfield has scrolled
 */
void FindMovingObjects(OBJECT **pObjList, Common::Point *pWin, Common::Rect *pClip, bool bNoVelocity, bool bScrolled) {
	OBJECT *pObj;			// object list traversal pointer

	for (pObj = *pObjList; pObj != NULL; pObj = pObj->pNext) {
		if (!bNoVelocity) {
			// we want to add velocities to objects position

			if (bScrolled) {
				// this playfield has scrolled

				// indicate change
				pObj->flags |= DMA_CHANGED;
			}
		}

		if ((pObj->flags & DMA_CHANGED) ||	// object changed
			HasPalMoved(pObj->pPal)) {	// or palette moved
			// object has changed in some way

			Common::Rect rcClip;	// objects clipped bounding rectangle
			Common::Rect rcObj;	// objects bounding rectangle

			// calc intersection of objects previous bounding rectangle
			// NOTE: previous position is in screen co-ords
			if (IntersectRectangle(rcClip, pObj->rcPrev, *pClip)) {
				// previous position is within clipping rect
				AddClipRect(rcClip);
			}

			// calc objects current bounding rectangle
			if (pObj->flags & DMA_ABS) {
				// object position is absolute
				rcObj.left = fracToInt(pObj->xPos);
				rcObj.top  = fracToInt(pObj->yPos);
			} else {
				// object position is relative to window
				rcObj.left = fracToInt(pObj->xPos) - pWin->x;
				rcObj.top  = fracToInt(pObj->yPos) - pWin->y;
			}
			rcObj.right  = rcObj.left + pObj->width;
			rcObj.bottom = rcObj.top  + pObj->height;

			// calc intersection of object with clipping rect
			if (IntersectRectangle(rcClip, rcObj, *pClip)) {
				// current position is within clipping rect
				AddClipRect(rcClip);

				// update previous position
				pObj->rcPrev = rcClip;
			} else {
				// clear previous position
				pObj->rcPrev = Common::Rect();
			}

			// clear changed flag
			pObj->flags &= ~DMA_CHANGED;
		}
	}
}
示例#2
0
BOOL dc_GenerateECRgn(PDC pdc, BOOL fForce)
{
    RECT rc, rcInter;
    PCLIPRECT pcr, pgcr;
    PCONTROL pCtrl;

    // is global clip region is empty?
    if ((!fForce) && (!dc_IsVisible (pdc)))
            return FALSE;

    // need regenerate?
    if (fForce || (pdc->oldage != pdc->pGCRInfo->age)) {
        EmptyClipRgn (&pdc->ecrgn);

        pcr = pdc->lcrgn.head;
        while (pcr) {
            rc = pcr->rc;
            coor_LP2SP (pdc, &rc.left, &rc.top);
            coor_LP2SP (pdc, &rc.right, &rc.bottom);
            
            pgcr = pdc->pGCRInfo->crgn.head;
            while (pgcr) {

                if (IntersectRect (&rcInter, &rc, &pgcr->rc))
                    AddClipRect (&pdc->ecrgn, &rcInter);

                pgcr = pgcr->next;
            }
            
            pcr = pcr->next;
        }
        
        if (pdc->lcrgn.head == NULL)
            ClipRgnCopy (&pdc->ecrgn, &pdc->pGCRInfo->crgn);

        // update the DevRC;
        if (pdc->bIsClient)
            WndClientRect (pdc->hwnd, &pdc->DevRC);
        else
            WndRect (pdc->hwnd, &pdc->DevRC);
            
        IntersectClipRect (&pdc->ecrgn, &pdc->DevRC);

        pCtrl = Control (pdc->hwnd);
        if (pCtrl && !(pCtrl->dwExStyle & WS_EX_CTRLASMAINWIN))
            RestrictControlECRGN (&pdc->ecrgn, pCtrl);

        pdc->oldage = pdc->pGCRInfo->age;
    }

    return TRUE;
}
示例#3
0
/**
 * Deletes an object from the specified object list and places it
 * on the free list.
 * @param pObjList			List to delete object from
 * @param pDelObj			Object to delete
 */
void DelObject(OBJECT *pObjList, OBJECT *pDelObj) {
	OBJECT *pPrev, *pObj;	// object list traversal pointers
	const Common::Rect rcScreen(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

	// validate object pointer
	assert(isValidObject(pDelObj));

#ifdef DEBUG
	// one less object in use
	--numObj;
	assert(numObj >= 0);
#endif

	for (pPrev = pObjList, pObj = pObjList->pNext; pObj != NULL; pPrev = pObj, pObj = pObj->pNext) {
		if (pObj == pDelObj) {
			// found object to delete

			if (IntersectRectangle(pDelObj->rcPrev, pDelObj->rcPrev, rcScreen)) {
				// allocate a clipping rect for objects previous pos
				AddClipRect(pDelObj->rcPrev);
			}

			// make PREV next = OBJ next - removes OBJ from list
			pPrev->pNext = pObj->pNext;

			// place free list in OBJ next
			pObj->pNext = pFreeObjects;

			// add OBJ to top of free list
			pFreeObjects = pObj;

			// delete objects palette
			if (pObj->pPal)
				FreePalette(pObj->pPal);

			// quit
			return;
		}
	}

	// if we get to here - object has not been found on the list
	// This can be triggered in Act 3 in DW1 while talking to the guard,
	// so this has been turned to a warning instead of an error
	warning("DelObject(): formally 'assert(0)!'");
}