From 1780f82dac08264c46a8e5d49c5da20d82ce071f Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Wed, 1 Jul 2009 13:49:49 +0000 Subject: [PATCH] implement peeking z value from ppc. currently only works in single core mode. the pixel format may be slightly off of what the game actually desires. someone check please? :) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3627 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/PluginVideo.cpp | 6 +++- Source/Core/Common/Src/PluginVideo.h | 2 ++ Source/Core/Core/Src/HW/MemmapFunctions.cpp | 16 +++++----- Source/PluginSpecs/pluginspecs_video.h | 15 +++++++++ Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 35 +++++++++++++++++++++ 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/Source/Core/Common/Src/PluginVideo.cpp b/Source/Core/Common/Src/PluginVideo.cpp index 96833da0ca..6f2b740f7b 100644 --- a/Source/Core/Common/Src/PluginVideo.cpp +++ b/Source/Core/Common/Src/PluginVideo.cpp @@ -29,6 +29,7 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo Video_ExitLoop = 0; Video_Screenshot = 0; Video_AddMessage = 0; + Video_AccessEFB = 0; Video_Prepare = reinterpret_cast (LoadSymbol("Video_Prepare")); @@ -44,6 +45,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo (LoadSymbol("Video_ExitLoop")); Video_AddMessage = reinterpret_cast (LoadSymbol("Video_AddMessage")); + Video_AccessEFB = reinterpret_cast + (LoadSymbol("Video_AccessEFB")); if ((Video_Prepare != 0) && (Video_SendFifoData != 0) && @@ -51,7 +54,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo (Video_EnterLoop != 0) && (Video_ExitLoop != 0) && (Video_Screenshot != 0) && - (Video_AddMessage != 0)) + (Video_AddMessage != 0) && + (Video_AccessEFB != 0)) validVideo = true; } diff --git a/Source/Core/Common/Src/PluginVideo.h b/Source/Core/Common/Src/PluginVideo.h index 6b6940fd2c..76472ac81d 100644 --- a/Source/Core/Common/Src/PluginVideo.h +++ b/Source/Core/Common/Src/PluginVideo.h @@ -30,6 +30,7 @@ typedef bool (__cdecl* TVideo_Screenshot)(const char* filename); typedef void (__cdecl* TVideo_EnterLoop)(); typedef void (__cdecl* TVideo_ExitLoop)(); typedef void (__cdecl* TVideo_AddMessage)(const char* pstr, unsigned int milliseconds); +typedef u32 (__cdecl* TVideo_AccessEFB)(EFBAccessType, u32, u32); class PluginVideo : public CPlugin { @@ -43,6 +44,7 @@ public: TVideo_EnterLoop Video_EnterLoop; TVideo_ExitLoop Video_ExitLoop; TVideo_UpdateXFB Video_UpdateXFB; + TVideo_AccessEFB Video_AccessEFB; TVideo_AddMessage Video_AddMessage; TVideo_Screenshot Video_Screenshot; diff --git a/Source/Core/Core/Src/HW/MemmapFunctions.cpp b/Source/Core/Core/Src/HW/MemmapFunctions.cpp index 44c57553c6..ff41da7911 100644 --- a/Source/Core/Core/Src/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/Src/HW/MemmapFunctions.cpp @@ -21,6 +21,7 @@ #include "WII_IOB.h" #include "../Core.h" #include "../PowerPC/PowerPC.h" +#include "../PluginManager.h" namespace Memory { @@ -35,8 +36,8 @@ GXPeekZ 80322df8: or r0, r3, r0 a |= x; 80322dfc: rlwinm r0, r0, 0, 10, 7 (ff3fffff) a &= 0xff3fffff 80322e00: oris r3, r0, 0x0040 x = a | 0x00400000 -80322e04: lwz r0, 0 (r3) -80322e08: stw r0, 0 (r5) +80322e04: lwz r0, 0 (r3) r0 = *r3 +80322e08: stw r0, 0 (r5) z = 80322e0c: blr */ @@ -125,15 +126,14 @@ void ReadFromHardware(T &_var, u32 em_address, u32 effective_address, Memory::XC { if (em_address < 0xcc000000) { - // TODO: glReadPixels :p - _var = 0; - int x = (em_address & 0xfff) >> 2; int y = (em_address >> 12) & 0x3ff; if (em_address & 0x00400000) { - DEBUG_LOG(MEMMAP, "EFB Z Read @ %i, %i", x, y); + _var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(EFBAccessType::PEEK_Z, x, y); + DEBUG_LOG(MEMMAP, "EFB Z Read @ %i, %i\t= %i", x, y, _var); } else { - DEBUG_LOG(MEMMAP, "EFB Color Read @ %i, %i", x, y); + _var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(EFBAccessType::PEEK_COLOR, x, y); + DEBUG_LOG(MEMMAP, "EFB Color Read @ %i, %i\t= %i", x, y, _var); } } else if (em_address <= 0xcc009000) @@ -203,8 +203,10 @@ void WriteToHardware(u32 em_address, const T data, u32 effective_address, Memory int x = (em_address & 0xfff) >> 2; int y = (em_address >> 12) & 0x3ff; if (em_address & 0x00400000) { + CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(EFBAccessType::POKE_Z, x, y); DEBUG_LOG(MEMMAP, "EFB Z Write %08x @ %i, %i", data, x, y); } else { + CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(EFBAccessType::POKE_COLOR, x, y); DEBUG_LOG(MEMMAP, "EFB Color Write %08x @ %i, %i", data, x, y); } return; diff --git a/Source/PluginSpecs/pluginspecs_video.h b/Source/PluginSpecs/pluginspecs_video.h index b81964a9e4..4cbdba0579 100644 --- a/Source/PluginSpecs/pluginspecs_video.h +++ b/Source/PluginSpecs/pluginspecs_video.h @@ -23,6 +23,14 @@ typedef void (*TUpdateInterrupts)(void); typedef void (*TUpdateFPSDisplay)(const char* text); // sets the window title typedef void (*TKeyPressed)(int keycode, bool shift, bool control); // sets the window title +enum EFBAccessType +{ + PEEK_Z = 0, + POKE_Z, + PEEK_COLOR, + POKE_COLOR +}; + typedef struct { // fifo registers @@ -112,6 +120,13 @@ EXPORT void CALL Video_SendFifoData(u8* _uData, u32 len); // EXPORT void CALL Video_UpdateXFB(u32 _dwXFBAddr, u32 _dwWidth, u32 _dwHeight, s32 _dwYOffset, bool scheduling); +// __________________________________________________________________________________________________ +// Function: Video_AccessEFB +// input: type of access (r/w, z/color, ...), x coord, y coord +// output: response to the access request (ex: peek z data at specified coord) +// +EXPORT u32 CALL Video_AccessEFB(EFBAccessType type, u32 x, u32 y); + // __________________________________________________________________________________________________ // Function: Video_Screenshot // input: Filename diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 599fafee2e..83095cabd5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -458,3 +458,38 @@ void Video_UpdateXFB(u32 _dwXFBAddr, u32 _dwWidth, u32 _dwHeight, s32 _dwYOffset } } +u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y) +{ + switch (type) + { + case EFBAccessType::PEEK_Z: + { + if (!g_VideoInitialize.bUseDualCore) + { + u32 z = 0; + TRectangle source, scaledTargetSource; + ComputeBackbufferRectangle(&source); + source.Scale(Renderer::GetTargetScaleX(), Renderer::GetTargetScaleY(), &scaledTargetSource); + GLuint depth_tex = Renderer::ResolveAndGetDepthTarget(scaledTargetSource); + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &z); + GL_REPORT_ERRORD(); + return z; + } + } + break; + + case EFBAccessType::POKE_Z: + break; + + case EFBAccessType::PEEK_COLOR: + break; + + case EFBAccessType::POKE_COLOR: + break; + + default: + break; + } + return 0; +} +