⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macroot.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	// Forcing the source rect to equal the destination rect; all the
	// complicated math actually takes place elsewhere so this is an
	// OK thing to do.
	Rect srcR = dstR;

	if (CHXMacSite::zm_bFullScreenActive)
	{
	    CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
	    if (!pMacSite->m_bInternalResizeOnFullscreen)
	    {
		dstR.right = dstR.left + (long)(((double)dstR.right - (double)dstR.left)*pMacSite->m_fStretchMultiple);
		dstR.bottom = dstR.top + (long)(((double)dstR.bottom - (double)dstR.top)*pMacSite->m_fStretchMultiple);
	    }
	}

	if (m_nBlitDepthEnum >= 0)
	{
	    RGBColor blackRGB = {0x0000, 0x0000, 0x0000};
	    RGBColor whiteRGB = {0xffff, 0xffff, 0xffff};
	    
	    ColorSpec prevFore;
	    ColorSpec prevBack;
	    
	    ::SaveFore(&prevFore);
	    ::SaveBack(&prevBack);
	    
	    ::RGBForeColor(&blackRGB);
	    ::RGBBackColor(&whiteRGB);
            
	    ::CopyBits( (BitMap*)*m_RootGWorldPixMap[m_nBlitDepthEnum],
		    GetPortBitMapForCopyBits(GetWindowPort(macWindow)),
		    &srcR, &dstR, srcCopy, nil );
	    
	    ::QDFlushPortBuffer( ::GetWindowPort(macWindow), NULL );
	    ::RestoreFore(&prevFore);
	    ::RestoreBack(&prevBack);
	}

	SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
	::SetPort(savePort);
    }
}


unsigned long
CMacRootSurface::_GetScreenPixelValue(long globX, long globY)
{
    unsigned long retVal = 0;
    int whichDevice;
    for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
    {
	HX_ASSERT(zm_AttachedDevice[whichDevice]);
	
	PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
	unsigned long dstPtr = (unsigned long)::GetPixBaseAddr(thePMH);
	int pixelSize = (**thePMH).pixelSize;
	
	Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
	
	if (globX >= deviceRect.left && globX <= deviceRect.right
		&& globY >= deviceRect.top && globY <= deviceRect.bottom)
	{
	    int rowOffset = (globY - deviceRect.top) * ((**thePMH).rowBytes & 0x3fff);
	    int columnOffset = (globX - deviceRect.left) * pixelSize / 8;
	    dstPtr += rowOffset + columnOffset;
	    switch (pixelSize)
	    {
		case 32:
		    retVal = *(unsigned long*)dstPtr;
		    break;

		case 16:
		    retVal = *(unsigned short*)dstPtr;
		    break;

		case 8:
		    retVal = *(unsigned char*)dstPtr;
		    break;
	    }
	}
    }
    return retVal;
}

unsigned long
CMacRootSurface::_GetGWorldPixelValue(int whichDepth, long x, long y)
{
    unsigned long retVal = 0;
    unsigned long offscreenPtr = (unsigned long)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
    offscreenPtr += y * ((**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff);
    switch (whichDepth)
    {
	case kEightBitDepth:
	    offscreenPtr += x;
	    retVal = *(unsigned char*)offscreenPtr;
	    break;
	case kSixteenBitDepth:
	    offscreenPtr += 2*x;
	    retVal = *(unsigned short*)offscreenPtr;
	    break;
	case kThirtyTwoBitDepth:
	    offscreenPtr += 4*x;
	    retVal = *(unsigned long*)offscreenPtr;
	    break;
    }
    return retVal;
}

/************************************************************************
 *  Method:
 *    CMacRootSurface::InternalReflectRect
 *
 *    Note that theRectToBlit needs to be in global coords!
 *
 *    This is the function that slams it home. All obscuring menus have
 *    been taken care of. Any vis region holes have been taken care of.
 *    The rectangles that arrive at this rectangle are honest-to-God
 *    blittable rectangles.
 *
 */
void
CMacRootSurface::InternalReflectRect(Rect theRectToBlit)
{
    int whichDevice;
    for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
    {
	HX_ASSERT(zm_AttachedDevice[whichDevice]);
	
	PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
	unsigned char* dstPtr = (unsigned char*)::GetPixBaseAddr(thePMH);
	int pixelSize = (**thePMH).pixelSize;
	
	INT32 whichDepth = DepthToDepthEnum(pixelSize);
	
	if ( 1 /* m_RootSurfaceGWorld[whichDepth] */ ) // <== this may be useful later but for now I want the assert to be executed that's maybe a dozen lines down.
	{
	    Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
	    
	    Rect intersectionRect; // <== should always be equal to theRectToBlit I think XXXbobclark
	    if (::SectRect(&theRectToBlit, &deviceRect, &intersectionRect))
	    {
		// XXXbobclark
		// in the old site code we manually trimmed theRectToBlit to the limits of
		// intersectionRect; but since nowadays we're supposedly ensuring that we're
		// only getting rects wholly enclosed by their monitors we shouldn't need
		// to do that. Theoretically the only reason to do SectRect is to see if
		// this is actually the monitor that we need to blit to right now.
		
		
		HX_ASSERT(m_RootSurfaceGWorld[whichDepth]);
		if (!m_RootSurfaceGWorld[whichDepth]) return;
		
		unsigned char* offscreenPtr = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
		
		int localLeft = intersectionRect.left - m_LocalToGlobalCoords.h;
		int localTop = intersectionRect.top - m_LocalToGlobalCoords.v;
		int localRight = intersectionRect.right - m_LocalToGlobalCoords.h;
		int localBottom = intersectionRect.bottom - m_LocalToGlobalCoords.v;
		
		int localScreenLeft = intersectionRect.left - (**zm_AttachedDevice[whichDevice]).gdRect.left;
		int localScreenRight = intersectionRect.right - (**zm_AttachedDevice[whichDevice]).gdRect.left;
		int localScreenTop = intersectionRect.top - (**zm_AttachedDevice[whichDevice]).gdRect.top;
		int localScreenBottom = intersectionRect.bottom - (**zm_AttachedDevice[whichDevice]).gdRect.top;
		
		for (int localScreenRow = localScreenTop; localScreenRow < localScreenBottom; localScreenRow++)
		{
		    int bytesPerPixel = pixelSize / 8;
		    if (bytesPerPixel >= 1) // only ITB if at least 8-bit monitor
		    {
			int localRow = (localScreenRow-localScreenTop) + localTop;
			long offscreenOffset = ((**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff) * localRow + localLeft * bytesPerPixel;
			long localScreenOffset = ((**thePMH).rowBytes & 0x3fff) * localScreenRow + localScreenLeft * bytesPerPixel;
			
			long srcP = (long)offscreenPtr + offscreenOffset;
			long dstP = (long)dstPtr + localScreenOffset;
			
			switch (bytesPerPixel)
			{
			    case 4:
				// XXXbobclark
				// now we'll trash srcP and dstP...
				// it turns out that poking longs by hand is a lot faster
				// than going through BlockMoveData for some reason. In a
				// simplified test case, it was using 7-8 microseconds for
				// poking by hand, compared to 17-18 microseconds for using
				// BlockMoveData.
				
				{
                                    long maxP = dstP + (localRight-localLeft) * bytesPerPixel;
                                    for ( ; dstP < maxP; )
                                    {
                                        // if the pixel is lined up on an eight-byte boundary
                                        // and won't overwrite the right edge of the rectangle
                                        // then copy eight bytes at once.
                                        if ( (dstP % 8 == 0) && (maxP - dstP >= 8) )
                                        {
                                            *(double*)dstP = *(double*)srcP;
                                            srcP += 8;
                                            dstP += 8;
                                        }
                                        else
                                        {
                                            *(long*)dstP = *(long*)srcP;
                                            srcP += 4;
                                            dstP += 4;
                                        }
                                    }
                                }
				break;
			    
			    default:
				// XXXbobclark
				// I could do something similar to the 32-bit case here,
				// where I attempt to outdo BlockMoveData()... but for
				// one thing, it would be even clunkier, since I'd need
				// more cases when it doesn't happen to line up on eight-
				// byte boundaries for super-fast copies, plus non-32-bit
				// cases are rarer than 32-bit cases.
				::BlockMoveData( (void*)srcP, (void*)dstP, (localRight-localLeft)*bytesPerPixel );
				break;
			}
		    }
		}
	    }
	}
    }
}


/************************************************************************
 *  Method:
 *    CMacRootSurface::InternalReflectRectInVisRegion
 *
 *    Note that theRectToBlit needs to be in global coords!
 *
 */
void
CMacRootSurface::InternalReflectRectInVisRegion(Rect theRectToBlit)
{
    CHXSimpleList::Iterator ndx = m_pVisRgnRects->Begin();
    for (; ndx != m_pVisRgnRects->End(); ++ndx)
    {
	Rect* r = (Rect*)(*ndx);
	
	Rect blittableRect = theRectToBlit;
	
	if (blittableRect.left < r->left) blittableRect.left = r->left;
	if (blittableRect.top < r->top) blittableRect.top = r->top;
	if (blittableRect.right > r->right) blittableRect.right = r->right;
	if (blittableRect.bottom > r->bottom) blittableRect.bottom = r->bottom;
	
	if (blittableRect.left < blittableRect.right && blittableRect.top < blittableRect.bottom)
	{
	    InternalReflectRect(blittableRect);
	}
    }
}



/************************************************************************
 *  Method:
 *    CMacRootSurface::PotentiallyAddRect
 *
 *    Useful shortcut for constructing lists of rectangles for
 *    menu-down blitting.
 *
 */
void
CMacRootSurface::PotentiallyAddRect( CHXSimpleList* theList, Rect originalVisRect, short left, short top, short right, short bottom )
{
    if ( left < originalVisRect.left ) left = originalVisRect.left;
    if ( top < originalVisRect.top ) top = originalVisRect.top;
    if ( right > originalVisRect.right ) right = originalVisRect.right;
    if ( bottom > originalVisRect.bottom ) bottom = originalVisRect.bottom;
    
    if ( left < right && top < bottom )
    {
	// OK, it's a legal rect so let's add it.
	Rect* r = new Rect;
	r->left = left;
	r->top = top;
	r->right = right;
	r->bottom = bottom;
	theList->AddTail( r );
    }
}


/************************************************************************
 *  Method:
 *    CMacRootSurface::ReflectRectToFullScreen
 *
 *    Note that theOriginalRectToBlit needs to be in global coords!
 *
 */
void
CMacRootSurface::ReflectRectToFullScreen(Rect theOriginalRectToBlit)
{
    // xxxbobclark assumptions include that this rectangle
    // is smaller than the main screen (which is where it
    // assumes the full-screen is playing).
    
    // See InternalReflectRect for details of what up
    
    HX_ASSERT(CHXMacSite::zm_bFullScreenActive);
    
    int whichDevice;
    for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
    {
	PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
	unsigned char* dstPtr = (unsigned char*)::GetPixBaseAddr(thePMH);
	int honestScreenRowBytes = (**thePMH).rowBytes & 0x3fff;
	int pixelSize = (**thePMH).pixelSize;
	
	INT32 whichDepth = DepthToDepthEnum(pixelSize);
	
	if (m_RootSurfaceGWorld[whichDepth])
	{
	    Rect adjustedRect;
	    CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
	    double stretch = pMacSite->m_fStretchMultiple;
	    
	    adjustedRect.left = theOriginalRectToBlit.left + stretch * (theOriginalRectToBlit.left - m_LocalToGlobalCoords.h);
	    adjustedRect.top = theOriginalRectToBlit.top + stretch * (theOriginalRectToBlit.top - m_LocalToGlobalCoords.v);
	    adjustedRect.right = theOriginalRectToBlit.left + stretch * (theOriginalRectToBlit.right - m_LocalToGlobalCoords.h);
	    adjustedRect.bottom = theOriginalRectToBlit.top + stretch * (theOriginalRectToBlit.bottom - m_LocalToGlobalCoords.v);
	    
	    Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
	    if (adjustedRect.left >= deviceRect.left
		&& adjustedRect.top >= deviceRect.top
		&& adjustedRect.right <= deviceRect.right
		&& adjustedRect.bottom <= deviceRect.bottom)
	    {
		// xxxbobclark whew, we can blit here since it's full
		// screen and wholly enclosed.
		
		int bytesPerPixel = pixelSize / 8;
		if (bytesPerPixel < 1) return; // ack, can't handle less than 8-bit!
		
		unsigned char* offscreenPtr = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
		int honestOffscreenRowBytes = (**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff;
		
		int fromLeft = theOriginalRectToBlit.left - m_LocalToGlobalCoords.h;
		int fromTop = theOriginalRectToBlit.top - m_LocalToGlobalCoords.v;
		int fromRight = theOriginalRectToBlit.right - m_LocalToGlobalCoords.h;
		int fromBottom = theOriginalRectToBlit.bottom - m_LocalToGlobalCoords.v;
		
		for (int fromRow = fromTop; fromRow < fromBottom; fromRow++)
		{
		    for (int fromColumn = fromLeft; fromColumn < fromRight; fromColumn++)
		    {
			// xxxbobclark OK now here we have one pixel
			// in the offscreen. This could grow to
			// multiple pixels on screen so we'll have to
			// blit all of them.
			
			long* pixelPtr = (long*)((long)offscreenPtr + fromRow*(long)honestOffscreenRowBytes);
			pixelPtr = (long*)((long)pixelPtr + bytesPerPixel * fromColumn);
			
			long pixelValue = *pixelPtr;
			
			// ok, got the pixel value, now figure out where all we
			// need to poke it.
			
			int destLeft = (int)((double)(fromColumn - fromLeft) * stretch + (double)adjustedRect.left);
			int destTop = (int)((double)(fromRow - fromTop) * stretch + (double)adjustedRect.top);
			int destRight = (int)((double)(fromColumn - fromLeft + 1) * stretch + (double)adjustedRect.left);
			int destBottom = (int)((double)(fromRow - fromTop + 1) * stretch + (double)adjustedRect.top);
			
			pixelPtr = (long*)((long)dstPtr + destTop * honestScreenRowBytes);
			pixelPtr = (long*)((long)pixelPtr + bytesPerPixel * destLeft);
			
			for (int destRow = destTop; destRow < destBottom; destRow++)
			{
			    for (int destColumn = destLeft; destColumn < destRight; destColumn++)
			    {
				*pixelPtr = pixelValue;
				
				pixelPtr = (long*)((long)pixelPtr + bytesPerPixel);
			    }
			    pixelPtr = (long*)((long)pixelPtr + honestScreenRowBytes - (bytesPerPixel * (destRight-destLeft)));
			}
		    }
		}
	    }
	}
    }
}


/************************************************************************
 *  Method:
 *    CMacRootSurface::DepthToDepthEnum
 */
int
CMacRootSurface::DepthToDepthEnum( short depth )
{
    int result = kEightBitDepth;
    switch ( depth )
    {
	case 32:
	    result = kThirtyTwoBitDepth;
	    break;
	case 16:
	    result = kSixteenBitDepth;
	    break;
    }
    return result;
}


/************************************************************************
 *  Method:
 *    CMacRootSurface::VisRgnChangedCallback
 *
 *    This is called from several trap patches which can
 *    change the vis region. This prevents subsequent blits
 *    until the vis region we know about can be updated.
 */

/* static */
pascal void
CMacRootSurface::VisRgnChangedCallback(void)
{
#ifndef _MAC_UNIX
    HXMM_INTERRUPTON();
#endif
    // since the visRgn probably changed in the patched trap, let's wait until
    // we can update our version of the visRgn before doing any more interrupt-
    // time blits.
    
    CHXSimpleList::Iterator ndxSite = zm_RootSurfaceList.Begin();

    for (;  ndxSite != zm_RootSurfaceList.End(); ++ndxSite)
    {
	CMacRootSurface* pRootSurface = (CMacRootSurface*)(*ndxSite);
	
	if ( pRootSurface )
	{
	    pRootSurface->m_bItsOKToDoAnInterruptBlit = FALSE;
	}
    }
    
    if (CMacSurface::zm_pOverlaySurface)
    {
	CMacSurface::zm_bSafeToOverlayBlit = FALSE;
    }
#ifndef _MAC_UNIX
    HXMM_INTERRUPTOFF();
#endif
}

#define kSizeOfSimpleRectangleRegion 10

/************************************************************************
 *  Method:
 *    CMacRootSurface::CheckRectRgn
 *
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -