📄 gfx.cpp
字号:
uint32 VOff = LineData [Y].BG[2].VOffset - 1;// 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; if(BGMode != 4) { if((ScreenLine & 0x1f) == 0x1f) { if(ScreenLine & 0x20) VOffsetOffset = BPS0 - BPS2 - 0x1f*32; else VOffsetOffset = BPS2 - BPS0 - 0x1f*32; } else { VOffsetOffset = 32; } } 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; //added: uint32 LineHOffset=LineData [Y].BG[bg].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 = 8; uint32 s = Left * GFX.PixSize + Y * GFX.PPL; bool8 left_hand_edge = (Left == 0); Width = Right - Left; 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 at the left-hand edge of the screen. VOffset = LineData [Y].BG[bg].VOffset; //MKendora; use temp var to reduce memory accesses //HOffset = LineData [Y].BG[bg].HOffset; HOffset = LineHOffset; //End MK left_hand_edge = FALSE; } else { // All subsequent offset tile data is shifted left by one, // hence the - 1 below. Quot2 = ((HOff + Left - 1) & 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; //MKendora another mem access hack //HOffset = LineData [Y].BG[bg].HOffset; HOffset=LineHOffset; //end MK 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; //MKendora Strike Gunner fix if ((HCellOffset & OffsetEnableMask)) { //HOffset= HCellOffset; HOffset = (HCellOffset & ~7)|(LineHOffset&7); //HOffset |= LineData [Y].BG[bg].HOffset&7; } else HOffset=LineHOffset; //HOffset = LineData [Y].BG[bg].HOffset - //Settings.StrikeGunnerOffsetHack; //HOffset &= (~7); //end MK } } 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; //Count =1; 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; } } }}void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2){ CHECK_SOUND(); if(IPPU.Interlace) { 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((SC1-(unsigned short*)Memory.VRAM)>0x10000) SC1=(uint16*)&Memory.VRAM[(((uint8*)SC1)-Memory.VRAM)%0x10000]; 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; int Lines; int VOffsetMask; int VOffsetShift; if (BG.TileSize == 16) { VOffsetMask = 0x3ff; VOffsetShift = 4; } else { VOffsetMask = 0x1ff; VOffsetShift = 3; } int endy = IPPU.Interlace ? 1 + (GFX.EndY << 1) : GFX.EndY; for (int Y = IPPU.Interlace ? GFX.StartY << 1 : GFX.StartY; Y <= endy; Y += Lines) { int y = IPPU.Interlace ? (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; } else { t1 = 0; t2 = 16; } uint16 *b1; uint16 *b2; if (ScreenLine & 0x20) b1 = SC2, b2 = SC3; else b1 = SC0, b2 = SC1; b1 += (ScreenLine & 0x1f) << 5; b2 += (ScreenLine & 0x1f) << 5; int clipcount = GFX.pCurrentClip->Count [bg]; if (!clipcount) clipcount = 1; for (int clip = 0; clip < clipcount; clip++) { int Left; int Right; if (!GFX.pCurrentClip->Count [bg]) { Left = 0; Right = 512; } else { Left = GFX.pCurrentClip->Left [clip][bg] * 2; Right = GFX.pCurrentClip->Right [clip][bg] * 2; if (Right <= Left) continue; } uint32 s = Left * GFX.PixSize + Y * GFX.PPL; uint32 HPos = (HOffset + Left * GFX.PixSize) & 0x3ff; uint32 Quot = HPos >> 3; uint32 Count = 0; uint16 *t; if (Quot > 63) t = b2 + ((Quot >> 1) & 0x1f); else t = b1 + (Quot >> 1); Width = Right - Left; // Left hand edge clipped tile if (HPos & 7) { int Offset = (HPos & 7); Count = 8 - Offset; if (Count > Width) Count = Width; s -= Offset; Tile = READ_2BYTES (t); GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; if (BG.TileSize == 8) { if (!(Tile & H_FLIP)) { // Normal, unflipped (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), s, Offset, Count, VirtAlign, Lines); } else { // H flip (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), s, Offset, Count, VirtAlign, Lines); } } else { if (!(Tile & (V_FLIP | H_FLIP))) { // Normal, unflipped (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), s, Offset, Count, VirtAlign, Lines); } else if (Tile & H_FLIP) { if (Tile & V_FLIP) { // H & V flip (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), s, Offset, Count, VirtAlign, Lines); } else { // H flip only (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), s, Offset, Count, VirtAlign, Lines); } } else { // V flip only (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), s, Offset, Count, VirtAlign, Lines); } } t += Quot & 1; if (Quot == 63) t = b2; else if (Quot == 127) t = b1; Quot++; s += 8; } // Middle, unclipped tiles Count = Width - Count; int Middle = Count >> 3; Count &= 7; for (int C = Middle; C > 0; s += 8, Quot++, C--) { Tile = READ_2BYTES(t); GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; if (BG.TileSize == 8) { if (!(Tile & H_FLIP)) { // Normal, unflipped (*DrawHiResTilePtr) (Tile + (Quot & 1), s, VirtAlign, Lines); } else { // H flip (*DrawHiResTilePtr) (Tile + 1 - (Quot & 1), s, VirtAlign, Lines); } } else { if (!(Tile & (V_FLIP | H_FLIP))) { // Normal, unflipped (*DrawHiResTilePtr) (Tile + t1 + (Quot & 1), s, VirtAlign, Lines); } else if (Tile & H_FLIP) { if (Tile & V_FLIP) { // H & V flip (*DrawHiResTilePtr) (Tile + t2 + 1 - (Quot & 1), s, VirtAlign, Lines); } else { // H flip only (*DrawHiResTilePtr) (Tile + t1 + 1 - (Quot & 1), s, VirtAlign, Lines); } } else { // V flip only (*DrawHiResTilePtr) (Tile + t2 + (Quot & 1), s, VirtAlign, Lines); } } t += Quot & 1; if (Quot == 63) t = b2; else if (Quot == 127) t = b1; } // Right-hand edge clipped tiles if (Count) { Tile = READ_2BYTES(t); GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; if (BG.TileSize == 8) { if (!(Tile & H_FLIP)) { // Normal, unflipped (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), s, 0, Count, VirtAlign, Lines); } else { // H flip (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), s, 0, Count, VirtAlign, Lines);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -