/* * 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, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #pragma once #include "GS.h" #include "GSLocalMemory.h" #include "GSDrawingContext.h" #include "GSDrawingEnvironment.h" #include "GSVertex.h" #include "GSVertexList.h" #include "GSUtil.h" #include "GSDirtyRect.h" #include "GSPerfMon.h" #include "GSVector.h" #include "GSDevice.h" #include "GSCrc.h" #include "GSAlignedClass.h" #include "GSDump.h" class GSState : public GSAlignedClass<16> { typedef void (GSState::*GIFPackedRegHandler)(GIFPackedReg* r); GIFPackedRegHandler m_fpGIFPackedRegHandlers[16]; void GIFPackedRegHandlerNull(GIFPackedReg* r); void GIFPackedRegHandlerPRIM(GIFPackedReg* r); void GIFPackedRegHandlerRGBA(GIFPackedReg* r); void GIFPackedRegHandlerSTQ(GIFPackedReg* r); void GIFPackedRegHandlerUV(GIFPackedReg* r); void GIFPackedRegHandlerXYZF2(GIFPackedReg* r); void GIFPackedRegHandlerXYZ2(GIFPackedReg* r); template void GIFPackedRegHandlerTEX0(GIFPackedReg* r); template void GIFPackedRegHandlerCLAMP(GIFPackedReg* r); void GIFPackedRegHandlerFOG(GIFPackedReg* r); void GIFPackedRegHandlerXYZF3(GIFPackedReg* r); void GIFPackedRegHandlerXYZ3(GIFPackedReg* r); void GIFPackedRegHandlerA_D(GIFPackedReg* r); void GIFPackedRegHandlerNOP(GIFPackedReg* r); typedef void (GSState::*GIFRegHandler)(GIFReg* r); GIFRegHandler m_fpGIFRegHandlers[256]; void GIFRegHandlerNull(GIFReg* r); void GIFRegHandlerPRIM(GIFReg* r); void GIFRegHandlerRGBAQ(GIFReg* r); void GIFRegHandlerST(GIFReg* r); void GIFRegHandlerUV(GIFReg* r); void GIFRegHandlerXYZF2(GIFReg* r); void GIFRegHandlerXYZ2(GIFReg* r); template void GIFRegHandlerTEX0(GIFReg* r); template void GIFRegHandlerCLAMP(GIFReg* r); void GIFRegHandlerFOG(GIFReg* r); void GIFRegHandlerXYZF3(GIFReg* r); void GIFRegHandlerXYZ3(GIFReg* r); void GIFRegHandlerNOP(GIFReg* r); template void GIFRegHandlerTEX1(GIFReg* r); template void GIFRegHandlerTEX2(GIFReg* r); template void GIFRegHandlerXYOFFSET(GIFReg* r); void GIFRegHandlerPRMODECONT(GIFReg* r); void GIFRegHandlerPRMODE(GIFReg* r); void GIFRegHandlerTEXCLUT(GIFReg* r); void GIFRegHandlerSCANMSK(GIFReg* r); template void GIFRegHandlerMIPTBP1(GIFReg* r); template void GIFRegHandlerMIPTBP2(GIFReg* r); void GIFRegHandlerTEXA(GIFReg* r); void GIFRegHandlerFOGCOL(GIFReg* r); void GIFRegHandlerTEXFLUSH(GIFReg* r); template void GIFRegHandlerSCISSOR(GIFReg* r); template void GIFRegHandlerALPHA(GIFReg* r); void GIFRegHandlerDIMX(GIFReg* r); void GIFRegHandlerDTHE(GIFReg* r); void GIFRegHandlerCOLCLAMP(GIFReg* r); template void GIFRegHandlerTEST(GIFReg* r); void GIFRegHandlerPABE(GIFReg* r); template void GIFRegHandlerFBA(GIFReg* r); template void GIFRegHandlerFRAME(GIFReg* r); template void GIFRegHandlerZBUF(GIFReg* r); void GIFRegHandlerBITBLTBUF(GIFReg* r); void GIFRegHandlerTRXPOS(GIFReg* r); void GIFRegHandlerTRXREG(GIFReg* r); void GIFRegHandlerTRXDIR(GIFReg* r); void GIFRegHandlerHWREG(GIFReg* r); void GIFRegHandlerSIGNAL(GIFReg* r); void GIFRegHandlerFINISH(GIFReg* r); void GIFRegHandlerLABEL(GIFReg* r); int m_version; int m_sssize; bool m_mt; void (*m_irq)(); bool m_path3hack; struct GSTransferBuffer { int x, y; int start, end, total; bool overflow; uint8* buff; GSTransferBuffer(); virtual ~GSTransferBuffer(); void Init(int tx, int ty); bool Update(int tw, int th, int bpp, int& len); } m_tr; void FlushWrite(); protected: bool IsBadFrame(int& skip); typedef void (GSState::*VertexKickPtr)(bool skip); VertexKickPtr m_vk[8][2][2]; VertexKickPtr m_vkf; template void InitVertexKick() { m_vk[GS_POINTLIST][0][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_POINTLIST][0][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_POINTLIST][1][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_POINTLIST][1][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINELIST][0][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINELIST][0][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINELIST][1][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINELIST][1][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINESTRIP][0][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINESTRIP][0][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINESTRIP][1][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_LINESTRIP][1][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLELIST][0][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLELIST][0][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLELIST][1][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLELIST][1][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLESTRIP][0][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLESTRIP][0][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLESTRIP][1][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLESTRIP][1][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLEFAN][0][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLEFAN][0][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLEFAN][1][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_TRIANGLEFAN][1][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_SPRITE][0][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_SPRITE][0][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_SPRITE][1][0] = (VertexKickPtr)&T::VertexKick; m_vk[GS_SPRITE][1][1] = (VertexKickPtr)&T::VertexKick; m_vk[GS_INVALID][0][0] = &GSState::VertexKickNull; m_vk[GS_INVALID][0][1] = &GSState::VertexKickNull; m_vk[GS_INVALID][1][0] = &GSState::VertexKickNull; m_vk[GS_INVALID][1][1] = &GSState::VertexKickNull; } void UpdateVertexKick() { m_vkf = m_vk[PRIM->PRIM][PRIM->TME][PRIM->FST]; } void VertexKickNull(bool skip) { ASSERT(0); } void VertexKick(bool skip) { (this->*m_vkf)(skip); } public: GIFPath m_path[3]; GIFRegPRIM* PRIM; GSPrivRegSet* m_regs; GSLocalMemory m_mem; GSDrawingEnvironment m_env; GSDrawingContext* m_context; GSVertex m_v; float m_q; uint32 m_vprim; GSPerfMon m_perfmon; uint32 m_crc; int m_options; int m_frameskip; CRC::Game m_game; GSDump m_dump; public: GSState(uint8* base, bool mt, void (*irq)()); virtual ~GSState(); void ResetHandlers(); GSVector4i GetDisplayRect(int i = -1); GSVector4i GetFrameRect(int i = -1); GSVector2i GetDeviceSize(int i = -1); bool IsEnabled(int i); int GetFPS(); virtual void Reset(); virtual void Flush(); virtual void FlushPrim() = 0; virtual void ResetPrim() = 0; virtual void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {} virtual void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r) {} virtual void InvalidateTextureCache() {} void Move(); void Write(uint8* mem, int len); void Read(uint8* mem, int len); void SoftReset(uint32 mask); void WriteCSR(uint32 csr) {m_regs->CSR.u32[1] = csr;} void ReadFIFO(uint8* mem, int size); template void Transfer(uint8* mem, uint32 size); int Freeze(GSFreezeData* fd, bool sizeonly); int Defrost(const GSFreezeData* fd); void GetLastTag(uint32* tag) {*tag = m_path3hack; m_path3hack = 0;} virtual void SetGameCRC(uint32 crc, int options); void SetFrameSkip(int frameskip); };