📄 gfx.cpp
字号:
else if (Quot == 63) t = b1; } else { 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) (*DrawClippedTilePtr) (Tile, s, 0, Count, VirtAlign, Lines); else { if (!(Tile & (V_FLIP | H_FLIP))) { // Normal, unflipped (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, 0, Count, VirtAlign, Lines); } else if (Tile & H_FLIP) { if (Tile & V_FLIP) { // H & V flip (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), s, 0, Count, VirtAlign, Lines); } else { // H flip only (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), s, 0, Count, VirtAlign, Lines); } } else { // V flip only (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), s, 0, Count, VirtAlign, Lines); } } } } }}#define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \ CHECK_SOUND(); \\ uint8 *VRAM1 = Memory.VRAM + 1; \ if (GFX.r2130 & 1) \ { \ if (IPPU.DirectColourMapsNeedRebuild) \ S9xBuildDirectColourMaps (); \ GFX.ScreenColors = DirectColourMaps [0]; \ } \ else \ GFX.ScreenColors = IPPU.ScreenColors; \\ int aa, cc; \ int dir; \ int startx, endx; \ uint32 Left = 0; \ uint32 Right = 256; \ uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \\ if (!ClipCount) \ ClipCount = 1; \\ Screen += GFX.StartY * GFX.Pitch; \ uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \ struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \\ for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \ { \ int yy; \\ int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \ int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \\ int32 CentreX = ((int32) l->CentreX << M7) >> M7; \ int32 CentreY = ((int32) l->CentreY << M7) >> M7; \\ if (PPU.Mode7VFlip) \ yy = 261 - (int) Line; \ else \ yy = Line; \\ if (PPU.Mode7Repeat == 0) \ yy += (VOffset - CentreY) % 1023; \ else \ yy += VOffset - CentreY; \ int BB = l->MatrixB * yy + (CentreX << 8); \ int DD = l->MatrixD * yy + (CentreY << 8); \\ for (uint32 clip = 0; clip < ClipCount; clip++) \ { \ if (GFX.pCurrentClip->Count [bg]) \ { \ Left = GFX.pCurrentClip->Left [clip][bg]; \ Right = GFX.pCurrentClip->Right [clip][bg]; \ if (Right <= Left) \ continue; \ } \ TYPE *p = (TYPE *) Screen + Left; \ uint8 *d = Depth + Left; \\ if (PPU.Mode7HFlip) \ { \ startx = Right - 1; \ endx = Left - 1; \ dir = -1; \ aa = -l->MatrixA; \ cc = -l->MatrixC; \ } \ else \ { \ startx = Left; \ endx = Right; \ dir = 1; \ aa = l->MatrixA; \ cc = l->MatrixC; \ } \ int xx; \ if (PPU.Mode7Repeat == 0) \ xx = startx + (HOffset - CentreX) % 1023; \ else \ xx = startx + HOffset - CentreX; \ int AA = l->MatrixA * xx; \ int CC = l->MatrixC * xx; \\ if (!PPU.Mode7Repeat) \ { \ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ { \ int X = ((AA + BB) >> 8) & 0x3ff; \ int Y = ((CC + DD) >> 8) & 0x3ff; \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && b) \ { \ *p = (FUNC); \ *d = GFX.Z1; \ } \ } \ } \ else \ { \ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ { \ int X = ((AA + BB) >> 8); \ int Y = ((CC + DD) >> 8); \\ if (Settings.Dezaemon && PPU.Mode7Repeat == 2) \ { \ X &= 0x7ff; \ Y &= 0x7ff; \ } \\ if (((X | Y) & ~0x3ff) == 0) \ { \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && b) \ { \ *p = (FUNC); \ *d = GFX.Z1; \ } \ } \ else \ { \ if (PPU.Mode7Repeat == 3) \ { \ X = (x + HOffset) & 7; \ Y = (yy + CentreY) & 7; \ uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ if (GFX.Z1 > *d && b) \ { \ *p = (FUNC); \ *d = GFX.Z1; \ } \ } \ } \ } \ } \ } \ }#if 0#define _BUILD_SETUP(F) \GFX.BuildPixel = BuildPixel##F; \GFX.BuildPixel2 = BuildPixel2##F; \GFX.DecomposePixel = DecomposePixel##F; \RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_##F; \GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_##F; \BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_##F; \RED_HI_BIT_MASK = RED_HI_BIT_MASK_##F; \GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_##F; \BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_##F; \MAX_RED = MAX_RED_##F; \MAX_GREEN = MAX_GREEN_##F; \MAX_BLUE = MAX_BLUE_##F; \GREEN_HI_BIT = ((MAX_GREEN_##F + 1) >> 1); \SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_##F; \RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_##F | \ GREEN_LOW_BIT_MASK_##F | \ BLUE_LOW_BIT_MASK_##F); \RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_##F | \ GREEN_HI_BIT_MASK_##F | \ BLUE_HI_BIT_MASK_##F); \RGB_HI_BITS_MASKx2 = ((RED_HI_BIT_MASK_##F | \ GREEN_HI_BIT_MASK_##F | \ BLUE_HI_BIT_MASK_##F) << 1); \RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK;#endifvoid DrawBGMode7Background (uint8 *Screen, int bg){ RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask))}void DrawBGMode7Background16 (uint8 *Screen, int bg){ RENDER_BACKGROUND_MODE7 (uint16, GFX.ScreenColors [b & GFX.Mode7Mask]);}void DrawBGMode7Background16Add (uint8 *Screen, int bg){ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], p [GFX.Delta]) : COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], GFX.FixedColour)) : GFX.ScreenColors [b & GFX.Mode7Mask]);}void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg){ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? COLOR_ADD1_2 (GFX.ScreenColors [b & GFX.Mode7Mask], p [GFX.Delta]) : COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], GFX.FixedColour)) : GFX.ScreenColors [b & GFX.Mode7Mask]);}void DrawBGMode7Background16Sub (uint8 *Screen, int bg){ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], p [GFX.Delta]) : COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], GFX.FixedColour)) : GFX.ScreenColors [b & GFX.Mode7Mask]);}void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg){ RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? (*(d + GFX.DepthDelta) != 1 ? COLOR_SUB1_2 (GFX.ScreenColors [b & GFX.Mode7Mask], p [GFX.Delta]) : COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], GFX.FixedColour)) : GFX.ScreenColors [b & GFX.Mode7Mask]);}#define RENDER_BACKGROUND_MODE7_i(TYPE,FUNC,COLORFUNC) \ CHECK_SOUND(); \\ uint8 *VRAM1 = Memory.VRAM + 1; \ if (GFX.r2130 & 1) \ { \ if (IPPU.DirectColourMapsNeedRebuild) \ S9xBuildDirectColourMaps (); \ GFX.ScreenColors = DirectColourMaps [0]; \ } \ else \ GFX.ScreenColors = IPPU.ScreenColors; \ \ int aa, cc; \ int dir; \ int startx, endx; \ uint32 Left = 0; \ uint32 Right = 256; \ uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \ \ if (!ClipCount) \ ClipCount = 1; \ \ Screen += GFX.StartY * GFX.Pitch; \ uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \ struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \ bool8 allowSimpleCase = FALSE; \ if (!l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100) \ && !LineMatrixData[GFX.EndY].MatrixB && !LineMatrixData[GFX.EndY].MatrixC \ && (LineMatrixData[GFX.EndY].MatrixA == 0x0100) && (LineMatrixData[GFX.EndY].MatrixD == 0x0100) \ ) \ allowSimpleCase = TRUE; \ \ for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \ { \ int yy; \ \ int HOffset = ((int) LineData [Line].BG[0].HOffset << M7) >> M7; \ int VOffset = ((int) LineData [Line].BG[0].VOffset << M7) >> M7; \ \ int CentreX = ((int) l->CentreX << M7) >> M7; \ int CentreY = ((int) l->CentreY << M7) >> M7; \ \ if (PPU.Mode7VFlip) \ yy = 261 - (int) Line; \ else \ yy = Line; \ \ if (PPU.Mode7Repeat == 0) \ yy += (VOffset - CentreY) % 1023; \ else \ yy += VOffset - CentreY; \ bool8 simpleCase = FALSE; \ int BB; \ int DD; \ /* Make a special case for the identity matrix, since it's a common case and */ \ /* can be done much more quickly without special effects */ \ if (allowSimpleCase && !l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100)) \ { \ BB = CentreX << 8; \ DD = (yy + CentreY) << 8; \ simpleCase = TRUE; \ } \ else \ { \ BB = l->MatrixB * yy + (CentreX << 8); \ DD = l->MatrixD * yy + (CentreY << 8); \ } \ \ for (uint32 clip = 0; clip < ClipCount; clip++) \ { \ if (GFX.pCurrentClip->Count [bg]) \ { \ Left = GFX.pCurrentClip->Left [clip][bg]; \ Right = GFX.pCurrentClip->Right [clip][bg]; \ if (Right <= Left) \ continue; \ } \ TYPE *p = (TYPE *) Screen + Left; \ uint8 *d = Depth + Left; \ \ if (PPU.Mode7HFlip) \ { \ startx = Right - 1; \ endx = Left - 1; \ dir = -1; \ aa = -l->MatrixA; \ cc = -l->MatrixC; \ } \ else \ { \ startx = Left; \ endx = Right; \ dir = 1; \ aa = l->MatrixA; \ cc = l->MatrixC; \ } \ int xx; \ if (PPU.Mode7Repeat == 0) \ xx = startx + (HOffset - CentreX) % 1023; \ else \ xx = startx + HOffset - CentreX; \ int AA, CC = 0; \ if (simpleCase) \ { \ AA = xx << 8; \ } \ else \ { \ AA = l->MatrixA * xx; \ CC = l->MatrixC * xx; \ } \ if (simpleCase) \ { \ if (!PPU.Mode7Repeat) \ { \ int x = 0; \ int theEnd = Right - Left; \ do \ { \ int X = ((AA + BB) >> 8) & 0x3ff; \ int Y = (DD >> 8) & 0x3ff; \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ uint32 b; \ if ((GFX.Z1 > *d) && (b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)))) \ { \ TYPE theColor = COLORFUNC; \ *p = (FUNC); \ *d = GFX.Z2; \ } \ AA += aa, p++, d++; \ x += dir; \ } while (x != theEnd); \ } \ else \ { \ int x = startx; \ do { \ int X = (AA + BB) >> 8; \ int Y = DD >> 8; \\ if(Settings.Dezaemon && PPU.Mode7Repeat == 2) \ { \ X &= 0x7ff; \ Y &= 0x7ff; \ } \\ if (((X | Y) & ~0x3ff) == 0) \ { \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ uint32 b; \ if ((GFX.Z1 > *d) && (b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)))) \ { \ *p = COLORFUNC; \ *d = GFX.Z2; \ } \ } \ else if (PPU.Mode7Repeat == 3) \ { \ X = (x + HOffset) & 7; \ Y = (yy + CentreY) & 7; \ uint32 b; \ if (GFX.Z1 > *d && \ (b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)))) \ { \ TYPE theColor = COLORFUNC; \ *p = (FUNC); \ *d = GFX.Z2; \ } \ } \ AA += aa, p++, d++; \ x += dir; \ } while (x != endx); \ } \ } \ else if (!PPU.Mode7Repeat) \ { \ /* The bilinear interpolator: get the colors at the four points surrounding */ \ /* the location of one point in the _sampled_ image, and weight them according */ \ /* to their (city block) distance. It's very smooth, but blurry with "close up" */ \ /* points. */ \ \ /* 460 (slightly less than 2 source pixels per displayed pixel) is an educated */ \ /* guess for where bilinear filtering will become a poor method for averaging. */ \ /* (When reducing the image, the weighting used by a bilinear filter becomes */ \ /* arbitrary, and a simple mean is a better way to represent the source image.) */ \ /* You can think of this as a kind of mipmapping. */ \ if ((aa < 460 && aa > -460) && (cc < 460 && cc > -460)) \ {\ for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ { \ uint32 xPos = AA + BB; \ uint32 xPix = xPos >> 8; \ uint32 yPos = CC + DD; \ uint32 yPix = yPos >> 8; \ uint32 X = xPix & 0x3ff; \ uint32 Y = yPix & 0x3ff; \ uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ uint32 b; \ if ((GFX.Z1 > *d) &&\ (b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)))) \ { \ /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \ uint32 X10 = (xPix + dir) & 0x3ff; \ uint32 Y01 = (yPix + dir) & 0x3ff; \ uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ uint32 p1 = COLORFUNC; \ p1 = (p1 & FIRST_THIRD_COLOR_MASK) | ((p1 & SECOND_COLOR_MASK) << 16); \ b = *(TileData10 + ((Y & 7) << 4) + ((X10 & 7) << 1)); \ uint32 p2 = COLORFUNC; \ p2 = (p2 & FIRST_THIRD_COLOR_MASK) | ((p2 & SECOND_COLOR_MASK) << 16); \ b = *(TileData11 + ((Y01 & 7) << 4) + ((X10 & 7) << 1)); \ uint32 p4 = COLORFUNC; \ p4 = (p4 & FIRST_THIRD_COLOR_MASK) | ((p4 & SECOND_COLOR_MASK) << 16); \ b = *(TileData01 + ((Y01 & 7) << 4) + ((X & 7) << 1)); \ uint32 p3 = COLORFUNC; \ p3 = (p3 & FIRST_THIRD_COLOR_MASK) | ((p3 & SECOND_COLOR_MASK) << 16); \ /* Xdel, Ydel: position (in 1/32nds) between the points */ \ uint32 Xdel = (xPos >> 3) & 0x1F; \ uint32 Ydel = (yPos >> 3) & 0x1F; \ uint32 XY = (Xdel*Ydel) >> 5; \ uint32 area1 = 0x20 + XY - Xdel - Ydel; \ uint32 area2 = Xdel - XY; \ uint32 area3 = Ydel - XY; \ uint32 area4 = XY; \ uint32 tempColor = ((area1 * p1) + \ (area2 * p2) + \ (area3 * p3) + \ (area4 * p4)) >> 5; \ TYPE theColor = (tempColor & FIRST_THIRD_COLOR_MASK) | ((tempColor >> 16) & SECOND_COLOR_MASK); \ *p = (FUNC); \ *d = GFX.Z2; \ } \ } \ } \ else \ /* The oversampling method: get the colors at four corners of a square */ \ /* in the _displayed_ image, and average them. It's sharp and clean, but */ \ /* gives the usual huge pixels when the source image gets "close." */ \ { \ /* Find the dimensions of the square in the source image whose corners will be examined. */ \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -