mirror of https://github.com/PCSX2/pcsx2.git
1515 lines
28 KiB
C++
1515 lines
28 KiB
C++
/*
|
|
* Copyright (C) 2007-2009 Gabest
|
|
* http://www.gabest.org
|
|
*
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This Program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNU Make; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
// This file is filled with stuff that breaks clang-format
|
|
// clang-format off
|
|
|
|
#define PLUGIN_VERSION 0
|
|
|
|
#define VM_SIZE 4194304u
|
|
#define HALF_VM_SIZE (VM_SIZE / 2u)
|
|
#define PAGE_SIZE 8192u
|
|
#define BLOCK_SIZE 256u
|
|
#define COLUMN_SIZE 64u
|
|
|
|
#define MAX_PAGES (VM_SIZE / PAGE_SIZE)
|
|
#define MAX_BLOCKS (VM_SIZE / BLOCK_SIZE)
|
|
#define MAX_COLUMNS (VM_SIZE / COLUMN_SIZE)
|
|
|
|
//if defined, will send much info in reply to the API title info queri from PCSX2
|
|
//default should be undefined
|
|
//#define GSTITLEINFO_API_FORCE_VERBOSE
|
|
|
|
#include "GSVector.h"
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
enum GS_PRIM
|
|
{
|
|
GS_POINTLIST = 0,
|
|
GS_LINELIST = 1,
|
|
GS_LINESTRIP = 2,
|
|
GS_TRIANGLELIST = 3,
|
|
GS_TRIANGLESTRIP = 4,
|
|
GS_TRIANGLEFAN = 5,
|
|
GS_SPRITE = 6,
|
|
GS_INVALID = 7,
|
|
};
|
|
|
|
enum GS_PRIM_CLASS
|
|
{
|
|
GS_POINT_CLASS = 0,
|
|
GS_LINE_CLASS = 1,
|
|
GS_TRIANGLE_CLASS = 2,
|
|
GS_SPRITE_CLASS = 3,
|
|
GS_INVALID_CLASS = 7,
|
|
};
|
|
|
|
enum GIF_REG
|
|
{
|
|
GIF_REG_PRIM = 0x00,
|
|
GIF_REG_RGBA = 0x01,
|
|
GIF_REG_STQ = 0x02,
|
|
GIF_REG_UV = 0x03,
|
|
GIF_REG_XYZF2 = 0x04,
|
|
GIF_REG_XYZ2 = 0x05,
|
|
GIF_REG_TEX0_1 = 0x06,
|
|
GIF_REG_TEX0_2 = 0x07,
|
|
GIF_REG_CLAMP_1 = 0x08,
|
|
GIF_REG_CLAMP_2 = 0x09,
|
|
GIF_REG_FOG = 0x0a,
|
|
GIF_REG_INVALID = 0x0b,
|
|
GIF_REG_XYZF3 = 0x0c,
|
|
GIF_REG_XYZ3 = 0x0d,
|
|
GIF_REG_A_D = 0x0e,
|
|
GIF_REG_NOP = 0x0f,
|
|
};
|
|
|
|
enum GIF_REG_COMPLEX
|
|
{
|
|
GIF_REG_STQRGBAXYZF2 = 0x00,
|
|
GIF_REG_STQRGBAXYZ2 = 0x01,
|
|
};
|
|
|
|
enum GIF_A_D_REG
|
|
{
|
|
GIF_A_D_REG_PRIM = 0x00,
|
|
GIF_A_D_REG_RGBAQ = 0x01,
|
|
GIF_A_D_REG_ST = 0x02,
|
|
GIF_A_D_REG_UV = 0x03,
|
|
GIF_A_D_REG_XYZF2 = 0x04,
|
|
GIF_A_D_REG_XYZ2 = 0x05,
|
|
GIF_A_D_REG_TEX0_1 = 0x06,
|
|
GIF_A_D_REG_TEX0_2 = 0x07,
|
|
GIF_A_D_REG_CLAMP_1 = 0x08,
|
|
GIF_A_D_REG_CLAMP_2 = 0x09,
|
|
GIF_A_D_REG_FOG = 0x0a,
|
|
GIF_A_D_REG_XYZF3 = 0x0c,
|
|
GIF_A_D_REG_XYZ3 = 0x0d,
|
|
GIF_A_D_REG_NOP = 0x0f,
|
|
GIF_A_D_REG_TEX1_1 = 0x14,
|
|
GIF_A_D_REG_TEX1_2 = 0x15,
|
|
GIF_A_D_REG_TEX2_1 = 0x16,
|
|
GIF_A_D_REG_TEX2_2 = 0x17,
|
|
GIF_A_D_REG_XYOFFSET_1 = 0x18,
|
|
GIF_A_D_REG_XYOFFSET_2 = 0x19,
|
|
GIF_A_D_REG_PRMODECONT = 0x1a,
|
|
GIF_A_D_REG_PRMODE = 0x1b,
|
|
GIF_A_D_REG_TEXCLUT = 0x1c,
|
|
GIF_A_D_REG_SCANMSK = 0x22,
|
|
GIF_A_D_REG_MIPTBP1_1 = 0x34,
|
|
GIF_A_D_REG_MIPTBP1_2 = 0x35,
|
|
GIF_A_D_REG_MIPTBP2_1 = 0x36,
|
|
GIF_A_D_REG_MIPTBP2_2 = 0x37,
|
|
GIF_A_D_REG_TEXA = 0x3b,
|
|
GIF_A_D_REG_FOGCOL = 0x3d,
|
|
GIF_A_D_REG_TEXFLUSH = 0x3f,
|
|
GIF_A_D_REG_SCISSOR_1 = 0x40,
|
|
GIF_A_D_REG_SCISSOR_2 = 0x41,
|
|
GIF_A_D_REG_ALPHA_1 = 0x42,
|
|
GIF_A_D_REG_ALPHA_2 = 0x43,
|
|
GIF_A_D_REG_DIMX = 0x44,
|
|
GIF_A_D_REG_DTHE = 0x45,
|
|
GIF_A_D_REG_COLCLAMP = 0x46,
|
|
GIF_A_D_REG_TEST_1 = 0x47,
|
|
GIF_A_D_REG_TEST_2 = 0x48,
|
|
GIF_A_D_REG_PABE = 0x49,
|
|
GIF_A_D_REG_FBA_1 = 0x4a,
|
|
GIF_A_D_REG_FBA_2 = 0x4b,
|
|
GIF_A_D_REG_FRAME_1 = 0x4c,
|
|
GIF_A_D_REG_FRAME_2 = 0x4d,
|
|
GIF_A_D_REG_ZBUF_1 = 0x4e,
|
|
GIF_A_D_REG_ZBUF_2 = 0x4f,
|
|
GIF_A_D_REG_BITBLTBUF = 0x50,
|
|
GIF_A_D_REG_TRXPOS = 0x51,
|
|
GIF_A_D_REG_TRXREG = 0x52,
|
|
GIF_A_D_REG_TRXDIR = 0x53,
|
|
GIF_A_D_REG_HWREG = 0x54,
|
|
GIF_A_D_REG_SIGNAL = 0x60,
|
|
GIF_A_D_REG_FINISH = 0x61,
|
|
GIF_A_D_REG_LABEL = 0x62,
|
|
};
|
|
|
|
enum GIF_FLG
|
|
{
|
|
GIF_FLG_PACKED = 0,
|
|
GIF_FLG_REGLIST = 1,
|
|
GIF_FLG_IMAGE = 2,
|
|
GIF_FLG_IMAGE2 = 3,
|
|
};
|
|
|
|
enum GS_PSM
|
|
{
|
|
PSM_PSMCT32 = 0, // 0000-0000
|
|
PSM_PSMCT24 = 1, // 0000-0001
|
|
PSM_PSMCT16 = 2, // 0000-0010
|
|
PSM_PSMCT16S = 10, // 0000-1010
|
|
PSM_PSGPU24 = 18, // 0001-0010
|
|
PSM_PSMT8 = 19, // 0001-0011
|
|
PSM_PSMT4 = 20, // 0001-0100
|
|
PSM_PSMT8H = 27, // 0001-1011
|
|
PSM_PSMT4HL = 36, // 0010-0100
|
|
PSM_PSMT4HH = 44, // 0010-1100
|
|
PSM_PSMZ32 = 48, // 0011-0000
|
|
PSM_PSMZ24 = 49, // 0011-0001
|
|
PSM_PSMZ16 = 50, // 0011-0010
|
|
PSM_PSMZ16S = 58, // 0011-1010
|
|
};
|
|
|
|
enum GS_TFX
|
|
{
|
|
TFX_MODULATE = 0,
|
|
TFX_DECAL = 1,
|
|
TFX_HIGHLIGHT = 2,
|
|
TFX_HIGHLIGHT2 = 3,
|
|
TFX_NONE = 4,
|
|
};
|
|
|
|
enum GS_CLAMP
|
|
{
|
|
CLAMP_REPEAT = 0,
|
|
CLAMP_CLAMP = 1,
|
|
CLAMP_REGION_CLAMP = 2,
|
|
CLAMP_REGION_REPEAT = 3,
|
|
};
|
|
|
|
enum GS_ZTST
|
|
{
|
|
ZTST_NEVER = 0,
|
|
ZTST_ALWAYS = 1,
|
|
ZTST_GEQUAL = 2,
|
|
ZTST_GREATER = 3,
|
|
};
|
|
|
|
enum GS_ATST
|
|
{
|
|
ATST_NEVER = 0,
|
|
ATST_ALWAYS = 1,
|
|
ATST_LESS = 2,
|
|
ATST_LEQUAL = 3,
|
|
ATST_EQUAL = 4,
|
|
ATST_GEQUAL = 5,
|
|
ATST_GREATER = 6,
|
|
ATST_NOTEQUAL = 7,
|
|
};
|
|
|
|
enum GS_AFAIL
|
|
{
|
|
AFAIL_KEEP = 0,
|
|
AFAIL_FB_ONLY = 1,
|
|
AFAIL_ZB_ONLY = 2,
|
|
AFAIL_RGB_ONLY = 3,
|
|
};
|
|
|
|
enum class GS_MIN_FILTER : uint8_t
|
|
{
|
|
Nearest = 0,
|
|
Linear = 1,
|
|
Nearest_Mipmap_Nearest = 2,
|
|
Nearest_Mipmap_Linear = 3,
|
|
Linear_Mipmap_Nearest = 4,
|
|
Linear_Mipmap_Linear = 5,
|
|
};
|
|
|
|
enum class GSRendererType : int8_t
|
|
{
|
|
Undefined = -1,
|
|
NO_RENDERER = 0,
|
|
DX1011_HW = 3,
|
|
Null = 11,
|
|
OGL_HW = 12,
|
|
OGL_SW = 13,
|
|
|
|
#ifdef _WIN32
|
|
Default = Undefined
|
|
#else
|
|
// Use ogl renderer as default otherwise it crash at startup
|
|
// GSRenderOGL only GSDeviceOGL (not GSDeviceNULL)
|
|
Default = OGL_HW
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
#define REG32(name) \
|
|
union name \
|
|
{ \
|
|
uint32 u32; \
|
|
struct { \
|
|
|
|
#define REG64(name) \
|
|
union name \
|
|
{ \
|
|
uint64 u64; \
|
|
uint32 u32[2]; \
|
|
void operator = (const GSVector4i& v) {GSVector4i::storel(this, v);} \
|
|
bool operator == (const union name& r) const {return ((GSVector4i)r).eq(*this);} \
|
|
bool operator != (const union name& r) const {return !((GSVector4i)r).eq(*this);} \
|
|
operator GSVector4i() const {return GSVector4i::loadl(this);} \
|
|
struct {
|
|
|
|
#define REG128(name) \
|
|
union name \
|
|
{ \
|
|
uint64 u64[2]; \
|
|
uint32 u32[4]; \
|
|
struct {
|
|
|
|
#define REG32_(prefix, name) REG32(prefix##name)
|
|
#define REG64_(prefix, name) REG64(prefix##name)
|
|
#define REG128_(prefix, name) REG128(prefix##name)
|
|
|
|
#define REG_END }; };
|
|
#define REG_END2 };
|
|
|
|
#define REG32_SET(name) \
|
|
union name \
|
|
{ \
|
|
uint32 u32;
|
|
|
|
#define REG64_SET(name) \
|
|
union name \
|
|
{ \
|
|
uint64 u64; \
|
|
uint32 u32[2];
|
|
|
|
#define REG128_SET(name) \
|
|
union name \
|
|
{ \
|
|
__m128i m128; \
|
|
uint64 u64[2]; \
|
|
uint32 u32[4];
|
|
|
|
#define REG_SET_END };
|
|
|
|
REG64_(GSReg, BGCOLOR)
|
|
uint8 R;
|
|
uint8 G;
|
|
uint8 B;
|
|
uint8 _PAD1[5];
|
|
REG_END
|
|
|
|
REG64_(GSReg, BUSDIR)
|
|
uint32 DIR : 1;
|
|
uint32 _PAD1 : 31;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GSReg, CSR)
|
|
uint32 rSIGNAL : 1;
|
|
uint32 rFINISH : 1;
|
|
uint32 rHSINT : 1;
|
|
uint32 rVSINT : 1;
|
|
uint32 rEDWINT : 1;
|
|
uint32 rZERO1 : 1;
|
|
uint32 rZERO2 : 1;
|
|
uint32 r_PAD1 : 1;
|
|
uint32 rFLUSH : 1;
|
|
uint32 rRESET : 1;
|
|
uint32 r_PAD2 : 2;
|
|
uint32 rNFIELD : 1;
|
|
uint32 rFIELD : 1;
|
|
uint32 rFIFO : 2;
|
|
uint32 rREV : 8;
|
|
uint32 rID : 8;
|
|
uint32 wSIGNAL : 1;
|
|
uint32 wFINISH : 1;
|
|
uint32 wHSINT : 1;
|
|
uint32 wVSINT : 1;
|
|
uint32 wEDWINT : 1;
|
|
uint32 wZERO1 : 1;
|
|
uint32 wZERO2 : 1;
|
|
uint32 w_PAD1 : 1;
|
|
uint32 wFLUSH : 1;
|
|
uint32 wRESET : 1;
|
|
uint32 w_PAD2 : 2;
|
|
uint32 wNFIELD : 1;
|
|
uint32 wFIELD : 1;
|
|
uint32 wFIFO : 2;
|
|
uint32 wREV : 8;
|
|
uint32 wID : 8;
|
|
REG_END
|
|
|
|
REG64_(GSReg, DISPFB) // (-1/2)
|
|
uint32 FBP : 9;
|
|
uint32 FBW : 6;
|
|
uint32 PSM : 5;
|
|
uint32 _PAD : 12;
|
|
uint32 DBX : 11;
|
|
uint32 DBY : 11;
|
|
uint32 _PAD2 : 10;
|
|
REG_END2
|
|
uint32 Block() const { return FBP << 5; }
|
|
REG_END2
|
|
|
|
REG64_(GSReg, DISPLAY) // (-1/2)
|
|
uint32 DX : 12;
|
|
uint32 DY : 11;
|
|
uint32 MAGH : 4;
|
|
uint32 MAGV : 2;
|
|
uint32 _PAD : 3;
|
|
uint32 DW : 12;
|
|
uint32 DH : 11;
|
|
uint32 _PAD2 : 9;
|
|
REG_END
|
|
|
|
REG64_(GSReg, EXTBUF)
|
|
uint32 EXBP : 14;
|
|
uint32 EXBW : 6;
|
|
uint32 FBIN : 2;
|
|
uint32 WFFMD : 1;
|
|
uint32 EMODA : 2;
|
|
uint32 EMODC : 2;
|
|
uint32 _PAD1 : 5;
|
|
uint32 WDX : 11;
|
|
uint32 WDY : 11;
|
|
uint32 _PAD2 : 10;
|
|
REG_END
|
|
|
|
REG64_(GSReg, EXTDATA)
|
|
uint32 SX : 12;
|
|
uint32 SY : 11;
|
|
uint32 SMPH : 4;
|
|
uint32 SMPV : 2;
|
|
uint32 _PAD1 : 3;
|
|
uint32 WW : 12;
|
|
uint32 WH : 11;
|
|
uint32 _PAD2 : 9;
|
|
REG_END
|
|
|
|
REG64_(GSReg, EXTWRITE)
|
|
uint32 WRITE : 1;
|
|
uint32 _PAD1 : 31;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GSReg, IMR)
|
|
uint32 _PAD1 : 8;
|
|
uint32 SIGMSK : 1;
|
|
uint32 FINISHMSK : 1;
|
|
uint32 HSMSK : 1;
|
|
uint32 VSMSK : 1;
|
|
uint32 EDWMSK : 1;
|
|
uint32 _PAD2 : 19;
|
|
uint32 _PAD3 : 32;
|
|
REG_END
|
|
|
|
REG64_(GSReg, PMODE)
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32 EN1 : 1;
|
|
uint32 EN2 : 1;
|
|
uint32 CRTMD : 3;
|
|
uint32 MMOD : 1;
|
|
uint32 AMOD : 1;
|
|
uint32 SLBG : 1;
|
|
uint32 ALP : 8;
|
|
uint32 _PAD : 16;
|
|
uint32 _PAD1 : 32;
|
|
};
|
|
|
|
struct
|
|
{
|
|
uint32 EN : 2;
|
|
uint32 _PAD2 : 30;
|
|
uint32 _PAD3 : 32;
|
|
};
|
|
};
|
|
REG_END
|
|
|
|
REG64_(GSReg, SIGLBLID)
|
|
uint32 SIGID;
|
|
uint32 LBLID;
|
|
REG_END
|
|
|
|
REG64_(GSReg, SMODE1)
|
|
uint32 RC : 3;
|
|
uint32 LC : 7;
|
|
uint32 T1248 : 2;
|
|
uint32 SLCK : 1;
|
|
uint32 CMOD : 2;
|
|
uint32 EX : 1;
|
|
uint32 PRST : 1;
|
|
uint32 SINT : 1;
|
|
uint32 XPCK : 1;
|
|
uint32 PCK2 : 2;
|
|
uint32 SPML : 4;
|
|
uint32 GCONT : 1; // YCrCb
|
|
uint32 PHS : 1;
|
|
uint32 PVS : 1;
|
|
uint32 PEHS : 1;
|
|
uint32 PEVS : 1;
|
|
uint32 CLKSEL : 2;
|
|
uint32 NVCK : 1;
|
|
uint32 SLCK2 : 1;
|
|
uint32 VCKSEL : 2;
|
|
uint32 VHP : 1;
|
|
uint32 _PAD1 : 27;
|
|
REG_END
|
|
|
|
/*
|
|
|
|
// pal
|
|
|
|
CLKSEL=1 CMOD=3 EX=0 GCONT=0 LC=32 NVCK=1 PCK2=0 PEHS=0 PEVS=0 PHS=0 PRST=1 PVS=0 RC=4 SINT=0 SLCK=0 SLCK2=1 SPML=4 T1248=1 VCKSEL=1 VHP=0 XPCK=0
|
|
|
|
// ntsc
|
|
|
|
CLKSEL=1 CMOD=2 EX=0 GCONT=0 LC=32 NVCK=1 PCK2=0 PEHS=0 PEVS=0 PHS=0 PRST=1 PVS=0 RC=4 SINT=0 SLCK=0 SLCK2=1 SPML=4 T1248=1 VCKSEL=1 VHP=0 XPCK=0
|
|
|
|
// ntsc progressive (SoTC)
|
|
|
|
CLKSEL=1 CMOD=0 EX=0 GCONT=0 LC=32 NVCK=1 PCK2=0 PEHS=0 PEVS=0 PHS=0 PRST=1 PVS=0 RC=4 SINT=0 SLCK=0 SLCK2=1 SPML=2 T1248=1 VCKSEL=1 VHP=1 XPCK=0
|
|
|
|
*/
|
|
|
|
REG64_(GSReg, SMODE2)
|
|
uint32 INT : 1;
|
|
uint32 FFMD : 1;
|
|
uint32 DPMS : 2;
|
|
uint32 _PAD2 : 28;
|
|
uint32 _PAD3 : 32;
|
|
REG_END
|
|
|
|
REG64_(GSReg, SRFSH)
|
|
uint32 _DUMMY;
|
|
// TODO
|
|
REG_END
|
|
|
|
REG64_(GSReg, SYNCH1)
|
|
uint32 _DUMMY;
|
|
// TODO
|
|
REG_END
|
|
|
|
REG64_(GSReg, SYNCH2)
|
|
uint32 _DUMMY;
|
|
// TODO
|
|
REG_END
|
|
|
|
REG64_(GSReg, SYNCV)
|
|
uint32 VFP : 10; // Vertical Front Porchinterval (?s)
|
|
uint32 VFPE : 10; // Vertical Front Porchinterval End (?s)
|
|
uint32 VBP : 12; // Vertical Back Porchinterval (?s)
|
|
uint32 VBPE : 10; // Vertical Back Porchinterval End (?s)
|
|
uint32 VDP : 11; // Vertical Differential Phase
|
|
uint32 VS : 11; // Vertical Synchronization Timing
|
|
REG_END
|
|
|
|
REG64_SET(GSReg)
|
|
GSRegBGCOLOR BGCOLOR;
|
|
GSRegBUSDIR BUSDIR;
|
|
GSRegCSR CSR;
|
|
GSRegDISPFB DISPFB;
|
|
GSRegDISPLAY DISPLAY;
|
|
GSRegEXTBUF EXTBUF;
|
|
GSRegEXTDATA EXTDATA;
|
|
GSRegEXTWRITE EXTWRITE;
|
|
GSRegIMR IMR;
|
|
GSRegPMODE PMODE;
|
|
GSRegSIGLBLID SIGLBLID;
|
|
GSRegSMODE1 SMODE1;
|
|
GSRegSMODE2 SMODE2;
|
|
REG_SET_END
|
|
|
|
//
|
|
// GIFTag
|
|
|
|
REG128(GIFTag)
|
|
uint32 NLOOP : 15;
|
|
uint32 EOP : 1;
|
|
uint32 _PAD1 : 16;
|
|
uint32 _PAD2 : 14;
|
|
uint32 PRE : 1;
|
|
uint32 PRIM : 11;
|
|
uint32 FLG : 2; // enum GIF_FLG
|
|
uint32 NREG : 4;
|
|
uint64 REGS;
|
|
REG_END
|
|
|
|
// GIFReg
|
|
|
|
REG64_(GIFReg, ALPHA)
|
|
uint32 A : 2;
|
|
uint32 B : 2;
|
|
uint32 C : 2;
|
|
uint32 D : 2;
|
|
uint32 _PAD1 : 24;
|
|
uint8 FIX;
|
|
uint8 _PAD2[3];
|
|
REG_END2
|
|
// opaque => output will be Cs/As
|
|
__forceinline bool IsOpaque() const { return ((A == B || (C == 2 && FIX == 0)) && D == 0) || (A == 0 && B == D && C == 2 && FIX == 0x80); }
|
|
__forceinline bool IsOpaque(int amin, int amax) const { return ((A == B || amax == 0) && D == 0) || (A == 0 && B == D && amin == 0x80 && amax == 0x80); }
|
|
__forceinline bool IsCd() { return (A == B) && (D == 1); }
|
|
REG_END2
|
|
|
|
REG64_(GIFReg, BITBLTBUF)
|
|
uint32 SBP : 14;
|
|
uint32 _PAD1 : 2;
|
|
uint32 SBW : 6;
|
|
uint32 _PAD2 : 2;
|
|
uint32 SPSM : 6;
|
|
uint32 _PAD3 : 2;
|
|
uint32 DBP : 14;
|
|
uint32 _PAD4 : 2;
|
|
uint32 DBW : 6;
|
|
uint32 _PAD5 : 2;
|
|
uint32 DPSM : 6;
|
|
uint32 _PAD6 : 2;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, CLAMP)
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32 WMS : 2;
|
|
uint32 WMT : 2;
|
|
uint32 MINU : 10;
|
|
uint32 MAXU : 10;
|
|
uint32 _PAD1 : 8;
|
|
uint32 _PAD2 : 2;
|
|
uint32 MAXV : 10;
|
|
uint32 _PAD3 : 20;
|
|
};
|
|
|
|
struct
|
|
{
|
|
uint64 _PAD4 : 24;
|
|
uint64 MINV : 10;
|
|
uint64 _PAD5 : 30;
|
|
};
|
|
};
|
|
REG_END
|
|
|
|
REG64_(GIFReg, COLCLAMP)
|
|
uint32 CLAMP : 1;
|
|
uint32 _PAD1 : 31;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, DIMX)
|
|
int32 DM00 : 3;
|
|
int32 _PAD00 : 1;
|
|
int32 DM01 : 3;
|
|
int32 _PAD01 : 1;
|
|
int32 DM02 : 3;
|
|
int32 _PAD02 : 1;
|
|
int32 DM03 : 3;
|
|
int32 _PAD03 : 1;
|
|
int32 DM10 : 3;
|
|
int32 _PAD10 : 1;
|
|
int32 DM11 : 3;
|
|
int32 _PAD11 : 1;
|
|
int32 DM12 : 3;
|
|
int32 _PAD12 : 1;
|
|
int32 DM13 : 3;
|
|
int32 _PAD13 : 1;
|
|
int32 DM20 : 3;
|
|
int32 _PAD20 : 1;
|
|
int32 DM21 : 3;
|
|
int32 _PAD21 : 1;
|
|
int32 DM22 : 3;
|
|
int32 _PAD22 : 1;
|
|
int32 DM23 : 3;
|
|
int32 _PAD23 : 1;
|
|
int32 DM30 : 3;
|
|
int32 _PAD30 : 1;
|
|
int32 DM31 : 3;
|
|
int32 _PAD31 : 1;
|
|
int32 DM32 : 3;
|
|
int32 _PAD32 : 1;
|
|
int32 DM33 : 3;
|
|
int32 _PAD33 : 1;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, DTHE)
|
|
uint32 DTHE : 1;
|
|
uint32 _PAD1 : 31;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, FBA)
|
|
uint32 FBA : 1;
|
|
uint32 _PAD1 : 31;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, FINISH)
|
|
uint32 _PAD1[2];
|
|
REG_END
|
|
|
|
REG64_(GIFReg, FOG)
|
|
uint8 _PAD1[7];
|
|
uint8 F;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, FOGCOL)
|
|
uint8 FCR;
|
|
uint8 FCG;
|
|
uint8 FCB;
|
|
uint8 _PAD1[5];
|
|
REG_END
|
|
|
|
REG64_(GIFReg, FRAME)
|
|
uint32 FBP : 9;
|
|
uint32 _PAD1 : 7;
|
|
uint32 FBW : 6;
|
|
uint32 _PAD2 : 2;
|
|
uint32 PSM : 6;
|
|
uint32 _PAD3 : 2;
|
|
uint32 FBMSK;
|
|
REG_END2
|
|
uint32 Block() const { return FBP << 5; }
|
|
REG_END2
|
|
|
|
REG64_(GIFReg, HWREG)
|
|
uint32 DATA_LOWER;
|
|
uint32 DATA_UPPER;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, LABEL)
|
|
uint32 ID;
|
|
uint32 IDMSK;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, MIPTBP1)
|
|
uint64 TBP1 : 14;
|
|
uint64 TBW1 : 6;
|
|
uint64 TBP2 : 14;
|
|
uint64 TBW2 : 6;
|
|
uint64 TBP3 : 14;
|
|
uint64 TBW3 : 6;
|
|
uint64 _PAD : 4;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, MIPTBP2)
|
|
uint64 TBP4 : 14;
|
|
uint64 TBW4 : 6;
|
|
uint64 TBP5 : 14;
|
|
uint64 TBW5 : 6;
|
|
uint64 TBP6 : 14;
|
|
uint64 TBW6 : 6;
|
|
uint64 _PAD : 4;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, NOP)
|
|
uint32 _PAD[2];
|
|
REG_END
|
|
|
|
REG64_(GIFReg, PABE)
|
|
uint32 PABE : 1;
|
|
uint32 _PAD1 : 31;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, PRIM)
|
|
uint32 PRIM : 3;
|
|
uint32 IIP : 1;
|
|
uint32 TME : 1;
|
|
uint32 FGE : 1;
|
|
uint32 ABE : 1;
|
|
uint32 AA1 : 1;
|
|
uint32 FST : 1;
|
|
uint32 CTXT : 1;
|
|
uint32 FIX : 1;
|
|
uint32 _PAD1 : 21;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, PRMODE)
|
|
uint32 _PRIM : 3;
|
|
uint32 IIP : 1;
|
|
uint32 TME : 1;
|
|
uint32 FGE : 1;
|
|
uint32 ABE : 1;
|
|
uint32 AA1 : 1;
|
|
uint32 FST : 1;
|
|
uint32 CTXT : 1;
|
|
uint32 FIX : 1;
|
|
uint32 _PAD2 : 21;
|
|
uint32 _PAD3 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, PRMODECONT)
|
|
uint32 AC : 1;
|
|
uint32 _PAD1 : 31;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, RGBAQ)
|
|
uint8 R;
|
|
uint8 G;
|
|
uint8 B;
|
|
uint8 A;
|
|
float Q;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, SCANMSK)
|
|
uint32 MSK : 2;
|
|
uint32 _PAD1 : 30;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, SCISSOR)
|
|
uint32 SCAX0 : 11;
|
|
uint32 _PAD1 : 5;
|
|
uint32 SCAX1 : 11;
|
|
uint32 _PAD2 : 5;
|
|
uint32 SCAY0 : 11;
|
|
uint32 _PAD3 : 5;
|
|
uint32 SCAY1 : 11;
|
|
uint32 _PAD4 : 5;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, SIGNAL)
|
|
uint32 ID;
|
|
uint32 IDMSK;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, ST)
|
|
float S;
|
|
float T;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, TEST)
|
|
uint32 ATE : 1;
|
|
uint32 ATST : 3;
|
|
uint32 AREF : 8;
|
|
uint32 AFAIL : 2;
|
|
uint32 DATE : 1;
|
|
uint32 DATM : 1;
|
|
uint32 ZTE : 1;
|
|
uint32 ZTST : 2;
|
|
uint32 _PAD1 : 13;
|
|
uint32 _PAD2 : 32;
|
|
REG_END2
|
|
__forceinline bool DoFirstPass() const { return !ATE || ATST != ATST_NEVER; } // not all pixels fail automatically
|
|
__forceinline bool DoSecondPass() const { return ATE && ATST != ATST_ALWAYS && AFAIL != AFAIL_KEEP; } // pixels may fail, write fb/z
|
|
__forceinline bool NoSecondPass() const { return ATE && ATST != ATST_ALWAYS && AFAIL == AFAIL_KEEP; } // pixels may fail, no output
|
|
REG_END2
|
|
|
|
REG64_(GIFReg, TEX0)
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32 TBP0 : 14;
|
|
uint32 TBW : 6;
|
|
uint32 PSM : 6;
|
|
uint32 TW : 4;
|
|
uint32 _PAD1 : 2;
|
|
uint32 _PAD2 : 2;
|
|
uint32 TCC : 1;
|
|
uint32 TFX : 2;
|
|
uint32 CBP : 14;
|
|
uint32 CPSM : 4;
|
|
uint32 CSM : 1;
|
|
uint32 CSA : 5;
|
|
uint32 CLD : 3;
|
|
};
|
|
|
|
struct
|
|
{
|
|
uint64 _PAD3 : 30;
|
|
uint64 TH : 4;
|
|
uint64 _PAD4 : 30;
|
|
};
|
|
};
|
|
REG_END2
|
|
__forceinline bool IsRepeating() const
|
|
{
|
|
if (TBW < 2)
|
|
{
|
|
if (PSM == PSM_PSMT8)
|
|
return TW > 7 || TH > 6;
|
|
if (PSM == PSM_PSMT4)
|
|
return TW > 7 || TH > 7;
|
|
}
|
|
|
|
// The recast of TBW seems useless but it avoid tons of warning from GCC...
|
|
return ((uint32)TBW << 6u) < (1u << TW);
|
|
}
|
|
REG_END2
|
|
|
|
REG64_(GIFReg, TEX1)
|
|
uint32 LCM : 1;
|
|
uint32 _PAD1 : 1;
|
|
uint32 MXL : 3;
|
|
uint32 MMAG : 1;
|
|
uint32 MMIN : 3;
|
|
uint32 MTBA : 1;
|
|
uint32 _PAD2 : 9;
|
|
uint32 L : 2;
|
|
uint32 _PAD3 : 11;
|
|
int32 K : 12; // 1:7:4
|
|
uint32 _PAD4 : 20;
|
|
REG_END2
|
|
bool IsMinLinear() const { return (MMIN == 1) || (MMIN & 4); }
|
|
bool IsMagLinear() const { return MMAG; }
|
|
REG_END2
|
|
|
|
REG64_(GIFReg, TEX2)
|
|
uint32 _PAD1 : 20;
|
|
uint32 PSM : 6;
|
|
uint32 _PAD2 : 6;
|
|
uint32 _PAD3 : 5;
|
|
uint32 CBP : 14;
|
|
uint32 CPSM : 4;
|
|
uint32 CSM : 1;
|
|
uint32 CSA : 5;
|
|
uint32 CLD : 3;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, TEXA)
|
|
uint8 TA0;
|
|
uint8 _PAD1 : 7;
|
|
uint8 AEM : 1;
|
|
uint16 _PAD2;
|
|
uint8 TA1 : 8;
|
|
uint8 _PAD3[3];
|
|
REG_END
|
|
|
|
REG64_(GIFReg, TEXCLUT)
|
|
uint32 CBW : 6;
|
|
uint32 COU : 6;
|
|
uint32 COV : 10;
|
|
uint32 _PAD1 : 10;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, TEXFLUSH)
|
|
uint32 _PAD1 : 32;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, TRXDIR)
|
|
uint32 XDIR : 2;
|
|
uint32 _PAD1 : 30;
|
|
uint32 _PAD2 : 32;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, TRXPOS)
|
|
uint32 SSAX : 11;
|
|
uint32 _PAD1 : 5;
|
|
uint32 SSAY : 11;
|
|
uint32 _PAD2 : 5;
|
|
uint32 DSAX : 11;
|
|
uint32 _PAD3 : 5;
|
|
uint32 DSAY : 11;
|
|
uint32 DIRY : 1;
|
|
uint32 DIRX : 1;
|
|
uint32 _PAD4 : 3;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, TRXREG)
|
|
uint32 RRW : 12;
|
|
uint32 _PAD1 : 20;
|
|
uint32 RRH : 12;
|
|
uint32 _PAD2 : 20;
|
|
REG_END
|
|
|
|
// GSState::GIFPackedRegHandlerUV and GSState::GIFRegHandlerUV will make sure that the _PAD1/2 bits are set to zero
|
|
|
|
REG64_(GIFReg, UV)
|
|
uint16 U;
|
|
// uint32 _PAD1 : 2;
|
|
uint16 V;
|
|
// uint32 _PAD2 : 2;
|
|
uint32 _PAD3;
|
|
REG_END
|
|
|
|
// GSState::GIFRegHandlerXYOFFSET will make sure that the _PAD1/2 bits are set to zero
|
|
|
|
REG64_(GIFReg, XYOFFSET)
|
|
uint32 OFX; // : 16; uint32 _PAD1 : 16;
|
|
uint32 OFY; // : 16; uint32 _PAD2 : 16;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, XYZ)
|
|
uint16 X;
|
|
uint16 Y;
|
|
uint32 Z;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, XYZF)
|
|
uint16 X;
|
|
uint16 Y;
|
|
uint32 Z : 24;
|
|
uint32 F : 8;
|
|
REG_END
|
|
|
|
REG64_(GIFReg, ZBUF)
|
|
uint32 ZBP : 9;
|
|
uint32 _PAD1 : 15;
|
|
// uint32 PSM : 4;
|
|
// uint32 _PAD2 : 4;
|
|
uint32 PSM : 6;
|
|
uint32 _PAD2 : 2;
|
|
uint32 ZMSK : 1;
|
|
uint32 _PAD3 : 31;
|
|
REG_END2
|
|
uint32 Block() const { return ZBP << 5; }
|
|
REG_END2
|
|
|
|
REG64_SET(GIFReg)
|
|
GIFRegALPHA ALPHA;
|
|
GIFRegBITBLTBUF BITBLTBUF;
|
|
GIFRegCLAMP CLAMP;
|
|
GIFRegCOLCLAMP COLCLAMP;
|
|
GIFRegDIMX DIMX;
|
|
GIFRegDTHE DTHE;
|
|
GIFRegFBA FBA;
|
|
GIFRegFINISH FINISH;
|
|
GIFRegFOG FOG;
|
|
GIFRegFOGCOL FOGCOL;
|
|
GIFRegFRAME FRAME;
|
|
GIFRegHWREG HWREG;
|
|
GIFRegLABEL LABEL;
|
|
GIFRegMIPTBP1 MIPTBP1;
|
|
GIFRegMIPTBP2 MIPTBP2;
|
|
GIFRegNOP NOP;
|
|
GIFRegPABE PABE;
|
|
GIFRegPRIM PRIM;
|
|
GIFRegPRMODE PRMODE;
|
|
GIFRegPRMODECONT PRMODECONT;
|
|
GIFRegRGBAQ RGBAQ;
|
|
GIFRegSCANMSK SCANMSK;
|
|
GIFRegSCISSOR SCISSOR;
|
|
GIFRegSIGNAL SIGNAL;
|
|
GIFRegST ST;
|
|
GIFRegTEST TEST;
|
|
GIFRegTEX0 TEX0;
|
|
GIFRegTEX1 TEX1;
|
|
GIFRegTEX2 TEX2;
|
|
GIFRegTEXA TEXA;
|
|
GIFRegTEXCLUT TEXCLUT;
|
|
GIFRegTEXFLUSH TEXFLUSH;
|
|
GIFRegTRXDIR TRXDIR;
|
|
GIFRegTRXPOS TRXPOS;
|
|
GIFRegTRXREG TRXREG;
|
|
GIFRegUV UV;
|
|
GIFRegXYOFFSET XYOFFSET;
|
|
GIFRegXYZ XYZ;
|
|
GIFRegXYZF XYZF;
|
|
GIFRegZBUF ZBUF;
|
|
REG_SET_END
|
|
|
|
// GIFPacked
|
|
|
|
REG128_(GIFPacked, PRIM)
|
|
uint32 PRIM : 11;
|
|
uint32 _PAD1 : 21;
|
|
uint32 _PAD2[3];
|
|
REG_END
|
|
|
|
REG128_(GIFPacked, RGBA)
|
|
uint8 R;
|
|
uint8 _PAD1[3];
|
|
uint8 G;
|
|
uint8 _PAD2[3];
|
|
uint8 B;
|
|
uint8 _PAD3[3];
|
|
uint8 A;
|
|
uint8 _PAD4[3];
|
|
REG_END
|
|
|
|
REG128_(GIFPacked, STQ)
|
|
float S;
|
|
float T;
|
|
float Q;
|
|
uint32 _PAD1 : 32;
|
|
REG_END
|
|
|
|
REG128_(GIFPacked, UV)
|
|
uint32 U : 14;
|
|
uint32 _PAD1 : 18;
|
|
uint32 V : 14;
|
|
uint32 _PAD2 : 18;
|
|
uint32 _PAD3 : 32;
|
|
uint32 _PAD4 : 32;
|
|
REG_END
|
|
|
|
REG128_(GIFPacked, XYZF2)
|
|
uint16 X;
|
|
uint16 _PAD1;
|
|
uint16 Y;
|
|
uint16 _PAD2;
|
|
uint32 _PAD3 : 4;
|
|
uint32 Z : 24;
|
|
uint32 _PAD4 : 4;
|
|
uint32 _PAD5 : 4;
|
|
uint32 F : 8;
|
|
uint32 _PAD6 : 3;
|
|
uint32 ADC : 1;
|
|
uint32 _PAD7 : 16;
|
|
REG_END2
|
|
uint32 Skip() const { return u32[3] & 0x8000; }
|
|
REG_END2
|
|
|
|
REG128_(GIFPacked, XYZ2)
|
|
uint16 X;
|
|
uint16 _PAD1;
|
|
uint16 Y;
|
|
uint16 _PAD2;
|
|
uint32 Z;
|
|
uint32 _PAD3 : 15;
|
|
uint32 ADC : 1;
|
|
uint32 _PAD4 : 16;
|
|
REG_END2
|
|
uint32 Skip() const { return u32[3] & 0x8000; }
|
|
REG_END2
|
|
|
|
REG128_(GIFPacked, FOG)
|
|
uint32 _PAD1;
|
|
uint32 _PAD2;
|
|
uint32 _PAD3;
|
|
uint32 _PAD4 : 4;
|
|
uint32 F : 8;
|
|
uint32 _PAD5 : 20;
|
|
REG_END
|
|
|
|
REG128_(GIFPacked, A_D)
|
|
uint64 DATA;
|
|
uint8 ADDR : 8; // enum GIF_A_D_REG
|
|
uint8 _PAD1[3 + 4];
|
|
REG_END
|
|
|
|
REG128_(GIFPacked, NOP)
|
|
uint32 _PAD1;
|
|
uint32 _PAD2;
|
|
uint32 _PAD3;
|
|
uint32 _PAD4;
|
|
REG_END
|
|
|
|
REG128_SET(GIFPackedReg)
|
|
GIFReg r;
|
|
GIFPackedPRIM PRIM;
|
|
GIFPackedRGBA RGBA;
|
|
GIFPackedSTQ STQ;
|
|
GIFPackedUV UV;
|
|
GIFPackedXYZF2 XYZF2;
|
|
GIFPackedXYZ2 XYZ2;
|
|
GIFPackedFOG FOG;
|
|
GIFPackedA_D A_D;
|
|
GIFPackedNOP NOP;
|
|
REG_SET_END
|
|
|
|
struct alignas(32) GIFPath
|
|
{
|
|
GIFTag tag;
|
|
uint32 nloop;
|
|
uint32 nreg;
|
|
uint32 reg;
|
|
uint32 type;
|
|
GSVector4i regs;
|
|
|
|
enum
|
|
{
|
|
TYPE_UNKNOWN,
|
|
TYPE_ADONLY,
|
|
TYPE_STQRGBAXYZF2,
|
|
TYPE_STQRGBAXYZ2
|
|
};
|
|
|
|
__forceinline void SetTag(const void* mem)
|
|
{
|
|
const GIFTag* RESTRICT src = (const GIFTag*)mem;
|
|
|
|
// the compiler has a hard time not reloading every time a field of src is accessed
|
|
|
|
uint32 a = src->u32[0];
|
|
uint32 b = src->u32[1];
|
|
|
|
tag.u32[0] = a;
|
|
tag.u32[1] = b;
|
|
|
|
nloop = a & 0x7fff;
|
|
|
|
if (nloop == 0)
|
|
return;
|
|
|
|
GSVector4i v = GSVector4i::loadl(&src->REGS); // REGS not stored to tag.REGS, only into this->regs, restored before saving the state though
|
|
|
|
nreg = (b & 0xf0000000) ? (b >> 28) : 16; // src->NREG
|
|
regs = v.upl8(v >> 4) & GSVector4i::x0f(nreg);
|
|
reg = 0;
|
|
|
|
type = TYPE_UNKNOWN;
|
|
|
|
if (tag.FLG == GIF_FLG_PACKED)
|
|
{
|
|
if (regs.eq8(GSVector4i(0x0e0e0e0e)).mask() == (1 << nreg) - 1)
|
|
{
|
|
type = TYPE_ADONLY;
|
|
}
|
|
else
|
|
{
|
|
switch (nreg)
|
|
{
|
|
case 1:
|
|
break;
|
|
case 2:
|
|
break;
|
|
case 3:
|
|
// many games, TODO: formats mixed with NOPs (xeno2: 040f010f02, 04010f020f, mgs3: 04010f0f02, 0401020f0f, 04010f020f)
|
|
if (regs.u32[0] == 0x00040102)
|
|
type = TYPE_STQRGBAXYZF2;
|
|
// GoW (has other crazy formats, like ...030503050103)
|
|
if (regs.u32[0] == 0x00050102)
|
|
type = TYPE_STQRGBAXYZ2;
|
|
// TODO: common types with UV instead
|
|
break;
|
|
case 4:
|
|
break;
|
|
case 5:
|
|
break;
|
|
case 6:
|
|
break;
|
|
case 7:
|
|
break;
|
|
case 8:
|
|
break;
|
|
case 9:
|
|
// ffx
|
|
if (regs.u32[0] == 0x02040102 && regs.u32[1] == 0x01020401 && regs.u32[2] == 0x00000004)
|
|
{
|
|
type = TYPE_STQRGBAXYZF2;
|
|
nreg = 3;
|
|
nloop *= 3;
|
|
}
|
|
break;
|
|
case 10:
|
|
break;
|
|
case 11:
|
|
break;
|
|
case 12:
|
|
// dq8 (not many, mostly 040102)
|
|
if (regs.u32[0] == 0x02040102 && regs.u32[1] == 0x01020401 && regs.u32[2] == 0x04010204)
|
|
{
|
|
type = TYPE_STQRGBAXYZF2;
|
|
nreg = 3;
|
|
nloop *= 4;
|
|
}
|
|
break;
|
|
case 13:
|
|
break;
|
|
case 14:
|
|
break;
|
|
case 15:
|
|
break;
|
|
case 16:
|
|
break;
|
|
default:
|
|
__assume(0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
__forceinline uint8 GetReg() const
|
|
{
|
|
return regs.u8[reg];
|
|
}
|
|
|
|
__forceinline uint8 GetReg(uint32 index) const
|
|
{
|
|
return regs.u8[index];
|
|
}
|
|
|
|
__forceinline bool StepReg()
|
|
{
|
|
if (++reg == nreg)
|
|
{
|
|
reg = 0;
|
|
|
|
if (--nloop == 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
struct GSPrivRegSet
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
GSRegPMODE PMODE;
|
|
uint64 _pad1;
|
|
GSRegSMODE1 SMODE1;
|
|
uint64 _pad2;
|
|
GSRegSMODE2 SMODE2;
|
|
uint64 _pad3;
|
|
GSRegSRFSH SRFSH;
|
|
uint64 _pad4;
|
|
GSRegSYNCH1 SYNCH1;
|
|
uint64 _pad5;
|
|
GSRegSYNCH2 SYNCH2;
|
|
uint64 _pad6;
|
|
GSRegSYNCV SYNCV;
|
|
uint64 _pad7;
|
|
struct
|
|
{
|
|
GSRegDISPFB DISPFB;
|
|
uint64 _pad1;
|
|
GSRegDISPLAY DISPLAY;
|
|
uint64 _pad2;
|
|
} DISP[2];
|
|
GSRegEXTBUF EXTBUF;
|
|
uint64 _pad8;
|
|
GSRegEXTDATA EXTDATA;
|
|
uint64 _pad9;
|
|
GSRegEXTWRITE EXTWRITE;
|
|
uint64 _pad10;
|
|
GSRegBGCOLOR BGCOLOR;
|
|
uint64 _pad11;
|
|
};
|
|
|
|
uint8 _pad12[0x1000];
|
|
};
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
GSRegCSR CSR;
|
|
uint64 _pad13;
|
|
GSRegIMR IMR;
|
|
uint64 _pad14;
|
|
uint64 _unk1[4];
|
|
GSRegBUSDIR BUSDIR;
|
|
uint64 _pad15;
|
|
uint64 _unk2[6];
|
|
GSRegSIGLBLID SIGLBLID;
|
|
uint64 _pad16;
|
|
};
|
|
|
|
uint8 _pad17[0x1000];
|
|
};
|
|
|
|
void Dump(FILE* fp)
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
if (!fp)
|
|
return;
|
|
|
|
if (i == 0 && !PMODE.EN1)
|
|
continue;
|
|
if (i == 1 && !PMODE.EN2)
|
|
continue;
|
|
|
|
fprintf(fp, "DISPFB[%d] BP=%05x BW=%u PSM=%u DBX=%u DBY=%u\n",
|
|
i,
|
|
DISP[i].DISPFB.Block(),
|
|
DISP[i].DISPFB.FBW,
|
|
DISP[i].DISPFB.PSM,
|
|
DISP[i].DISPFB.DBX,
|
|
DISP[i].DISPFB.DBY);
|
|
|
|
fprintf(fp, "DISPLAY[%d] DX=%u DY=%u DW=%u DH=%u MAGH=%u MAGV=%u\n",
|
|
i,
|
|
DISP[i].DISPLAY.DX,
|
|
DISP[i].DISPLAY.DY,
|
|
DISP[i].DISPLAY.DW,
|
|
DISP[i].DISPLAY.DH,
|
|
DISP[i].DISPLAY.MAGH,
|
|
DISP[i].DISPLAY.MAGV);
|
|
}
|
|
|
|
fprintf(fp, "PMODE EN1=%u EN2=%u CRTMD=%u MMOD=%u AMOD=%u SLBG=%u ALP=%u\n",
|
|
PMODE.EN1,
|
|
PMODE.EN2,
|
|
PMODE.CRTMD,
|
|
PMODE.MMOD,
|
|
PMODE.AMOD,
|
|
PMODE.SLBG,
|
|
PMODE.ALP);
|
|
|
|
fprintf(fp, "SMODE1 CLKSEL=%u CMOD=%u EX=%u GCONT=%u LC=%u NVCK=%u PCK2=%u PEHS=%u PEVS=%u PHS=%u PRST=%u PVS=%u RC=%u SINT=%u SLCK=%u SLCK2=%u SPML=%u T1248=%u VCKSEL=%u VHP=%u XPCK=%u\n",
|
|
SMODE1.CLKSEL,
|
|
SMODE1.CMOD,
|
|
SMODE1.EX,
|
|
SMODE1.GCONT,
|
|
SMODE1.LC,
|
|
SMODE1.NVCK,
|
|
SMODE1.PCK2,
|
|
SMODE1.PEHS,
|
|
SMODE1.PEVS,
|
|
SMODE1.PHS,
|
|
SMODE1.PRST,
|
|
SMODE1.PVS,
|
|
SMODE1.RC,
|
|
SMODE1.SINT,
|
|
SMODE1.SLCK,
|
|
SMODE1.SLCK2,
|
|
SMODE1.SPML,
|
|
SMODE1.T1248,
|
|
SMODE1.VCKSEL,
|
|
SMODE1.VHP,
|
|
SMODE1.XPCK);
|
|
|
|
fprintf(fp, "SMODE2 INT=%u FFMD=%u DPMS=%u\n",
|
|
SMODE2.INT,
|
|
SMODE2.FFMD,
|
|
SMODE2.DPMS);
|
|
|
|
fprintf(fp, "SRFSH %08x_%08x\n",
|
|
SRFSH.u32[0],
|
|
SRFSH.u32[1]);
|
|
|
|
fprintf(fp, "SYNCH1 %08x_%08x\n",
|
|
SYNCH1.u32[0],
|
|
SYNCH1.u32[1]);
|
|
|
|
fprintf(fp, "SYNCH2 %08x_%08x\n",
|
|
SYNCH2.u32[0],
|
|
SYNCH2.u32[1]);
|
|
|
|
fprintf(fp, "SYNCV VBP=%u VBPE=%u VDP=%u VFP=%u VFPE=%u VS=%u\n",
|
|
SYNCV.VBP,
|
|
SYNCV.VBPE,
|
|
SYNCV.VDP,
|
|
SYNCV.VFP,
|
|
SYNCV.VFPE,
|
|
SYNCV.VS);
|
|
|
|
fprintf(fp, "CSR %08x_%08x\n",
|
|
CSR.u32[0],
|
|
CSR.u32[1]);
|
|
|
|
fprintf(fp, "BGCOLOR B=%u G=%u R=%u\n",
|
|
BGCOLOR.B,
|
|
BGCOLOR.G,
|
|
BGCOLOR.R);
|
|
|
|
fprintf(fp, "EXTBUF BP=0x%x BW=%u FBIN=%u WFFMD=%u EMODA=%u EMODC=%u WDX=%u WDY=%u\n",
|
|
EXTBUF.EXBP, EXTBUF.EXBW, EXTBUF.FBIN, EXTBUF.WFFMD,
|
|
EXTBUF.EMODA, EXTBUF.EMODC, EXTBUF.WDX, EXTBUF.WDY);
|
|
|
|
fprintf(fp, "EXTDATA SX=%u SY=%u SMPH=%u SMPV=%u WW=%u WH=%u\n",
|
|
EXTDATA.SX, EXTDATA.SY, EXTDATA.SMPH, EXTDATA.SMPV, EXTDATA.WW, EXTDATA.WH);
|
|
|
|
fprintf(fp, "EXTWRITE EN=%u\n", EXTWRITE.WRITE);
|
|
}
|
|
|
|
void Dump(const std::string& filename)
|
|
{
|
|
FILE* fp = fopen(filename.c_str(), "wt");
|
|
if (fp)
|
|
{
|
|
Dump(fp);
|
|
fclose(fp);
|
|
}
|
|
}
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
enum
|
|
{
|
|
KEYPRESS = 1,
|
|
KEYRELEASE = 2
|
|
};
|
|
struct GSKeyEventData
|
|
{
|
|
uint32 key, type;
|
|
};
|
|
|
|
enum
|
|
{
|
|
FREEZE_LOAD = 0,
|
|
FREEZE_SAVE = 1,
|
|
FREEZE_SIZE = 2
|
|
};
|
|
struct GSFreezeData
|
|
{
|
|
int size;
|
|
uint8* data;
|
|
};
|
|
|
|
enum stateType
|
|
{
|
|
ST_WRITE,
|
|
ST_TRANSFER,
|
|
ST_VSYNC
|
|
};
|
|
|
|
enum class GSVideoMode : uint8
|
|
{
|
|
Unknown,
|
|
NTSC,
|
|
PAL,
|
|
VESA,
|
|
SDTV_480P,
|
|
HDTV_720P,
|
|
HDTV_1080I
|
|
};
|
|
|
|
// Ordering was done to keep compatibility with older ini file.
|
|
enum class BiFiltering : uint8
|
|
{
|
|
Nearest,
|
|
Forced,
|
|
PS2,
|
|
Forced_But_Sprite,
|
|
};
|
|
|
|
enum class TriFiltering : uint8
|
|
{
|
|
None,
|
|
PS2,
|
|
Forced,
|
|
};
|
|
|
|
enum class HWMipmapLevel : int
|
|
{
|
|
Automatic = -1,
|
|
Off,
|
|
Basic,
|
|
Full
|
|
};
|
|
|
|
enum class CRCHackLevel : int8
|
|
{
|
|
Automatic = -1,
|
|
None,
|
|
Minimum,
|
|
Partial,
|
|
Full,
|
|
Aggressive
|
|
};
|
|
|
|
#ifdef ENABLE_ACCURATE_BUFFER_EMULATION
|
|
const GSVector2i default_rt_size(2048, 2048);
|
|
#else
|
|
const GSVector2i default_rt_size(1280, 1024);
|
|
#endif
|