📄 gfx.cpp
字号:
if(j<32) GFX.OBJLines[Y].OBJ[j].Sprite=-1; } }#ifdef MK_DEBUG_RTO if(Settings.BGLayering) { fprintf(stderr, "Sprites per line:\n"); for(int xxx=0; xxx<SNES_HEIGHT_EXTENDED; xxx++){ fprintf(stderr, "Line %d: RTO=%02x Tiles=%d", xxx, GFX.OBJLines[xxx].RTOFlags, 34-GFX.OBJLines[xxx].Tiles); for(int j=0; j<32 && GFX.OBJLines[xxx].OBJ[j].Sprite>=0; j++){ fprintf(stderr, " %02x.%d", GFX.OBJLines[xxx].OBJ[j].Sprite, GFX.OBJLines[xxx].OBJ[j].Line); } fprintf(stderr, "\n"); } fprintf(stderr, "Exiting SetupObj()\n"); }#endif IPPU.OBJChanged = FALSE;}void DrawOBJS (bool8 OnMain = FALSE, uint8 D = 0){#ifdef MK_DEBUG_RTO if(Settings.BGLayering) fprintf(stderr, "Entering DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY);#endif 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; struct { uint16 Pos; bool8 Value; } Windows[7]; int clipcount = GFX.pCurrentClip->Count [4]; if (!clipcount){ Windows[0].Pos=0; Windows[0].Value=TRUE; Windows[1].Pos=256; Windows[1].Value=FALSE; Windows[2].Pos=1000; Windows[2].Value=FALSE; } else { Windows[0].Pos=1000; Windows[0].Value=FALSE; for(int clip=0, i=1; clip<clipcount; clip++){ if(GFX.pCurrentClip->Right[clip][4]<=GFX.pCurrentClip->Left[clip][4]) continue; int j; for(j=0; j<i && Windows[j].Pos<GFX.pCurrentClip->Left[clip][4]; j++); if(j<i && Windows[j].Pos==GFX.pCurrentClip->Left[clip][4]){ Windows[j].Value = TRUE; } else { if(j<i) memmove(&Windows[j+1], &Windows[j], sizeof(Windows[0])*(i-j)); Windows[j].Pos = GFX.pCurrentClip->Left[clip][4]; Windows[j].Value = TRUE; i++; } for(j=0; j<i && Windows[j].Pos<GFX.pCurrentClip->Right[clip][4]; j++); if(j>=i || Windows[j].Pos!=GFX.pCurrentClip->Right[clip][4]){ if(j<i) memmove(&Windows[j+1], &Windows[j], sizeof(Windows[0])*(i-j)); Windows[j].Pos = GFX.pCurrentClip->Right[clip][4]; Windows[j].Value = FALSE; i++; } } }#ifdef MK_DEBUG_RTOif(Settings.BGLayering) { fprintf(stderr, "Windows:\n"); for(int xxx=0; xxx<6; xxx++){ fprintf(stderr, "%d: %d = %d\n", xxx, Windows[xxx].Pos, Windows[xxx].Value); }}#endif if (Settings.SupportHiRes) { if (PPU.BGMode == 5 || PPU.BGMode == 6) { // Bah, OnMain is never used except to determine if calling // SelectTileRenderer is necessary. So let's hack it to false here // to stop SelectTileRenderer from being called when it causes // problems. OnMain = FALSE; GFX.PixSize = 2; if (IPPU.DoubleHeightPixels) { 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; for(uint32 Y=GFX.StartY, Offset=Y*GFX.PPL; Y<=GFX.EndY; Y++, Offset+=GFX.PPL){#ifdef MK_DEBUG_RTO bool8 Flag=0;#endif int I = 0;#ifdef MK_DISABLE_TIME_OVER int tiles=0;#else int tiles=GFX.OBJLines[Y].Tiles;#endif for (int S = GFX.OBJLines[Y].OBJ[I].Sprite; S >= 0 && I<32; S = GFX.OBJLines[Y].OBJ[++I].Sprite) { tiles+=GFX.OBJVisibleTiles[S]; if(tiles<=0){#ifdef MK_DEBUG_RTOif(Settings.BGLayering) { if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); } fprintf(stderr, " [%02x]", S);}#endif continue; }#ifdef MK_DEBUG_RTOif(Settings.BGLayering) { if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); } fprintf(stderr, " %02x", S);}#endif if (OnMain && SUB_OR_ADD(4)) { SelectTileRenderer (!GFX.Pseudo && PPU.OBJ [S].Palette < 4); } int BaseTile = (((GFX.OBJLines[Y].OBJ[I].Line<<1) + (PPU.OBJ[S].Name&0xf0))&0xf0) | (PPU.OBJ[S].Name&0x100) | (PPU.OBJ[S].Palette << 10); int TileX = PPU.OBJ[S].Name&0x0f; int TileLine = (GFX.OBJLines[Y].OBJ[I].Line&7)*8; int TileInc = 1; if (PPU.OBJ[S].HFlip) { TileX = (TileX + (GFX.OBJWidths[S] >> 3) - 1) & 0x0f; BaseTile |= H_FLIP; TileInc = -1; } GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D; bool8 WinStat=TRUE; int WinIdx=0, NextPos=-1000; int X=PPU.OBJ[S].HPos; if(X==-256) X=256; for(int t=tiles, O=Offset+X*GFX.PixSize; X<=256 && X<PPU.OBJ[S].HPos+GFX.OBJWidths[S]; TileX=(TileX+TileInc)&0x0f, X+=8, O+=8*GFX.PixSize){#ifdef MK_DEBUG_RTOif(Settings.BGLayering) { if(X<-7) continue; if((t-1)<0) fprintf(stderr, "-[%d]", 35-t); else fprintf(stderr, "-%d", 35-t);}#endif if(X<-7 || --t<0 || X==256) continue; if(X>=NextPos){ for(; WinIdx<7 && Windows[WinIdx].Pos<=X; WinIdx++); if(WinIdx==0) WinStat=FALSE; else WinStat=Windows[WinIdx-1].Value; NextPos=(WinIdx<7)?Windows[WinIdx].Pos:1000; } if(X+8<NextPos){ if(WinStat) (*DrawTilePtr) (BaseTile|TileX, O, TileLine, 1); } else { int x=X; while(x<X+8){ if(WinStat) (*DrawClippedTilePtr) (BaseTile|TileX, O, x-X, NextPos-x, TileLine, 1); x=NextPos; for(; WinIdx<7 && Windows[WinIdx].Pos<=x; WinIdx++); if(WinIdx==0) WinStat=FALSE; else WinStat=Windows[WinIdx-1].Value; NextPos=(WinIdx<7)?Windows[WinIdx].Pos:1000; if(NextPos>X+8) NextPos=X+8; } } } }#ifdef MK_DEBUG_RTO if(Settings.BGLayering) if(Flag) fprintf(stderr, "\n");#endif }#ifdef MK_DEBUG_RTO if(Settings.BGLayering) fprintf(stderr, "Exiting DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY);#endif}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(((uint8*)SC1-Memory.VRAM)>=0x10000) SC1-=0x08000; if (PPU.BG[bg].SCSize & 2) SC2 = SC1 + 1024; else SC2 = SC0; if(((uint8*)SC2-Memory.VRAM)>=0x10000) SC2-=0x08000; if (PPU.BG[bg].SCSize & 1) SC3 = SC2 + 1024; else SC3 = SC2; if(((uint8*)SC3-Memory.VRAM)>=0x10000) SC3-=0x08000; uint32 Lines; uint32 OffsetMask; uint32 OffsetShift; if (BG.TileSize == 16) { OffsetMask = 0x3ff; OffsetShift = 4; } else { OffsetMask = 0x1ff; OffsetShift = 3; } int m5 = (BGMode == 5 || BGMode == 6) ? 1 : 0; 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 << m5; HOffset <<= m5; uint32 ClipCount = GFX.pCurrentClip->Count [bg]; uint32 HPos = HOffset; uint32 PixWidth = (PPU.Mosaic << m5); if (!ClipCount) ClipCount = 1; for (uint32 clip = 0; clip < ClipCount; clip++) { if (GFX.pCurrentClip->Count [bg]) { Left = GFX.pCurrentClip->Left [clip][bg] << m5; Right = GFX.pCurrentClip->Right [clip][bg] << m5; uint32 r = Left % (PPU.Mosaic << m5); HPos = HOffset + Left; PixWidth = (PPU.Mosaic << m5) - 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 << m5)) { uint32 Quot = (HPos & OffsetMask) >> 3; if (x + PixWidth >= Right) PixWidth = Right - x; if (BG.TileSize == 8 && !m5) { 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 + (Quot & 1) * m5, 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(((uint8*)SC1-Memory.VRAM)>=0x10000) SC1-=0x08000; if (PPU.BG[bg].SCSize & 2) SC2 = SC1 + 1024; else SC2 = SC0; if(((uint8*)SC2-Memory.VRAM)>=0x10000) SC2-=0x08000; if (PPU.BG[bg].SCSize & 1) SC3 = SC2 + 1024; else SC3 = SC2; if(((uint8*)SC3-Memory.VRAM)>=0x10000) SC3-=0x08000; 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++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -