/* * 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 #include "GSRenderer.h" #include "GSTextureCache.h" #include "GSCrc.h" #include "GSFunctionMap.h" #include "GSState.h" class GSRendererHW : public GSRenderer { private: int m_width; int m_height; bool m_reset; int m_upscale_multiplier; bool m_userhacks_align_sprite_X; bool m_userhacks_disable_gs_mem_clear; #pragma region hacks typedef bool (GSRendererHW::*OI_Ptr)(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); typedef void (GSRendererHW::*OO_Ptr)(); typedef bool (GSRendererHW::*CU_Ptr)(); // Require special argument bool OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Source* t, const GSVector4i& r_draw); void OI_GsMemClear(); // always on bool OI_DoubleHalfClear(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_FFXII(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_FFX(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_MetalSlug6(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_GodOfWar2(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_SimpsonsGame(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_RozenMaidenGebetGarden(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_SpidermanWoS(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_TyTasmanianTiger(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_DigimonRumbleArena2(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_BlackHawkDown(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_StarWarsForceUnleashed(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_XmenOriginsWolverine(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_CallofDutyFinalFronts(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_SpyroNewBeginning(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_SpyroEternalNight(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_TalesOfLegendia(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_SMTNocturne(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_PointListPalette(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_SuperManReturns(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_ArTonelico2(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); void OO_DBZBT2(); void OO_MajokkoALaMode2(); bool CU_DBZBT2(); bool CU_MajokkoALaMode2(); bool CU_TalesOfAbyss(); class Hacks { template class HackEntry { public: CRC::Title title; CRC::Region region; T func; HackEntry(CRC::Title t, CRC::Region r, T f) { title = t; region = r; func = f; } }; template class FunctionMap : public GSFunctionMap { list >& m_tbl; T GetDefaultFunction(uint32 key) { CRC::Title title = (CRC::Title)(key & 0xffffff); CRC::Region region = (CRC::Region)(key >> 24); for(typename list >::iterator i = m_tbl.begin(); i != m_tbl.end(); i++) { if(i->title == title && (i->region == CRC::RegionCount || i->region == region)) { return i->func; } } return NULL; } public: FunctionMap(list >& tbl) : m_tbl(tbl) {} }; list > m_oi_list; list > m_oo_list; list > m_cu_list; FunctionMap m_oi_map; FunctionMap m_oo_map; FunctionMap m_cu_map; public: OI_Ptr m_oi; OO_Ptr m_oo; CU_Ptr m_cu; Hacks(); void SetGameCRC(const CRC::Game& game); } m_hacks; #pragma endregion uint16 Interpolate_UV(float alpha, int t0, int t1); float alpha0(int L, int X0, int X1); float alpha1(int L, int X0, int X1); template void RoundSpriteOffset(); protected: GSTextureCache* m_tc; virtual void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex) = 0; int m_userhacks_round_sprite_offset; bool m_channel_shuffle; bool m_double_downscale; public: GSRendererHW(GSTextureCache* tc); virtual ~GSRendererHW(); void SetGameCRC(uint32 crc, int options); bool CanUpscale(); int GetUpscaleMultiplier(); virtual GSVector2i GetInternalResolution(); void SetScaling(); void Reset(); void VSync(int field); void ResetDevice(); GSTexture* GetOutput(int i, int& y_offset); void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); void InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r, bool clut = false); void Draw(); };