forked from dolphin-emu/dolphin
		
	Some warning fixes and cleanup. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7361 8ced0084-cf51-0410-be5f-012b33b47a6e
		
			
				
	
	
		
			546 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			546 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (C) 2003-2009 Dolphin Project.
 | 
						|
 | 
						|
// 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, version 2.0.
 | 
						|
 | 
						|
// 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 2.0 for more details.
 | 
						|
 | 
						|
// A copy of the GPL 2.0 should have been included with the program.
 | 
						|
// If not, see http://www.gnu.org/licenses/
 | 
						|
 | 
						|
// Official SVN repository and contact information can be found at
 | 
						|
// http://code.google.com/p/dolphin-emu/
 | 
						|
 | 
						|
#include "Common.h"
 | 
						|
 | 
						|
#include "EfbInterface.h"
 | 
						|
#include "BPMemLoader.h"
 | 
						|
#include "LookUpTables.h"
 | 
						|
#include "SWPixelEngine.h"
 | 
						|
 | 
						|
 | 
						|
u8 efb[EFB_WIDTH*EFB_HEIGHT*6];
 | 
						|
 | 
						|
 | 
						|
namespace EfbInterface
 | 
						|
{
 | 
						|
    u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4];
 | 
						|
 | 
						|
    inline u32 GetColorOffset(u16 x, u16 y)
 | 
						|
    {
 | 
						|
        return (x + y * EFB_WIDTH) * 3;
 | 
						|
    }
 | 
						|
 | 
						|
    inline u32 GetDepthOffset(u16 x, u16 y)
 | 
						|
    {
 | 
						|
        return (x + y * EFB_WIDTH) * 3 + DEPTH_BUFFER_START;
 | 
						|
    }
 | 
						|
 | 
						|
    void SetPixelAlphaOnly(u32 offset, u8 a)
 | 
						|
    {
 | 
						|
         switch (bpmem.zcontrol.pixel_format)
 | 
						|
        {
 | 
						|
        case PIXELFMT_RGB8_Z24:
 | 
						|
        case PIXELFMT_Z24:
 | 
						|
        case PIXELFMT_RGB565_Z16:
 | 
						|
            // do nothing
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGBA6_Z24:
 | 
						|
            {
 | 
						|
				u32 a32 = a;
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xffffffc0;
 | 
						|
				val |= (a32 >> 2) & 0x0000003f;
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;        
 | 
						|
        default:
 | 
						|
            ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void SetPixelColorOnly(u32 offset, u8 *rgb)
 | 
						|
    {
 | 
						|
        switch (bpmem.zcontrol.pixel_format)
 | 
						|
        {
 | 
						|
        case PIXELFMT_RGB8_Z24:
 | 
						|
        case PIXELFMT_Z24:
 | 
						|
            {
 | 
						|
				u32 src = *(u32*)rgb;
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff000000;
 | 
						|
				val |= src >> 8;
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGBA6_Z24:
 | 
						|
            {
 | 
						|
				u32 src = *(u32*)rgb;
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff00003f;
 | 
						|
				val |= (src >> 4) & 0x00000fc0;	// blue
 | 
						|
				val |= (src >> 6) & 0x0003f000;	// green
 | 
						|
				val |= (src >> 8) & 0x00fc0000;	// red
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGB565_Z16:
 | 
						|
            {
 | 
						|
                INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
 | 
						|
                u32 src = *(u32*)rgb;
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff000000;
 | 
						|
				val |= src >> 8;
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void SetPixelAlphaColor(u32 offset, u8 *color)
 | 
						|
    {
 | 
						|
         switch (bpmem.zcontrol.pixel_format)
 | 
						|
        {
 | 
						|
        case PIXELFMT_RGB8_Z24:
 | 
						|
        case PIXELFMT_Z24:
 | 
						|
            {
 | 
						|
                u32 src = *(u32*)color;
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff000000;
 | 
						|
				val |= src >> 8;
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGBA6_Z24:
 | 
						|
            {
 | 
						|
				u32 src = *(u32*)color;
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff000000;
 | 
						|
				val |= (src >> 2) & 0x0000003f;	// alpha
 | 
						|
				val |= (src >> 4) & 0x00000fc0;	// blue
 | 
						|
				val |= (src >> 6) & 0x0003f000;	// green
 | 
						|
				val |= (src >> 8) & 0x00fc0000;	// red
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGB565_Z16:
 | 
						|
            {
 | 
						|
                INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
 | 
						|
				u32 src = *(u32*)color;
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff000000;
 | 
						|
				val |= src >> 8;
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
     void GetPixelColor(u32 offset, u8 *color)
 | 
						|
    {
 | 
						|
        switch (bpmem.zcontrol.pixel_format)
 | 
						|
        {
 | 
						|
        case PIXELFMT_RGB8_Z24:
 | 
						|
        case PIXELFMT_Z24:
 | 
						|
            {
 | 
						|
    			u32 src = *(u32*)&efb[offset];
 | 
						|
				u32 *dst = (u32*)color;
 | 
						|
				u32 val = 0xff | ((src & 0x00ffffff) << 8);
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGBA6_Z24:
 | 
						|
            {
 | 
						|
				u32 src = *(u32*)&efb[offset];
 | 
						|
				color[ALP_C] = Convert6To8(src & 0x3f);
 | 
						|
				color[BLU_C] = Convert6To8((src >> 6) & 0x3f);
 | 
						|
				color[GRN_C] = Convert6To8((src >> 12) & 0x3f);
 | 
						|
				color[RED_C] = Convert6To8((src >> 18) & 0x3f);
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGB565_Z16:
 | 
						|
            {
 | 
						|
                INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
 | 
						|
				u32 src = *(u32*)&efb[offset];
 | 
						|
				u32 *dst = (u32*)color;
 | 
						|
				u32 val = 0xff | ((src & 0x00ffffff) << 8);
 | 
						|
				*dst = val;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void SetPixelDepth(u32 offset, u32 depth)
 | 
						|
    {
 | 
						|
        switch (bpmem.zcontrol.pixel_format)
 | 
						|
        {
 | 
						|
        case PIXELFMT_RGB8_Z24:
 | 
						|
        case PIXELFMT_RGBA6_Z24:
 | 
						|
        case PIXELFMT_Z24:
 | 
						|
            {
 | 
						|
    			u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff000000;
 | 
						|
				val |= depth & 0x00ffffff;
 | 
						|
				*dst = val;				
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGB565_Z16:
 | 
						|
            {
 | 
						|
                INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
 | 
						|
				u32 *dst = (u32*)&efb[offset];
 | 
						|
				u32 val = *dst & 0xff000000;
 | 
						|
				val |= depth & 0x00ffffff;
 | 
						|
				*dst = val;		
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
 | 
						|
        }        
 | 
						|
    }
 | 
						|
 | 
						|
     u32 GetPixelDepth(u32 offset)
 | 
						|
    {
 | 
						|
        u32 depth = 0;
 | 
						|
 | 
						|
        switch (bpmem.zcontrol.pixel_format)
 | 
						|
        {
 | 
						|
        case PIXELFMT_RGB8_Z24:
 | 
						|
        case PIXELFMT_RGBA6_Z24:
 | 
						|
        case PIXELFMT_Z24:
 | 
						|
            {
 | 
						|
				depth = (*(u32*)&efb[offset]) & 0x00ffffff;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        case PIXELFMT_RGB565_Z16:
 | 
						|
            {
 | 
						|
                INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
 | 
						|
				depth = (*(u32*)&efb[offset]) & 0x00ffffff;
 | 
						|
            }
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            ERROR_LOG(VIDEO, "Unsupported pixel format: %i", bpmem.zcontrol.pixel_format);
 | 
						|
        }
 | 
						|
 | 
						|
        return depth;
 | 
						|
    }
 | 
						|
 | 
						|
    u32 GetSourceFactor(u8 *srcClr, u8 *dstClr, int mode)
 | 
						|
    {
 | 
						|
        switch (mode) {
 | 
						|
            case 0:  // zero
 | 
						|
                return 0;
 | 
						|
            case 1:  // one
 | 
						|
                return 0xffffffff;
 | 
						|
            case 2:  // dstclr
 | 
						|
                return *(u32*)dstClr;
 | 
						|
            case 3:  // invdstclr
 | 
						|
                return 0xffffffff - *(u32*)dstClr;                     
 | 
						|
            case 4:  // srcalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = srcClr[ALP_C];
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
            case 5:  // invsrcalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = 0xff - srcClr[ALP_C];
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
            case 6:  // dstalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = dstClr[ALP_C];
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
            case 7:  // invdstalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = 0xff - dstClr[ALP_C];
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
        }
 | 
						|
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    u32 GetDestinationFactor(u8 *srcClr, u8 *dstClr, int mode)
 | 
						|
    {
 | 
						|
        switch (mode) {
 | 
						|
            case 0:  // zero
 | 
						|
                return 0;
 | 
						|
            case 1:  // one
 | 
						|
                return 0xffffffff;
 | 
						|
             case 2:  // srcclr
 | 
						|
                return *(u32*)srcClr;
 | 
						|
            case 3:  // invsrcclr
 | 
						|
                return 0xffffffff - *(u32*)srcClr;            
 | 
						|
            case 4:  // srcalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = srcClr[ALP_C];
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
            case 5:  // invsrcalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = 0xff - srcClr[ALP_C];
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
            case 6:  // dstalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = dstClr[ALP_C] & 0xff;
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
            case 7:  // invdstalpha
 | 
						|
                {
 | 
						|
                    u8 alpha = 0xff - dstClr[ALP_C];
 | 
						|
                    u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
 | 
						|
                    return factor;
 | 
						|
                }
 | 
						|
        }
 | 
						|
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    void BlendColor(u8 *srcClr, u8 *dstClr)
 | 
						|
    {
 | 
						|
        u32 srcFactor = GetSourceFactor(srcClr, dstClr, bpmem.blendmode.srcfactor);
 | 
						|
        u32 dstFactor = GetDestinationFactor(srcClr, dstClr, bpmem.blendmode.dstfactor);
 | 
						|
 | 
						|
        for (int i = 0; i < 4; i++)
 | 
						|
        {
 | 
						|
            // add MSB of factors to make their range 0 -> 256
 | 
						|
            u32 sf = (srcFactor & 0xff);
 | 
						|
            sf += sf >> 7;
 | 
						|
            
 | 
						|
            u32 df = (dstFactor & 0xff);
 | 
						|
            df += df >> 7;
 | 
						|
 | 
						|
            u32 color = (srcClr[i] * sf + dstClr[i] * df) >> 8;
 | 
						|
            dstClr[i] = (color>255)?255:color;
 | 
						|
 | 
						|
            dstFactor >>= 8;
 | 
						|
            srcFactor >>= 8;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void LogicBlend(u32 srcClr, u32 &dstClr, int op)
 | 
						|
    {
 | 
						|
        switch (op) {
 | 
						|
            case 0:  // clear
 | 
						|
                dstClr = 0;
 | 
						|
                break;
 | 
						|
            case 1:  // and
 | 
						|
                dstClr = srcClr & dstClr;
 | 
						|
                break;
 | 
						|
            case 2:  // revand
 | 
						|
                dstClr = srcClr & (~dstClr);
 | 
						|
                break;
 | 
						|
            case 3:  // copy
 | 
						|
                dstClr = srcClr;
 | 
						|
                break;
 | 
						|
            case 4:  // invand
 | 
						|
                dstClr = (~srcClr) & dstClr;
 | 
						|
                break;
 | 
						|
            case 5:  // noop
 | 
						|
                dstClr = dstClr;
 | 
						|
                break;
 | 
						|
            case 6:  // xor
 | 
						|
                dstClr = srcClr ^ dstClr;
 | 
						|
                break;
 | 
						|
            case 7:  // or
 | 
						|
                dstClr = srcClr | dstClr;
 | 
						|
                break;
 | 
						|
            case 8:  // nor
 | 
						|
                dstClr = ~(srcClr | dstClr);
 | 
						|
                break;
 | 
						|
            case 9:  // equiv
 | 
						|
                dstClr = ~(srcClr ^ dstClr);
 | 
						|
                break;
 | 
						|
            case 10: // inv
 | 
						|
                dstClr = ~dstClr;
 | 
						|
                break;
 | 
						|
            case 11: // revor
 | 
						|
                dstClr = srcClr | (~dstClr);
 | 
						|
                break;
 | 
						|
            case 12: // invcopy
 | 
						|
                dstClr = ~srcClr;
 | 
						|
                break;
 | 
						|
            case 13: // invor
 | 
						|
                dstClr = (~srcClr) | dstClr;
 | 
						|
                break;
 | 
						|
            case 14: // nand
 | 
						|
                dstClr = ~(srcClr & dstClr);
 | 
						|
                break;
 | 
						|
            case 15: // set
 | 
						|
                dstClr = 0xffffffff;
 | 
						|
                break;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void SubtractBlend(u8 *srcClr, u8 *dstClr)
 | 
						|
    {
 | 
						|
        for (int i = 0; i < 4; i++)
 | 
						|
        {
 | 
						|
            int c = (int)dstClr[i] - (int)srcClr[i];
 | 
						|
            dstClr[i] = (c < 0)?0:c;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    void BlendTev(u16 x, u16 y, u8 *color)
 | 
						|
    {
 | 
						|
        u32 dstClr;
 | 
						|
        u32 offset = GetColorOffset(x, y);
 | 
						|
 | 
						|
        u8 *dstClrPtr = (u8*)&dstClr;
 | 
						|
 | 
						|
        GetPixelColor(offset, dstClrPtr);        
 | 
						|
 | 
						|
        if (bpmem.blendmode.blendenable)
 | 
						|
        {
 | 
						|
            if (bpmem.blendmode.subtract)
 | 
						|
                SubtractBlend(color, dstClrPtr);
 | 
						|
            else
 | 
						|
                BlendColor(color, dstClrPtr);
 | 
						|
        }
 | 
						|
        else if (bpmem.blendmode.logicopenable)
 | 
						|
            LogicBlend(*((u32*)color), dstClr, bpmem.blendmode.logicmode);
 | 
						|
        else
 | 
						|
            dstClrPtr = color;
 | 
						|
 | 
						|
        if (bpmem.dstalpha.enable)
 | 
						|
            dstClrPtr[ALP_C] = bpmem.dstalpha.alpha;
 | 
						|
 | 
						|
		if (bpmem.blendmode.colorupdate)
 | 
						|
        {
 | 
						|
            if (bpmem.blendmode.alphaupdate)
 | 
						|
                SetPixelAlphaColor(offset, dstClrPtr);
 | 
						|
            else
 | 
						|
                SetPixelColorOnly(offset, dstClrPtr);
 | 
						|
        }
 | 
						|
        else if (bpmem.blendmode.alphaupdate)
 | 
						|
            SetPixelAlphaOnly(offset, dstClrPtr[ALP_C]);
 | 
						|
 | 
						|
        // branchless bounding box update
 | 
						|
        SWPixelEngine::pereg.boxLeft = SWPixelEngine::pereg.boxLeft>x?x:SWPixelEngine::pereg.boxLeft;
 | 
						|
        SWPixelEngine::pereg.boxRight = SWPixelEngine::pereg.boxRight<x?x:SWPixelEngine::pereg.boxRight;
 | 
						|
        SWPixelEngine::pereg.boxTop = SWPixelEngine::pereg.boxTop>y?y:SWPixelEngine::pereg.boxTop;
 | 
						|
        SWPixelEngine::pereg.boxBottom = SWPixelEngine::pereg.boxBottom<y?y:SWPixelEngine::pereg.boxBottom;
 | 
						|
    }
 | 
						|
 | 
						|
    void SetColor(u16 x, u16 y, u8 *color)
 | 
						|
    {
 | 
						|
        u32 offset = GetColorOffset(x, y);
 | 
						|
        if (bpmem.blendmode.colorupdate)
 | 
						|
        {
 | 
						|
            if (bpmem.blendmode.alphaupdate)
 | 
						|
                SetPixelAlphaColor(offset, color);
 | 
						|
            else
 | 
						|
                SetPixelColorOnly(offset, color);
 | 
						|
        }
 | 
						|
        else if (bpmem.blendmode.alphaupdate)
 | 
						|
            SetPixelAlphaOnly(offset, color[ALP_C]);
 | 
						|
    }
 | 
						|
 | 
						|
    void SetDepth(u16 x, u16 y, u32 depth)
 | 
						|
    {
 | 
						|
        SetPixelDepth(GetDepthOffset(x, y), depth);
 | 
						|
    }
 | 
						|
 | 
						|
    void GetColor(u16 x, u16 y, u8 *color)
 | 
						|
    {
 | 
						|
        u32 offset = GetColorOffset(x, y);
 | 
						|
        GetPixelColor(offset, color);
 | 
						|
    }
 | 
						|
 | 
						|
    u32 GetDepth(u16 x, u16 y)
 | 
						|
    {
 | 
						|
        u32 offset = GetDepthOffset(x, y);
 | 
						|
        return GetPixelDepth(offset);        
 | 
						|
    }
 | 
						|
 | 
						|
    u8 *GetPixelPointer(u16 x, u16 y, bool depth)
 | 
						|
    {
 | 
						|
        if (depth)
 | 
						|
            return &efb[GetDepthOffset(x, y)];
 | 
						|
        return &efb[GetColorOffset(x, y)];
 | 
						|
    }
 | 
						|
 | 
						|
    void UpdateColorTexture()
 | 
						|
    {
 | 
						|
        u32 color;
 | 
						|
		u8* colorPtr = (u8*)&color;
 | 
						|
		u32* texturePtr = (u32*)efbColorTexture;
 | 
						|
        u32 textureAddress = 0;
 | 
						|
        u32 efbOffset = 0;
 | 
						|
        
 | 
						|
        for (u16 y = 0; y < EFB_HEIGHT; y++)
 | 
						|
        {
 | 
						|
            for (u16 x = 0; x < EFB_WIDTH; x++)
 | 
						|
            {
 | 
						|
                GetPixelColor(efbOffset, colorPtr);
 | 
						|
                efbOffset += 3;
 | 
						|
				texturePtr[textureAddress++] = Common::swap32(color);  // ABGR->RGBA
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    bool ZCompare(u16 x, u16 y, u32 z)
 | 
						|
    {
 | 
						|
        u32 offset = GetDepthOffset(x, y);        
 | 
						|
        u32 depth = GetPixelDepth(offset);
 | 
						|
 | 
						|
        bool pass;
 | 
						|
 | 
						|
        switch (bpmem.zmode.func)
 | 
						|
        {
 | 
						|
            case COMPARE_NEVER:
 | 
						|
                pass = false;
 | 
						|
                break;
 | 
						|
            case COMPARE_LESS:
 | 
						|
                pass = z < depth;
 | 
						|
                break;
 | 
						|
            case COMPARE_EQUAL:
 | 
						|
                pass = z == depth;
 | 
						|
                break;
 | 
						|
            case COMPARE_LEQUAL:
 | 
						|
                pass = z <= depth;
 | 
						|
                break;
 | 
						|
            case COMPARE_GREATER:
 | 
						|
                pass = z > depth;
 | 
						|
                break;
 | 
						|
            case COMPARE_NEQUAL:
 | 
						|
                pass = z != depth;
 | 
						|
                break;
 | 
						|
            case COMPARE_GEQUAL:
 | 
						|
                pass = z >= depth;
 | 
						|
                break;
 | 
						|
            case COMPARE_ALWAYS:
 | 
						|
                pass = true;
 | 
						|
                break;
 | 
						|
            default:
 | 
						|
                pass = false;
 | 
						|
                ERROR_LOG(VIDEO, "Bad Z compare mode %i", bpmem.zmode.func);
 | 
						|
        }
 | 
						|
 | 
						|
        if (pass && bpmem.zmode.updateenable)
 | 
						|
        {
 | 
						|
            SetPixelDepth(offset, z);
 | 
						|
        }
 | 
						|
    
 | 
						|
        return pass;
 | 
						|
    }
 | 
						|
}
 |