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

📄 gfx.cpp

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			b2 &= ~0x10;		    GFX.ZERO [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2);		    GFX.ZERO [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2);		}	    }	}    }    else    {	GFX.X2 = NULL;	GFX.ZERO_OR_X2 = NULL;	GFX.ZERO = NULL;    }    return (TRUE);}void S9xGraphicsDeinit (void){    // Free any memory allocated in S9xGraphicsInit    if (GFX.X2)    {	free ((char *) GFX.X2);	GFX.X2 = NULL;    }    if (GFX.ZERO_OR_X2)    {	free ((char *) GFX.ZERO_OR_X2);	GFX.ZERO_OR_X2 = NULL;    }    if (GFX.ZERO)    {	free ((char *) GFX.ZERO);	GFX.ZERO = NULL;    }}void S9xBuildDirectColourMaps (){    for (uint32 p = 0; p < 8; p++)    {	for (uint32 c = 0; c < 256; c++)	{// XXX: Brightness	    DirectColourMaps [p][c] = BUILD_PIXEL (((c & 7) << 2) | ((p & 1) << 1),						   ((c & 0x38) >> 1) | (p & 2),						   ((c & 0xc0) >> 3) | (p & 4));	}    }    IPPU.DirectColourMapsNeedRebuild = FALSE;}void S9xStartScreenRefresh (){    if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0)	GFX.InfoString = NULL;    if (IPPU.RenderThisFrame)    {	if (!S9xInitUpdate ())	{	    IPPU.RenderThisFrame = FALSE;	    return;	}	IPPU.RenderedFramesCount++;	IPPU.PreviousLine = IPPU.CurrentLine = 0;	IPPU.MaxBrightness = PPU.Brightness;	IPPU.LatchedBlanking = PPU.ForcedBlanking;	if(PPU.BGMode == 5 || PPU.BGMode == 6)		IPPU.Interlace = (Memory.FillRAM[0x2133] & 1);	if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 ||				      IPPU.Interlace))	{		if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace)		{			IPPU.RenderedScreenWidth = 512;			IPPU.DoubleWidthPixels = TRUE;		}		else		{			IPPU.RenderedScreenWidth = 256;			IPPU.DoubleWidthPixels = FALSE;		}		if (IPPU.Interlace)		{			IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1;			IPPU.DoubleHeightPixels = TRUE;			GFX.Pitch2 = GFX.RealPitch;			GFX.Pitch = GFX.RealPitch * 2;			if (Settings.SixteenBit)				GFX.PPL = GFX.PPLx2 = GFX.RealPitch;			else				GFX.PPL = GFX.PPLx2 = GFX.RealPitch << 1;		}		else		{			IPPU.RenderedScreenHeight = PPU.ScreenHeight;			GFX.Pitch2 = GFX.Pitch = GFX.RealPitch;            IPPU.DoubleHeightPixels = FALSE;			if (Settings.SixteenBit)				GFX.PPL = GFX.Pitch >> 1;			else				GFX.PPL = GFX.Pitch;			GFX.PPLx2 = GFX.PPL << 1;		}#if defined(USE_GLIDE) || defined(USE_OPENGL)	    GFX.ZPitch = GFX.RealPitch;	    if (Settings.SixteenBit)		GFX.ZPitch >>= 1;#endif	}	else	{	    IPPU.RenderedScreenWidth = 256;	    IPPU.RenderedScreenHeight = PPU.ScreenHeight;	    IPPU.DoubleWidthPixels = FALSE;        IPPU.DoubleHeightPixels = FALSE;#ifdef USE_GLIDE	    if (Settings.GlideEnable)	    {		// Speed up hack for Glide: render low res. SNES images		// into a handy 256x256 sized buffer that can be uploaded into		// texture memory with one Glide call without having to copy it		// into a second, suitably sized buffer first.		GFX.Pitch2 = GFX.Pitch = 256 * sizeof (uint16);		GFX.PPL = 256;                GFX.PPLx2 = GFX.Pitch;                GFX.ZPitch = 256;	    }	    else#endif#ifdef USE_OPENGL            if (Settings.OpenGLEnable)            {                GFX.Pitch2 = GFX.Pitch = 256 * sizeof (uint16);                GFX.PPL = 256;                GFX.PPLx2 = GFX.Pitch;                GFX.ZPitch = 256;            }            else#endif	    {		GFX.Pitch2 = GFX.Pitch = GFX.RealPitch;		GFX.PPL = GFX.PPLx2 >> 1;		GFX.ZPitch = GFX.RealPitch;		if (Settings.SixteenBit)		    GFX.ZPitch >>= 1;	    }	}	PPU.RecomputeClipWindows = TRUE;	GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer;	GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;    }    if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0)    {	IPPU.DisplayedRenderedFrameCount = IPPU.RenderedFramesCount;	IPPU.RenderedFramesCount = 0;	IPPU.FrameCount = 0;    }}void RenderLine (uint8 C){    if (IPPU.RenderThisFrame)	{		LineData[C].BG[0].VOffset = PPU.BG[0].VOffset + 1;		LineData[C].BG[0].HOffset = PPU.BG[0].HOffset;		LineData[C].BG[1].VOffset = PPU.BG[1].VOffset + 1;		LineData[C].BG[1].HOffset = PPU.BG[1].HOffset;		if (PPU.BGMode == 7)		{			struct SLineMatrixData *p = &LineMatrixData [C];			p->MatrixA = PPU.MatrixA;			p->MatrixB = PPU.MatrixB;			p->MatrixC = PPU.MatrixC;			p->MatrixD = PPU.MatrixD;			p->CentreX = PPU.CentreX;			p->CentreY = PPU.CentreY;		}		else		{			if (Settings.StarfoxHack && PPU.BG[2].VOffset == 0 &&				PPU.BG[2].HOffset == 0xe000)			{				LineData[C].BG[2].VOffset = 0xe1;				LineData[C].BG[2].HOffset = 0;			}			else			{				LineData[C].BG[2].VOffset = PPU.BG[2].VOffset + 1;				LineData[C].BG[2].HOffset = PPU.BG[2].HOffset;				LineData[C].BG[3].VOffset = PPU.BG[3].VOffset + 1;				LineData[C].BG[3].HOffset = PPU.BG[3].HOffset;			}		}		IPPU.CurrentLine = C + 1;	} else {		/* if we're not rendering this frame, we still need to update this */		// XXX: Check ForceBlank? Or anything else?		if(IPPU.OBJChanged) S9xSetupOBJ();		PPU.RangeTimeOver |= GFX.OBJLines[C].RTOFlags;	}}void S9xEndScreenRefresh (){    IPPU.HDMAStarted = FALSE;    if (IPPU.RenderThisFrame)    {	FLUSH_REDRAW ();	if (IPPU.ColorsChanged)	{	    uint32 saved = PPU.CGDATA[0];	    if (!Settings.SixteenBit)	    {		// Hack for Super Mario World - to get its sky blue		// (It uses Fixed colour addition on the backdrop colour)		if (!(Memory.FillRAM [0x2131] & 0x80) &&		    (Memory.FillRAM[0x2131] & 0x20) &&		    (PPU.FixedColourRed || PPU.FixedColourGreen ||		     PPU.FixedColourBlue))		{		    PPU.CGDATA[0] = PPU.FixedColourRed |				    (PPU.FixedColourGreen << 5) |				    (PPU.FixedColourBlue << 10);		}	    }	    IPPU.ColorsChanged = FALSE;	    S9xSetPalette ();	    PPU.CGDATA[0] = saved;	}        if (#ifdef USE_GLIDE            !Settings.GlideEnable &&#endif#ifdef USE_OPENGL            !Settings.OpenGLEnable &&#endif            TRUE)        {            GFX.Pitch = GFX.Pitch2 = GFX.RealPitch;            GFX.PPL = GFX.PPLx2 >> 1;        }//take screenshot here.        if(Settings.TakeScreenshot)            S9xDoScreenshot(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight);		if (Settings.DisplayFrameRate)	    S9xDisplayFrameRate ();	if (GFX.InfoString)	    S9xDisplayString (GFX.InfoString);	S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight,			 Settings.SixteenBit);    }    S9xApplyCheats ();#ifdef DEBUGGER    if (CPU.Flags & FRAME_ADVANCE_FLAG)    {	if (ICPU.FrameAdvanceCount)	{	    ICPU.FrameAdvanceCount--;	    IPPU.RenderThisFrame = TRUE;	    IPPU.FrameSkip = 0;	}	else	{	    CPU.Flags &= ~FRAME_ADVANCE_FLAG;	    CPU.Flags |= DEBUG_MODE_FLAG;	}    }#endif    if (CPU.SRAMModified)    {	if (!CPU.AutoSaveTimer)	{	    if (!(CPU.AutoSaveTimer = Settings.AutoSaveDelay * Memory.ROMFramesPerSecond))		CPU.SRAMModified = FALSE;	}	else	{	    if (!--CPU.AutoSaveTimer)	    {		S9xAutoSaveSRAM ();		CPU.SRAMModified = FALSE;	    }	}    }}void S9xSetInfoString (const char *string){    GFX.InfoString = string;    GFX.InfoStringTimeout = 120;}inline void SelectTileRenderer (bool8 normal){    if (normal)    {	DrawTilePtr = DrawTile16;	DrawClippedTilePtr = DrawClippedTile16;	DrawLargePixelPtr = DrawLargePixel16;    }    else    {	if (GFX.r2131 & 0x80)	{	    if (GFX.r2131 & 0x40)	    {		if (GFX.r2130 & 2)		{		    DrawTilePtr = DrawTile16Sub1_2;		    DrawClippedTilePtr = DrawClippedTile16Sub1_2;		}		else		{		    // Fixed colour substraction		    DrawTilePtr = DrawTile16FixedSub1_2;		    DrawClippedTilePtr = DrawClippedTile16FixedSub1_2;		}		DrawLargePixelPtr = DrawLargePixel16Sub1_2;	    }	    else	    {		DrawTilePtr = DrawTile16Sub;		DrawClippedTilePtr = DrawClippedTile16Sub;		DrawLargePixelPtr = DrawLargePixel16Sub;	    }	}	else	{	    if (GFX.r2131 & 0x40)	    {		if (GFX.r2130 & 2)		{		    DrawTilePtr = DrawTile16Add1_2;		    DrawClippedTilePtr = DrawClippedTile16Add1_2;		}		else		{		    // Fixed colour addition		    DrawTilePtr = DrawTile16FixedAdd1_2;		    DrawClippedTilePtr = DrawClippedTile16FixedAdd1_2;		}		DrawLargePixelPtr = DrawLargePixel16Add1_2;	    }	    else	    {		DrawTilePtr = DrawTile16Add;		DrawClippedTilePtr = DrawClippedTile16Add;		DrawLargePixelPtr = DrawLargePixel16Add;	    }	}    }}void S9xSetupOBJ (){#ifdef MK_DEBUG_RTO	if(Settings.BGLayering) fprintf(stderr, "Entering SetupOBJS()\n");#endif	int SmallWidth, SmallHeight;	int LargeWidth, LargeHeight;	switch (PPU.OBJSizeSelect)	{	  case 0:		SmallWidth = SmallHeight = 8;		LargeWidth = LargeHeight = 16;		break;	  case 1:		SmallWidth = SmallHeight = 8;		LargeWidth = LargeHeight = 32;		break;	  case 2:		SmallWidth = SmallHeight = 8;		LargeWidth = LargeHeight = 64;		break;	  case 3:		SmallWidth = SmallHeight = 16;		LargeWidth = LargeHeight = 32;		break;	  case 4:		SmallWidth = SmallHeight = 16;		LargeWidth = LargeHeight = 64;		break;	  default:	  case 5:		SmallWidth = SmallHeight = 32;		LargeWidth = LargeHeight = 64;		break;	  case 6:		SmallWidth = 16; SmallHeight = 32;		LargeWidth = 32; LargeHeight = 64;		break;	  case 7:		SmallWidth = 16; SmallHeight = 32;		LargeWidth = LargeHeight = 32;		break;	}	if(IPPU.InterlaceSprites)	{		SmallHeight>>=1; LargeHeight>>=1;	}#ifdef MK_DEBUG_RTO	if(Settings.BGLayering) fprintf(stderr, "Sizes are %dx%d and %dx%d\n", SmallWidth, SmallHeight, LargeWidth, LargeHeight);#endif	/* OK, we have three cases here. Either there's no priority, priority is	 * normal FirstSprite, or priority is FirstSprite+Y. The first two are	 * easy, the last is somewhat more ... interesting. So we split them up. */	int Height;	uint8 S;#ifdef MK_DEBUG_RTO	if(Settings.BGLayering) fprintf(stderr, "Priority rotation=%d, OAMAddr=%d -> ", PPU.OAMPriorityRotation, PPU.OAMAddr*2 | (PPU.OAMFlip&1));#endif	if(!PPU.OAMPriorityRotation || !(PPU.OAMFlip&PPU.OAMAddr&1)){#ifdef MK_DEBUG_RTO		if(Settings.BGLayering) fprintf(stderr, "normal FirstSprite = %02x\n", PPU.FirstSprite);#endif		/* normal case */		uint8 LineOBJ[SNES_HEIGHT_EXTENDED];		memset(LineOBJ, 0, sizeof(LineOBJ));		for(int i=0; i<SNES_HEIGHT_EXTENDED; i++){			GFX.OBJLines[i].RTOFlags=0;			GFX.OBJLines[i].Tiles=34;			for(int j=0; j<32; j++){ GFX.OBJLines[i].OBJ[j].Sprite=-1; }		}		uint8 FirstSprite=PPU.FirstSprite;		S=FirstSprite;		do {			if(PPU.OBJ[S].Size){				GFX.OBJWidths[S]=LargeWidth; Height=LargeHeight;			} else {				GFX.OBJWidths[S]=SmallWidth; Height=SmallHeight;			}			int HPos=PPU.OBJ[S].HPos; if(HPos==-256) HPos=256;			if(HPos>-GFX.OBJWidths[S] && HPos<=256)			{				if(HPos<0){					GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3;				} else if(HPos+GFX.OBJWidths[S]>=257){					GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3;				} else {					GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3;				}				for(uint8 line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line<Height; Y++, line++){					if(Y>=SNES_HEIGHT_EXTENDED) continue;					if(LineOBJ[Y]>=32){						GFX.OBJLines[Y].RTOFlags|=0x40;#ifdef MK_DEBUG_RTO						if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S);#endif						continue;					}					GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S];					if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80;					GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite=S;					if(PPU.OBJ[S].VFlip){						// Yes, Width not Height. It so happens that the						// sprites with H=2*W flip as two WxW sprites.						GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line^(GFX.OBJWidths[S]-1);					} else {						GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line;					}					LineOBJ[Y]++;				}			}			S=(S+1)&0x7F;		} while(S!=FirstSprite);		for(int Y=1; Y<SNES_HEIGHT_EXTENDED; Y++){			GFX.OBJLines[Y].RTOFlags |= GFX.OBJLines[Y-1].RTOFlags;		}	} else {		/* evil FirstSprite+Y case */#ifdef MK_DEBUG_RTO		if(Settings.BGLayering) fprintf(stderr, "FirstSprite+Y\n");#endif		/* First, find out which sprites are on which lines */		uint8 OBJOnLine[SNES_HEIGHT_EXTENDED][128];		memset(OBJOnLine, 0, sizeof(OBJOnLine));		for(S=0; S<128; S++){			if(PPU.OBJ[S].Size){				GFX.OBJWidths[S]=LargeWidth; Height=LargeHeight;			} else {				GFX.OBJWidths[S]=SmallWidth; Height=SmallHeight;			}			int HPos=PPU.OBJ[S].HPos; if(HPos==-256) HPos=256;			if(HPos>-GFX.OBJWidths[S] && HPos<=256)			{				if(HPos<0){					GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3;				} else if(HPos+GFX.OBJWidths[S]>=257){					GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3;				} else {					GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3;				}				for(uint8 line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line<Height; Y++, line++){					if(Y>=SNES_HEIGHT_EXTENDED) continue;					if(PPU.OBJ[S].VFlip){						// Yes, Width not Height. It so happens that the						// sprites with H=2*W flip as two WxW sprites.						OBJOnLine[Y][S]=(line^(GFX.OBJWidths[S]-1)) | 0x80;					} else {						OBJOnLine[Y][S]=line | 0x80;					}				}			}		}		/* Now go through and pull out those OBJ that are actually visible. */		int j;		for(int Y=0; Y<SNES_HEIGHT_EXTENDED; Y++){			GFX.OBJLines[Y].RTOFlags=Y?0:GFX.OBJLines[Y-1].RTOFlags;			GFX.OBJLines[Y].Tiles=34;			uint8 FirstSprite=(PPU.FirstSprite+Y)&0x7F;			S=FirstSprite; j=0;			do {				if(OBJOnLine[Y][S]){					if(j>=32){						GFX.OBJLines[Y].RTOFlags|=0x40;#ifdef MK_DEBUG_RTO						if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S);#endif						break;					}					GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S];					if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80;					GFX.OBJLines[Y].OBJ[j].Sprite=S;					GFX.OBJLines[Y].OBJ[j++].Line=OBJOnLine[Y][S]&~0x80;				}				S=(S+1)&0x7F;			} while(S!=FirstSprite);

⌨️ 快捷键说明

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