📄 gfx.cpp
字号:
GFX.Pitch = GFX.RealPitch * 2; GFX.PPL = GFX.PPLx2; } else { IPPU.RenderedScreenHeight = PPU.ScreenHeight; GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; GFX.PPL = GFX.PPLx2 >> 1; } } else { IPPU.RenderedScreenWidth = 256; IPPU.RenderedScreenHeight = PPU.ScreenHeight; IPPU.DoubleWidthPixels = 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; } else#endif { GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; GFX.PPL = GFX.PPLx2 >> 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; }}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; }#ifdef USE_GLIDE if (!Settings.GlideEnable)#endif { GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; GFX.PPL = GFX.PPLx2 >> 1; } if (Settings.DisplayFrameRate) S9xDisplayFrameRate (); if (GFX.InfoString) S9xDisplayString (GFX.InfoString); GFX.Pitch = GFX.RealPitch; GFX.PPL = GFX.PPLx2 >> 1; 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 (){ int SmallSize; int LargeSize; switch (PPU.OBJSizeSelect) { case 0: SmallSize = 8; LargeSize = 16; break; case 1: SmallSize = 8; LargeSize = 32; break; case 2: SmallSize = 8; LargeSize = 64; break; case 3: SmallSize = 16; LargeSize = 32; break; case 4: SmallSize = 16; LargeSize = 64; break; case 5: default: SmallSize = 32; LargeSize = 64; break; } int C = 0; int FirstSprite = PPU.FirstSprite & 0x7f; int S = FirstSprite; do { int Size; if (PPU.OBJ [S].Size) Size = LargeSize; else Size = SmallSize; long VPos = PPU.OBJ [S].VPos; if (VPos >= PPU.ScreenHeight) VPos -= 256; if (PPU.OBJ [S].HPos < 256 && PPU.OBJ [S].HPos > -Size && VPos < PPU.ScreenHeight && VPos > -Size) { GFX.OBJList [C++] = S; GFX.Sizes[S] = Size; GFX.VPositions[S] = VPos; } S = (S + 1) & 0x7f; } while (S != FirstSprite); // Terminate the list GFX.OBJList [C] = -1; IPPU.OBJChanged = FALSE;}void DrawOBJS (bool8 OnMain = FALSE, uint8 D = 0){ uint32 O; uint32 BaseTile, Tile; CHECK_SOUND(); BG.BitShift = 4; BG.TileShift = 5; BG.TileAddress = PPU.OBJNameBase; BG.StartPalette = 128; BG.PaletteShift = 4; BG.PaletteMask = 7; BG.Buffer = IPPU.TileCache [TILE_4BIT]; BG.Buffered = IPPU.TileCached [TILE_4BIT]; BG.NameSelect = PPU.OBJNameSelect; BG.DirectColourMode = FALSE; GFX.PixSize = 1; if (Settings.SupportHiRes) { if (PPU.BGMode == 5 || PPU.BGMode == 6) { GFX.PixSize = 2; if (IPPU.LatchedInterlace) { if (Settings.SixteenBit) { DrawTilePtr = DrawTile16x2x2; DrawClippedTilePtr = DrawClippedTile16x2x2; } else { DrawTilePtr = DrawTilex2x2; DrawClippedTilePtr = DrawClippedTilex2x2; } } else { if (Settings.SixteenBit) { DrawTilePtr = DrawTile16x2; DrawClippedTilePtr = DrawClippedTile16x2; } else { DrawTilePtr = DrawTilex2; DrawClippedTilePtr = DrawClippedTilex2; } } } else { if (Settings.SixteenBit) { DrawTilePtr = DrawTile16; DrawClippedTilePtr = DrawClippedTile16; } else { DrawTilePtr = DrawTile; DrawClippedTilePtr = DrawClippedTile; } } } GFX.Z1 = D + 2; int I = 0; for (int S = GFX.OBJList [I++]; S >= 0; S = GFX.OBJList [I++]) { int VPos = GFX.VPositions [S]; int Size = GFX.Sizes[S]; int TileInc = 1; int Offset; if (VPos + Size <= (int) GFX.StartY || VPos > (int) GFX.EndY) continue; if (OnMain && SUB_OR_ADD(4)) { SelectTileRenderer (!GFX.Pseudo && PPU.OBJ [S].Palette < 4); } BaseTile = PPU.OBJ[S].Name | (PPU.OBJ[S].Palette << 10); if (PPU.OBJ[S].HFlip) { BaseTile += ((Size >> 3) - 1) | H_FLIP; TileInc = -1; } if (PPU.OBJ[S].VFlip) BaseTile |= V_FLIP; int clipcount = GFX.pCurrentClip->Count [4]; if (!clipcount) clipcount = 1; GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D; for (int clip = 0; clip < clipcount; clip++) { int Left; int Right; if (!GFX.pCurrentClip->Count [4]) { Left = 0; Right = 256; } else { Left = GFX.pCurrentClip->Left [clip][4]; Right = GFX.pCurrentClip->Right [clip][4]; } if (Right <= Left || PPU.OBJ[S].HPos + Size <= Left || PPU.OBJ[S].HPos >= Right) continue; for (int Y = 0; Y < Size; Y += 8) { if (VPos + Y + 7 >= (int) GFX.StartY && VPos + Y <= (int) GFX.EndY) { int StartLine; int TileLine; int LineCount; int Last; if ((StartLine = VPos + Y) < (int) GFX.StartY) { StartLine = GFX.StartY - StartLine; LineCount = 8 - StartLine; } else { StartLine = 0; LineCount = 8; } if ((Last = VPos + Y + 7 - GFX.EndY) > 0) if ((LineCount -= Last) <= 0) break; TileLine = StartLine << 3; O = (VPos + Y + StartLine) * GFX.PPL; if (!PPU.OBJ[S].VFlip) Tile = BaseTile + (Y << 1); else Tile = BaseTile + ((Size - Y - 8) << 1); int Middle = Size >> 3; if (PPU.OBJ[S].HPos < Left) { Tile += ((Left - PPU.OBJ[S].HPos) >> 3) * TileInc; Middle -= (Left - PPU.OBJ[S].HPos) >> 3; O += Left * GFX.PixSize; if ((Offset = (Left - PPU.OBJ[S].HPos) & 7)) { O -= Offset * GFX.PixSize; int W = 8 - Offset; int Width = Right - Left; if (W > Width) W = Width; (*DrawClippedTilePtr) (Tile, O, Offset, W, TileLine, LineCount); if (W >= Width) continue; Tile += TileInc; Middle--; O += 8 * GFX.PixSize; } } else O += PPU.OBJ[S].HPos * GFX.PixSize; if (PPU.OBJ[S].HPos + Size >= Right) { Middle -= ((PPU.OBJ[S].HPos + Size + 7) - Right) >> 3; Offset = (Right - (PPU.OBJ[S].HPos + Size)) & 7; } else Offset = 0; for (int X = 0; X < Middle; X++, O += 8 * GFX.PixSize, Tile += TileInc) { (*DrawTilePtr) (Tile, O, TileLine, LineCount); } if (Offset) { (*DrawClippedTilePtr) (Tile, O, 0, Offset, TileLine, LineCount); } } } } }}void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2){ CHECK_SOUND(); uint32 Tile; uint16 *SC0; uint16 *SC1; uint16 *SC2; uint16 *SC3; uint8 depths [2] = {Z1, Z2}; if (BGMode == 0) BG.StartPalette = bg << 5; else 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; uint32 Lines; uint32 OffsetMask; uint32 OffsetShift; if (BG.TileSize == 16)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -