📄 gfx.cpp
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and * Jerremy Koot (jkoot@snes9x.com) * * Super FX C emulator code * (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and * Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. * C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: www.snes9x.com * * Permission to use, copy, modify and distribute Snes9x in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Snes9x is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Snes9x or software derived from Snes9x. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so everyone can benefit from the modifications * in future versions. * * Super NES and Super Nintendo Entertainment System are trademarks of * Nintendo Co., Limited and its subsidiary companies. */#include "snes9x.h"#include "memmap.h"#include "ppu.h"#include "cpuexec.h"#include "display.h"#include "gfx.h"#include "apu.h"#include "cheats.h"#define M7 19#define M8 19void ComputeClipWindows ();static void S9xDisplayFrameRate ();static void S9xDisplayString (const char *string);extern uint8 BitShifts[8][4];extern uint8 TileShifts[8][4];extern uint8 PaletteShifts[8][4];extern uint8 PaletteMasks[8][4];extern uint8 Depths[8][4];extern uint8 BGSizes [2];extern NormalTileRenderer DrawTilePtr;extern ClippedTileRenderer DrawClippedTilePtr;extern NormalTileRenderer DrawHiResTilePtr;extern ClippedTileRenderer DrawHiResClippedTilePtr;extern LargePixelRenderer DrawLargePixelPtr;extern struct SBG BG;extern struct SLineData LineData[240];extern struct SLineMatrixData LineMatrixData [240];extern uint8 Mode7Depths [2];#define ON_MAIN(N) \(GFX.r212c & (1 << (N)) && \ !(PPU.BG_Forced & (1 << (N))))#define SUB_OR_ADD(N) \(GFX.r2131 & (1 << (N)))#define ON_SUB(N) \((GFX.r2130 & 0x30) != 0x30 && \ (GFX.r2130 & 2) && \ (GFX.r212d & (1 << N)) && \ !(PPU.BG_Forced & (1 << (N))))#define ANYTHING_ON_SUB \((GFX.r2130 & 0x30) != 0x30 && \ (GFX.r2130 & 2) && \ (GFX.r212d & 0x1f))#define ADD_OR_SUB_ON_ANYTHING \(GFX.r2131 & 0x3f)void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTilex2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTilex2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTilex2x2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawLargePixel (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Pixels, uint32 StartLine, uint32 LineCount);void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16x2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawLargePixel16 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Pixels, uint32 StartLine, uint32 LineCount);void DrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16Add (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16Sub (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount);void DrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Width, uint32 StartLine, uint32 LineCount);void DrawLargePixel16Add (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Pixels, uint32 StartLine, uint32 LineCount);void DrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Pixels, uint32 StartLine, uint32 LineCount);void DrawLargePixel16Sub (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Pixels, uint32 StartLine, uint32 LineCount);void DrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartPixel, uint32 Pixels, uint32 StartLine, uint32 LineCount);bool8 S9xGraphicsInit (){ register uint32 PixelOdd = 1; register uint32 PixelEven = 2;#ifdef GFX_MULTI_FORMAT if (GFX.BuildPixel == NULL) S9xSetRenderPixelFormat (RGB565);#endif for (uint8 bitshift = 0; bitshift < 4; bitshift++) { for (register char i = 0; i < 16; i++) { register uint32 h = 0; register uint32 l = 0;#if defined(LSB_FIRST) if (i & 8) h |= PixelOdd; if (i & 4) h |= PixelOdd << 8; if (i & 2) h |= PixelOdd << 16; if (i & 1) h |= PixelOdd << 24; if (i & 8) l |= PixelOdd; if (i & 4) l |= PixelOdd << 8; if (i & 2) l |= PixelOdd << 16; if (i & 1) l |= PixelOdd << 24;#else if (i & 8) h |= (PixelOdd << 24); if (i & 4) h |= (PixelOdd << 16); if (i & 2) h |= (PixelOdd << 8); if (i & 1) h |= PixelOdd; if (i & 8) l |= (PixelOdd << 24); if (i & 4) l |= (PixelOdd << 16); if (i & 2) l |= (PixelOdd << 8); if (i & 1) l |= PixelOdd;#endif odd_high[bitshift][i] = h; odd_low[bitshift][i] = l; h = l = 0;#if defined(LSB_FIRST) if (i & 8) h |= PixelEven; if (i & 4) h |= PixelEven << 8; if (i & 2) h |= PixelEven << 16; if (i & 1) h |= PixelEven << 24; if (i & 8) l |= PixelEven; if (i & 4) l |= PixelEven << 8; if (i & 2) l |= PixelEven << 16; if (i & 1) l |= PixelEven << 24;#else if (i & 8) h |= (PixelEven << 24); if (i & 4) h |= (PixelEven << 16); if (i & 2) h |= (PixelEven << 8); if (i & 1) h |= PixelEven; if (i & 8) l |= (PixelEven << 24); if (i & 4) l |= (PixelEven << 16); if (i & 2) l |= (PixelEven << 8); if (i & 1) l |= PixelEven;#endif even_high[bitshift][i] = h; even_low[bitshift][i] = l; } PixelEven <<= 2; PixelOdd <<= 2; } GFX.RealPitch = GFX.Pitch2 = GFX.Pitch; GFX.ZPitch = GFX.Pitch; if (Settings.SixteenBit) GFX.ZPitch >>= 1; GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; //GFX.InfoStringTimeout = 0; //GFX.InfoString = NULL; PPU.BG_Forced = 0; IPPU.OBJChanged = TRUE; if (Settings.Transparency) Settings.SixteenBit = TRUE; IPPU.DirectColourMapsNeedRebuild = TRUE; GFX.PixSize = 1; if (Settings.SixteenBit) { DrawTilePtr = DrawTile16; DrawClippedTilePtr = DrawClippedTile16; DrawLargePixelPtr = DrawLargePixel16; DrawHiResTilePtr= DrawTile16; DrawHiResClippedTilePtr = DrawClippedTile16; GFX.PPL = GFX.Pitch >> 1; GFX.PPLx2 = GFX.Pitch; } else { DrawTilePtr = DrawTile; DrawClippedTilePtr = DrawClippedTile; DrawLargePixelPtr = DrawLargePixel; DrawHiResTilePtr = DrawTile; DrawHiResClippedTilePtr = DrawClippedTile; GFX.PPL = GFX.Pitch; GFX.PPLx2 = GFX.Pitch * 2; } S9xFixColourBrightness (); if (Settings.SixteenBit) { if (!(GFX.X2 = new uint16 [0x10000])) return (FALSE); if (!(GFX.ZERO_OR_X2 = new uint16 [0x10000]) || !(GFX.ZERO = new uint16 [0x10000])) { delete GFX.ZERO_OR_X2; delete GFX.X2; GFX.X2 = NULL; return (FALSE); } uint32 r, g, b; // Build a lookup table that multiplies a packed RGB value by 2 with // saturation. for (r = 0; r <= MAX_RED; r++) { uint32 r2 = r << 1; if (r2 > MAX_RED) r2 = MAX_RED; for (g = 0; g <= MAX_GREEN; g++) { uint32 g2 = g << 1; if (g2 > MAX_GREEN) g2 = MAX_GREEN; for (b = 0; b <= MAX_BLUE; b++) { uint32 b2 = b << 1; if (b2 > MAX_BLUE) b2 = MAX_BLUE; GFX.X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); } } } ZeroMemory (GFX.ZERO, 0x10000 * sizeof (uint16)); ZeroMemory (GFX.ZERO_OR_X2, 0x10000 * sizeof (uint16)); // Build a lookup table that if the top bit of the color value is zero // then the value is zero, otherwise multiply the value by 2. Used by // the color subtraction code.#if 0 for (r = 0; r <= MAX_RED; r++) { uint32 r2 = r; if ((r2 & 0x10) == 0) r2 = 0; else r2 = (r2 << 1) & MAX_RED; for (g = 0; g <= MAX_GREEN; g++) { uint32 g2 = g; if ((g2 & GREEN_HI_BIT) == 0) g2 = 0; else g2 = (g2 << 1) & MAX_GREEN; for (b = 0; b <= MAX_BLUE; b++) { uint32 b2 = b; if ((b2 & 0x10) == 0) b2 = 0; else b2 = (b2 << 1) & MAX_BLUE; GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); } } }#else for (r = 0; r <= MAX_RED; r++) { uint32 r2 = r; if ((r2 & 0x10) == 0) r2 = 0; else r2 = (r2 << 1) & MAX_RED; if (r2 == 0) r2 = 1; for (g = 0; g <= MAX_GREEN; g++) { uint32 g2 = g; if ((g2 & GREEN_HI_BIT) == 0) g2 = 0; else g2 = (g2 << 1) & MAX_GREEN; if (g2 == 0) g2 = 1; for (b = 0; b <= MAX_BLUE; b++) { uint32 b2 = b; if ((b2 & 0x10) == 0) b2 = 0; else b2 = (b2 << 1) & MAX_BLUE; if (b2 == 0) b2 = 1; GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); } } }#endif // Build a lookup table that if the top bit of the color value is zero // then the value is zero, otherwise its just the value. for (r = 0; r <= MAX_RED; r++) { uint32 r2 = r; if ((r2 & 0x10) == 0) r2 = 0; else r2 &= ~0x10; for (g = 0; g <= MAX_GREEN; g++) { uint32 g2 = g; if ((g2 & GREEN_HI_BIT) == 0) g2 = 0; else g2 &= ~GREEN_HI_BIT; for (b = 0; b <= MAX_BLUE; b++) { uint32 b2 = b; if ((b2 & 0x10) == 0) b2 = 0; else b2 &= ~0x10; GFX.ZERO [BUILD_PIXEL2 (r, g, b)] = 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 delete GFX.X2; delete GFX.ZERO_OR_X2; delete GFX.ZERO; GFX.X2 = NULL; GFX.ZERO_OR_X2 = NULL; GFX.ZERO = NULL;}void S9xBuildDirectColourMaps (){ for (uint32 p = 0; p < 8; p++) { for (uint32 c = 0; c < 256; c++) { 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; IPPU.LatchedInterlace = (Memory.FillRAM[0x2133] & 1); if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.LatchedInterlace)) { if (PPU.BGMode == 5 || PPU.BGMode == 6) { IPPU.RenderedScreenWidth = 512; IPPU.DoubleWidthPixels = TRUE; } if (IPPU.LatchedInterlace) { IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; GFX.Pitch2 = GFX.RealPitch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -