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

📄 gfx.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {	OffsetMask = 0x3ff;	OffsetShift = 4;    }    else    {	OffsetMask = 0x1ff;	OffsetShift = 3;    }    for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines)    {	uint32 VOffset = LineData [Y].BG[bg].VOffset;	uint32 HOffset = LineData [Y].BG[bg].HOffset;	uint32 MosaicOffset = Y % PPU.Mosaic;	for (Lines = 1; Lines < PPU.Mosaic - MosaicOffset; Lines++)	    if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) ||		(HOffset != LineData [Y + Lines].BG[bg].HOffset))		break;		uint32 MosaicLine = VOffset + Y - MosaicOffset;	if (Y + Lines > GFX.EndY)	    Lines = GFX.EndY + 1 - Y;	uint32 VirtAlign = (MosaicLine & 7) << 3;		uint16 *b1;	uint16 *b2;	uint32 ScreenLine = MosaicLine >> OffsetShift;	uint32 Rem16 = MosaicLine & 15;	if (ScreenLine & 0x20)	    b1 = SC2, b2 = SC3;	else	    b1 = SC0, b2 = SC1;	b1 += (ScreenLine & 0x1f) << 5;	b2 += (ScreenLine & 0x1f) << 5;	uint16 *t;	uint32 Left = 0;	uint32 Right = 256;	uint32 ClipCount = GFX.pCurrentClip->Count [bg];	uint32 HPos = HOffset;	uint32 PixWidth = PPU.Mosaic;	if (!ClipCount)	    ClipCount = 1;	for (uint32 clip = 0; clip < ClipCount; clip++)	{	    if (GFX.pCurrentClip->Count [bg])	    {		Left = GFX.pCurrentClip->Left [clip][bg];		Right = GFX.pCurrentClip->Right [clip][bg];		uint32 r = Left % PPU.Mosaic;		HPos = HOffset + Left;		PixWidth = PPU.Mosaic - r;	    }	    uint32 s = Y * GFX.PPL + Left * GFX.PixSize;	    for (uint32 x = Left; x < Right; x += PixWidth, 		 s += PixWidth * GFX.PixSize,		 HPos += PixWidth, PixWidth = PPU.Mosaic)	    {		uint32 Quot = (HPos & OffsetMask) >> 3;		if (x + PixWidth >= Right)		    PixWidth = Right - x;		if (BG.TileSize == 8)		{		    if (Quot > 31)			t = b2 + (Quot & 0x1f);		    else			t = b1 + Quot;		}		else		{		    if (Quot > 63)			t = b2 + ((Quot >> 1) & 0x1f);		    else			t = b1 + (Quot >> 1);		}		Tile = READ_2BYTES (t);		GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];		// Draw tile...		if (BG.TileSize != 8)		{		    if (Tile & H_FLIP)		    {			// Horizontal flip, but what about vertical flip ?			if (Tile & V_FLIP)			{			    // Both horzontal & vertical flip			    if (Rem16 < 8)			    {				(*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			    else			    {				(*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			}			else			{			    // Horizontal flip only			    if (Rem16 > 7)			    {				(*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			    else			    {				(*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			}		    }		    else		    {			// No horizontal flip, but is there a vertical flip ?			if (Tile & V_FLIP)			{			    // Vertical flip only			    if (Rem16 < 8)			    {				(*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			    else			    {				(*DrawLargePixelPtr) (Tile + (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			}			else			{			    // Normal unflipped			    if (Rem16 > 7)			    {				(*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			    else			    {				(*DrawLargePixelPtr) (Tile + (Quot & 1), s,						      HPos & 7, PixWidth,						      VirtAlign, Lines);			    }			}		    }		}		else		    (*DrawLargePixelPtr) (Tile, s, HPos & 7, PixWidth,					  VirtAlign, Lines);	    }	}    }}void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2){    CHECK_SOUND();    uint32 Tile;    uint16 *SC0;    uint16 *SC1;    uint16 *SC2;    uint16 *SC3;    uint16 *BPS0;    uint16 *BPS1;    uint16 *BPS2;    uint16 *BPS3;    uint32 Width;    int VOffsetOffset = BGMode == 4 ? 0 : 32;    uint8 depths [2] = {Z1, Z2};        BG.StartPalette = 0;    BPS0 = (uint16 *) &Memory.VRAM[PPU.BG[2].SCBase << 1];    if (PPU.BG[2].SCSize & 1)	BPS1 = BPS0 + 1024;    else	BPS1 = BPS0;    if (PPU.BG[2].SCSize & 2)	BPS2 = BPS1 + 1024;    else	BPS2 = BPS0;    if (PPU.BG[2].SCSize & 1)	BPS3 = BPS2 + 1024;    else	BPS3 = BPS2;        SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1];    if (PPU.BG[bg].SCSize & 1)	SC1 = SC0 + 1024;    else	SC1 = SC0;    if (PPU.BG[bg].SCSize & 2)	SC2 = SC1 + 1024;    else	SC2 = SC0;    if (PPU.BG[bg].SCSize & 1)	SC3 = SC2 + 1024;    else	SC3 = SC2;    static const int Lines = 1;    int OffsetMask;    int OffsetShift;    int OffsetEnableMask = 1 << (bg + 13);    if (BG.TileSize == 16)    {	OffsetMask = 0x3ff;	OffsetShift = 4;    }    else    {	OffsetMask = 0x1ff;	OffsetShift = 3;    }    for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y++)    {	uint32 VOff = LineData [Y].BG[2].VOffset;	uint32 HOff = LineData [Y].BG[2].HOffset;	int VirtAlign;	int ScreenLine = VOff >> 3;	int t1;	int t2;	uint16 *s0;	uint16 *s1;	uint16 *s2;	if (ScreenLine & 0x20)	    s1 = BPS2, s2 = BPS3;	else	    s1 = BPS0, s2 = BPS1;	s1 += (ScreenLine & 0x1f) << 5;	s2 += (ScreenLine & 0x1f) << 5;	int clipcount = GFX.pCurrentClip->Count [bg];	if (!clipcount)	    clipcount = 1;	for (int clip = 0; clip < clipcount; clip++)	{	    uint32 Left;	    uint32 Right;	    if (!GFX.pCurrentClip->Count [bg])	    {		Left = 0;		Right = 256;	    }	    else	    {		Left = GFX.pCurrentClip->Left [clip][bg];		Right = GFX.pCurrentClip->Right [clip][bg];		if (Right <= Left)		    continue;	    }	    uint32 VOffset;	    uint32 HOffset;	    uint32 Offset;	    uint32 HPos;	    uint32 Quot;	    uint32 Count;	    uint16 *t;	    uint32 Quot2;	    uint32 VCellOffset;	    uint32 HCellOffset;	    uint16 *b1;	    uint16 *b2;	    uint32 TotalCount = 0;	    uint32 MaxCount;	    uint32 s = Left * GFX.PixSize + Y * GFX.PPL;	    bool8 left_hand_edge = Left == 0;	    Width = Right - Left;	    MaxCount = 8;	    if (Left & 7)		MaxCount = 8 - (Left & 7);	    while (Left < Right) 	    {		if (left_hand_edge)		{		    // The SNES offset-per-tile background mode has a		    // hardware limitation that the offsets cannot be set		    // for the tile of the left-hand edge of the screen.		    VOffset = LineData [Y].BG[bg].VOffset;		    HOffset = LineData [Y].BG[bg].HOffset;		}		else		{		    // All subsequent offset tile data is shifted left by one,		    // hence the - 1 below.		    Quot2 = ((HOff + Left - 1 + (LineData [Y].BG[bg].HOffset & 7)) & OffsetMask) >> 3;		    if (Quot2 > 31)			s0 = s2 + (Quot2 & 0x1f);		    else			s0 = s1 + Quot2;		    HCellOffset = READ_2BYTES (s0);		    if (BGMode == 4)		    {			VOffset = LineData [Y].BG[bg].VOffset;			HOffset = LineData [Y].BG[bg].HOffset;			if ((HCellOffset & OffsetEnableMask))			{			    if (HCellOffset & 0x8000)				VOffset = HCellOffset + 1;			    else				HOffset = HCellOffset;			}		    }		    else		    {			VCellOffset = READ_2BYTES (s0 + VOffsetOffset);			if ((VCellOffset & OffsetEnableMask))			    VOffset = VCellOffset + 1;			else			    VOffset = LineData [Y].BG[bg].VOffset;			if ((HCellOffset & OffsetEnableMask))			    HOffset = HCellOffset;			else			    HOffset = LineData [Y].BG[bg].HOffset;		    }		}		VirtAlign = ((Y + VOffset) & 7) << 3;		ScreenLine = (VOffset + Y) >> OffsetShift;		if (((VOffset + Y) & 15) > 7)		{		    t1 = 16;		    t2 = 0;		}		else		{		    t1 = 0;		    t2 = 16;		}		if (ScreenLine & 0x20)		    b1 = SC2, b2 = SC3;		else		    b1 = SC0, b2 = SC1;		b1 += (ScreenLine & 0x1f) << 5;		b2 += (ScreenLine & 0x1f) << 5;		HPos = (HOffset + Left) & OffsetMask;		Quot = HPos >> 3;		if (BG.TileSize == 8)		{		    if (Quot > 31)			t = b2 + (Quot & 0x1f);		    else			t = b1 + Quot;		}		else		{		    if (Quot > 63)			t = b2 + ((Quot >> 1) & 0x1f);		    else			t = b1 + (Quot >> 1);		}		if (MaxCount + TotalCount > Width)		    MaxCount = Width - TotalCount;		Offset = HPos & 7;		if (MaxCount > 8 - Offset)		    MaxCount = 8 - Offset;		Count = 8 - Offset;		if (Count > MaxCount)		    Count = MaxCount;		s -= Offset * GFX.PixSize;		Tile = READ_2BYTES(t);		GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];		if (BG.TileSize == 8)		    (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines);		else		{		    if (!(Tile & (V_FLIP | H_FLIP)))		    {			// Normal, unflipped			(*DrawClippedTilePtr) (Tile + t1 + (Quot & 1),					       s, Offset, Count, VirtAlign, Lines);		    }		    else		    if (Tile & H_FLIP)		    {			if (Tile & V_FLIP)			{			    // H & V flip			    (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),						   s, Offset, Count, VirtAlign, Lines);			}			else			{			    // H flip only			    (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),						   s, Offset, Count, VirtAlign, Lines);			}		    }		    else		    {			// V flip only			(*DrawClippedTilePtr) (Tile + t2 + (Quot & 1),					       s, Offset, Count, VirtAlign, Lines);		    }		}		Left += Count;		TotalCount += Count;		s += (Offset + Count) * GFX.PixSize;		MaxCount = 8;		left_hand_edge = FALSE;	    }	}    }}void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2){    CHECK_SOUND();    GFX.Pitch = GFX.RealPitch;    GFX.PPL = GFX.PPLx2 >> 1;    GFX.PixSize = 1;    uint8 depths [2] = {Z1, Z2};    uint32 Tile;    uint16 *SC0;    uint16 *SC1;    uint16 *SC2;    uint16 *SC3;    uint32 Width;        BG.StartPalette = 0;    SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1];    if ((PPU.BG[bg].SCSize & 1))	SC1 = SC0 + 1024;    else	SC1 = SC0;    if ((PPU.BG[bg].SCSize & 2))	SC2 = SC1 + 1024;    else	SC2 = SC0;    if ((PPU.BG[bg].SCSize & 1))	SC3 = SC2 + 1024;    else	SC3 = SC2;        int Lines;    int VOffsetMask;    int VOffsetShift;    if (BG.TileSize == 16)    {	VOffsetMask = 0x3ff;	VOffsetShift = 4;    }    else    {	VOffsetMask = 0x1ff;	VOffsetShift = 3;    }    int endy = IPPU.LatchedInterlace ? GFX.EndY << 1 : GFX.EndY;    for (int Y = IPPU.LatchedInterlace ? GFX.StartY << 1 : GFX.StartY; Y <= endy; Y += Lines)    {	int y = IPPU.LatchedInterlace ? (Y >> 1) : Y;	uint32 VOffset = LineData [y].BG[bg].VOffset;	uint32 HOffset = LineData [y].BG[bg].HOffset;	int VirtAlign = (Y + VOffset) & 7;		for (Lines = 1; Lines < 8 - VirtAlign; Lines++)	    if ((VOffset != LineData [y + Lines].BG[bg].VOffset) ||		(HOffset != LineData [y + Lines].BG[bg].HOffset))		break;	HOffset <<= 1;	if (Y + Lines > endy)	    Lines = endy + 1 - Y;	VirtAlign <<= 3;		int ScreenLine = (VOffset + Y) >> VOffsetShift;	int t1;	int t2;	if (((VOffset + Y) & 15) > 7)	{	    t1 = 16;	    t2 = 0;	}

⌨️ 快捷键说明

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