From 4d8d86bd6a27e9eea5bbf1440cbf317f02320519 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 29 May 2012 13:54:20 +0200 Subject: [PATCH 001/167] D3D11: Implement some PE pixel performance metrics. Super Mario Sunshine is using a cool trick: To determine how much goop has been cleaned in ep. 6 of Sirena Beach, it counts the number of pixels that are input to the blending stage. For that it's using the PE performance registers ;) Fixes issue 1498. --- Source/Core/VideoCommon/Src/BPMemory.h | 2 +- Source/Core/VideoCommon/Src/BPStructs.cpp | 13 +- Source/Core/VideoCommon/Src/PixelEngine.cpp | 71 +++++++--- Source/Core/VideoCommon/Src/PixelEngine.h | 27 ++-- Source/Core/VideoCommon/Src/RenderBase.h | 14 ++ .../VideoCommon/Src/VertexManagerBase.cpp | 2 + Source/Core/VideoCommon/Src/VideoConfig.cpp | 5 + Source/Core/VideoCommon/Src/VideoConfig.h | 2 + .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 133 ++++++++++++++++++ Source/Plugins/Plugin_VideoDX11/Src/Render.h | 6 + .../Plugin_VideoDX11/Src/VertexManager.cpp | 3 +- Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 1 + Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 1 + Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 1 + 14 files changed, 245 insertions(+), 36 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index 9284674aa1..ce65bcb824 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -62,7 +62,7 @@ #define BPMEM_COPYFILTER1 0x54 #define BPMEM_CLEARBBOX1 0x55 #define BPMEM_CLEARBBOX2 0x56 -#define BPMEM_UNKNOWN_57 0x57 +#define BPMEM_CLEAR_PIXEL_PERF 0x57 #define BPMEM_REVBITS 0x58 #define BPMEM_SCISSOROFFSET 0x59 #define BPMEM_PRELOAD_ADDR 0x60 diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index 179196e412..bc6de89bf2 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -62,7 +62,6 @@ void RenderToXFB(const BPCmd &bp, const EFBRectangle &rc, float yScale, float xf { Renderer::RenderToXFB(xfbAddr, dstWidth, dstHeight, rc, gamma); } - void BPWritten(const BPCmd& bp) { /* @@ -141,7 +140,8 @@ void BPWritten(const BPCmd& bp) || bp.address == BPMEM_LOADTLUT0 || bp.address == BPMEM_LOADTLUT1 || bp.address == BPMEM_TEXINVALIDATE - || bp.address == BPMEM_PRELOAD_MODE)) + || bp.address == BPMEM_PRELOAD_MODE + || bp.address == BPMEM_CLEAR_PIXEL_PERF)) { return; } @@ -265,6 +265,8 @@ void BPWritten(const BPCmd& bp) UPE_Copy PE_copy = bpmem.triggerEFBCopy; + g_renderer->ResumePixelPerf(true); + // Check if we are to copy from the EFB or draw to the XFB if (PE_copy.copy_to_xfb == 0) { @@ -303,6 +305,8 @@ void BPWritten(const BPCmd& bp) s_gammaLUT[PE_copy.gamma]); } + g_renderer->PausePixelPerf(true); + // Clear the rectangular region after copying it. if (PE_copy.clear) { @@ -481,8 +485,9 @@ void BPWritten(const BPCmd& bp) case BPMEM_REVBITS: // Always set to 0x0F when GX_InitRevBits() is called. break; - case BPMEM_UNKNOWN_57: // Sunshine alternates this register between values 0x000 and 0xAAA - DEBUG_LOG(VIDEO, "Unknown BP Reg 0x57: %08x", bp.newvalue); + case BPMEM_CLEAR_PIXEL_PERF: + // GXClearPixMetric writes 0xAAA here, Sunshine alternates this register between values 0x000 and 0xAAA + g_renderer->ResetPixelPerf(); break; case BPMEM_PRELOAD_ADDR: diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index a488e52b42..4aac3c2456 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -28,6 +28,7 @@ #include "ConfigManager.h" #include "PixelEngine.h" +#include "RenderBase.h" #include "CommandProcessor.h" #include "HW/ProcessorInterface.h" #include "DLCache.h" @@ -255,23 +256,59 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) break; } - case PE_PERF_0L: - case PE_PERF_0H: - case PE_PERF_1L: - case PE_PERF_1H: - case PE_PERF_2L: - case PE_PERF_2H: - case PE_PERF_3L: - case PE_PERF_3H: - case PE_PERF_4L: - case PE_PERF_4H: - case PE_PERF_5L: - case PE_PERF_5H: - INFO_LOG(PIXELENGINE, "(r16) perf counter @ %08x", _iAddress); - // git r90a2096a24f4 (svn r3663) added the PE_PERF cases, without setting - // _uReturnValue to anything, this reverts to the previous behaviour which allows - // The timer in SMS:Scrubbing Serena Beach to countdown correctly - _uReturnValue = 1; + // NOTE(neobrain): only PE_PERF_ZCOMP_OUTPUT is implemented in D3D11, but the other values shouldn't be contradictionary to the value of that register (i.e. INPUT registers should always be greater or equal to their corresponding OUTPUT registers). + case PE_PERF_ZCOMP_INPUT_ZCOMPLOC_L: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT_ZCOMPLOC) & 0xFFFF; + break; + + case PE_PERF_ZCOMP_INPUT_ZCOMPLOC_H: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT_ZCOMPLOC) >> 16; + break; + + case PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_L: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT_ZCOMPLOC) & 0xFFFF; + break; + + case PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_H: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT_ZCOMPLOC) >> 16; + break; + + case PE_PERF_ZCOMP_INPUT_L: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT) & 0xFFFF; + break; + + case PE_PERF_ZCOMP_INPUT_H: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT) >> 16; + break; + + case PE_PERF_ZCOMP_OUTPUT_L: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT) & 0xFFFF; + break; + + case PE_PERF_ZCOMP_OUTPUT_H: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT) >> 16; + break; + + case PE_PERF_BLEND_INPUT_L: + // Super Mario Sunshine uses this register in episode 6 of Sirena Beach: + // The amount of remaining goop is determined by checking how many pixels reach the blending stage. + // Once this register falls below a particular value (around 0x90), the game regards the challenge finished. + // In very old builds, Dolphin only returned 0. That caused the challenge to be immediately finished without any goop being cleaned (the timer just didn't even start counting from 3:00:00). + // Later builds returned 1 for the high register. That caused the timer to actually count down, but made the challenge unbeatable because the game always thought you didn't clear any goop at all. + // Note that currently this functionality is only implemented in the D3D11 backend. + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_BLEND_INPUT) & 0xFFFF; + break; + + case PE_PERF_BLEND_INPUT_H: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_BLEND_INPUT) >> 16; + break; + + case PE_PERF_EFB_COPY_CLOCKS_L: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_EFB_COPY_CLOCKS) & 0xFFFF; + break; + + case PE_PERF_EFB_COPY_CLOCKS_H: + _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_EFB_COPY_CLOCKS) >> 16; break; default: diff --git a/Source/Core/VideoCommon/Src/PixelEngine.h b/Source/Core/VideoCommon/Src/PixelEngine.h index 64f959009f..eaf55f0031 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.h +++ b/Source/Core/VideoCommon/Src/PixelEngine.h @@ -36,19 +36,20 @@ enum PE_BBOX_TOP = 0x14, // Flip Top PE_BBOX_BOTTOM = 0x16, // Flip Bottom - // These have not yet been RE:d. They are the perf counters. - PE_PERF_0L = 0x18, - PE_PERF_0H = 0x1a, - PE_PERF_1L = 0x1c, - PE_PERF_1H = 0x1e, - PE_PERF_2L = 0x20, - PE_PERF_2H = 0x22, - PE_PERF_3L = 0x24, - PE_PERF_3H = 0x26, - PE_PERF_4L = 0x28, - PE_PERF_4H = 0x2a, - PE_PERF_5L = 0x2c, - PE_PERF_5H = 0x2e, + // NOTE: Order not verified + // These indicate the number of quads that are being used as input/output for each particular stage + PE_PERF_ZCOMP_INPUT_ZCOMPLOC_L = 0x18, + PE_PERF_ZCOMP_INPUT_ZCOMPLOC_H = 0x1a, + PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_L = 0x1c, + PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_H = 0x1e, + PE_PERF_ZCOMP_INPUT_L = 0x20, + PE_PERF_ZCOMP_INPUT_H = 0x22, + PE_PERF_ZCOMP_OUTPUT_L = 0x24, + PE_PERF_ZCOMP_OUTPUT_H = 0x26, + PE_PERF_BLEND_INPUT_L = 0x28, + PE_PERF_BLEND_INPUT_H = 0x2a, + PE_PERF_EFB_COPY_CLOCKS_L = 0x2c, + PE_PERF_EFB_COPY_CLOCKS_H = 0x2e, }; namespace PixelEngine diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h index e8d4c55a20..4d288143c0 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.h +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -52,6 +52,15 @@ public: Renderer(); virtual ~Renderer(); + enum PixelPerfQuery { + PP_ZCOMP_INPUT_ZCOMPLOC, + PP_ZCOMP_OUTPUT_ZCOMPLOC, + PP_ZCOMP_INPUT, + PP_ZCOMP_OUTPUT, + PP_BLEND_INPUT, + PP_EFB_COPY_CLOCKS + }; + virtual void SetColorMask() = 0; virtual void SetBlendMode(bool forceUpdate) = 0; virtual void SetScissorRect(const TargetRectangle& rc) = 0; @@ -119,6 +128,11 @@ public: static unsigned int GetPrevPixelFormat() { return prev_efb_format; } static void StorePixelFormat(unsigned int new_format) { prev_efb_format = new_format; } + virtual void ResetPixelPerf() {}; + virtual void ResumePixelPerf(bool efb_copies) {}; + virtual void PausePixelPerf(bool efb_copies) {}; + virtual u32 GetPixelPerfResult(PixelPerfQuery type) { return 0; }; + // TODO: doesn't belong here virtual void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) = 0; virtual void SetPSConstant4fv(unsigned int const_number, const float *f) = 0; diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 4118e3dcbd..86dd891386 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -253,7 +253,9 @@ void VertexManager::Flush() //if (g_nativeVertexFmt) g_nativeVertexFmt->SetupVertexPointers(); + g_renderer->ResumePixelPerf(false); g_vertex_manager->Draw(stride, false); + g_renderer->PausePixelPerf(false); // run through vertex groups again to set alpha if (false == g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index c5628c19a1..5f464c3322 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -104,6 +104,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true); iniFile.Get("Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable, false); iniFile.Get("Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false); + iniFile.Get("Hacks", "DisablePixelPerf", &bDisablePixelPerf, true); iniFile.Get("Hardware", "Adapter", &iAdapter, 0); @@ -153,6 +154,7 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video_Hacks", "EFBScaledCopy", &bCopyEFBScaled); iniFile.GetIfExists("Video_Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable); iniFile.GetIfExists("Video_Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges); + iniFile.GetIfExists("Video_Hacks", "DisablePixelPerf", &bDisablePixelPerf); iniFile.GetIfExists("Video", "ProjectionHack", &iPhackvalue[0]); iniFile.GetIfExists("Video", "PH_SZNear", &iPhackvalue[1]); @@ -172,6 +174,7 @@ void VideoConfig::VerifyValidity() if (!backend_info.bSupports3DVision) b3DVision = false; if (!backend_info.bSupportsFormatReinterpretation) bEFBEmulateFormatChanges = false; if (!backend_info.bSupportsPixelLighting) bEnablePixelLighting = false; + if (!backend_info.bSupportsPixelPerfQuery) bDisablePixelPerf = true; } void VideoConfig::Save(const char *ini_file) @@ -231,6 +234,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled); iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); + iniFile.Set("Hacks", "DisablePixelPerf", bDisablePixelPerf); iniFile.Set("Hardware", "Adapter", iAdapter); @@ -287,6 +291,7 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini) SET_IF_DIFFERS("Video_Hacks", "EFBScaledCopy", bCopyEFBScaled); SET_IF_DIFFERS("Video_Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); SET_IF_DIFFERS("Video_Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); + SET_IF_DIFFERS("Video_Hacks", "DisablePixelPerf", bDisablePixelPerf); iniFile.Save(game_ini); } diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 7653972ec8..8593de4fd7 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -133,6 +133,7 @@ struct VideoConfig bool bUseBBox; bool bEnablePixelLighting; bool bEnablePerPixelDepth; + bool bDisablePixelPerf; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped @@ -161,6 +162,7 @@ struct VideoConfig bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL bool bSupportsFormatReinterpretation; bool bSupportsPixelLighting; + bool bSupportsPixelPerfQuery; } backend_info; }; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 3a725452e7..3f88d7f99d 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -65,6 +65,19 @@ ID3D11RasterizerState* resetraststate = NULL; static ID3D11Texture2D* s_screenshot_texture = NULL; +// Using a vector of query objects to avoid flushing the gpu pipeline all the time +// TODO: Could probably optimized further by using a ring buffer or something +#define MAX_PIXEL_PERF_QUERIES 20 // 20 is an arbitrary guess +std::vector pixel_perf_queries; +static int pixel_perf_query_index = 0; + +static u64 pixel_perf = 0; +static bool pixel_perf_active = false; +static bool pixel_perf_dirty = false; + +ID3D11Query* gpu_finished_query = NULL; + + // GX pipeline state struct { @@ -302,6 +315,9 @@ void SetupDeviceObjects() D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState"); s_screenshot_texture = NULL; + + D3D11_QUERY_DESC qdesc = CD3D11_QUERY_DESC(D3D11_QUERY_EVENT, 0); + D3D::device->CreateQuery(&qdesc, &gpu_finished_query); } // Kill off all device objects @@ -309,6 +325,12 @@ void TeardownDeviceObjects() { delete g_framebuffer_manager; + while (!pixel_perf_queries.empty()) + { + SAFE_RELEASE(pixel_perf_queries.back()); + pixel_perf_queries.pop_back(); + } + SAFE_RELEASE(gpu_finished_query); SAFE_RELEASE(access_efb_cbuf); SAFE_RELEASE(clearblendstates[0]); SAFE_RELEASE(clearblendstates[1]); @@ -357,6 +379,11 @@ Renderer::Renderer() s_LastEFBScale = g_ActiveConfig.iEFBScale; CalculateTargetSize(); + pixel_perf_query_index = 0; + pixel_perf = 0; + pixel_perf_active = false; + pixel_perf_dirty = false; + SetupDeviceObjects(); @@ -777,6 +804,112 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); } +void Renderer::ResetPixelPerf() +{ + if (g_ActiveConfig.bDisablePixelPerf) + return; + + if (pixel_perf_active) + PausePixelPerf(false); + + pixel_perf_query_index = 0; + pixel_perf = 0; +} + +void Renderer::ResumePixelPerf(bool efb_copies) +{ + if (g_ActiveConfig.bDisablePixelPerf) + return; + + if (efb_copies) + return; + + if(pixel_perf_active) + return; + + if (pixel_perf_queries.size() < pixel_perf_query_index+1 && pixel_perf_query_index < MAX_PIXEL_PERF_QUERIES) + { + D3D11_QUERY_DESC qdesc = CD3D11_QUERY_DESC(D3D11_QUERY_OCCLUSION, 0); + ID3D11Query* tmpquery = NULL; + D3D::device->CreateQuery(&qdesc, &tmpquery); + pixel_perf_queries.push_back(tmpquery); + pixel_perf_query_index = pixel_perf_queries.size() - 1; + } + else if (pixel_perf_queries.size() < pixel_perf_query_index+1) + { + StorePixelPerfResult(PP_ZCOMP_OUTPUT); + pixel_perf_query_index = 0; + } + // This will spam the D3D11 debug runtime output with QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS warnings which safely can be ignored. Mute them in the DX control panel if you need to read the debug runtime output. + D3D::context->Begin(pixel_perf_queries[pixel_perf_query_index]); + pixel_perf_active = true; + pixel_perf_dirty = true; +} + +void Renderer::PausePixelPerf(bool efb_copies) +{ + if (g_ActiveConfig.bDisablePixelPerf) + return; + + if(!pixel_perf_active) + return; + + D3D::context->End(pixel_perf_queries[pixel_perf_query_index]); + pixel_perf_query_index++; + pixel_perf_active = false; +} + +void Renderer::StorePixelPerfResult(PixelPerfQuery type) +{ + // First, make sure the GPU has finished rendering so that query results are valid + D3D::context->End(gpu_finished_query); + BOOL gpu_finished = FALSE; + while (!gpu_finished) + { + // If nothing goes horribly wrong here, this should complete in finite time... + D3D::context->GetData(gpu_finished_query, &gpu_finished, sizeof(gpu_finished), 0); + } + + for(int i = 0; i < pixel_perf_query_index; ++i) + { + UINT64 buf = 0; + D3D::context->GetData(pixel_perf_queries[i], &buf, sizeof(buf), 0); + + // Reported pixel metrics should be referenced to native resolution: + pixel_perf += buf * EFB_WIDTH * EFB_HEIGHT / GetTargetWidth() / GetTargetHeight(); + } + pixel_perf_dirty = false; +} + +u32 Renderer::GetPixelPerfResult(PixelPerfQuery type) +{ + if (g_ActiveConfig.bDisablePixelPerf) + return 0; + + if (type == PP_EFB_COPY_CLOCKS) + { + // not implemented + return 0; + } + + if (type == PE_PERF_ZCOMP_INPUT_ZCOMPLOC_L || + type == PE_PERF_ZCOMP_INPUT_ZCOMPLOC_H || + type == PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_L || + type == PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_H) + { + // return zero for now because ZCOMP_OUTPUT_ZCOMPLOC + ZCOMP_OUTPUT should equal BLEND_INPUT + // TODO: Instead, should keep separate counters for zcomploc and non-zcomploc registers. + return 0; + } + + // Basically we only implement PP_ZCOMP_OUTPUT, but we're returning the same value for PP_ZCOMP_INPUT and PP_BLEND_INPUT anyway + if (pixel_perf_dirty) + StorePixelPerfResult(PP_ZCOMP_OUTPUT); + + // Dividing by 4 because we're expected to return the number of 2x2 quads instead of pixels + return std::min(pixel_perf / 4, (u64)0xFFFFFFFF); +} + void SetSrcBlend(D3D11_BLEND val) { // Colors should blend against SRC_ALPHA diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h index 8f6c78fae1..6db829c205 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.h @@ -46,6 +46,12 @@ public: void ReinterpretPixelData(unsigned int convtype); + void ResetPixelPerf(); + void ResumePixelPerf(bool efb_copies); + void PausePixelPerf(bool efb_copies); + u32 GetPixelPerfResult(PixelPerfQuery type); + void StorePixelPerfResult(PixelPerfQuery type); // internal + void UpdateViewport(Matrix44& vpCorrection); bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 58bad98cc6..4bb04bc302 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -198,7 +198,6 @@ void VertexManager::Draw(UINT stride) if (IndexGenerator::GetNumLines() > 0 || IndexGenerator::GetNumPoints() > 0) ((DX11::Renderer*)g_renderer)->RestoreCull(); } - void VertexManager::vFlush() { if (LocalVBuffer == s_pCurBufferPointer) return; @@ -266,7 +265,9 @@ void VertexManager::vFlush() g_renderer->ApplyState(useDstAlpha); LoadBuffers(); + g_renderer->ResumePixelPerf(false); Draw(stride); + g_renderer->PausePixelPerf(false); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index cb348b8684..161321cf08 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -94,6 +94,7 @@ void InitBackendInfo() g_Config.backend_info.bSupportsDualSourceBlend = true; g_Config.backend_info.bSupportsFormatReinterpretation = true; g_Config.backend_info.bSupportsPixelLighting = true; + g_Config.backend_info.bSupportsPixelPerfQuery = true; IDXGIFactory* factory; IDXGIAdapter* ad; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 5aeca6751d..1d1a2db112 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -96,6 +96,7 @@ void InitBackendInfo() g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupportsDualSourceBlend = false; g_Config.backend_info.bSupportsFormatReinterpretation = true; + g_Config.backend_info.bSupportsPixelPerfQuery = false; g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 543fb9824d..2c8f6d4716 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -135,6 +135,7 @@ void InitBackendInfo() g_Config.backend_info.bSupportsDualSourceBlend = false; // supported, but broken g_Config.backend_info.bSupportsFormatReinterpretation = false; g_Config.backend_info.bSupportsPixelLighting = true; + g_Config.backend_info.bSupportsPixelPerfQuery = false; // aamodes const char* caamodes[] = {"None", "2x", "4x", "8x", "8x CSAA", "8xQ CSAA", "16x CSAA", "16xQ CSAA"}; From cf8744cf2c1de2231d180348c4b55ebc2b35240f Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 17 Jun 2012 13:58:29 +0200 Subject: [PATCH 002/167] OGL: Implement pixel metrics (untested) --- Source/Core/VideoCommon/CMakeLists.txt | 1 + Source/Core/VideoCommon/Src/BPStructs.cpp | 3 +- Source/Core/VideoCommon/Src/PerfQueryBase.cpp | 3 + Source/Core/VideoCommon/Src/PerfQueryBase.h | 39 ++++++++++ Source/Core/VideoCommon/Src/PixelEngine.cpp | 26 ++++--- Source/Plugins/Plugin_VideoOGL/CMakeLists.txt | 1 + .../Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp | 78 +++++++++++++++++++ .../Plugins/Plugin_VideoOGL/Src/PerfQuery.h | 22 ++++++ .../Plugin_VideoOGL/Src/VertexManager.cpp | 4 + Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 2 + 10 files changed, 166 insertions(+), 13 deletions(-) create mode 100644 Source/Core/VideoCommon/Src/PerfQueryBase.cpp create mode 100644 Source/Core/VideoCommon/Src/PerfQueryBase.h create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp create mode 100644 Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index d0e28f571c..5a4ed87c1d 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -16,6 +16,7 @@ set(SRCS Src/BPFunctions.cpp Src/OpcodeDecoding.cpp Src/OpenCL.cpp Src/OpenCL/OCLTextureDecoder.cpp + Src/PerfQueryBase.cpp Src/PixelEngine.cpp Src/PixelShaderGen.cpp Src/PixelShaderManager.cpp diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index bc6de89bf2..cda0f7c7c0 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -31,6 +31,7 @@ #include "VertexShaderManager.h" #include "Thread.h" #include "HW/Memmap.h" +#include "PerfQueryBase.h" using namespace BPFunctions; @@ -487,7 +488,7 @@ void BPWritten(const BPCmd& bp) case BPMEM_CLEAR_PIXEL_PERF: // GXClearPixMetric writes 0xAAA here, Sunshine alternates this register between values 0x000 and 0xAAA - g_renderer->ResetPixelPerf(); + g_perf_query->ResetQuery(); break; case BPMEM_PRELOAD_ADDR: diff --git a/Source/Core/VideoCommon/Src/PerfQueryBase.cpp b/Source/Core/VideoCommon/Src/PerfQueryBase.cpp new file mode 100644 index 0000000000..c537d176f6 --- /dev/null +++ b/Source/Core/VideoCommon/Src/PerfQueryBase.cpp @@ -0,0 +1,3 @@ +#include "PerfQueryBase.h" + +PerfQueryBase* g_perf_query = 0; diff --git a/Source/Core/VideoCommon/Src/PerfQueryBase.h b/Source/Core/VideoCommon/Src/PerfQueryBase.h new file mode 100644 index 0000000000..0520e9244c --- /dev/null +++ b/Source/Core/VideoCommon/Src/PerfQueryBase.h @@ -0,0 +1,39 @@ +#ifndef _PERFQUERY_BASE_H_ +#define _PERFQUERY_BASE_H_ + +#include "CommonTypes.h" + +enum PerfQueryType +{ + PQ_ZCOMP_INPUT_ZCOMPLOC = 0, + PQ_ZCOMP_OUTPUT_ZCOMPLOC, + PQ_ZCOMP_INPUT, + PQ_ZCOMP_OUTPUT, + PQ_BLEND_INPUT, + PQ_EFB_COPY_CLOCKS, + PQ_NUM_MEMBERS +}; + +enum PerfQueryGroup +{ + PQG_ZCOMP_ZCOMPLOC, + PQG_ZCOMP, + PQG_EFB_COPY_CLOCKS, + PQG_NUM_MEMBERS, +}; + +class PerfQueryBase +{ +public: + PerfQueryBase() {}; + virtual ~PerfQueryBase() {} + + virtual void EnableQuery(PerfQueryGroup type) {} + virtual void DisableQuery(PerfQueryGroup type) {} + virtual void ResetQuery() {} + virtual u32 GetQueryResult(PerfQueryType type) { return 0; } +}; + +extern PerfQueryBase* g_perf_query; + +#endif // _PERFQUERY_H_ diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index 4aac3c2456..005468f63c 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -33,6 +33,8 @@ #include "HW/ProcessorInterface.h" #include "DLCache.h" #include "State.h" +#include "PerfQueryBase.h" + namespace PixelEngine { @@ -258,35 +260,35 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) // NOTE(neobrain): only PE_PERF_ZCOMP_OUTPUT is implemented in D3D11, but the other values shouldn't be contradictionary to the value of that register (i.e. INPUT registers should always be greater or equal to their corresponding OUTPUT registers). case PE_PERF_ZCOMP_INPUT_ZCOMPLOC_L: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT_ZCOMPLOC) & 0xFFFF; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT_ZCOMPLOC) & 0xFFFF; break; case PE_PERF_ZCOMP_INPUT_ZCOMPLOC_H: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT_ZCOMPLOC) >> 16; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT_ZCOMPLOC) >> 16; break; case PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_L: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT_ZCOMPLOC) & 0xFFFF; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT_ZCOMPLOC) & 0xFFFF; break; case PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_H: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT_ZCOMPLOC) >> 16; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT_ZCOMPLOC) >> 16; break; case PE_PERF_ZCOMP_INPUT_L: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT) & 0xFFFF; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT) & 0xFFFF; break; case PE_PERF_ZCOMP_INPUT_H: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_INPUT) >> 16; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT) >> 16; break; case PE_PERF_ZCOMP_OUTPUT_L: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT) & 0xFFFF; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT) & 0xFFFF; break; case PE_PERF_ZCOMP_OUTPUT_H: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_ZCOMP_OUTPUT) >> 16; + _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT) >> 16; break; case PE_PERF_BLEND_INPUT_L: @@ -296,19 +298,19 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) // In very old builds, Dolphin only returned 0. That caused the challenge to be immediately finished without any goop being cleaned (the timer just didn't even start counting from 3:00:00). // Later builds returned 1 for the high register. That caused the timer to actually count down, but made the challenge unbeatable because the game always thought you didn't clear any goop at all. // Note that currently this functionality is only implemented in the D3D11 backend. - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_BLEND_INPUT) & 0xFFFF; + _uReturnValue = g_perf_query->GetQueryResult(PQ_BLEND_INPUT) & 0xFFFF; break; case PE_PERF_BLEND_INPUT_H: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_BLEND_INPUT) >> 16; + _uReturnValue = g_perf_query->GetQueryResult(PQ_BLEND_INPUT) >> 16; break; case PE_PERF_EFB_COPY_CLOCKS_L: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_EFB_COPY_CLOCKS) & 0xFFFF; + _uReturnValue = g_perf_query->GetQueryResult(PQ_EFB_COPY_CLOCKS) & 0xFFFF; break; case PE_PERF_EFB_COPY_CLOCKS_H: - _uReturnValue = g_renderer->GetPixelPerfResult(Renderer::PP_EFB_COPY_CLOCKS) >> 16; + _uReturnValue = g_perf_query->GetQueryResult(PQ_EFB_COPY_CLOCKS) >> 16; break; default: diff --git a/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt b/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt index b506087106..834e905faa 100644 --- a/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt +++ b/Source/Plugins/Plugin_VideoOGL/CMakeLists.txt @@ -2,6 +2,7 @@ set(SRCS Src/FramebufferManager.cpp Src/GLUtil.cpp Src/main.cpp Src/NativeVertexFormat.cpp + Src/PerfQuery.cpp Src/PixelShaderCache.cpp Src/PostProcessing.cpp Src/RasterFont.cpp diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp new file mode 100644 index 0000000000..cb659e6921 --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp @@ -0,0 +1,78 @@ +#include "GLUtil.h" +#include "PerfQuery.h" + +namespace OGL { + +u32 results[PQG_NUM_MEMBERS] = { 0 }; +GLuint query_id; + +PerfQueryGroup active_query; + +PerfQuery::PerfQuery() +{ + glGenQueries(1, &query_id); +} + +PerfQuery::~PerfQuery() +{ + glDeleteQueries(1, &query_id); +} + +void PerfQuery::EnableQuery(PerfQueryGroup type) +{ + // start query + if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) + { + glBeginQuery(GL_SAMPLES_PASSED, query_id); + } + active_query = type; +} + +void PerfQuery::DisableQuery(PerfQueryGroup type) +{ + // stop query + if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) + { + glEndQuery(GL_SAMPLES_PASSED); + + GLuint query_result = GL_FALSE; + while (query_result != GL_TRUE) + { + glGetQueryObjectuiv(query_id, GL_QUERY_RESULT_AVAILABLE, &query_result); + } + + glGetQueryObjectuiv(query_id, GL_QUERY_RESULT, &query_result); + + results[active_query] += query_result; + } +} + +void PerfQuery::ResetQuery() +{ + memset(results, 0, sizeof(results)); +} + +u32 PerfQuery::GetQueryResult(PerfQueryType type) +{ + if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC || type == PQ_BLEND_INPUT) + { + + } + if (type == PQ_ZCOMP_INPUT || type == PQ_ZCOMP_OUTPUT || type == PQ_BLEND_INPUT) + { + + } + if (type == PQ_BLEND_INPUT) + { + results[PQ_BLEND_INPUT] = results[PQ_ZCOMP_OUTPUT] + results[PQ_ZCOMP_OUTPUT_ZCOMPLOC]; + } + + if (type == PQ_EFB_COPY_CLOCKS) + { + // TODO + } + + return results[type]; +} + +} // namespace diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h new file mode 100644 index 0000000000..776c576e2d --- /dev/null +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h @@ -0,0 +1,22 @@ +#ifndef _PERFQUERY_H_ +#define _PERFQUERY_H_ + +#include "PerfQueryBase.h" + +namespace OGL { + +class PerfQuery : public PerfQueryBase +{ +public: + PerfQuery(); + ~PerfQuery(); + + void EnableQuery(PerfQueryGroup type); + void DisableQuery(PerfQueryGroup type); + void ResetQuery(); + u32 GetQueryResult(PerfQueryType type); +}; + +} // namespace + +#endif // _PERFQUERY_H_ diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 0a37b0e654..b2f55adec5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -40,6 +40,7 @@ #include "OpcodeDecoding.h" #include "FileUtil.h" #include "Debugger.h" +#include "PerfQueryBase.h" #include "main.h" @@ -207,7 +208,10 @@ void VertexManager::vFlush() if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here. if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid); + g_perf_query->EnableQuery(bpmem.zcontrol.zcomploc ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); Draw(); + g_perf_query->DisableQuery(bpmem.zcontrol.zcomploc ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + ERROR_LOG(VIDEO, "PerfQuery result: %d", g_perf_query->GetQueryResult(bpmem.zcontrol.zcomploc ? PQ_ZCOMP_OUTPUT_ZCOMPLOC : PQ_ZCOMP_OUTPUT)); // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 2c8f6d4716..329d131ded 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -93,6 +93,7 @@ Make AA apply instantly during gameplay if possible #include "FramebufferManager.h" #include "Core.h" #include "Host.h" +#include "PerfQuery.h" #include "VideoState.h" #include "VideoBackend.h" @@ -194,6 +195,7 @@ void VideoBackend::Video_Prepare() BPInit(); g_vertex_manager = new VertexManager; + g_perf_query = new PerfQuery; Fifo_Init(); // must be done before OpcodeDecoder_Init() OpcodeDecoder_Init(); VertexShaderCache::Init(); From 26de63a8cd3e0b05c1ca01bd19e25ace5631943f Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 17 Jun 2012 19:49:48 +0200 Subject: [PATCH 003/167] Video_Software: Implement PE pixel metrics --- .../Plugin_VideoSoftware/Src/BPMemLoader.cpp | 9 ++++++++ .../Plugin_VideoSoftware/Src/Rasterizer.cpp | 15 ++++++++---- .../Plugin_VideoSoftware/Src/SWPixelEngine.h | 23 +++++++++++++++++++ .../Plugins/Plugin_VideoSoftware/Src/Tev.cpp | 18 +++++++++++---- 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp index 95ec555181..ad730a485c 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp @@ -90,6 +90,15 @@ void SWBPWritten(int address, int newvalue) SWPixelEngine::pereg.boxBottom = newvalue >> 10; SWPixelEngine::pereg.boxTop = newvalue & 0x3ff; break; + case BPMEM_CLEAR_PIXEL_PERF: + // TODO: Parameter? + SWPixelEngine::pereg.perfZcompInputZcomploc = 0; + SWPixelEngine::pereg.perfZcompOutputZcomploc = 0; + SWPixelEngine::pereg.perfZcompInput = 0; + SWPixelEngine::pereg.perfZcompOutput = 0; + SWPixelEngine::pereg.perfBlendInput = 0; + SWPixelEngine::pereg.perfEfbCopyClocks = 0; + break; case BPMEM_LOADTLUT0: // This one updates bpmem.tlutXferSrc, no need to do anything here. break; case BPMEM_LOADTLUT1: // Load a Texture Look Up Table diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp index c212c93601..a23d85f27f 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp @@ -23,6 +23,7 @@ #include "BPMemLoader.h" #include "XFMemLoader.h" #include "Tev.h" +#include "SWPixelEngine.h" #include "SWStatistics.h" #include "SWVideoConfig.h" @@ -125,11 +126,17 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi) if (z < 0 || z > 0x00ffffff) return; - if (bpmem.zcontrol.zcomploc && bpmem.zmode.testenable) + if (bpmem.zcontrol.zcomploc) { - // early z - if (!EfbInterface::ZCompare(x, y, z)) - return; + // TODO: Verify that perf regs are being incremented even if test is disabled + SWPixelEngine::pereg.perfZcompInputZcomploc++; + if (bpmem.zmode.testenable) + { + // early z + if (!EfbInterface::ZCompare(x, y, z)) + return; + } + SWPixelEngine::pereg.perfZcompOutputZcomploc++; } RasterBlockPixel& pixel = rasterBlock.Pixel[xi][yi]; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h index 6a87143e8c..764488c32e 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h @@ -38,6 +38,21 @@ namespace SWPixelEngine PE_BBOX_RIGHT = 0x012, // Flip Right PE_BBOX_TOP = 0x014, // Flip Top PE_BBOX_BOTTOM = 0x016, // Flip Bottom + + // NOTE: Order not verified + // These indicate the number of quads that are being used as input/output for each particular stage + PE_PERF_ZCOMP_INPUT_ZCOMPLOC_L = 0x18, + PE_PERF_ZCOMP_INPUT_ZCOMPLOC_H = 0x1a, + PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_L = 0x1c, + PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_H = 0x1e, + PE_PERF_ZCOMP_INPUT_L = 0x20, + PE_PERF_ZCOMP_INPUT_H = 0x22, + PE_PERF_ZCOMP_OUTPUT_L = 0x24, + PE_PERF_ZCOMP_OUTPUT_H = 0x26, + PE_PERF_BLEND_INPUT_L = 0x28, + PE_PERF_BLEND_INPUT_H = 0x2a, + PE_PERF_EFB_COPY_CLOCKS_L = 0x2c, + PE_PERF_EFB_COPY_CLOCKS_H = 0x2e, }; union UPEZConfReg @@ -125,10 +140,18 @@ namespace SWPixelEngine UPECtrlReg ctrl; u16 unk0; u16 token; + u16 boxLeft; u16 boxRight; u16 boxTop; u16 boxBottom; + + u16 perfZcompInputZcomploc; + u16 perfZcompOutputZcomploc; + u16 perfZcompInput; + u16 perfZcompOutput; + u16 perfBlendInput; + u16 perfEfbCopyClocks; }; extern PEReg pereg; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp index c67ee53837..83d9de2784 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp @@ -20,6 +20,7 @@ #include "Tev.h" #include "EfbInterface.h" #include "TextureSampler.h" +#include "SWPixelEngine.h" #include "SWStatistics.h" #include "SWVideoConfig.h" #include "DebugUtil.h" @@ -784,11 +785,16 @@ void Tev::Draw() output[BLU_C] = (output[BLU_C] * invFog + fogInt * bpmem.fog.color.b) >> 8; } - if (!bpmem.zcontrol.zcomploc && bpmem.zmode.testenable) - { - if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2])) - return; - } + if (!bpmem.zcontrol.zcomploc) + { + SWPixelEngine::pereg.perfZcompInput++; + if (bpmem.zmode.testenable) + { + if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2])) + return; + } + SWPixelEngine::pereg.perfZcompOutput++; + } #if ALLOW_TEV_DUMPS if (g_SWVideoConfig.bDumpTevStages) @@ -812,6 +818,8 @@ void Tev::Draw() INCSTAT(swstats.thisFrame.tevPixelsOut); + SWPixelEngine::pereg.perfBlendInput++; + EfbInterface::BlendTev(Position[0], Position[1], output); } From 1c1ae63b697fa5589772c92a78a635ef68f67f83 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 19 Jun 2012 23:05:39 +0200 Subject: [PATCH 004/167] Windows build fix. --- Source/Core/VideoCommon/VideoCommon.vcxproj | 2 ++ Source/Core/VideoCommon/VideoCommon.vcxproj.filters | 6 ++++++ Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj | 2 ++ .../Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj.filters | 6 ++++++ 4 files changed, 16 insertions(+) diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj b/Source/Core/VideoCommon/VideoCommon.vcxproj index f53c18cb37..e458a8d87c 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj @@ -194,6 +194,7 @@ + @@ -240,6 +241,7 @@ + diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index c933fbc939..0a61595c45 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -119,6 +119,9 @@ Shader Generators + + Base + @@ -246,6 +249,9 @@ Shader Generators + + Base + diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj index 18b8ac4d84..8d73bfda05 100644 --- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj +++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj @@ -200,6 +200,7 @@ + @@ -222,6 +223,7 @@ + diff --git a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj.filters b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj.filters index cd170691da..f423a77f0b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj.filters +++ b/Source/Plugins/Plugin_VideoOGL/Plugin_VideoOGL.vcxproj.filters @@ -36,6 +36,9 @@ Render + + Render + @@ -72,6 +75,9 @@ Render + + Render + From 4607ebea2ad5fb472a53d5772af0c395c6f73810 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 26 Aug 2012 20:21:51 +0200 Subject: [PATCH 005/167] Video_Software: Fix a small issue that prevented perf queries from working at all. --- Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp index 33a6164b01..525b39b0b6 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp @@ -77,7 +77,7 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) u16 address = _iAddress & 0xFFF; - if (address <= 0x16) + if (address <= 0x2e) _uReturnValue = ((u16*)&pereg)[address >> 1]; } @@ -109,7 +109,7 @@ void Write16(const u16 _iValue, const u32 _iAddress) } break; default: - if (address <= 0x16) + if (address <= 0x2e) ((u16*)&pereg)[address >> 1] = _iValue; break; } From 87d8feb53df8499e61096e4df022d00e25edb3c3 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sun, 26 Aug 2012 20:25:00 +0200 Subject: [PATCH 006/167] Video_Software: Add some debugging logs for PE perf queries --- Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp index 525b39b0b6..9ae13d4e3b 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp @@ -79,6 +79,11 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) if (address <= 0x2e) _uReturnValue = ((u16*)&pereg)[address >> 1]; + + if (address > 0x16) + { + ERROR_LOG(PIXELENGINE, "Read from address %#08x, returning %#08x\n", address, _uReturnValue); + } } void Write32(const u32 _iValue, const u32 _iAddress) From d734a5b486059d724f55e6662cf019fd71995c2b Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 27 Aug 2012 00:57:17 +0200 Subject: [PATCH 007/167] More debugging logs for RDilux --- Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp index 9ae13d4e3b..63885513f5 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp @@ -82,7 +82,7 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) if (address > 0x16) { - ERROR_LOG(PIXELENGINE, "Read from address %#08x, returning %#08x\n", address, _uReturnValue); + ERROR_LOG(PIXELENGINE, "addr %#08x, ret %#08x; %#08x, %#08x, %#08x, %#08x, %#08x, %#08x\n", address, _uReturnValue, pereg.perfZcompInputZcomploc, pereg.perfZcompOutputZcomploc, pereg.perfZcompInput, pereg.perfZcompOutput, pereg.perfBlendInput, pereg.perfEfbCopyClocks); } } From 49d1da5e7e0e9ba3aecc8fc02285ca537623c3ea Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 27 Aug 2012 23:51:35 +0200 Subject: [PATCH 008/167] Video_Software: Fix stuff. --- .../Plugin_VideoSoftware/Src/BPMemLoader.cpp | 18 ++++++++++++------ .../Plugin_VideoSoftware/Src/Rasterizer.cpp | 7 +++++-- .../Plugin_VideoSoftware/Src/SWPixelEngine.cpp | 2 +- .../Plugin_VideoSoftware/Src/SWPixelEngine.h | 18 ++++++++++++------ .../Plugins/Plugin_VideoSoftware/Src/Tev.cpp | 9 ++++++--- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp index ad730a485c..4de9f435fa 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp @@ -92,12 +92,18 @@ void SWBPWritten(int address, int newvalue) break; case BPMEM_CLEAR_PIXEL_PERF: // TODO: Parameter? - SWPixelEngine::pereg.perfZcompInputZcomploc = 0; - SWPixelEngine::pereg.perfZcompOutputZcomploc = 0; - SWPixelEngine::pereg.perfZcompInput = 0; - SWPixelEngine::pereg.perfZcompOutput = 0; - SWPixelEngine::pereg.perfBlendInput = 0; - SWPixelEngine::pereg.perfEfbCopyClocks = 0; + SWPixelEngine::pereg.perfZcompInputZcomplocLo = 0; + SWPixelEngine::pereg.perfZcompInputZcomplocHi = 0; + SWPixelEngine::pereg.perfZcompOutputZcomplocLo = 0; + SWPixelEngine::pereg.perfZcompOutputZcomplocHi = 0; + SWPixelEngine::pereg.perfZcompInputLo = 0; + SWPixelEngine::pereg.perfZcompInputHi = 0; + SWPixelEngine::pereg.perfZcompOutputLo = 0; + SWPixelEngine::pereg.perfZcompOutputHi = 0; + SWPixelEngine::pereg.perfBlendInputLo = 0; + SWPixelEngine::pereg.perfBlendInputHi = 0; + SWPixelEngine::pereg.perfEfbCopyClocksLo = 0; + SWPixelEngine::pereg.perfEfbCopyClocksHi = 0; break; case BPMEM_LOADTLUT0: // This one updates bpmem.tlutXferSrc, no need to do anything here. break; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp index a23d85f27f..c9c3b8c26c 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp @@ -129,14 +129,17 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi) if (bpmem.zcontrol.zcomploc) { // TODO: Verify that perf regs are being incremented even if test is disabled - SWPixelEngine::pereg.perfZcompInputZcomploc++; + if (++SWPixelEngine::pereg.perfZcompInputZcomplocLo == 0) + SWPixelEngine::pereg.perfZcompInputZcomplocHi++; + if (bpmem.zmode.testenable) { // early z if (!EfbInterface::ZCompare(x, y, z)) return; } - SWPixelEngine::pereg.perfZcompOutputZcomploc++; + if (++SWPixelEngine::pereg.perfZcompOutputZcomplocLo == 0) + SWPixelEngine::pereg.perfZcompOutputZcomplocHi++; } RasterBlockPixel& pixel = rasterBlock.Pixel[xi][yi]; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp index 63885513f5..d489d033ae 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp @@ -82,7 +82,7 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) if (address > 0x16) { - ERROR_LOG(PIXELENGINE, "addr %#08x, ret %#08x; %#08x, %#08x, %#08x, %#08x, %#08x, %#08x\n", address, _uReturnValue, pereg.perfZcompInputZcomploc, pereg.perfZcompOutputZcomploc, pereg.perfZcompInput, pereg.perfZcompOutput, pereg.perfBlendInput, pereg.perfEfbCopyClocks); + ERROR_LOG(PIXELENGINE, "addr %#08x, ret %#08x\n", address, _uReturnValue); } } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h index 764488c32e..7deb69a164 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h @@ -146,12 +146,18 @@ namespace SWPixelEngine u16 boxTop; u16 boxBottom; - u16 perfZcompInputZcomploc; - u16 perfZcompOutputZcomploc; - u16 perfZcompInput; - u16 perfZcompOutput; - u16 perfBlendInput; - u16 perfEfbCopyClocks; + u16 perfZcompInputZcomplocLo; + u16 perfZcompInputZcomplocHi; + u16 perfZcompOutputZcomplocLo; + u16 perfZcompOutputZcomplocHi; + u16 perfZcompInputLo; + u16 perfZcompInputHi; + u16 perfZcompOutputLo; + u16 perfZcompOutputHi; + u16 perfBlendInputLo; + u16 perfBlendInputHi; + u16 perfEfbCopyClocksLo; + u16 perfEfbCopyClocksHi; }; extern PEReg pereg; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp index 83d9de2784..fad8806a9f 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp @@ -787,13 +787,15 @@ void Tev::Draw() if (!bpmem.zcontrol.zcomploc) { - SWPixelEngine::pereg.perfZcompInput++; + if (++SWPixelEngine::pereg.perfZcompInputLo == 0) + SWPixelEngine::pereg.perfZcompInputHi++; if (bpmem.zmode.testenable) { if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2])) return; } - SWPixelEngine::pereg.perfZcompOutput++; + if (++SWPixelEngine::pereg.perfZcompOutputLo == 0) + SWPixelEngine::pereg.perfZcompOutputHi++; } #if ALLOW_TEV_DUMPS @@ -818,7 +820,8 @@ void Tev::Draw() INCSTAT(swstats.thisFrame.tevPixelsOut); - SWPixelEngine::pereg.perfBlendInput++; + if (++SWPixelEngine::pereg.perfBlendInputLo) + SWPixelEngine::pereg.perfBlendInputHi++; EfbInterface::BlendTev(Position[0], Position[1], output); } From 3d56ce18fb60a5617ba037d988f7918f7d29aae5 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 31 Aug 2012 20:49:59 +0200 Subject: [PATCH 009/167] Video_Software: Fix moar stuff --- Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp index fad8806a9f..80d68833b6 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp @@ -820,7 +820,7 @@ void Tev::Draw() INCSTAT(swstats.thisFrame.tevPixelsOut); - if (++SWPixelEngine::pereg.perfBlendInputLo) + if (++SWPixelEngine::pereg.perfBlendInputLo == 0) SWPixelEngine::pereg.perfBlendInputHi++; EfbInterface::BlendTev(Position[0], Position[1], output); From 54947b1e2246804ddf5ec0378f8111905a6d04bd Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 31 Aug 2012 21:30:12 +0200 Subject: [PATCH 010/167] Video_Software: Some more debugging logs. --- Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp index d489d033ae..ad19eb87ee 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp @@ -82,7 +82,13 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) if (address > 0x16) { - ERROR_LOG(PIXELENGINE, "addr %#08x, ret %#08x\n", address, _uReturnValue); + ERROR_LOG(PIXELENGINE, "addr %#08x, ret %#04x; %#04x%04x, %#04x%04x, %#04x%04x, %#04x%04x, %#04x%04x, %#04x%04x\n", address, _uReturnValue, + pereg.perfZcompInputZcomplocHi, pereg.perfZcompInputZcomplocLo, + pereg.perfZcompOutputZcomplocHi, pereg.perfZcompOutputZcomplocLo, + pereg.perfZcompInputHi, pereg.perfZcompInputLo, + pereg.perfZcompOutputHi, pereg.perfZcompOutputLo, + pereg.perfBlendInputHi, pereg.perfBlendInputLo, + pereg.perfEfbCopyClocksHi, pereg.perfEfbCopyClocksLo); } } From b2acae44b780ecf86ffb88cd32861edb25642e20 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 15 Jan 2013 21:15:54 -0600 Subject: [PATCH 011/167] Real wiimote continuous scanning working on Linux. Windows and OS X totally broken from various refactoring. --- Source/Core/Core/Src/HW/Wiimote.h | 2 +- .../Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp | 2 +- .../Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp | 2 +- Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 229 ++++++------- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 312 ++++++++++++------ .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 73 +++- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 16 +- 7 files changed, 370 insertions(+), 266 deletions(-) diff --git a/Source/Core/Core/Src/HW/Wiimote.h b/Source/Core/Core/Src/HW/Wiimote.h index 5e0ab8d05e..d514cf9909 100644 --- a/Source/Core/Core/Src/HW/Wiimote.h +++ b/Source/Core/Core/Src/HW/Wiimote.h @@ -38,7 +38,7 @@ void Update(int _number); namespace WiimoteReal { -unsigned int Initialize(); +void Initialize(); void Shutdown(); void Refresh(); diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp index 5c34fff9ac..cfb81bb768 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp @@ -248,7 +248,7 @@ void Wiimote::RequestStatus(const wm_request_status* const rs) { using namespace WiimoteReal; - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(g_refresh_lock); if (g_wiimotes[m_index]) { diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp index b7652e973a..30fad4b458 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteEmu.cpp @@ -685,7 +685,7 @@ void Wiimote::Update() { using namespace WiimoteReal; - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(g_refresh_lock); if (g_wiimotes[m_index]) { Report rpt = g_wiimotes[m_index]->ProcessReadQueue(); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index ec838d9313..82630aaebb 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -15,16 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include -#include - -#include -#include -#include -#include -#include -#include - #include #include #include @@ -32,114 +22,117 @@ #include "Common.h" #include "WiimoteReal.h" -#include "Host.h" namespace WiimoteReal { +WiimoteScanner::WiimoteScanner() + : run_thread() + , want_wiimotes() + , device_id(-1) + , device_sock(-1) +{ + // Get the id of the first bluetooth device. + device_id = hci_get_route(NULL); + if (device_id < 0) + { + NOTICE_LOG(WIIMOTE, "Bluetooth not found."); + return; + } + + // Create a socket to the device + device_sock = hci_open_dev(device_id); + if (device_sock < 0) + { + ERROR_LOG(WIIMOTE, "Unable to open bluetooth."); + return; + } +} + +bool WiimoteScanner::IsReady() const +{ + return device_sock > 0; +} + +WiimoteScanner::~WiimoteScanner() +{ + if (IsReady()) + close(device_sock); +} + // Find wiimotes. // Does not replace already found wiimotes even if they are disconnected. // wm is an array of max_wiimotes wiimotes // Returns the total number of found wiimotes. -int FindWiimotes(Wiimote** wm, int max_wiimotes) +std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) { - int device_id; - int device_sock; - int found_devices; - int found_wiimotes = 0; - int i; + std::vector found_wiimotes; - // Count the number of already found wiimotes - for (i = 0; i < MAX_WIIMOTES; ++i) - { - if (wm[i]) - found_wiimotes++; - } + // supposedly 1.28 seconds + int const wait_len = 1; - // Get the id of the first bluetooth device. - if ((device_id = hci_get_route(NULL)) < 0) + int const max_infos = 255; + inquiry_info scan_infos[max_infos] = {}; + auto* scan_infos_ptr = scan_infos; + + // Scan for bluetooth devices + int const found_devices = hci_inquiry(device_id, wait_len, max_infos, NULL, &scan_infos_ptr, IREQ_CACHE_FLUSH); + if (found_devices < 0) { - NOTICE_LOG(WIIMOTE, "Bluetooth not found."); + ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices."); return found_wiimotes; } - // Create a socket to the device - if ((device_sock = hci_open_dev(device_id)) < 0) - { - ERROR_LOG(WIIMOTE, "Unable to open bluetooth."); - return found_wiimotes; - } + DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices); - int try_num = 0; - while ((try_num < 5) && (found_wiimotes < max_wiimotes)) + // Display discovered devices + for (int i = 0; (i < found_devices) && (found_wiimotes.size() < max_wiimotes); ++i) { - inquiry_info scan_info_arr[128]; - inquiry_info* scan_info = scan_info_arr; - memset(&scan_info_arr, 0, sizeof(scan_info_arr)); - - // Scan for bluetooth devices for approximately one second - found_devices = hci_inquiry(device_id, 1, 128, NULL, &scan_info, IREQ_CACHE_FLUSH); - if (found_devices < 0) + ERROR_LOG(WIIMOTE, "found a device..."); + + // BT names are a maximum of 248 bytes apparently + char name[255] = {}; + if (hci_read_remote_name(device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 0) < 0) { - ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices."); - return found_wiimotes; + ERROR_LOG(WIIMOTE, "name request failed"); + continue; } - DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices); - - // Display discovered devices - for (i = 0; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) + ERROR_LOG(WIIMOTE, "device name %s", name); + if (IsValidBluetoothName(name)) { - char name[1000]; - memset(name, 0, sizeof(name)); - ERROR_LOG(WIIMOTE, "found a device..."); - if (hci_read_remote_name(device_sock, &scan_info[i].bdaddr, sizeof(name), name, 0) < 0) { - ERROR_LOG(WIIMOTE, "name request failed"); - continue; - } - ERROR_LOG(WIIMOTE, "device name %s", name); - if (IsValidBluetoothName(name)) + bool new_wiimote = true; + + // TODO: do this + + // Determine if this wiimote has already been found. + //for (int j = 0; j < MAX_WIIMOTES && new_wiimote; ++j) + //{ + // if (wm[j] && bacmp(&scan_infos[i].bdaddr,&wm[j]->bdaddr) == 0) + // new_wiimote = false; + //} + + if (new_wiimote) { - bool new_wiimote = true; - // Determine if this wiimote has already been found. - for (int j = 0; j < MAX_WIIMOTES && new_wiimote; ++j) - { - if (wm[j] && bacmp(&scan_info[i].bdaddr,&wm[j]->bdaddr) == 0) - new_wiimote = false; - } + // Found a new device + char bdaddr_str[18] = {}; + ba2str(&scan_infos[i].bdaddr, bdaddr_str); - if (new_wiimote) - { - // Find an unused slot - unsigned int k = 0; - for (; k < MAX_WIIMOTES && !(WIIMOTE_SRC_REAL & g_wiimote_sources[k] && !wm[k]); ++k); - wm[k] = new Wiimote(k); - - // Found a new device - char bdaddr_str[18]; - ba2str(&scan_info[i].bdaddr, bdaddr_str); - - NOTICE_LOG(WIIMOTE, "Found wiimote %i, (%s).", - wm[k]->index + 1, bdaddr_str); - - wm[k]->bdaddr = scan_info[i].bdaddr; - ++found_wiimotes; - } + auto* const wm = new Wiimote; + wm->bdaddr = scan_infos[i].bdaddr; + found_wiimotes.push_back(wm); + + NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str); } } - try_num++; } - close(device_sock); return found_wiimotes; } // Connect to a wiimote with a known address. -bool Wiimote::Connect() +bool Wiimote::Open() { - if (IsConnected()) - return false; - sockaddr_l2 addr; addr.l2_family = AF_BLUETOOTH; addr.l2_bdaddr = bdaddr; @@ -148,7 +141,7 @@ bool Wiimote::Connect() // Output channel addr.l2_psm = htobs(WM_OUTPUT_CHANNEL); if ((cmd_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1 || - connect(cmd_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) + connect(cmd_sock, (sockaddr*)&addr, sizeof(addr)) < 0) { DEBUG_LOG(WIIMOTE, "Unable to open output socket to wiimote."); close(cmd_sock); @@ -159,7 +152,7 @@ bool Wiimote::Connect() // Input channel addr.l2_psm = htobs(WM_INPUT_CHANNEL); if ((int_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1 || - connect(int_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) + connect(int_sock, (sockaddr*)&addr, sizeof(addr)) < 0) { DEBUG_LOG(WIIMOTE, "Unable to open input socket from wiimote."); close(int_sock); @@ -168,57 +161,37 @@ bool Wiimote::Connect() return false; } - NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", index + 1); - - m_connected = true; - - // Do the handshake - Handshake(); - - // Set LEDs - SetLEDs(WIIMOTE_LED_1 << index); - - m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this); - return true; } -// Disconnect a wiimote. -void Wiimote::RealDisconnect() +void Wiimote::StartThread() { - if (!IsConnected()) - return; - - NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i.", index + 1); - - m_connected = false; + m_run_thread = true; + m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this); +} +void Wiimote::StopThread() +{ + m_run_thread = false; if (m_wiimote_thread.joinable()) m_wiimote_thread.join(); - - Close(); } void Wiimote::Close() { - if (IsOpen()) - { - Host_ConnectWiimote(index, false); + close(cmd_sock); + close(int_sock); - close(cmd_sock); - close(int_sock); - - cmd_sock = -1; - int_sock = -1; - } + cmd_sock = -1; + int_sock = -1; } bool Wiimote::IsOpen() const { - return IsConnected() && cmd_sock != -1 && int_sock != -1; + return cmd_sock != -1;// && int_sock != -1; } -int Wiimote::IORead(unsigned char *buf) +int Wiimote::IORead(u8* buf) { // Block select for 1/2000th of a second timeval tv; @@ -232,11 +205,11 @@ int Wiimote::IORead(unsigned char *buf) if (select(int_sock + 1, &fds, NULL, NULL, &tv) == -1) { ERROR_LOG(WIIMOTE, "Unable to select wiimote %i input socket.", index + 1); - return 0; + return -1; } if (!FD_ISSET(int_sock, &fds)) - return 0; + return -1; // Read the pending message into the buffer int r = read(int_sock, buf, MAX_PAYLOAD); @@ -250,21 +223,15 @@ int Wiimote::IORead(unsigned char *buf) // This can happen if the bluetooth dongle is disconnected ERROR_LOG(WIIMOTE, "Bluetooth appears to be disconnected. " "Wiimote %i will be disconnected.", index + 1); - Close(); } - return 0; - } - else if (!r) - { - // Disconnect - Close(); + r = 0; } return r; } -int Wiimote::IOWrite(unsigned char* buf, int len) +int Wiimote::IOWrite(u8 const* buf, int len) { return write(int_sock, buf, len); } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 2381793f30..2735c1a312 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -23,6 +23,7 @@ #include "IniFile.h" #include "StringUtil.h" #include "Timer.h" +#include "Host.h" #include "WiimoteReal.h" @@ -33,15 +34,20 @@ unsigned int g_wiimote_sources[MAX_WIIMOTES]; namespace WiimoteReal { +void HandleFoundWiimotes(const std::vector&); +void HandleWiimoteConnect(Wiimote*); +void HandleWiimoteDisconnect(int index); + bool g_real_wiimotes_initialized = false; -unsigned int g_wiimotes_found = 0; -std::mutex g_refresh_lock; +std::recursive_mutex g_refresh_lock; -Wiimote *g_wiimotes[MAX_WIIMOTES]; +Wiimote* g_wiimotes[MAX_WIIMOTES]; -Wiimote::Wiimote(const unsigned int _index) - : index(_index) +WiimoteScanner g_wiimote_scanner; + +Wiimote::Wiimote() + : index() #ifdef __APPLE__ , inputlen(0) #elif defined(__linux__) && HAVE_BLUEZ @@ -49,8 +55,8 @@ Wiimote::Wiimote(const unsigned int _index) #elif defined(_WIN32) , dev_handle(0), stack(MSBT_STACK_UNKNOWN) #endif - , leds(0), m_last_data_report(Report((u8 *)NULL, 0)) - , m_channel(0), m_connected(false) + , m_last_data_report(Report((u8 *)NULL, 0)) + , m_channel(0), m_run_thread(false) { #if defined(__linux__) && HAVE_BLUEZ bdaddr = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; @@ -61,8 +67,11 @@ Wiimote::Wiimote(const unsigned int _index) Wiimote::~Wiimote() { - RealDisconnect(); + StopThread(); + if (IsOpen()) + Close(); + ClearReadQueue(); // clear write queue @@ -111,7 +120,7 @@ void Wiimote::ControlChannel(const u16 channel, const void* const data, const u3 { // Check for custom communication if (99 == channel) - Disconnect(); + EmuStop(); else { InterruptChannel(channel, data, size); @@ -168,6 +177,9 @@ bool Wiimote::Read() rpt.first = new unsigned char[MAX_PAYLOAD]; rpt.second = IORead(rpt.first); + if (0 == rpt.second) + Close(); + if (rpt.second > 0 && m_channel > 0) { // Add it to queue m_read_reports.Push(rpt); @@ -234,24 +246,18 @@ void Wiimote::Update() delete[] rpt.first; } -void Wiimote::Disconnect() +void Wiimote::EmuStop() { m_channel = 0; DisableDataReporting(); -} -bool Wiimote::IsConnected() const -{ - return m_connected; + NOTICE_LOG(WIIMOTE, "Stopping wiimote data reporting"); } // Rumble briefly void Wiimote::Rumble() { - if (!IsConnected()) - return; - unsigned char buffer = 0x01; DEBUG_LOG(WIIMOTE, "Starting rumble..."); SendRequest(WM_CMD_RUMBLE, &buffer, 1); @@ -264,37 +270,29 @@ void Wiimote::Rumble() } // Set the active LEDs. -// leds is a bitwise or of WIIMOTE_LED_1 through WIIMOTE_LED_4. +// leds is a bitwise OR of WIIMOTE_LED_1 through WIIMOTE_LED_4. void Wiimote::SetLEDs(int new_leds) { - unsigned char buffer; - - if (!IsConnected()) - return; - // Remove the lower 4 bits because they control rumble - buffer = leds = (new_leds & 0xF0); - + u8 const buffer = (new_leds & 0xF0); SendRequest(WM_CMD_LED, &buffer, 1); } -// Send a handshake -bool Wiimote::Handshake() +bool Wiimote::EmuStart() { + // Send a handshake + // Set buffer[0] to 0x04 for continuous reporting - unsigned char buffer[2] = {0x04, 0x30}; + u8 const buffer[2] = {0x04, 0x30}; - if (!IsConnected()) - return 0; - - DEBUG_LOG(WIIMOTE, "Sending handshake to wiimote"); + NOTICE_LOG(WIIMOTE, "Sending handshake to wiimote"); return SendRequest(WM_CMD_REPORT_TYPE, buffer, 2); } // Send a packet to the wiimote. // report_type should be one of WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc. -bool Wiimote::SendRequest(unsigned char report_type, unsigned char* data, int length) +bool Wiimote::SendRequest(u8 report_type, u8 const* data, int length) { unsigned char buffer[32] = {WM_SET_REPORT | WM_BT_OUTPUT, report_type}; @@ -303,59 +301,99 @@ bool Wiimote::SendRequest(unsigned char report_type, unsigned char* data, int le return (IOWrite(buffer, length + 2) != 0); } +unsigned int CalculateWantedWiimotes() +{ + // Figure out how many real wiimotes are required + unsigned int wanted_wiimotes = 0; + for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) + if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i]) + ++wanted_wiimotes; + + return wanted_wiimotes; +} + +void WiimoteScanner::WantWiimotes(size_t count) +{ + want_wiimotes = count; +} + +void WiimoteScanner::StartScanning() +{ + run_thread = true; + scan_thread = std::thread(std::mem_fun(&WiimoteScanner::ThreadFunc), this); +} + +void WiimoteScanner::StopScanning() +{ + run_thread = false; + if (scan_thread.joinable()) + { + scan_thread.join(); + NOTICE_LOG(WIIMOTE, "Wiimote scanning has stopped"); + } +} + +void WiimoteScanner::ThreadFunc() +{ + Common::SetCurrentThreadName("Wiimote Scanning Thread"); + + NOTICE_LOG(WIIMOTE, "Wiimote scanning has started"); + + while (run_thread) + { + auto const found_wiimotes = FindWiimotes(want_wiimotes); + HandleFoundWiimotes(found_wiimotes); +#if 1 + { + // TODO: this code here is ugly + std::lock_guard lk(g_refresh_lock); + for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + if (g_wiimotes[i] && !g_wiimotes[i]->IsOpen()) + HandleWiimoteDisconnect(i); + } +#endif + //std::this_thread::yield(); + Common::SleepCurrentThread(500); + } +} + void Wiimote::ThreadFunc() { - char thname[] = "Wiimote # Thread"; - thname[8] = (char)('1' + index); - Common::SetCurrentThreadName(thname); + Common::SetCurrentThreadName("Wiimote Device Thread"); // rumble briefly Rumble(); // main loop - while (IsOpen()) + while (m_run_thread && IsOpen()) { #ifdef __APPLE__ while (Write()) {} Common::SleepCurrentThread(1); #else - bool read = false; - while (Write() || (read = true, IsOpen() && Read())) + // TODO: this is all a mess + while (m_run_thread && IsOpen()) { - if (m_audio_reports.Size() && !read) - Read(); - Common::SleepCurrentThread(m_audio_reports.Size() ? 5 : 2); - read = false; + bool const did_write = Write(); + + if (did_write) + break; + else + if (!Read()) + break; + + // TODO: what is this doing? + //if (m_audio_reports.Size() && did_write) + // Read(); + + // TODO: make work well + //Common::SleepCurrentThread(m_audio_reports.Size() ? 5 : 2); + Common::SleepCurrentThread(2); } #endif } } -#ifndef _WIN32 -// Connect all discovered wiimotes -// Return the number of wiimotes that successfully connected. -static int ConnectWiimotes(Wiimote** wm) -{ - int connected = 0; - - for (int i = 0; i < MAX_WIIMOTES; ++i) - { - if (!wm[i] || wm[i]->IsConnected()) - continue; - - if (wm[i]->Connect()) - ++connected; - else - { - delete wm[i]; - wm[i] = NULL; - } - } - - return connected; -} -#endif - void LoadSettings() { std::string ini_filename = File::GetUserPath(D_CONFIG_IDX) + WIIMOTE_INI_NAME ".ini"; @@ -373,71 +411,124 @@ void LoadSettings() } } -unsigned int Initialize() +void Initialize() { - // Return if already initialized + NOTICE_LOG(WIIMOTE, "WiimoteReal::Initialize"); + + std::lock_guard lk(g_refresh_lock); + if (g_real_wiimotes_initialized) - return g_wiimotes_found; + return; - memset(g_wiimotes, 0, sizeof(g_wiimotes)); + auto const wanted_wiimotes = CalculateWantedWiimotes(); + g_wiimote_scanner.WantWiimotes(wanted_wiimotes); - // Only call FindWiimotes with the number of slots configured for real wiimotes - unsigned int wanted_wiimotes = 0; - for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) - if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]) - ++wanted_wiimotes; + //if (wanted_wiimotes > 0) + g_wiimote_scanner.StartScanning(); - // Don't bother initializing if we don't want any real wiimotes - if (0 == wanted_wiimotes) - { - g_wiimotes_found = 0; - return 0; - } - - // Initialized g_real_wiimotes_initialized = true; - - g_wiimotes_found = FindWiimotes(g_wiimotes, wanted_wiimotes); - - DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted", - g_wiimotes_found, wanted_wiimotes); - -#ifndef _WIN32 - atexit(WiimoteReal::Shutdown); - g_wiimotes_found = ConnectWiimotes(g_wiimotes); -#endif - - DEBUG_LOG(WIIMOTE, "Connected to %i Real Wiimotes", g_wiimotes_found); - - return g_wiimotes_found; } void Shutdown(void) { - if (false == g_real_wiimotes_initialized) + NOTICE_LOG(WIIMOTE, "WiimoteReal::Shutdown"); + + g_wiimote_scanner.StopScanning(); + + std::lock_guard lk(g_refresh_lock); + + if (!g_real_wiimotes_initialized) return; - // Uninitialized g_real_wiimotes_initialized = false; - // Delete wiimotes for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) - if (g_wiimotes[i]) + HandleWiimoteDisconnect(i); +} + +void ChangeWiimoteSource(unsigned int index, int source) +{ + std::lock_guard lk(g_refresh_lock); + + g_wiimote_sources[index] = source; + + // source is emulated, kill any real connection + if (!(WIIMOTE_SRC_REAL & g_wiimote_sources[index])) + HandleWiimoteDisconnect(index); + + auto const wanted_wiimotes = CalculateWantedWiimotes(); + g_wiimote_scanner.WantWiimotes(wanted_wiimotes); +} + +void HandleWiimoteConnect(Wiimote* wm) +{ + std::lock_guard lk(g_refresh_lock); + + for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + { + if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i]) { - delete g_wiimotes[i]; - g_wiimotes[i] = NULL; + g_wiimotes[i] = wm; + + wm->index = i; + wm->StartThread(); + wm->SetLEDs(WIIMOTE_LED_1 << i); + + Host_ConnectWiimote(i, true); + + NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", i + 1); + + wm = NULL; + break; } + } + + delete wm; + + auto const want_wiimotes = CalculateWantedWiimotes(); + g_wiimote_scanner.WantWiimotes(want_wiimotes); +} + +void HandleWiimoteDisconnect(int index) +{ + // locked above + //std::lock_guard lk(g_refresh_lock); + + Host_ConnectWiimote(index, false); + + if (g_wiimotes[index]) + { + delete g_wiimotes[index]; + g_wiimotes[index] = NULL; + + NOTICE_LOG(WIIMOTE, "Disconnected wiimote %i.", index + 1); + } + + auto const want_wiimotes = CalculateWantedWiimotes(); + g_wiimote_scanner.WantWiimotes(want_wiimotes); +} + +void HandleFoundWiimotes(const std::vector& wiimotes) +{ + std::for_each(wiimotes.begin(), wiimotes.end(), [](Wiimote* const wm) + { + if (wm->Open()) + HandleWiimoteConnect(wm); + else + delete wm; + }); } // This is called from the GUI thread void Refresh() { - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(g_refresh_lock); #ifdef _WIN32 Shutdown(); Initialize(); #else +/* // Make sure real wiimotes have been initialized if (!g_real_wiimotes_initialized) { @@ -477,12 +568,13 @@ void Refresh() g_wiimotes_found = num_wiimotes; } +*/ #endif } void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) { - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(g_refresh_lock); if (g_wiimotes[_WiimoteNumber]) g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size); @@ -490,7 +582,7 @@ void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u3 void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) { - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(g_refresh_lock); if (g_wiimotes[_WiimoteNumber]) g_wiimotes[_WiimoteNumber]->ControlChannel(_channelID, _pData, _Size); @@ -500,7 +592,7 @@ void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 // Read the Wiimote once void Update(int _WiimoteNumber) { - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(g_refresh_lock); if (g_wiimotes[_WiimoteNumber]) g_wiimotes[_WiimoteNumber]->Update(); @@ -508,7 +600,7 @@ void Update(int _WiimoteNumber) void StateChange(EMUSTATE_CHANGE newState) { - //std::lock_guard lk(g_refresh_lock); + //std::lock_guard lk(g_refresh_lock); // TODO: disable/enable auto reporting, maybe } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 9fdb305a56..5f8206bf14 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -20,6 +20,7 @@ #define WIIMOTE_REAL_H #include +#include #include "WiimoteRealBase.h" #include "ChunkFile.h" @@ -41,7 +42,7 @@ class Wiimote : NonCopyable { friend class WiimoteEmu::Wiimote; public: - Wiimote(const unsigned int _index); + Wiimote(); ~Wiimote(); void ControlChannel(const u16 channel, const void* const data, const u32 size); @@ -52,16 +53,28 @@ public: bool Read(); bool Write(); - bool Connect(); - bool IsConnected() const; + + void StartThread(); + void StopThread(); + + // "handshake" / stop packets + bool EmuStart(); + void EmuStop(); + + // connecting and disconnecting from physical devices + bool Open(); + void Close(); + + // TODO: change to something like IsRelevant bool IsOpen() const; - void Disconnect(); + + void SetLEDs(int leds); + void DisableDataReporting(); void Rumble(); void SendPacket(const u8 rpt_id, const void* const data, const unsigned int size); - void RealDisconnect(); - const unsigned int index; + int index; #if defined(__APPLE__) IOBluetoothDevice *btd; @@ -74,8 +87,6 @@ public: int cmd_sock; // Command socket int int_sock; // Interrupt socket - void Close(); - #elif defined(_WIN32) char devicepath[255]; // Unique wiimote reference //ULONGLONG btaddr; // Bluetooth address @@ -83,7 +94,6 @@ public: OVERLAPPED hid_overlap; // Overlap handle enum win_bt_stack_t stack; // Type of bluetooth stack to use #endif - unsigned char leds; // Currently lit leds protected: Report m_last_data_report; @@ -91,21 +101,51 @@ protected: private: void ClearReadQueue(); - bool SendRequest(unsigned char report_type, unsigned char* data, int length); - bool Handshake(); - void SetLEDs(int leds); - int IORead(unsigned char* buf); - int IOWrite(unsigned char* buf, int len); + bool SendRequest(u8 report_type, u8 const* data, int length); + + int IORead(u8* buf); + int IOWrite(u8 const* buf, int len); + void ThreadFunc(); - bool m_connected; + bool m_run_thread; std::thread m_wiimote_thread; + Common::FifoQueue m_read_reports; Common::FifoQueue m_write_reports; Common::FifoQueue m_audio_reports; }; -extern std::mutex g_refresh_lock; +class WiimoteScanner +{ +public: + WiimoteScanner(); + ~WiimoteScanner(); + + bool IsReady() const; + + void WantWiimotes(size_t count); + + void StartScanning(); + void StopScanning(); + + std::vector FindWiimotes(size_t max_wiimotes); + +private: + void ThreadFunc(); + + std::thread scan_thread; + + volatile bool run_thread; + + // TODO: this should probably be atomic + volatile size_t want_wiimotes; + + int device_id; + int device_sock; +}; + +extern std::recursive_mutex g_refresh_lock; extern Wiimote *g_wiimotes[4]; void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size); @@ -116,6 +156,7 @@ void DoState(PointerWrap &p); void StateChange(EMUSTATE_CHANGE newState); int FindWiimotes(Wiimote** wm, int max_wiimotes); +void ChangeWiimoteSource(unsigned int index, int source); bool IsValidBluetoothName(const std::string& name); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index ea23e532e7..ba2186d17a 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -4,11 +4,12 @@ #include "HW/WiimoteReal/WiimoteReal.h" #include "Frame.h" -const wxString& ConnectedWiimotesString() +wxString ConnectedWiimotesString() { - static wxString str; - str.Printf(_("%i connected"), WiimoteReal::Initialize()); - return str; + //static wxString str; + //str.Printf(_("%i connected"), WiimoteReal::Initialize()); + //return str; + return "TODO: this text"; } WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin) @@ -222,13 +223,16 @@ void WiimoteConfigDiag::SelectSource(wxCommandEvent& event) // This needs to be changed now in order for refresh to work right. // Revert if the dialog is canceled. int index = m_wiimote_index_from_ctrl_id[event.GetId()]; - g_wiimote_sources[index] = event.GetInt(); + + WiimoteReal::ChangeWiimoteSource(index, event.GetInt()); + if (g_wiimote_sources[index] != WIIMOTE_SRC_EMU && g_wiimote_sources[index] != WIIMOTE_SRC_HYBRID) wiimote_configure_bt[index]->Disable(); else wiimote_configure_bt[index]->Enable(); } +// TODO: race conditiions void WiimoteConfigDiag::UpdateWiimoteStatus() { for (int index = 0; index < 4; ++index) @@ -241,7 +245,7 @@ void WiimoteConfigDiag::UpdateWiimoteStatus() if (WIIMOTE_SRC_EMU & g_wiimote_sources[index]) CFrame::ConnectWiimote(index, true); else if (WIIMOTE_SRC_REAL & g_wiimote_sources[index] && WiimoteReal::g_wiimotes[index]) - CFrame::ConnectWiimote(index, WiimoteReal::g_wiimotes[index]->IsConnected()); + CFrame::ConnectWiimote(index, WiimoteReal::g_wiimotes[index]->IsOpen()); } } } From 54497be653dfdf2de558426cf460a8b8a96bd524 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 15 Jan 2013 22:57:25 -0600 Subject: [PATCH 012/167] Untested Windows buildfix attempt. --- .../Core/Core/Src/HW/WiimoteReal/IODummy.cpp | 16 +- Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 6 +- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 213 ++++++++---------- .../Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 19 +- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 14 +- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 13 +- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 2 +- 7 files changed, 139 insertions(+), 144 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index 49afee8ad1..b22f1c7795 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -21,9 +21,19 @@ namespace WiimoteReal { -int FindWiimotes(Wiimote **wm, int max_wiimotes) +WiimoteScanner::WiimoteScanner() { - return 0; + return; +} + +std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) +{ + return std::vector() +} + +bool WiimoteScanner::IsReady() const +{ + return false; } bool Wiimote::Connect() @@ -31,7 +41,7 @@ bool Wiimote::Connect() return 0; } -void Wiimote::RealDisconnect() +void Wiimote::Disconnect() { return; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index 82630aaebb..24e25e9a2b 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -131,7 +131,7 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) } // Connect to a wiimote with a known address. -bool Wiimote::Open() +bool Wiimote::Connect() { sockaddr_l2 addr; addr.l2_family = AF_BLUETOOTH; @@ -177,7 +177,7 @@ void Wiimote::StopThread() m_wiimote_thread.join(); } -void Wiimote::Close() +void Wiimote::Disconnect() { close(cmd_sock); close(int_sock); @@ -186,7 +186,7 @@ void Wiimote::Close() int_sock = -1; } -bool Wiimote::IsOpen() const +bool Wiimote::IsConnected() const { return cmd_sock != -1;// && int_sock != -1; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index cc05bc10e1..f862193ff9 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -127,12 +127,21 @@ inline void init_lib() namespace WiimoteReal { +WiimoteScanner::WiimoteScanner() +{ + init_lib(); +} + // Find and connect wiimotes. // Does not replace already found wiimotes even if they are disconnected. // wm is an array of max_wiimotes wiimotes // Returns the total number of found and connected wiimotes. -int FindWiimotes(Wiimote** wm, int max_wiimotes) +std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) { + PairUp(); + + std::vector wiimotes; + GUID device_id; HANDLE dev; HDEVINFO device_info; @@ -142,8 +151,6 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes) PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; HIDD_ATTRIBUTES attr; - init_lib(); - // Count the number of already found wiimotes for (int i = 0; i < MAX_WIIMOTES; ++i) { @@ -207,22 +214,11 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes) // Find an unused slot unsigned int k = 0; - for (; k < MAX_WIIMOTES && !(WIIMOTE_SRC_REAL & g_wiimote_sources[k] && !wm[k]); ++k); - wm[k] = new Wiimote(k); - wm[k]->dev_handle = dev; - memcpy(wm[k]->devicepath, detail_data->DevicePath, 197); + auto const wm = new Wiimote; + wm->dev_handle = dev; + memcpy(wm->devicepath, detail_data->DevicePath, 197); - if (!wm[k]->Connect()) - { - ERROR_LOG(WIIMOTE, "Unable to connect to wiimote %i.", wm[k]->index + 1); - delete wm[k]; - wm[k] = NULL; - CloseHandle(dev); - } - else - { - ++found_wiimotes; - } + found_wiimotes.push_back(wm); } if (detail_data) @@ -233,87 +229,64 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes) return found_wiimotes; } +bool WiimoteScanner::IsReady() const +{ + // TODO: impl + return true; +} + // Connect to a wiimote with a known device path. bool Wiimote::Connect() { - if (IsConnected()) return false; + dev_handle = CreateFile(devicepath, + (GENERIC_READ | GENERIC_WRITE), + (FILE_SHARE_READ | FILE_SHARE_WRITE), + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - if (!dev_handle) + if (dev_handle == INVALID_HANDLE_VALUE) { - dev_handle = CreateFile(devicepath, - (GENERIC_READ | GENERIC_WRITE), - (FILE_SHARE_READ | FILE_SHARE_WRITE), - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - if (dev_handle == INVALID_HANDLE_VALUE) - return false; + dev_handle = 0; + return false; } hid_overlap.hEvent = CreateEvent(NULL, 1, 1, _T("")); hid_overlap.Offset = 0; hid_overlap.OffsetHigh = 0; - m_connected = true; - - // Try a handshake to see if the device is actually connected - if (!Handshake()) - { - m_connected = false; - return false; - } - - // Set LEDs - SetLEDs(WIIMOTE_LED_1 << index); - - m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this); - + // TODO: do this elsewhere // This isn't as drastic as it sounds, since the process in which the threads // reside is normal priority. Needed for keeping audio reports at a decent rate +/* if (!SetThreadPriority(m_wiimote_thread.native_handle(), THREAD_PRIORITY_TIME_CRITICAL)) { ERROR_LOG(WIIMOTE, "Failed to set wiimote thread priority"); } - - NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", index + 1); +*/ return true; } -void Wiimote::RealDisconnect() +void Wiimote::Disconnect() { - if (!IsConnected()) - return; - - m_connected = false; - - if (m_wiimote_thread.joinable()) - m_wiimote_thread.join(); - CloseHandle(dev_handle); dev_handle = 0; - ResetEvent(&hid_overlap); + //ResetEvent(&hid_overlap); + CloseHandle(hid_overlap.hEvent); } -bool Wiimote::IsOpen() const +bool Wiimote::IsConnected() const { - return IsConnected(); + return dev_handle != 0; } int Wiimote::IORead(unsigned char* buf) { - DWORD b, r; - - init_lib(); - - if (!IsConnected()) - return 0; - - *buf = 0; + //*buf = 0; if (!ReadFile(dev_handle, buf, MAX_PAYLOAD, &b, &hid_overlap)) { // Partial read - b = GetLastError(); - + auto const b = GetLastError(); if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) { // Remote disconnect @@ -321,7 +294,7 @@ int Wiimote::IORead(unsigned char* buf) return 0; } - r = WaitForSingleObject(hid_overlap.hEvent, WIIMOTE_DEFAULT_TIMEOUT); + auto const r = WaitForSingleObject(hid_overlap.hEvent, WIIMOTE_DEFAULT_TIMEOUT); if (r == WAIT_TIMEOUT) { // Timeout - cancel and continue @@ -357,77 +330,71 @@ int Wiimote::IORead(unsigned char* buf) int Wiimote::IOWrite(unsigned char* buf, int len) { - DWORD bytes, dw; - int i; - - init_lib(); - - if (!IsConnected()) - return 0; - switch (stack) { - case MSBT_STACK_UNKNOWN: - { - // Try to auto-detect the stack type - if (i = WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap)) - { - // Bluesoleil will always return 1 here, even if it's not connected - stack = MSBT_STACK_BLUESOLEIL; - return i; - } - - if (i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1)) - { - stack = MSBT_STACK_MS; - return i; - } - - dw = GetLastError(); - // Checking for 121 = timeout on semaphore/device off/disconnected to - // avoid trouble with other stacks toshiba/widcomm - if (dw == 121) - { - NOTICE_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]: Timeout"); - RealDisconnect(); - } - else ERROR_LOG(WIIMOTE, - "IOWrite[MSBT_STACK_UNKNOWN]: ERROR: %08x", dw); - return 0; - } - - case MSBT_STACK_MS: - i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1); - dw = GetLastError(); - - if (dw == 121) - { - // Semaphore timeout - NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to wiimote"); - RealDisconnect(); - return 0; - } + case MSBT_STACK_UNKNOWN: + { + // Try to auto-detect the stack type + DWORD bytes = 0; + auto i = WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap); + if (i) + { + // Bluesoleil will always return 1 here, even if it's not connected + stack = MSBT_STACK_BLUESOLEIL; return i; + } - case MSBT_STACK_BLUESOLEIL: - return WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap); + i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1); + if (i) + { + stack = MSBT_STACK_MS; + return i; + } + + auto const dw = GetLastError(); + // Checking for 121 = timeout on semaphore/device off/disconnected to + // avoid trouble with other stacks toshiba/widcomm + if (dw == 121) + { + NOTICE_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]: Timeout"); + return 0; + } + else + { + ERROR_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]: ERROR: %08x", dw); + // Correct? + return -1 + } + break; + } + case MSBT_STACK_MS: + { + i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1); + dw = GetLastError(); + + if (dw == 121) + { + // Semaphore timeout + NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to wiimote"); + RealDisconnect(); + return 0; + } + + return i; + break; + } + case MSBT_STACK_BLUESOLEIL: + return WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap); + break; } return 0; } -int UnPair() -{ - // TODO: - return 0; -} - // WiiMote Pair-Up, function will return amount of either new paired or unpaired devices // negative number on failure int PairUp(bool unpair) { - init_lib(); - // match strings like "Nintendo RVL-WBC-01", "Nintendo RVL-CNT-01", "Nintendo RVL-CNT-01-TR" const std::wregex wiimote_device_name(L"Nintendo RVL-\\w{3}-\\d{2}(-\\w{2})?"); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 64de880180..95068fe650 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -10,6 +10,19 @@ } @end +WiimoteScanner::WiimoteScanner() +{} + +std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) +{ + return std::vector(); +} + +bool WiimoteScanner::IsReady() const +{ + return false; +} + @implementation SearchBT - (void) deviceInquiryComplete: (IOBluetoothDeviceInquiry *) sender error: (IOReturn) error @@ -92,7 +105,7 @@ WARN_LOG(WIIMOTE, "Lost channel to wiimote %i", wm->index + 1); - wm->RealDisconnect(); + wm->Disconnect(); } @end @@ -182,7 +195,7 @@ bool Wiimote::Connect() if (ichan == NULL || cchan == NULL) { ERROR_LOG(WIIMOTE, "Unable to open L2CAP channels " "for wiimote %i", index + 1); - RealDisconnect(); + Disconnect(); return false; } @@ -207,7 +220,7 @@ bool Wiimote::Connect() } // Disconnect a wiimote. -void Wiimote::RealDisconnect() +void Wiimote::Disconnect() { if (!IsConnected()) return; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 2735c1a312..d25a78490d 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -69,8 +69,8 @@ Wiimote::~Wiimote() { StopThread(); - if (IsOpen()) - Close(); + if (IsConnected()) + Disconnect(); ClearReadQueue(); @@ -178,7 +178,7 @@ bool Wiimote::Read() rpt.second = IORead(rpt.first); if (0 == rpt.second) - Close(); + Disconnect(); if (rpt.second > 0 && m_channel > 0) { // Add it to queue @@ -348,7 +348,7 @@ void WiimoteScanner::ThreadFunc() // TODO: this code here is ugly std::lock_guard lk(g_refresh_lock); for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) - if (g_wiimotes[i] && !g_wiimotes[i]->IsOpen()) + if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected()) HandleWiimoteDisconnect(i); } #endif @@ -365,14 +365,14 @@ void Wiimote::ThreadFunc() Rumble(); // main loop - while (m_run_thread && IsOpen()) + while (m_run_thread && IsConnected()) { #ifdef __APPLE__ while (Write()) {} Common::SleepCurrentThread(1); #else // TODO: this is all a mess - while (m_run_thread && IsOpen()) + while (m_run_thread && IsConnected()) { bool const did_write = Write(); @@ -512,7 +512,7 @@ void HandleFoundWiimotes(const std::vector& wiimotes) { std::for_each(wiimotes.begin(), wiimotes.end(), [](Wiimote* const wm) { - if (wm->Open()) + if (wm->Connect()) HandleWiimoteConnect(wm); else delete wm; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 5f8206bf14..4c65768666 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -62,11 +62,11 @@ public: void EmuStop(); // connecting and disconnecting from physical devices - bool Open(); - void Close(); + bool Connect(); + void Disconnect(); // TODO: change to something like IsRelevant - bool IsOpen() const; + bool IsConnected() const; void SetLEDs(int leds); @@ -141,8 +141,13 @@ private: // TODO: this should probably be atomic volatile size_t want_wiimotes; +#if defined(_WIN32) + + +#elif defined(__linux__) && HAVE_BLUEZ int device_id; - int device_sock; + int device_sock; +#endif }; extern std::recursive_mutex g_refresh_lock; diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index ba2186d17a..b259cde2b9 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -245,7 +245,7 @@ void WiimoteConfigDiag::UpdateWiimoteStatus() if (WIIMOTE_SRC_EMU & g_wiimote_sources[index]) CFrame::ConnectWiimote(index, true); else if (WIIMOTE_SRC_REAL & g_wiimote_sources[index] && WiimoteReal::g_wiimotes[index]) - CFrame::ConnectWiimote(index, WiimoteReal::g_wiimotes[index]->IsOpen()); + CFrame::ConnectWiimote(index, WiimoteReal::g_wiimotes[index]->IsConnected()); } } } From 62f56eb731fa66f8613438777d13941626be3fa5 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 15 Jan 2013 23:05:30 -0600 Subject: [PATCH 013/167] Sloppily fix wiimotes not being connected after boot. --- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index d25a78490d..516fa3a51e 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -596,6 +596,8 @@ void Update(int _WiimoteNumber) if (g_wiimotes[_WiimoteNumber]) g_wiimotes[_WiimoteNumber]->Update(); + else + Host_ConnectWiimote(_WiimoteNumber, false); } void StateChange(EMUSTATE_CHANGE newState) From 246b11791bb415060eba52ee415c116ea64322ff Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 16 Jan 2013 16:14:23 -0600 Subject: [PATCH 014/167] More attempts at a Windows buildfix. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 43 ++++++++++--------- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 24 ++--------- Source/Core/DolphinWX/Src/WiimoteConfigDiag.h | 3 -- 3 files changed, 25 insertions(+), 45 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index f862193ff9..e285a33729 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -151,13 +151,6 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; HIDD_ATTRIBUTES attr; - // Count the number of already found wiimotes - for (int i = 0; i < MAX_WIIMOTES; ++i) - { - if (wm[i]) - found_wiimotes++; - } - device_data.cbSize = sizeof(device_data); // Get the device id @@ -187,19 +180,6 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) continue; - // Determine if this wiimote has already been found. - bool found = false; - for(int i = 0; i < MAX_WIIMOTES; i++) - { - if(wm[i] && strcmp(wm[i]->devicepath, detail_data->DevicePath) == 0) - { - found = true; - break; - } - } - if (found) - continue; - // Open new device dev = CreateFile(detail_data->DevicePath, (GENERIC_READ | GENERIC_WRITE), @@ -391,6 +371,26 @@ int Wiimote::IOWrite(unsigned char* buf, int len) return 0; } +// return true if a device using MS BT stack is available +bool CanPairUp() +{ + BLUETOOTH_FIND_RADIO_PARAMS radioParam; + radioParam.dwSize = sizeof(radioParam); + + HANDLE hRadio; + HBLUETOOTH_RADIO_FIND hFindRadio = Bth_BluetoothFindFirstRadio(&radioParam, &hRadio); + + if (NULL != hFindRadio) + { + Bth_BluetoothFindRadioClose(hFindRadio); + return true; + } + else + { + return false; + } +} + // WiiMote Pair-Up, function will return amount of either new paired or unpaired devices // negative number on failure int PairUp(bool unpair) @@ -409,7 +409,8 @@ int PairUp(bool unpair) srch.fReturnConnected = true; srch.fReturnUnknown = true; srch.fIssueInquiry = true; - srch.cTimeoutMultiplier = 2; // == (2 * 1.28) seconds + // multiple of 1.28 seconds + srch.cTimeoutMultiplier = 1; BLUETOOTH_FIND_RADIO_PARAMS radioParam; radioParam.dwSize = sizeof(radioParam); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index b259cde2b9..d38eadb0e1 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -71,11 +71,11 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin refresh_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::RefreshRealWiimotes, this); #ifdef _WIN32 - wxButton* const pairup_btn = new wxButton(this, -1, _("Pair Up"), wxDefaultPosition); - pairup_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::PairUpRealWiimotes, this); + //wxButton* const pairup_btn = new wxButton(this, -1, _("Pair Up"), wxDefaultPosition); + //pairup_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::PairUpRealWiimotes, this); + // TODO: text if can't Pair #endif - // "Real wiimotes" layout wxStaticBoxSizer* const real_wiimotes_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Real Wiimotes")); wxFlexGridSizer* const real_wiimotes_sizer = new wxFlexGridSizer(3, 5, 5); @@ -194,24 +194,6 @@ void WiimoteConfigDiag::UpdateGUI() connected_wiimotes_txt->SetLabel(ConnectedWiimotesString()); } -#ifdef _WIN32 -void WiimoteConfigDiag::PairUpRealWiimotes(wxCommandEvent&) -{ - const int paired = WiimoteReal::PairUp(); - - if (paired > 0) - { - // TODO: Maybe add a label of newly paired up wiimotes? - WiimoteReal::Refresh(); - UpdateGUI(); - } - else if (paired < 0) - PanicAlertT("A supported bluetooth device could not be found!\n" - "If you are not using Microsoft's bluetooth stack " - "you must manually pair your wiimotes and use only the \"Refresh\" button."); -} -#endif - void WiimoteConfigDiag::RefreshRealWiimotes(wxCommandEvent&) { WiimoteReal::Refresh(); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h index 2b2e60de4a..fbd715bd40 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h @@ -24,9 +24,6 @@ class WiimoteConfigDiag : public wxDialog public: WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin); -#ifdef _WIN32 - void PairUpRealWiimotes(wxCommandEvent& event); -#endif void RefreshRealWiimotes(wxCommandEvent& event); From 8f5fb7e6f98b3283b5f3688e15cdab30fe842eef Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 14:15:47 -0600 Subject: [PATCH 015/167] Hopefully buildfix Windows. (thanks for the patch, RachelB) --- Source/Core/Core/Src/HW/Wiimote.h | 5 ---- Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 13 -------- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 30 +++++++++++-------- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 13 ++++++++ Source/Core/DolphinWX/Src/Main.cpp | 4 --- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 2 +- 6 files changed, 32 insertions(+), 35 deletions(-) diff --git a/Source/Core/Core/Src/HW/Wiimote.h b/Source/Core/Core/Src/HW/Wiimote.h index d514cf9909..dd0e6df389 100644 --- a/Source/Core/Core/Src/HW/Wiimote.h +++ b/Source/Core/Core/Src/HW/Wiimote.h @@ -44,11 +44,6 @@ void Refresh(); void LoadSettings(); -#ifdef _WIN32 -int PairUp(bool unpair = false); -int UnPair(); -#endif - } #endif diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index 24e25e9a2b..2d3ed01e6d 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -164,19 +164,6 @@ bool Wiimote::Connect() return true; } -void Wiimote::StartThread() -{ - m_run_thread = true; - m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this); -} - -void Wiimote::StopThread() -{ - m_run_thread = false; - if (m_wiimote_thread.joinable()) - m_wiimote_thread.join(); -} - void Wiimote::Disconnect() { close(cmd_sock); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index e285a33729..77555bae86 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -73,6 +73,8 @@ HINSTANCE bthprops_lib = NULL; static int initialized = 0; +int PairUp(bool unpair); + inline void init_lib() { if (!initialized) @@ -132,6 +134,9 @@ WiimoteScanner::WiimoteScanner() init_lib(); } +WiimoteScanner::~WiimoteScanner() +{} + // Find and connect wiimotes. // Does not replace already found wiimotes even if they are disconnected. // wm is an array of max_wiimotes wiimotes @@ -198,7 +203,7 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) wm->dev_handle = dev; memcpy(wm->devicepath, detail_data->DevicePath, 197); - found_wiimotes.push_back(wm); + wiimotes.push_back(wm); } if (detail_data) @@ -206,7 +211,7 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) SetupDiDestroyDeviceInfoList(device_info); - return found_wiimotes; + return wiimotes; } bool WiimoteScanner::IsReady() const @@ -262,15 +267,15 @@ bool Wiimote::IsConnected() const int Wiimote::IORead(unsigned char* buf) { - //*buf = 0; + DWORD b; if (!ReadFile(dev_handle, buf, MAX_PAYLOAD, &b, &hid_overlap)) { // Partial read - auto const b = GetLastError(); + b = GetLastError(); if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) { // Remote disconnect - RealDisconnect(); + Disconnect(); return 0; } @@ -308,14 +313,15 @@ int Wiimote::IORead(unsigned char* buf) return MAX_PAYLOAD; // XXX } -int Wiimote::IOWrite(unsigned char* buf, int len) +int Wiimote::IOWrite(const u8* buf, int len) { + DWORD bytes = 0; switch (stack) { case MSBT_STACK_UNKNOWN: { // Try to auto-detect the stack type - DWORD bytes = 0; + auto i = WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap); if (i) { @@ -324,7 +330,7 @@ int Wiimote::IOWrite(unsigned char* buf, int len) return i; } - i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1); + i = HidD_SetOutputReport(dev_handle, (unsigned char*) buf + 1, len - 1); if (i) { stack = MSBT_STACK_MS; @@ -343,20 +349,20 @@ int Wiimote::IOWrite(unsigned char* buf, int len) { ERROR_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]: ERROR: %08x", dw); // Correct? - return -1 + return -1; } break; } case MSBT_STACK_MS: { - i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1); - dw = GetLastError(); + auto i = HidD_SetOutputReport(dev_handle, (unsigned char*) buf + 1, len - 1); + auto dw = GetLastError(); if (dw == 121) { // Semaphore timeout NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to wiimote"); - RealDisconnect(); + Disconnect(); return 0; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 516fa3a51e..eb4856d2f9 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -357,6 +357,19 @@ void WiimoteScanner::ThreadFunc() } } +void Wiimote::StartThread() +{ + m_run_thread = true; + m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this); +} + +void Wiimote::StopThread() +{ + m_run_thread = false; + if (m_wiimote_thread.joinable()) + m_wiimote_thread.join(); +} + void Wiimote::ThreadFunc() { Common::SetCurrentThreadName("Wiimote Device Thread"); diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index 338ed59547..d9d1908de3 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -390,10 +390,6 @@ void DolphinApp::InitLanguageSupport() int DolphinApp::OnExit() { WiimoteReal::Shutdown(); -#ifdef _WIN32 - if (SConfig::GetInstance().m_WiiAutoUnpair) - WiimoteReal::UnPair(); -#endif VideoBackend::ClearList(); SConfig::Shutdown(); LogManager::Shutdown(); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index d38eadb0e1..b50ec9bc5d 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -81,7 +81,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin wxFlexGridSizer* const real_wiimotes_sizer = new wxFlexGridSizer(3, 5, 5); real_wiimotes_sizer->Add(connected_wiimotes_txt, 0, wxALIGN_CENTER_VERTICAL); #ifdef _WIN32 - real_wiimotes_sizer->Add(pairup_btn); + //real_wiimotes_sizer->Add(pairup_btn); #endif real_wiimotes_sizer->Add(refresh_btn); real_wiimotes_group->Add(real_wiimotes_sizer, 1, wxALL, 5); From 85f25ded4c210b633411fd373a775de5f1792a1f Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 14:22:21 -0600 Subject: [PATCH 016/167] Buildfix! Programming for Windows on Linux is hard, OK? --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 77555bae86..1d82a19e1a 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -73,7 +73,7 @@ HINSTANCE bthprops_lib = NULL; static int initialized = 0; -int PairUp(bool unpair); +int PairUp(bool unpair = false); inline void init_lib() { From 9ecfb5e75d5f636a1c29c38bf67700dba6090d53 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 14:42:50 -0600 Subject: [PATCH 017/167] Buildfix for real! --- Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp | 13 ++++++++----- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index b22f1c7795..114feebeb7 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -26,9 +26,12 @@ WiimoteScanner::WiimoteScanner() return; } +WiimoteScanner::~WiimoteScanner() +{} + std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) { - return std::vector() + return std::vector(); } bool WiimoteScanner::IsReady() const @@ -46,17 +49,17 @@ void Wiimote::Disconnect() return; } -bool Wiimote::IsOpen() const +bool Wiimote::IsConnected() const { - return IsConnected(); + return false; } -int Wiimote::IORead(unsigned char* buf) +int Wiimote::Read(const u8* buf) { return 0; } -int Wiimote::IOWrite(unsigned char* buf, int len) +int Wiimote::Write(const u8* buf, int len) { return 0; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 1d82a19e1a..407e3b6f4f 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -73,8 +73,6 @@ HINSTANCE bthprops_lib = NULL; static int initialized = 0; -int PairUp(bool unpair = false); - inline void init_lib() { if (!initialized) @@ -129,6 +127,8 @@ inline void init_lib() namespace WiimoteReal { +int PairUp(bool unpair = false); + WiimoteScanner::WiimoteScanner() { init_lib(); From 57ea09dcc2b2d51193e7f3c07cbd38ea9a7f85bd Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 14:46:01 -0600 Subject: [PATCH 018/167] Fix BT-less! --- Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index 114feebeb7..c696cc8012 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -54,12 +54,12 @@ bool Wiimote::IsConnected() const return false; } -int Wiimote::Read(const u8* buf) +int Wiimote::IORead(const u8* buf) { return 0; } -int Wiimote::Write(const u8* buf, int len) +int Wiimote::IOWrite(const u8* buf, int len) { return 0; } From a2ca76ebd9c3300735c438b5ddc7bc726001b41a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 15:16:41 -0600 Subject: [PATCH 019/167] Buildfix. --- Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index c696cc8012..6af169f5ee 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -54,7 +54,7 @@ bool Wiimote::IsConnected() const return false; } -int Wiimote::IORead(const u8* buf) +int Wiimote::IORead(u8* buf) { return 0; } From 3063942dd05d432fe0b750770e5159252b4ae199 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 21:53:09 -0600 Subject: [PATCH 020/167] some cleanup --- .../Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp | 5 +- .../Core/Core/Src/HW/WiimoteEmu/WiimoteHid.h | 4 +- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 128 +++++------------- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 6 +- 4 files changed, 41 insertions(+), 102 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp index cfb81bb768..5c2a28b57a 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp @@ -252,9 +252,8 @@ void Wiimote::RequestStatus(const wm_request_status* const rs) if (g_wiimotes[m_index]) { - wm_request_status rpt; - rpt.rumble = 0; - g_wiimotes[m_index]->SendPacket(WM_REQUEST_STATUS, &rpt, sizeof(rpt)); + wm_request_status rpt = {}; + g_wiimotes[m_index]->QueueReport(WM_REQUEST_STATUS, &rpt, sizeof(rpt)); } return; diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteHid.h b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteHid.h index fd7c549e8d..9d1a2092a0 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteHid.h +++ b/Source/Core/Core/Src/HW/WiimoteEmu/WiimoteHid.h @@ -201,6 +201,7 @@ struct wm_report #define WM_LEDS 0x11 struct wm_leds { u8 rumble : 1; + // real wii also sets bit 0x2 (unknown purpose) u8 : 3; u8 leds : 4; }; @@ -208,8 +209,9 @@ struct wm_leds { #define WM_REPORT_MODE 0x12 struct wm_report_mode { u8 rumble : 1; - u8 continuous : 1; // these 2 seem to be named wrong + // unsure what "all_the_time" actually is, the real wii does set it (bit 0x2) u8 all_the_time : 1; + u8 continuous : 1; u8 : 5; u8 mode; }; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index a7963ec4e0..dda9e32b5f 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -61,13 +61,11 @@ Wiimote::Wiimote() #if defined(__linux__) && HAVE_BLUEZ bdaddr = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; #endif - - DisableDataReporting(); } Wiimote::~Wiimote() { - StopThread(); + StopThread(); if (IsConnected()) Disconnect(); @@ -80,26 +78,28 @@ Wiimote::~Wiimote() delete[] rpt.first; } -// Silly, copying data n stuff, o well, don't use this too often -void Wiimote::SendPacket(const u8 rpt_id, const void* const data, const unsigned int size) +// to be called from CPU thread +void Wiimote::QueueReport(u8 rpt_id, const void* _data, unsigned int size) { + auto const data = static_cast(_data); + Report rpt; rpt.second = size + 2; rpt.first = new u8[rpt.second]; - rpt.first[0] = 0xA1; + rpt.first[0] = WM_SET_REPORT | WM_BT_OUTPUT; rpt.first[1] = rpt_id; - memcpy(rpt.first + 2, data, size); + std::copy(data, data + size, rpt.first + 2); m_write_reports.Push(rpt); } void Wiimote::DisableDataReporting() { - wm_report_mode rpt; + wm_report_mode rpt = {}; rpt.mode = WM_REPORT_CORE; rpt.all_the_time = 0; rpt.continuous = 0; rpt.rumble = 0; - SendPacket(WM_REPORT_MODE, &rpt, sizeof(rpt)); + QueueReport(WM_REPORT_MODE, &rpt, sizeof(rpt)); } void Wiimote::ClearReadQueue() @@ -133,24 +133,24 @@ void Wiimote::ControlChannel(const u16 channel, const void* const data, const u3 } } -void Wiimote::InterruptChannel(const u16 channel, const void* const data, const u32 size) +void Wiimote::InterruptChannel(const u16 channel, const void* const _data, const u32 size) { - if (0 == m_channel) // first interrupt/control channel sent + // first interrupt/control channel sent + if (channel != m_channel) { + m_channel = channel; + ClearReadQueue(); - // request status - wm_request_status rpt; - rpt.rumble = 0; - SendPacket(WM_REQUEST_STATUS, &rpt, sizeof(rpt)); + EmuStart(); } - - m_channel = channel; // this right? + + auto const data = static_cast(_data); Report rpt; rpt.first = new u8[size]; rpt.second = (u8)size; - memcpy(rpt.first, (u8*)data, size); + std::copy(data, data + size, rpt.first); // Convert output DATA packets to SET_REPORT packets. // Nintendo Wiimotes work without this translation, but 3rd @@ -173,7 +173,8 @@ bool Wiimote::Read() if (0 == rpt.second) Disconnect(); - if (rpt.second > 0 && m_channel > 0) { + if (rpt.second > 0 && m_channel > 0) + { // Add it to queue m_read_reports.Push(rpt); return true; @@ -241,27 +242,18 @@ void Wiimote::Update() delete[] rpt.first; } -void Wiimote::EmuStop() -{ - m_channel = 0; - - DisableDataReporting(); - - NOTICE_LOG(WIIMOTE, "Stopping wiimote data reporting"); -} - // Rumble briefly -void Wiimote::Rumble() +void Wiimote::RumbleBriefly() { unsigned char buffer = 0x01; DEBUG_LOG(WIIMOTE, "Starting rumble..."); - SendRequest(WM_CMD_RUMBLE, &buffer, 1); + QueueReport(WM_CMD_RUMBLE, &buffer, sizeof(buffer)); SLEEP(200); DEBUG_LOG(WIIMOTE, "Stopping rumble..."); buffer = 0x00; - SendRequest(WM_CMD_RUMBLE, &buffer, 1); + QueueReport(WM_CMD_RUMBLE, &buffer, sizeof(buffer)); } // Set the active LEDs. @@ -270,30 +262,21 @@ void Wiimote::SetLEDs(int new_leds) { // Remove the lower 4 bits because they control rumble u8 const buffer = (new_leds & 0xF0); - SendRequest(WM_CMD_LED, &buffer, 1); + QueueReport(WM_CMD_LED, &buffer, sizeof(buffer)); } bool Wiimote::EmuStart() { - // Send a handshake - - // Set buffer[0] to 0x04 for continuous reporting - u8 const buffer[2] = {0x04, 0x30}; - - NOTICE_LOG(WIIMOTE, "Sending handshake to wiimote"); - - return SendRequest(WM_CMD_REPORT_TYPE, buffer, 2); + DisableDataReporting(); } -// Send a packet to the wiimote. -// report_type should be one of WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc. -bool Wiimote::SendRequest(u8 report_type, u8 const* data, int length) +void Wiimote::EmuStop() { - unsigned char buffer[32] = {WM_SET_REPORT | WM_BT_OUTPUT, report_type}; + m_channel = 0; - memcpy(buffer + 2, data, length); + DisableDataReporting(); - return (IOWrite(buffer, length + 2) != 0); + NOTICE_LOG(WIIMOTE, "Stopping wiimote data reporting"); } unsigned int CalculateWantedWiimotes() @@ -369,9 +352,6 @@ void Wiimote::ThreadFunc() { Common::SetCurrentThreadName("Wiimote Device Thread"); - // rumble briefly - Rumble(); - // main loop while (m_run_thread && IsConnected()) { @@ -464,7 +444,10 @@ void HandleWiimoteConnect(Wiimote* wm) wm->index = i; wm->StartThread(); + + wm->DisableDataReporting(); wm->SetLEDs(WIIMOTE_LED_1 << i); + wm->RumbleBriefly(); Host_ConnectWiimote(i, true); @@ -516,52 +499,7 @@ void Refresh() { std::lock_guard lk(g_refresh_lock); -#ifdef _WIN32 - Shutdown(); - Initialize(); -#else -/* - // Make sure real wiimotes have been initialized - if (!g_real_wiimotes_initialized) - { - Initialize(); - return; - } - - // Find the number of slots configured for real wiimotes - unsigned int wanted_wiimotes = 0; - for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) - if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]) - ++wanted_wiimotes; - - // Remove wiimotes that are paired with slots no longer configured for a - // real wiimote or that are disconnected - for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) - if (g_wiimotes[i] && (!(WIIMOTE_SRC_REAL & g_wiimote_sources[i]) || - !g_wiimotes[i]->IsConnected())) - { - delete g_wiimotes[i]; - g_wiimotes[i] = NULL; - --g_wiimotes_found; - } - - // Scan for wiimotes if we want more - if (wanted_wiimotes > g_wiimotes_found) - { - // Scan for wiimotes - unsigned int num_wiimotes = FindWiimotes(g_wiimotes, wanted_wiimotes); - - DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted", num_wiimotes, wanted_wiimotes); - - // Connect newly found wiimotes. - int num_new_wiimotes = ConnectWiimotes(g_wiimotes); - - DEBUG_LOG(WIIMOTE, "Connected to %i additional Real Wiimotes", num_new_wiimotes); - - g_wiimotes_found = num_wiimotes; - } -*/ -#endif + // TODO: stuff, maybe } void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index d61967b4f1..0dee443597 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -70,10 +70,11 @@ public: bool IsConnected() const; void SetLEDs(int leds); + void RumbleBriefly(); void DisableDataReporting(); - void Rumble(); - void SendPacket(const u8 rpt_id, const void* const data, const unsigned int size); + + void QueueReport(u8 rpt_id, const void* data, unsigned int size); int index; @@ -102,7 +103,6 @@ protected: private: void ClearReadQueue(); - bool SendRequest(u8 report_type, u8 const* data, int length); int IORead(u8* buf); int IOWrite(u8 const* buf, int len); From 026793fa4abfd7e2d1b6f443022e621b81bddac9 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 23:17:51 -0600 Subject: [PATCH 021/167] Fixup real wiimote GUI. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 42 +++++++------- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 29 +++++++--- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 3 +- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 57 +++---------------- Source/Core/DolphinWX/Src/WiimoteConfigDiag.h | 6 -- 5 files changed, 50 insertions(+), 87 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 1ac7ed03f4..25a83531dc 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -135,7 +135,10 @@ WiimoteScanner::WiimoteScanner() } WiimoteScanner::~WiimoteScanner() -{} +{ + // TODO: what do we want here? + //PairUp(true); +} // Find and connect wiimotes. // Does not replace already found wiimotes even if they are disconnected. @@ -216,8 +219,21 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) bool WiimoteScanner::IsReady() const { - // TODO: impl - return true; + BLUETOOTH_FIND_RADIO_PARAMS radioParam; + radioParam.dwSize = sizeof(radioParam); + + HANDLE hRadio; + HBLUETOOTH_RADIO_FIND hFindRadio = Bth_BluetoothFindFirstRadio(&radioParam, &hRadio); + + if (NULL != hFindRadio) + { + Bth_BluetoothFindRadioClose(hFindRadio); + return true; + } + else + { + return false; + } } // Connect to a wiimote with a known device path. @@ -377,26 +393,6 @@ int Wiimote::IOWrite(const u8* buf, int len) return 0; } -// return true if a device using MS BT stack is available -bool CanPairUp() -{ - BLUETOOTH_FIND_RADIO_PARAMS radioParam; - radioParam.dwSize = sizeof(radioParam); - - HANDLE hRadio; - HBLUETOOTH_RADIO_FIND hFindRadio = Bth_BluetoothFindFirstRadio(&radioParam, &hRadio); - - if (NULL != hFindRadio) - { - Bth_BluetoothFindRadioClose(hFindRadio); - return true; - } - else - { - return false; - } -} - // WiiMote Pair-Up, function will return amount of either new paired or unpaired devices // negative number on failure int PairUp(bool unpair) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index dda9e32b5f..5b8ee72f16 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -265,7 +265,7 @@ void Wiimote::SetLEDs(int new_leds) QueueReport(WM_CMD_LED, &buffer, sizeof(buffer)); } -bool Wiimote::EmuStart() +void Wiimote::EmuStart() { DisableDataReporting(); } @@ -298,7 +298,10 @@ void WiimoteScanner::WantWiimotes(size_t count) void WiimoteScanner::StartScanning() { run_thread = true; - scan_thread = std::thread(std::mem_fun(&WiimoteScanner::ThreadFunc), this); + if (IsReady()) + { + scan_thread = std::thread(std::mem_fun(&WiimoteScanner::ThreadFunc), this); + } } void WiimoteScanner::StopScanning() @@ -307,7 +310,6 @@ void WiimoteScanner::StopScanning() if (scan_thread.joinable()) { scan_thread.join(); - NOTICE_LOG(WIIMOTE, "Wiimote scanning has stopped"); } } @@ -333,6 +335,8 @@ void WiimoteScanner::ThreadFunc() //std::this_thread::yield(); Common::SleepCurrentThread(500); } + + NOTICE_LOG(WIIMOTE, "Wiimote scanning has stopped"); } void Wiimote::StartThread() @@ -395,8 +399,7 @@ void Initialize() auto const wanted_wiimotes = CalculateWantedWiimotes(); g_wiimote_scanner.WantWiimotes(wanted_wiimotes); - //if (wanted_wiimotes > 0) - g_wiimote_scanner.StartScanning(); + g_wiimote_scanner.StartScanning(); g_real_wiimotes_initialized = true; } @@ -497,9 +500,21 @@ void HandleFoundWiimotes(const std::vector& wiimotes) // This is called from the GUI thread void Refresh() { + g_wiimote_scanner.StopScanning(); + + { std::lock_guard lk(g_refresh_lock); - - // TODO: stuff, maybe + + auto wanted_wiimotes = CalculateWantedWiimotes(); + auto const found_wiimotes = g_wiimote_scanner.FindWiimotes(wanted_wiimotes); + + HandleFoundWiimotes(found_wiimotes); + + wanted_wiimotes = CalculateWantedWiimotes(); + g_wiimote_scanner.WantWiimotes(wanted_wiimotes); + } + + g_wiimote_scanner.StartScanning(); } void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 0dee443597..23631765ed 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -59,7 +59,7 @@ public: void StopThread(); // "handshake" / stop packets - bool EmuStart(); + void EmuStart(); void EmuStop(); // connecting and disconnecting from physical devices @@ -153,6 +153,7 @@ private: }; extern std::recursive_mutex g_refresh_lock; +extern WiimoteScanner g_wiimote_scanner; extern Wiimote *g_wiimotes[4]; void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index b50ec9bc5d..a4af2d5d9a 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -4,14 +4,6 @@ #include "HW/WiimoteReal/WiimoteReal.h" #include "Frame.h" -wxString ConnectedWiimotesString() -{ - //static wxString str; - //str.Printf(_("%i connected"), WiimoteReal::Initialize()); - //return str; - return "TODO: this text"; -} - WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin) : wxDialog(parent, -1, _("Dolphin Wiimote Configuration"), wxDefaultPosition, wxDefaultSize) , m_plugin(plugin) @@ -65,27 +57,17 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin // "Real wiimotes" controls - connected_wiimotes_txt = new wxStaticText(this, -1, ConnectedWiimotesString()); - wxButton* const refresh_btn = new wxButton(this, -1, _("Refresh"), wxDefaultPosition); refresh_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::RefreshRealWiimotes, this); -#ifdef _WIN32 - //wxButton* const pairup_btn = new wxButton(this, -1, _("Pair Up"), wxDefaultPosition); - //pairup_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::PairUpRealWiimotes, this); - // TODO: text if can't Pair -#endif - // "Real wiimotes" layout - wxStaticBoxSizer* const real_wiimotes_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Real Wiimotes")); - wxFlexGridSizer* const real_wiimotes_sizer = new wxFlexGridSizer(3, 5, 5); - real_wiimotes_sizer->Add(connected_wiimotes_txt, 0, wxALIGN_CENTER_VERTICAL); -#ifdef _WIN32 - //real_wiimotes_sizer->Add(pairup_btn); -#endif - real_wiimotes_sizer->Add(refresh_btn); - real_wiimotes_group->Add(real_wiimotes_sizer, 1, wxALL, 5); - + wxStaticBoxSizer* const real_wiimotes_group = new wxStaticBoxSizer(wxVERTICAL, this, _("Real Wiimotes")); + + if (!WiimoteReal::g_wiimote_scanner.IsReady()) + real_wiimotes_group->Add(new wxStaticText(this, -1, _("A supported bluetooth device could not be found.\n" + "You must manually pair your wiimotes.")), 0, wxALIGN_CENTER | wxALL, 5); + + real_wiimotes_group->Add(refresh_btn, 0, wxALIGN_CENTER); // "General Settings" controls const wxString str[] = { _("Bottom"), _("Top") }; @@ -189,15 +171,9 @@ void WiimoteConfigDiag::ConfigEmulatedWiimote(wxCommandEvent& ev) m_emu_config_diag->Destroy(); } -void WiimoteConfigDiag::UpdateGUI() -{ - connected_wiimotes_txt->SetLabel(ConnectedWiimotesString()); -} - void WiimoteConfigDiag::RefreshRealWiimotes(wxCommandEvent&) { WiimoteReal::Refresh(); - UpdateGUI(); } void WiimoteConfigDiag::SelectSource(wxCommandEvent& event) @@ -214,24 +190,6 @@ void WiimoteConfigDiag::SelectSource(wxCommandEvent& event) wiimote_configure_bt[index]->Enable(); } -// TODO: race conditiions -void WiimoteConfigDiag::UpdateWiimoteStatus() -{ - for (int index = 0; index < 4; ++index) - { - if (m_orig_wiimote_sources[index] != g_wiimote_sources[index]) - { - // Disconnect first, otherwise the new source doesn't seem to work - CFrame::ConnectWiimote(index, false); - // Connect wiimotes - if (WIIMOTE_SRC_EMU & g_wiimote_sources[index]) - CFrame::ConnectWiimote(index, true); - else if (WIIMOTE_SRC_REAL & g_wiimote_sources[index] && WiimoteReal::g_wiimotes[index]) - CFrame::ConnectWiimote(index, WiimoteReal::g_wiimotes[index]->IsConnected()); - } - } -} - void WiimoteConfigDiag::RevertSource() { for (int i = 0; i < 4; ++i) @@ -253,7 +211,6 @@ void WiimoteConfigDiag::Save(wxCommandEvent& event) sec.Set("Source", (int)g_wiimote_sources[i]); } - UpdateWiimoteStatus(); inifile.Save(ini_filename); diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h index fbd715bd40..316d0d48bf 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h @@ -26,15 +26,11 @@ public: void RefreshRealWiimotes(wxCommandEvent& event); - void SelectSource(wxCommandEvent& event); - void UpdateWiimoteStatus(); void RevertSource(); - void ConfigEmulatedWiimote(wxCommandEvent& event); void Save(wxCommandEvent& event); - void UpdateGUI(); void OnSensorBarPos(wxCommandEvent& event) { @@ -73,8 +69,6 @@ private: wxButton* wiimote_configure_bt[4]; std::map m_wiimote_index_from_conf_bt_id; - - wxStaticText* connected_wiimotes_txt; }; From 87bbdbf5428b94520b44a97df53a5f7ee1e9945d Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 23:23:32 -0600 Subject: [PATCH 022/167] Remove settings stuff that was not actually used anywhere. --- Source/Core/Core/Src/ConfigManager.cpp | 20 +------------------- Source/Core/Core/Src/ConfigManager.h | 5 ----- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index f6194c1bb7..978eadace1 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -100,9 +100,6 @@ SConfig::SConfig() { // Make sure we have log manager LoadSettings(); - //Make sure we load any extra settings - LoadSettingsWii(); - } void SConfig::Init() @@ -427,19 +424,4 @@ void SConfig::LoadSettings() } m_SYSCONF = new SysConf(); -} -void SConfig::LoadSettingsWii() -{ - IniFile ini; - //Wiimote configs - ini.Load((File::GetUserPath(D_CONFIG_IDX) + "Dolphin.ini")); - for (int i = 0; i < 4; i++) - { - char SectionName[32]; - sprintf(SectionName, "Wiimote%i", i + 1); - ini.Get(SectionName, "AutoReconnectRealWiimote", &m_WiiAutoReconnect[i], false); - } - ini.Load((File::GetUserPath(D_CONFIG_IDX) + "wiimote.ini")); - ini.Get("Real", "Unpair", &m_WiiAutoUnpair, false); - -} +} \ No newline at end of file diff --git a/Source/Core/Core/Src/ConfigManager.h b/Source/Core/Core/Src/ConfigManager.h index e92d29ee65..e3ad7b42a9 100644 --- a/Source/Core/Core/Src/ConfigManager.h +++ b/Source/Core/Core/Src/ConfigManager.h @@ -41,8 +41,6 @@ struct SConfig : NonCopyable // Wii Devices bool m_WiiSDCard; bool m_WiiKeyboard; - bool m_WiiAutoReconnect[4]; - bool m_WiiAutoUnpair; bool m_WiimoteReconnectOnLoad; // name of the last used filename @@ -107,9 +105,6 @@ struct SConfig : NonCopyable // load settings void LoadSettings(); - //Special load settings - void LoadSettingsWii(); - // Return the permanent and somewhat globally used instance of this struct static SConfig& GetInstance() {return(*m_Instance);} From 8ce58759e33202342b79a611f4ebdd0a5b1a2bf5 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 7 Feb 2013 23:52:50 -0600 Subject: [PATCH 023/167] Remove some old nonsense. --- Source/Core/Common/Src/Common.h | 1 - .../Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp | 3 +- Source/Core/DolphinWX/Src/Frame.cpp | 31 ------------------- Source/Core/VideoCommon/Src/EmuWindow.cpp | 4 --- 4 files changed, 1 insertion(+), 38 deletions(-) diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h index c3cab37dd8..0132915a5c 100644 --- a/Source/Core/Common/Src/Common.h +++ b/Source/Core/Common/Src/Common.h @@ -155,7 +155,6 @@ enum HOST_COMM WM_USER_CREATE, WM_USER_SETCURSOR, WM_USER_KEYDOWN, - WIIMOTE_DISCONNECT // Disconnect Wiimote }; // Used for notification on emulation state diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp index 6e06f60dd6..b3449ec059 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp @@ -211,8 +211,7 @@ void CWII_IPC_HLE_WiiMote::EventConnectionAccepted() void CWII_IPC_HLE_WiiMote::EventDisconnect() { // Send disconnect message to plugin - u8 Message = WIIMOTE_DISCONNECT; - Wiimote::ControlChannel(m_ConnectionHandle & 0xFF, 99, &Message, 0); + Wiimote::ControlChannel(m_ConnectionHandle & 0xFF, 99, NULL, 0); m_ConnectionState = CONN_INACTIVE; // Clear channel flags diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index d390b8afcd..46b3a1e8e5 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -100,37 +100,6 @@ CPanel::CPanel( else SetCursor(wxNullCursor); break; - - case WIIMOTE_DISCONNECT: - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) - { - const int wiimote_idx = lParam; - const int wiimote_num = wiimote_idx + 1; - - //Auto reconnect if option is turned on. - //TODO: Make this only auto reconnect wiimotes that have the option activated. - SConfig::GetInstance().LoadSettingsWii();//Make sure we are using the newest settings. - if (SConfig::GetInstance().m_WiiAutoReconnect[wiimote_idx]) - { - GetUsbPointer()->AccessWiiMote(wiimote_idx | 0x100)->Activate(true); - NOTICE_LOG(WIIMOTE, "Wiimote %i has been auto-reconnected...", wiimote_num); - } - else - { - // The Wiimote has been disconnected, we offer reconnect here. - wxMessageDialog *dlg = new wxMessageDialog( - this, - wxString::Format(_("Wiimote %i has been disconnected by system.\nMaybe this game doesn't support multi-wiimote,\nor maybe it is due to idle time out or other reason.\nDo you want to reconnect immediately?"), wiimote_num), - _("Reconnect Wiimote Confirm"), - wxYES_NO | wxSTAY_ON_TOP | wxICON_INFORMATION, //wxICON_QUESTION, - wxDefaultPosition); - - if (dlg->ShowModal() == wxID_YES) - GetUsbPointer()->AccessWiiMote(wiimote_idx | 0x100)->Activate(true); - - dlg->Destroy(); - } - } } break; diff --git a/Source/Core/VideoCommon/Src/EmuWindow.cpp b/Source/Core/VideoCommon/Src/EmuWindow.cpp index cbb0bc31ac..81227ba0ca 100644 --- a/Source/Core/VideoCommon/Src/EmuWindow.cpp +++ b/Source/Core/VideoCommon/Src/EmuWindow.cpp @@ -205,10 +205,6 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam ) OnKeyDown(lParam); FreeLookInput((u32)wParam, lParam); } - else if (wParam == WIIMOTE_DISCONNECT) - { - PostMessage(m_hParent, WM_USER, wParam, lParam); - } break; // Called when a screensaver wants to show up while this window is active From 1998da867b57a7f6cee3320059e9c259abee64bd Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 8 Feb 2013 12:14:45 -0600 Subject: [PATCH 024/167] OSX fix maybe. (based on jchadwick's patch) --- .../Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 87 ++++++++----------- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 1 + 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 95068fe650..2e53daca36 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -10,19 +10,6 @@ } @end -WiimoteScanner::WiimoteScanner() -{} - -std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) -{ - return std::vector(); -} - -bool WiimoteScanner::IsReady() const -{ - return false; -} - @implementation SearchBT - (void) deviceInquiryComplete: (IOBluetoothDeviceInquiry *) sender error: (IOReturn) error @@ -112,34 +99,35 @@ bool WiimoteScanner::IsReady() const namespace WiimoteReal { -// Find wiimotes. -// wm is an array of max_wiimotes wiimotes -// Returns the total number of found wiimotes. -int FindWiimotes(Wiimote **wm, int max_wiimotes) +WiimoteScanner::WiimoteScanner() +{} + +WiimoteScanner::~WiimoteScanner() +{} + +std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) { + // TODO: find the device in the constructor and save it for later + + std::vector wiimotes; IOBluetoothHostController *bth; IOBluetoothDeviceInquiry *bti; SearchBT *sbt; NSEnumerator *en; - int found_devices = 0, found_wiimotes = 0; - - // Count the number of already found wiimotes - for (int i = 0; i < MAX_WIIMOTES; ++i) - if (wm[i]) - found_wiimotes++; bth = [[IOBluetoothHostController alloc] init]; - if ([bth addressAsString] == nil) { + if ([bth addressAsString] == nil) + { WARN_LOG(WIIMOTE, "No bluetooth host controller"); [bth release]; - return found_wiimotes; + return wiimotes; } sbt = [[SearchBT alloc] init]; - sbt->maxDevices = max_wiimotes - found_wiimotes; + sbt->maxDevices = max_wiimotes; bti = [[IOBluetoothDeviceInquiry alloc] init]; [bti setDelegate: sbt]; - [bti setInquiryLength: 5]; + [bti setInquiryLength: 2]; if ([bti start] == kIOReturnSuccess) [bti retain]; @@ -149,10 +137,9 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes) CFRunLoopRun(); [bti stop]; - found_devices = [[bti foundDevices] count]; + int found_devices = [[bti foundDevices] count]; - NOTICE_LOG(WIIMOTE, "Found %i bluetooth device%c", found_devices, - found_devices == 1 ? '\0' : 's'); + NOTICE_LOG(WIIMOTE, "Found %i bluetooth devices", found_devices); en = [[bti foundDevices] objectEnumerator]; for (int i = 0; i < found_devices; i++) @@ -160,24 +147,26 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes) IOBluetoothDevice *dev = [en nextObject]; if (!IsValidBluetoothName([[dev name] UTF8String])) continue; - // Find an unused slot - for (int k = 0; k < MAX_WIIMOTES; k++) { - if (wm[k] != NULL || - !(g_wiimote_sources[k] & WIIMOTE_SRC_REAL)) - continue; - wm[k] = new Wiimote(k); - wm[k]->btd = dev; - found_wiimotes++; + Wiimote *wm = new Wiimote(); + wm->btd = dev; + wiimotes.push_back(wm); + + if(wiimotes.size() >= max_wiimotes) break; - } } [bth release]; [bti release]; [sbt release]; - return found_wiimotes; + return wiimotes; +} + +bool WiimoteScanner::IsReady() const +{ + // TODO: only return true when a BT device is present + return true; } // Connect to a wiimote with a known address. @@ -192,7 +181,8 @@ bool Wiimote::Connect() withPSM: kBluetoothL2CAPPSMHIDControl delegate: cbt]; [btd openL2CAPChannelSync: &ichan withPSM: kBluetoothL2CAPPSMHIDInterrupt delegate: cbt]; - if (ichan == NULL || cchan == NULL) { + if (ichan == NULL || cchan == NULL) + { ERROR_LOG(WIIMOTE, "Unable to open L2CAP channels " "for wiimote %i", index + 1); Disconnect(); @@ -209,11 +199,6 @@ bool Wiimote::Connect() m_connected = true; - Handshake(); - SetLEDs(WIIMOTE_LED_1 << index); - - m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this); - [cbt release]; return true; @@ -240,9 +225,9 @@ void Wiimote::Disconnect() ichan = NULL; } -bool Wiimote::IsOpen() const +bool Wiimote::IsConnected() const { - return IsConnected(); + return m_connected; } int Wiimote::IORead(unsigned char *buf) @@ -251,6 +236,8 @@ int Wiimote::IORead(unsigned char *buf) if (!IsConnected()) return 0; + + // TODO: race conditions here, yo bytes = inputlen; memcpy(buf, input, bytes); @@ -259,14 +246,14 @@ int Wiimote::IORead(unsigned char *buf) return bytes; } -int Wiimote::IOWrite(unsigned char *buf, int len) +int Wiimote::IOWrite(const unsigned char *buf, int len) { IOReturn ret; if (!IsConnected()) return 0; - ret = [ichan writeAsync: buf length: len refcon: nil]; + ret = [ichan writeAsync: const_cast((void *)buf) length: len refcon: nil]; if (ret == kIOReturnSuccess) return len; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 23631765ed..139d59ce99 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -84,6 +84,7 @@ public: IOBluetoothL2CAPChannel *cchan; char input[MAX_PAYLOAD]; int inputlen; + bool m_connected; #elif defined(__linux__) && HAVE_BLUEZ bdaddr_t bdaddr; // Bluetooth address int cmd_sock; // Command socket From 1f1b4a6992553d132de3fc8b097fdfbba78ff556 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 8 Feb 2013 16:54:48 -0600 Subject: [PATCH 025/167] Hopefully make real wiimotes on OSX less crashy. --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 12 ++++++++---- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 2e53daca36..030daa0973 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -40,8 +40,11 @@ { IOBluetoothDevice *device = [l2capChannel getDevice]; WiimoteReal::Wiimote *wm = NULL; + + std::lock_guard lk(g_refresh_lock); - for (int i = 0; i < MAX_WIIMOTES; i++) { + for (int i = 0; i < MAX_WIIMOTES; i++) + { if (WiimoteReal::g_wiimotes[i] == NULL) continue; if ([device isEqual: WiimoteReal::g_wiimotes[i]->btd] == TRUE) @@ -77,8 +80,11 @@ { IOBluetoothDevice *device = [l2capChannel getDevice]; WiimoteReal::Wiimote *wm = NULL; + + std::lock_guard lk(g_refresh_lock); - for (int i = 0; i < MAX_WIIMOTES; i++) { + for (int i = 0; i < MAX_WIIMOTES; i++) + { if (WiimoteReal::g_wiimotes[i] == NULL) continue; if ([device isEqual: WiimoteReal::g_wiimotes[i]->btd] == TRUE) @@ -236,8 +242,6 @@ int Wiimote::IORead(unsigned char *buf) if (!IsConnected()) return 0; - - // TODO: race conditions here, yo bytes = inputlen; memcpy(buf, input, bytes); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 5b8ee72f16..7ae1a9a961 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -360,13 +360,13 @@ void Wiimote::ThreadFunc() while (m_run_thread && IsConnected()) { #ifdef __APPLE__ - while (Write()) {} - Common::SleepCurrentThread(1); + // Reading happens elsewhere on OSX + bool const did_something = Write(); #else bool const did_something = Write() || Read(); +#endif if (!did_something) Common::SleepCurrentThread(1); -#endif } } From 9bb9286cd3b1dca212d9e5ebd95960f102ea79bc Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 8 Feb 2013 16:59:59 -0600 Subject: [PATCH 026/167] OSX buildfix! --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 030daa0973..02f3941fc8 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -41,7 +41,7 @@ IOBluetoothDevice *device = [l2capChannel getDevice]; WiimoteReal::Wiimote *wm = NULL; - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(WiimoteReal::g_refresh_lock); for (int i = 0; i < MAX_WIIMOTES; i++) { @@ -81,7 +81,7 @@ IOBluetoothDevice *device = [l2capChannel getDevice]; WiimoteReal::Wiimote *wm = NULL; - std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(WiimoteReal::g_refresh_lock); for (int i = 0; i < MAX_WIIMOTES; i++) { From 50c83d614cba54f2720b889be3dd3bd8fea4840c Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 8 Feb 2013 21:20:54 -0600 Subject: [PATCH 027/167] More attempts at fixing Windows and OS X. --- Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 3 ++ Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 45 ++++++++++--------- .../Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 6 --- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index 2d3ed01e6d..e926d44ec0 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -178,6 +178,9 @@ bool Wiimote::IsConnected() const return cmd_sock != -1;// && int_sock != -1; } +// positive = read packet +// negative = didn't read packet +// zero = error int Wiimote::IORead(u8* buf) { // Block select for 1/2000th of a second diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 25a83531dc..8226c784e8 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -148,12 +148,9 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) { PairUp(); - std::vector wiimotes; - GUID device_id; HANDLE dev; HDEVINFO device_info; - int found_wiimotes = 0; DWORD len; SP_DEVICE_INTERFACE_DATA device_data; PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; @@ -167,13 +164,11 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) // Get all hid devices connected device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); - for (int index = 0; found_wiimotes < max_wiimotes; ++index) + std::vector wiimotes; + for (int index = 0; wiimotes.size() < max_wiimotes; ++index) { - if (detail_data) - { - free(detail_data); - detail_data = NULL; - } + free(detail_data); + detail_data = NULL; // Query the next hid device info if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) @@ -188,7 +183,10 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) continue; + auto const wm = new Wiimote; + // Open new device +#if 0 dev = CreateFile(detail_data->DevicePath, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), @@ -199,18 +197,15 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) // Get device attributes attr.Size = sizeof(attr); HidD_GetAttributes(dev, &attr); - - // Find an unused slot - unsigned int k = 0; - auto const wm = new Wiimote; + wm->dev_handle = dev; +#endif wm->devicepath = detail_data->DevicePath; wiimotes.push_back(wm); } - if (detail_data) - free(detail_data); + free(detail_data); SetupDiDestroyDeviceInfoList(device_info); @@ -219,6 +214,8 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) bool WiimoteScanner::IsReady() const { + // TODO: don't search for a radio each time + BLUETOOTH_FIND_RADIO_PARAMS radioParam; radioParam.dwSize = sizeof(radioParam); @@ -241,7 +238,7 @@ bool Wiimote::Connect() { dev_handle = CreateFile(devicepath.c_str(), (GENERIC_READ | GENERIC_WRITE), - (FILE_SHARE_READ | FILE_SHARE_WRITE), + /*(FILE_SHARE_READ | FILE_SHARE_WRITE)*/ 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (dev_handle == INVALID_HANDLE_VALUE) @@ -281,8 +278,13 @@ bool Wiimote::IsConnected() const return dev_handle != 0; } +// positive = read packet +// negative = didn't read packet +// zero = error int Wiimote::IORead(unsigned char* buf) { + *buf = 0; + DWORD b; if (!ReadFile(dev_handle, buf, MAX_PAYLOAD, &b, &hid_overlap)) { @@ -291,7 +293,6 @@ int Wiimote::IORead(unsigned char* buf) if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) { // Remote disconnect - Disconnect(); return 0; } @@ -299,24 +300,23 @@ int Wiimote::IORead(unsigned char* buf) if (r == WAIT_TIMEOUT) { // Timeout - cancel and continue - if (*buf) WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).", WIIMOTE_DEFAULT_TIMEOUT); CancelIo(dev_handle); ResetEvent(hid_overlap.hEvent); - return 0; + return -1; } else if (r == WAIT_FAILED) { WARN_LOG(WIIMOTE, "A wait error occured on reading from wiimote %i.", index + 1); - return 0; + return -1; } if (!GetOverlappedResult(dev_handle, &hid_overlap, &b, 0)) { - return 0; + return -1; } } @@ -378,7 +378,6 @@ int Wiimote::IOWrite(const u8* buf, int len) { // Semaphore timeout NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to wiimote"); - Disconnect(); return 0; } @@ -418,6 +417,8 @@ int PairUp(bool unpair) radioParam.dwSize = sizeof(radioParam); HANDLE hRadio; + + // TODO: save radio(s) in the WiimoteScanner constructor // Enumerate BT radios HBLUETOOTH_RADIO_FIND hFindRadio = Bth_BluetoothFindFirstRadio(&radioParam, &hRadio); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 02f3941fc8..f3c90d810d 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -213,16 +213,10 @@ bool Wiimote::Connect() // Disconnect a wiimote. void Wiimote::Disconnect() { - if (!IsConnected()) - return; - NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i", index + 1); m_connected = false; - if (m_wiimote_thread.joinable()) - m_wiimote_thread.join(); - [btd closeConnection]; [ichan release]; [cchan release]; From 05ec90488b3951d5af29e41bec47955dc36baaec Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 03:39:09 -0600 Subject: [PATCH 028/167] Make real wiimotes not so crappy on Windows hopefully. --- .../Core/Core/Src/HW/WiimoteReal/IODummy.cpp | 5 +- Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 11 +- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 262 +++++++++++------- .../Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 10 +- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 140 +++++----- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 23 +- .../Core/Src/HW/WiimoteReal/WiimoteRealBase.h | 5 +- 7 files changed, 259 insertions(+), 197 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index 6af169f5ee..3a017354eb 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -29,7 +29,10 @@ WiimoteScanner::WiimoteScanner() WiimoteScanner::~WiimoteScanner() {} -std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) +void WiimoteScanner::Update() +{} + +std::vector WiimoteScanner::FindWiimotes() { return std::vector(); } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index e926d44ec0..62fd2e4ac5 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -60,11 +60,10 @@ WiimoteScanner::~WiimoteScanner() close(device_sock); } -// Find wiimotes. -// Does not replace already found wiimotes even if they are disconnected. -// wm is an array of max_wiimotes wiimotes -// Returns the total number of found wiimotes. -std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) +void WiimoteScanner::Update() +{} + +std::vector WiimoteScanner::FindWiimotes() { std::vector found_wiimotes; @@ -86,7 +85,7 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices); // Display discovered devices - for (int i = 0; (i < found_devices) && (found_wiimotes.size() < max_wiimotes); ++i) + for (int i = 0; i < found_devices; ++i) { ERROR_LOG(WIIMOTE, "found a device..."); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 8226c784e8..c88cdebdbc 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,8 @@ HINSTANCE bthprops_lib = NULL; static int initialized = 0; +static std::unordered_set g_connected_devices; + inline void init_lib() { if (!initialized) @@ -127,7 +130,12 @@ inline void init_lib() namespace WiimoteReal { -int PairUp(bool unpair = false); +template +void ProcessWiimotes(bool new_scan, T& callback); + +bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); +void RemoveWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); +bool ForgetWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); WiimoteScanner::WiimoteScanner() { @@ -137,24 +145,47 @@ WiimoteScanner::WiimoteScanner() WiimoteScanner::~WiimoteScanner() { // TODO: what do we want here? - //PairUp(true); + ProcessWiimotes(false, RemoveWiimote); +} + +void WiimoteScanner::Update() +{ + bool forgot_some = false; + + ProcessWiimotes(false, [&](HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) + { + forgot_some |= ForgetWiimote(hRadio, btdi); + }); + + // Some hacks that allows disconnects to be detected before connections are handled + // workaround for wiimote 1 moving to slot 2 on temporary disconnect + if (forgot_some) + SLEEP(100); } // Find and connect wiimotes. // Does not replace already found wiimotes even if they are disconnected. // wm is an array of max_wiimotes wiimotes // Returns the total number of found and connected wiimotes. -std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) +std::vector WiimoteScanner::FindWiimotes() { - PairUp(); + bool attached_some; + + ProcessWiimotes(true, [&](HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) + { + ForgetWiimote(hRadio, btdi); + attached_some |= AttachWiimote(hRadio, btdi); + }); + + // Hacks... + if (attached_some) + SLEEP(1000); GUID device_id; - HANDLE dev; HDEVINFO device_info; DWORD len; SP_DEVICE_INTERFACE_DATA device_data; PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; - HIDD_ATTRIBUTES attr; device_data.cbSize = sizeof(device_data); @@ -165,7 +196,7 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); std::vector wiimotes; - for (int index = 0; wiimotes.size() < max_wiimotes; ++index) + for (int index = 0; true; ++index) { free(detail_data); detail_data = NULL; @@ -184,24 +215,7 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) continue; auto const wm = new Wiimote; - - // Open new device -#if 0 - dev = CreateFile(detail_data->DevicePath, - (GENERIC_READ | GENERIC_WRITE), - (FILE_SHARE_READ | FILE_SHARE_WRITE), - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - if (dev == INVALID_HANDLE_VALUE) - continue; - - // Get device attributes - attr.Size = sizeof(attr); - HidD_GetAttributes(dev, &attr); - - wm->dev_handle = dev; -#endif wm->devicepath = detail_data->DevicePath; - wiimotes.push_back(wm); } @@ -236,9 +250,15 @@ bool WiimoteScanner::IsReady() const // Connect to a wiimote with a known device path. bool Wiimote::Connect() { + // This is where we disallow connecting to the same device twice + if (g_connected_devices.count(devicepath)) + return false; + dev_handle = CreateFile(devicepath.c_str(), (GENERIC_READ | GENERIC_WRITE), - /*(FILE_SHARE_READ | FILE_SHARE_WRITE)*/ 0, + // TODO: Just do FILE_SHARE_READ and remove "g_connected_devices"? + // That is what "WiiYourself" does. + (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (dev_handle == INVALID_HANDLE_VALUE) @@ -247,11 +267,12 @@ bool Wiimote::Connect() return false; } + hid_overlap = OVERLAPPED(); hid_overlap.hEvent = CreateEvent(NULL, 1, 1, _T("")); hid_overlap.Offset = 0; hid_overlap.OffsetHigh = 0; - // TODO: do this elsewhere + // TODO: thread isn't started here now, do this elsewhere // This isn't as drastic as it sounds, since the process in which the threads // reside is normal priority. Needed for keeping audio reports at a decent rate /* @@ -261,15 +282,17 @@ bool Wiimote::Connect() } */ + g_connected_devices.insert(devicepath); return true; } void Wiimote::Disconnect() { + g_connected_devices.erase(devicepath); + CloseHandle(dev_handle); dev_handle = 0; - //ResetEvent(&hid_overlap); CloseHandle(hid_overlap.hEvent); } @@ -283,50 +306,73 @@ bool Wiimote::IsConnected() const // zero = error int Wiimote::IORead(unsigned char* buf) { + // used below for a warning *buf = 0; - DWORD b; - if (!ReadFile(dev_handle, buf, MAX_PAYLOAD, &b, &hid_overlap)) + DWORD bytes; + ResetEvent(hid_overlap.hEvent); + if (!ReadFile(dev_handle, buf, MAX_PAYLOAD - 1, &bytes, &hid_overlap)) { - // Partial read - b = GetLastError(); - if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) + auto const err = GetLastError(); + + if (ERROR_IO_PENDING == err) + { + auto const r = WaitForSingleObject(hid_overlap.hEvent, WIIMOTE_DEFAULT_TIMEOUT); + if (WAIT_TIMEOUT == r) + { + // Timeout - cancel and continue + if (*buf) + WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).", + WIIMOTE_DEFAULT_TIMEOUT); + + CancelIo(dev_handle); + bytes = -1; + } + else if (WAIT_FAILED == r) + { + WARN_LOG(WIIMOTE, "A wait error occured on reading from wiimote %i.", index + 1); + bytes = 0; + } + else if (WAIT_OBJECT_0 == r) + { + if (!GetOverlappedResult(dev_handle, &hid_overlap, &bytes, TRUE)) + { + WARN_LOG(WIIMOTE, "GetOverlappedResult failed on wiimote %i.", index + 1); + bytes = 0; + } + } + else + { + bytes = 0; + } + } + else if (ERROR_HANDLE_EOF == err) { // Remote disconnect - return 0; + bytes = 0; } - - auto const r = WaitForSingleObject(hid_overlap.hEvent, WIIMOTE_DEFAULT_TIMEOUT); - if (r == WAIT_TIMEOUT) + else if (ERROR_DEVICE_NOT_CONNECTED == err) { - // Timeout - cancel and continue - if (*buf) - WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).", - WIIMOTE_DEFAULT_TIMEOUT); - - CancelIo(dev_handle); - ResetEvent(hid_overlap.hEvent); - return -1; + // Remote disconnect + bytes = 0; } - else if (r == WAIT_FAILED) + else { - WARN_LOG(WIIMOTE, "A wait error occured on reading from wiimote %i.", index + 1); - return -1; - } - - if (!GetOverlappedResult(dev_handle, &hid_overlap, &b, 0)) - { - return -1; + bytes = 0; } } - // This needs to be done even if ReadFile fails, essential during init - // Move the data over one, so we can add back in data report indicator byte (here, 0xa1) - memmove(buf + 1, buf, MAX_PAYLOAD - 1); - buf[0] = 0xa1; + if (bytes > 0) + { + // Move the data over one, so we can add back in data report indicator byte (here, 0xa1) + memmove(buf + 1, buf, MAX_PAYLOAD - 1); + buf[0] = 0xa1; - ResetEvent(hid_overlap.hEvent); - return MAX_PAYLOAD; // XXX + // TODO: is this really needed? + bytes = MAX_PAYLOAD; + } + + return bytes; } int Wiimote::IOWrite(const u8* buf, int len) @@ -392,14 +438,12 @@ int Wiimote::IOWrite(const u8* buf, int len) return 0; } -// WiiMote Pair-Up, function will return amount of either new paired or unpaired devices -// negative number on failure -int PairUp(bool unpair) +// invokes callback for each found wiimote bluetooth device +template +void ProcessWiimotes(bool new_scan, T& callback) { // match strings like "Nintendo RVL-WBC-01", "Nintendo RVL-CNT-01", "Nintendo RVL-CNT-01-TR" - const std::wregex wiimote_device_name(L"Nintendo RVL-\\w{3}-\\d{2}(-\\w{2})?"); - - int nPaired = 0; + const std::wregex wiimote_device_name(L"Nintendo RVL-.*"); BLUETOOTH_DEVICE_SEARCH_PARAMS srch; srch.dwSize = sizeof(srch); @@ -409,7 +453,7 @@ int PairUp(bool unpair) // fConnected BT Devices srch.fReturnConnected = true; srch.fReturnUnknown = true; - srch.fIssueInquiry = true; + srch.fIssueInquiry = new_scan; // multiple of 1.28 seconds srch.cTimeoutMultiplier = 1; @@ -418,14 +462,10 @@ int PairUp(bool unpair) HANDLE hRadio; - // TODO: save radio(s) in the WiimoteScanner constructor + // TODO: save radio(s) in the WiimoteScanner constructor? // Enumerate BT radios HBLUETOOTH_RADIO_FIND hFindRadio = Bth_BluetoothFindFirstRadio(&radioParam, &hRadio); - - if (NULL == hFindRadio) - return -1; - while (hFindRadio) { BLUETOOTH_RADIO_INFO radioInfo; @@ -449,40 +489,7 @@ int PairUp(bool unpair) if (std::regex_match(btdi.szName, wiimote_device_name)) { - if (unpair) - { - if (SUCCEEDED(Bth_BluetoothRemoveDevice(&btdi.Address))) - { - NOTICE_LOG(WIIMOTE, - "Pair-Up: Automatically removed BT Device on shutdown: %08x", - GetLastError()); - ++nPaired; - } - } - else - { - if (false == btdi.fConnected) - { - // TODO: improve the read of the BT driver, esp. when batteries - // of the wiimote are removed while being fConnected - if (btdi.fRemembered) - { - // Make Windows forget old expired pairing. We can pretty - // much ignore the return value here. It either worked - // (ERROR_SUCCESS), or the device did not exist - // (ERROR_NOT_FOUND). In both cases, there is nothing left. - Bth_BluetoothRemoveDevice(&btdi.Address); - } - - // Activate service - const DWORD hr = Bth_BluetoothSetServiceState(hRadio, &btdi, - &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE); - if (SUCCEEDED(hr)) - ++nPaired; - else - ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr); - } - } + callback(hRadio, btdi); } if (false == Bth_BluetoothFindNextDevice(hFindDevice, &btdi)) @@ -498,8 +505,53 @@ int PairUp(bool unpair) hFindRadio = NULL; } } +} - return nPaired; +void RemoveWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) +{ + //if (btdi.fConnected) + { + if (SUCCEEDED(Bth_BluetoothRemoveDevice(&btdi.Address))) + { + NOTICE_LOG(WIIMOTE, "Removed BT Device", GetLastError()); + } + } +} + +bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) +{ + if (!btdi.fConnected && !btdi.fRemembered) + { + NOTICE_LOG(WIIMOTE, "Found wiimote. Enabling HID service."); + + // Activate service + const DWORD hr = Bth_BluetoothSetServiceState(hRadio, &btdi, + &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE); + + if (FAILED(hr)) + ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr); + else + return true; + } + + return false; +} + +// Removes remembered non-connected devices +bool ForgetWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) +{ + if (!btdi.fConnected && btdi.fRemembered) + { + // We don't want "remembered" devices. + // SetServiceState seems to just fail with them. + // Make Windows forget about them. + NOTICE_LOG(WIIMOTE, "Removing remembered wiimote."); + Bth_BluetoothRemoveDevice(&btdi.Address); + + return true; + } + + return false; } }; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index f3c90d810d..9ed78800cc 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -111,7 +111,10 @@ WiimoteScanner::WiimoteScanner() WiimoteScanner::~WiimoteScanner() {} -std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) +void WiimoteScanner::Update() +{} + +std::vector WiimoteScanner::FindWiimotes() { // TODO: find the device in the constructor and save it for later @@ -130,7 +133,7 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) } sbt = [[SearchBT alloc] init]; - sbt->maxDevices = max_wiimotes; + sbt->maxDevices = 32; bti = [[IOBluetoothDeviceInquiry alloc] init]; [bti setDelegate: sbt]; [bti setInquiryLength: 2]; @@ -157,9 +160,6 @@ std::vector WiimoteScanner::FindWiimotes(size_t max_wiimotes) Wiimote *wm = new Wiimote(); wm->btd = dev; wiimotes.push_back(wm); - - if(wiimotes.size() >= max_wiimotes) - break; } [bth release]; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 7ae1a9a961..6a5d91fa00 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -35,7 +35,7 @@ namespace WiimoteReal { void HandleFoundWiimotes(const std::vector&); -void HandleWiimoteConnect(Wiimote*); +void TryToConnectWiimote(Wiimote*); void HandleWiimoteDisconnect(int index); bool g_real_wiimotes_initialized = false; @@ -171,7 +171,10 @@ bool Wiimote::Read() rpt.second = IORead(rpt.first); if (0 == rpt.second) + { + WARN_LOG(WIIMOTE, "Wiimote::IORead failed. Disconnecting wiimote %d.", index + 1); Disconnect(); + } if (rpt.second > 0 && m_channel > 0) { @@ -192,12 +195,12 @@ bool Wiimote::Write() bool const is_speaker_data = rpt.first[1] == WM_WRITE_SPEAKER_DATA; - if (!is_speaker_data || last_audio_report.GetTimeDifference() > 5) + if (!is_speaker_data || m_last_audio_report.GetTimeDifference() > 5) { IOWrite(rpt.first, rpt.second); if (is_speaker_data) - last_audio_report.Update(); + m_last_audio_report.Update(); delete[] rpt.first; m_write_reports.Pop(); @@ -242,27 +245,24 @@ void Wiimote::Update() delete[] rpt.first; } -// Rumble briefly -void Wiimote::RumbleBriefly() +bool Wiimote::Prepare(int _index) { - unsigned char buffer = 0x01; - DEBUG_LOG(WIIMOTE, "Starting rumble..."); - QueueReport(WM_CMD_RUMBLE, &buffer, sizeof(buffer)); + index = _index; - SLEEP(200); + // Set the active LEDs. + u8 const led_report[] = {HID_TYPE_SET_REPORT, WM_CMD_LED, WIIMOTE_LED_1 << index}; - DEBUG_LOG(WIIMOTE, "Stopping rumble..."); - buffer = 0x00; - QueueReport(WM_CMD_RUMBLE, &buffer, sizeof(buffer)); -} + // Rumble briefly + u8 rumble_report[] = {HID_TYPE_SET_REPORT, WM_CMD_RUMBLE, 1}; -// Set the active LEDs. -// leds is a bitwise OR of WIIMOTE_LED_1 through WIIMOTE_LED_4. -void Wiimote::SetLEDs(int new_leds) -{ - // Remove the lower 4 bits because they control rumble - u8 const buffer = (new_leds & 0xF0); - QueueReport(WM_CMD_LED, &buffer, sizeof(buffer)); + // don't really care what is read, just that reading works + u8 input_buf[MAX_PAYLOAD]; + + // TODO: request status and check for sane response? + + return (IOWrite(led_report, sizeof(led_report)) + && IOWrite(rumble_report, sizeof(rumble_report)) + && (rumble_report[2] = 0, SLEEP(200), IOWrite(rumble_report, sizeof(rumble_report)))); } void Wiimote::EmuStart() @@ -290,48 +290,66 @@ unsigned int CalculateWantedWiimotes() return wanted_wiimotes; } -void WiimoteScanner::WantWiimotes(size_t count) +void WiimoteScanner::WantWiimotes(bool do_want) { - want_wiimotes = count; + m_want_wiimotes = do_want; } void WiimoteScanner::StartScanning() { - run_thread = true; + m_run_thread = true; if (IsReady()) { - scan_thread = std::thread(std::mem_fun(&WiimoteScanner::ThreadFunc), this); + m_scan_thread = std::thread(std::mem_fun(&WiimoteScanner::ThreadFunc), this); } } void WiimoteScanner::StopScanning() { - run_thread = false; - if (scan_thread.joinable()) + m_run_thread = false; + if (m_scan_thread.joinable()) { - scan_thread.join(); + m_scan_thread.join(); } } + +void CheckForDisconnectedWiimotes() +{ + std::lock_guard lk(g_refresh_lock); + + for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected()) + HandleWiimoteDisconnect(i); +} + void WiimoteScanner::ThreadFunc() { Common::SetCurrentThreadName("Wiimote Scanning Thread"); NOTICE_LOG(WIIMOTE, "Wiimote scanning has started"); - while (run_thread) + while (m_run_thread) { - auto const found_wiimotes = FindWiimotes(want_wiimotes); - HandleFoundWiimotes(found_wiimotes); -#if 1 + std::vector found_wiimotes; + + //NOTICE_LOG(WIIMOTE, "in loop"); + + if (m_want_wiimotes) + found_wiimotes = FindWiimotes(); + else { - // TODO: this code here is ugly - std::lock_guard lk(g_refresh_lock); - for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) - if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected()) - HandleWiimoteDisconnect(i); + // Does stuff needed to detect disconnects on Windows + Update(); } -#endif + + //NOTICE_LOG(WIIMOTE, "after update"); + + // TODO: this is a fairly lame place for this + CheckForDisconnectedWiimotes(); + + HandleFoundWiimotes(found_wiimotes); + //std::this_thread::yield(); Common::SleepCurrentThread(500); } @@ -396,8 +414,7 @@ void Initialize() if (g_real_wiimotes_initialized) return; - auto const wanted_wiimotes = CalculateWantedWiimotes(); - g_wiimote_scanner.WantWiimotes(wanted_wiimotes); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); g_wiimote_scanner.StartScanning(); @@ -431,26 +448,23 @@ void ChangeWiimoteSource(unsigned int index, int source) if (!(WIIMOTE_SRC_REAL & g_wiimote_sources[index])) HandleWiimoteDisconnect(index); - auto const wanted_wiimotes = CalculateWantedWiimotes(); - g_wiimote_scanner.WantWiimotes(wanted_wiimotes); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); } -void HandleWiimoteConnect(Wiimote* wm) +void TryToConnectWiimote(Wiimote* wm) { std::lock_guard lk(g_refresh_lock); for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) { - if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && !g_wiimotes[i]) + if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] + && !g_wiimotes[i] + && wm->Connect() + && wm->Prepare(i)) { g_wiimotes[i] = wm; - wm->index = i; wm->StartThread(); - - wm->DisableDataReporting(); - wm->SetLEDs(WIIMOTE_LED_1 << i); - wm->RumbleBriefly(); Host_ConnectWiimote(i, true); @@ -463,14 +477,12 @@ void HandleWiimoteConnect(Wiimote* wm) delete wm; - auto const want_wiimotes = CalculateWantedWiimotes(); - g_wiimote_scanner.WantWiimotes(want_wiimotes); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); } void HandleWiimoteDisconnect(int index) { - // locked above - //std::lock_guard lk(g_refresh_lock); + std::lock_guard lk(g_refresh_lock); Host_ConnectWiimote(index, false); @@ -482,19 +494,12 @@ void HandleWiimoteDisconnect(int index) NOTICE_LOG(WIIMOTE, "Disconnected wiimote %i.", index + 1); } - auto const want_wiimotes = CalculateWantedWiimotes(); - g_wiimote_scanner.WantWiimotes(want_wiimotes); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); } void HandleFoundWiimotes(const std::vector& wiimotes) { - std::for_each(wiimotes.begin(), wiimotes.end(), [](Wiimote* const wm) - { - if (wm->Connect()) - HandleWiimoteConnect(wm); - else - delete wm; - }); + std::for_each(wiimotes.begin(), wiimotes.end(), TryToConnectWiimote); } // This is called from the GUI thread @@ -504,14 +509,13 @@ void Refresh() { std::lock_guard lk(g_refresh_lock); + + CheckForDisconnectedWiimotes(); - auto wanted_wiimotes = CalculateWantedWiimotes(); - auto const found_wiimotes = g_wiimote_scanner.FindWiimotes(wanted_wiimotes); - - HandleFoundWiimotes(found_wiimotes); - - wanted_wiimotes = CalculateWantedWiimotes(); - g_wiimote_scanner.WantWiimotes(wanted_wiimotes); + if (0 != CalculateWantedWiimotes()) + { + HandleFoundWiimotes(g_wiimote_scanner.FindWiimotes()); + } } g_wiimote_scanner.StartScanning(); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 139d59ce99..4b8f4365d3 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -63,14 +63,16 @@ public: void EmuStop(); // connecting and disconnecting from physical devices + // (using address inserted by FindWiimotes) + + // FYI, Connect/Disconnect are not thread safe even between unique objects (on windows) bool Connect(); void Disconnect(); // TODO: change to something like IsRelevant bool IsConnected() const; - void SetLEDs(int leds); - void RumbleBriefly(); + bool Prepare(int index); void DisableDataReporting(); @@ -116,7 +118,7 @@ private: Common::FifoQueue m_read_reports; Common::FifoQueue m_write_reports; - Common::Timer last_audio_report; + Common::Timer m_last_audio_report; }; class WiimoteScanner @@ -127,22 +129,23 @@ public: bool IsReady() const; - void WantWiimotes(size_t count); + void WantWiimotes(bool do_want); void StartScanning(); void StopScanning(); - std::vector FindWiimotes(size_t max_wiimotes); + std::vector FindWiimotes(); + + // function called when not looking for more wiimotes + void Update(); private: void ThreadFunc(); - std::thread scan_thread; + std::thread m_scan_thread; - volatile bool run_thread; - - // TODO: this should probably be atomic - volatile size_t want_wiimotes; + volatile bool m_run_thread; + volatile bool m_want_wiimotes; #if defined(_WIN32) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h index 75a6d3e6a3..15bbc2917f 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h @@ -66,8 +66,9 @@ // End Wiimote internal codes -#define MAX_PAYLOAD 32 -#define WIIMOTE_DEFAULT_TIMEOUT 30 +// It's 23. NOT 32! +#define MAX_PAYLOAD 23 +#define WIIMOTE_DEFAULT_TIMEOUT 1000 #ifdef _WIN32 // Available bluetooth stacks for Windows. From 7a053d0f0715a5308300a9ee05928433a8250953 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 03:50:54 -0600 Subject: [PATCH 029/167] buildfix! --- Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 4 ++-- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 2 ++ Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 2 ++ Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 5 +---- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index 62fd2e4ac5..87ddc5086b 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -27,8 +27,8 @@ namespace WiimoteReal { WiimoteScanner::WiimoteScanner() - : run_thread() - , want_wiimotes() + : m_run_thread() + , m_want_wiimotes() , device_id(-1) , device_sock(-1) { diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index c88cdebdbc..1920577de4 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -138,6 +138,8 @@ void RemoveWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); bool ForgetWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); WiimoteScanner::WiimoteScanner() + : m_run_thread() + , m_want_wiimotes() { init_lib(); } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 9ed78800cc..51dcd17785 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -106,6 +106,8 @@ namespace WiimoteReal { WiimoteScanner::WiimoteScanner() + : m_run_thread() + , m_want_wiimotes() {} WiimoteScanner::~WiimoteScanner() diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 6a5d91fa00..821eccea0c 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -250,14 +250,11 @@ bool Wiimote::Prepare(int _index) index = _index; // Set the active LEDs. - u8 const led_report[] = {HID_TYPE_SET_REPORT, WM_CMD_LED, WIIMOTE_LED_1 << index}; + u8 const led_report[] = {HID_TYPE_SET_REPORT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index)}; // Rumble briefly u8 rumble_report[] = {HID_TYPE_SET_REPORT, WM_CMD_RUMBLE, 1}; - // don't really care what is read, just that reading works - u8 input_buf[MAX_PAYLOAD]; - // TODO: request status and check for sane response? return (IOWrite(led_report, sizeof(led_report)) From c267be2682cd6d6fbcf163893a1361aa49511c8f Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 05:30:51 -0600 Subject: [PATCH 030/167] Hopefully fix windows! --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 13 +++++++++++-- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 10 +++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 1920577de4..7c6f6f20d0 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -379,6 +380,14 @@ int Wiimote::IORead(unsigned char* buf) int Wiimote::IOWrite(const u8* buf, int len) { + u8 big_buf[MAX_PAYLOAD]; + if (len < MAX_PAYLOAD) + { + std::copy(buf, buf + len, big_buf); + std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0); + buf = big_buf; + } + DWORD bytes = 0; switch (stack) { @@ -386,7 +395,7 @@ int Wiimote::IOWrite(const u8* buf, int len) { // Try to auto-detect the stack type - auto i = WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap); + auto i = WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap); if (i) { // Bluesoleil will always return 1 here, even if it's not connected @@ -433,7 +442,7 @@ int Wiimote::IOWrite(const u8* buf, int len) break; } case MSBT_STACK_BLUESOLEIL: - return WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap); + return WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap); break; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 821eccea0c..e006ec1f69 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -249,15 +249,19 @@ bool Wiimote::Prepare(int _index) { index = _index; + // core buttons, no continuous reporting + u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_REPORT_TYPE, 0, 0x30}; + // Set the active LEDs. - u8 const led_report[] = {HID_TYPE_SET_REPORT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index)}; + u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index)}; // Rumble briefly - u8 rumble_report[] = {HID_TYPE_SET_REPORT, WM_CMD_RUMBLE, 1}; + u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_RUMBLE, 1}; // TODO: request status and check for sane response? - return (IOWrite(led_report, sizeof(led_report)) + return (IOWrite(mode_report, sizeof(mode_report)) + && IOWrite(led_report, sizeof(led_report)) && IOWrite(rumble_report, sizeof(rumble_report)) && (rumble_report[2] = 0, SLEEP(200), IOWrite(rumble_report, sizeof(rumble_report)))); } From b8fd5c0c307aa45f846b4ec412e05608d0e93e41 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 05:57:55 -0600 Subject: [PATCH 031/167] Fix Windows for real! --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 7c6f6f20d0..d9b6a665ef 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -421,8 +421,7 @@ int Wiimote::IOWrite(const u8* buf, int len) else { ERROR_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]: ERROR: %08x", dw); - // Correct? - return -1; + return 0; } break; } From c2d2fb8c7c84ab2abf439f1ccdafd44d71b41b64 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 15:21:58 -0600 Subject: [PATCH 032/167] Try to improve real wiimotes on Windows. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 126 ++++++++++-------- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 56 +++++--- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 2 +- 3 files changed, 112 insertions(+), 72 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index d9b6a665ef..d6bc5dd28b 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -270,10 +270,22 @@ bool Wiimote::Connect() return false; } - hid_overlap = OVERLAPPED(); - hid_overlap.hEvent = CreateEvent(NULL, 1, 1, _T("")); - hid_overlap.Offset = 0; - hid_overlap.OffsetHigh = 0; +#if 0 + HIDD_ATTRIBUTES attr; + attr.Size = sizeof(attr); + if (!HidD_GetAttributes(dev_handle, &attr)) + { + CloseHandle(dev_handle); + dev_handle = 0; + return false; + } +#endif + + hid_overlap_read = OVERLAPPED(); + hid_overlap_read.hEvent = CreateEvent(NULL, true, false, NULL); + + hid_overlap_write = OVERLAPPED(); + hid_overlap_write.hEvent = CreateEvent(NULL, true, false, NULL); // TODO: thread isn't started here now, do this elsewhere // This isn't as drastic as it sounds, since the process in which the threads @@ -296,7 +308,8 @@ void Wiimote::Disconnect() CloseHandle(dev_handle); dev_handle = 0; - CloseHandle(hid_overlap.hEvent); + CloseHandle(hid_overlap_read.hEvent); + CloseHandle(hid_overlap_write.hEvent); } bool Wiimote::IsConnected() const @@ -307,20 +320,20 @@ bool Wiimote::IsConnected() const // positive = read packet // negative = didn't read packet // zero = error -int Wiimote::IORead(unsigned char* buf) +int Wiimote::IORead(u8* buf) { // used below for a warning *buf = 0; DWORD bytes; - ResetEvent(hid_overlap.hEvent); - if (!ReadFile(dev_handle, buf, MAX_PAYLOAD - 1, &bytes, &hid_overlap)) + ResetEvent(hid_overlap_read.hEvent); + if (!ReadFile(dev_handle, buf, MAX_PAYLOAD - 1, &bytes, &hid_overlap_read)) { auto const err = GetLastError(); if (ERROR_IO_PENDING == err) { - auto const r = WaitForSingleObject(hid_overlap.hEvent, WIIMOTE_DEFAULT_TIMEOUT); + auto const r = WaitForSingleObject(hid_overlap_read.hEvent, WIIMOTE_DEFAULT_TIMEOUT); if (WAIT_TIMEOUT == r) { // Timeout - cancel and continue @@ -338,7 +351,7 @@ int Wiimote::IORead(unsigned char* buf) } else if (WAIT_OBJECT_0 == r) { - if (!GetOverlappedResult(dev_handle, &hid_overlap, &bytes, TRUE)) + if (!GetOverlappedResult(dev_handle, &hid_overlap_read, &bytes, TRUE)) { WARN_LOG(WIIMOTE, "GetOverlappedResult failed on wiimote %i.", index + 1); bytes = 0; @@ -380,70 +393,76 @@ int Wiimote::IORead(unsigned char* buf) int Wiimote::IOWrite(const u8* buf, int len) { - u8 big_buf[MAX_PAYLOAD]; - if (len < MAX_PAYLOAD) - { - std::copy(buf, buf + len, big_buf); - std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0); - buf = big_buf; - } - - DWORD bytes = 0; switch (stack) { case MSBT_STACK_UNKNOWN: { // Try to auto-detect the stack type - - auto i = WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap); - if (i) + stack = MSBT_STACK_BLUESOLEIL; + if (IOWrite(buf, len)) + return 1; + + stack = MSBT_STACK_MS; + if (IOWrite(buf, len)) { - // Bluesoleil will always return 1 here, even if it's not connected - stack = MSBT_STACK_BLUESOLEIL; - return i; + // Don't mind me, just a random sleep to fix stuff on Windows + SLEEP(1000); + return 1; } - i = HidD_SetOutputReport(dev_handle, (unsigned char*) buf + 1, len - 1); - if (i) - { - stack = MSBT_STACK_MS; - return i; - } - - auto const dw = GetLastError(); - // Checking for 121 = timeout on semaphore/device off/disconnected to - // avoid trouble with other stacks toshiba/widcomm - if (dw == 121) - { - NOTICE_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]: Timeout"); - return 0; - } - else - { - ERROR_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]: ERROR: %08x", dw); - return 0; - } + stack = MSBT_STACK_UNKNOWN; break; } case MSBT_STACK_MS: { - auto i = HidD_SetOutputReport(dev_handle, (unsigned char*) buf + 1, len - 1); - auto dw = GetLastError(); + auto result = HidD_SetOutputReport(dev_handle, const_cast(buf) + 1, len - 1); + //FlushFileBuffers(dev_handle); - if (dw == 121) + if (!result) { - // Semaphore timeout - NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to wiimote"); - return 0; + auto err = GetLastError(); + if (err == 121) + { + // Semaphore timeout + NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to wiimote"); + } + else + { + ERROR_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); + } } - return i; + return result; break; } case MSBT_STACK_BLUESOLEIL: - return WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap); + { + u8 big_buf[MAX_PAYLOAD]; + if (len < MAX_PAYLOAD) + { + std::copy(buf, buf + len, big_buf); + std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0); + buf = big_buf; + } + + ResetEvent(hid_overlap_write.hEvent); + DWORD bytes = 0; + if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write)) + { + // WriteFile always returns true with bluesoleil. + return 1; + } + else + { + auto const err = GetLastError(); + if (ERROR_IO_PENDING == err) + { + CancelIo(dev_handle); + } + } break; } + } return 0; } @@ -555,6 +574,7 @@ bool ForgetWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) // We don't want "remembered" devices. // SetServiceState seems to just fail with them. // Make Windows forget about them. + // This is also required to detect a disconnect for some reason.. NOTICE_LOG(WIIMOTE, "Removing remembered wiimote."); Bth_BluetoothRemoveDevice(&btdi.Address); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index e006ec1f69..6e9a72eb00 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -232,6 +232,12 @@ Report Wiimote::ProcessReadQueue() void Wiimote::Update() { + if (!IsConnected()) + { + HandleWiimoteDisconnect(index); + return; + } + // Pop through the queued reports Report const rpt = ProcessReadQueue(); @@ -252,18 +258,17 @@ bool Wiimote::Prepare(int _index) // core buttons, no continuous reporting u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_REPORT_TYPE, 0, 0x30}; - // Set the active LEDs. - u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index)}; + // Set the active LEDs and turn on rumble. + u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index) | 0x1}; - // Rumble briefly - u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_RUMBLE, 1}; + // Turn off rumble + u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_RUMBLE, 0}; // TODO: request status and check for sane response? return (IOWrite(mode_report, sizeof(mode_report)) && IOWrite(led_report, sizeof(led_report)) - && IOWrite(rumble_report, sizeof(rumble_report)) - && (rumble_report[2] = 0, SLEEP(200), IOWrite(rumble_report, sizeof(rumble_report)))); + && (SLEEP(200), IOWrite(rumble_report, sizeof(rumble_report)))); } void Wiimote::EmuStart() @@ -375,6 +380,8 @@ void Wiimote::ThreadFunc() { Common::SetCurrentThreadName("Wiimote Device Thread"); + Host_ConnectWiimote(index, true); + // main loop while (m_run_thread && IsConnected()) { @@ -408,13 +415,13 @@ void LoadSettings() void Initialize() { - NOTICE_LOG(WIIMOTE, "WiimoteReal::Initialize"); - std::lock_guard lk(g_refresh_lock); if (g_real_wiimotes_initialized) return; + NOTICE_LOG(WIIMOTE, "WiimoteReal::Initialize"); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); g_wiimote_scanner.StartScanning(); @@ -423,9 +430,7 @@ void Initialize() } void Shutdown(void) -{ - NOTICE_LOG(WIIMOTE, "WiimoteReal::Shutdown"); - +{ g_wiimote_scanner.StopScanning(); std::lock_guard lk(g_refresh_lock); @@ -433,6 +438,8 @@ void Shutdown(void) if (!g_real_wiimotes_initialized) return; + NOTICE_LOG(WIIMOTE, "WiimoteReal::Shutdown"); + g_real_wiimotes_initialized = false; for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) @@ -466,8 +473,6 @@ void TryToConnectWiimote(Wiimote* wm) g_wiimotes[i] = wm; wm->StartThread(); - - Host_ConnectWiimote(i, true); NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", i + 1); @@ -485,8 +490,6 @@ void HandleWiimoteDisconnect(int index) { std::lock_guard lk(g_refresh_lock); - Host_ConnectWiimote(index, false); - if (g_wiimotes[index]) { delete g_wiimotes[index]; @@ -511,12 +514,24 @@ void Refresh() { std::lock_guard lk(g_refresh_lock); - CheckForDisconnectedWiimotes(); + std::vector found_wiimotes; if (0 != CalculateWantedWiimotes()) { - HandleFoundWiimotes(g_wiimote_scanner.FindWiimotes()); + found_wiimotes = g_wiimote_scanner.FindWiimotes(); } + + CheckForDisconnectedWiimotes(); + + // Brief rumble for already connected wiimotes. + for (int i = 0; i != MAX_WIIMOTES; ++i) + { + // kinda sloppy + if (g_wiimotes[i]) + g_wiimotes[i]->Prepare(i); + } + + HandleFoundWiimotes(found_wiimotes); } g_wiimote_scanner.StartScanning(); @@ -546,8 +561,13 @@ void Update(int _WiimoteNumber) if (g_wiimotes[_WiimoteNumber]) g_wiimotes[_WiimoteNumber]->Update(); - else + + // Wiimote::Update() may remove the wiimote if it was disconnected. + if (!g_wiimotes[_WiimoteNumber]) + { + NOTICE_LOG(WIIMOTE, "Emulating disconnect of wiimote %d.", _WiimoteNumber + 1); Host_ConnectWiimote(_WiimoteNumber, false); + } } void StateChange(EMUSTATE_CHANGE newState) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 4b8f4365d3..55fc552abd 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -96,7 +96,7 @@ public: std::string devicepath; // Unique wiimote reference //ULONGLONG btaddr; // Bluetooth address HANDLE dev_handle; // HID handle - OVERLAPPED hid_overlap; // Overlap handle + OVERLAPPED hid_overlap_read, hid_overlap_write; // Overlap handle enum win_bt_stack_t stack; // Type of bluetooth stack to use #endif From 0fb7f65e04f966f9eef1b8dfcb7d8d8ebec834ae Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 15:58:23 -0600 Subject: [PATCH 033/167] Problems on Windows? Just SLEEP twice as long! --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 6 +++++- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h | 2 -- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index d6bc5dd28b..3052f4b737 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -75,6 +75,7 @@ HINSTANCE bthprops_lib = NULL; static int initialized = 0; +std::mutex g_connected_devices_lock; static std::unordered_set g_connected_devices; inline void init_lib() @@ -182,7 +183,7 @@ std::vector WiimoteScanner::FindWiimotes() // Hacks... if (attached_some) - SLEEP(1000); + SLEEP(2000); GUID device_id; HDEVINFO device_info; @@ -253,6 +254,8 @@ bool WiimoteScanner::IsReady() const // Connect to a wiimote with a known device path. bool Wiimote::Connect() { + std::lock_guard lk(g_connected_devices_lock); + // This is where we disallow connecting to the same device twice if (g_connected_devices.count(devicepath)) return false; @@ -303,6 +306,7 @@ bool Wiimote::Connect() void Wiimote::Disconnect() { + std::lock_guard lk(g_connected_devices_lock); g_connected_devices.erase(devicepath); CloseHandle(dev_handle); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 55fc552abd..793a13ceb0 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -64,8 +64,6 @@ public: // connecting and disconnecting from physical devices // (using address inserted by FindWiimotes) - - // FYI, Connect/Disconnect are not thread safe even between unique objects (on windows) bool Connect(); void Disconnect(); From f3d25f2cb04002b0ede883f0c482acfd5de978a9 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 16:07:01 -0600 Subject: [PATCH 034/167] OSX buildfix! --- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 6e9a72eb00..7647698c63 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -259,7 +259,7 @@ bool Wiimote::Prepare(int _index) u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_REPORT_TYPE, 0, 0x30}; // Set the active LEDs and turn on rumble. - u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index) | 0x1}; + u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index | 0x1)}; // Turn off rumble u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_RUMBLE, 0}; From fa10335c55520ec674e26835e1e0d0fc9d5dfb37 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 17:58:56 -0600 Subject: [PATCH 035/167] Make continuous scanning optional. --- Source/Core/Core/Src/ConfigManager.cpp | 4 +++- Source/Core/Core/Src/ConfigManager.h | 1 + .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 19 ++++++++++++------- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 12 ++++++++++-- Source/Core/DolphinWX/Src/WiimoteConfigDiag.h | 6 ++++++ 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 978eadace1..282c369161 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -241,6 +241,7 @@ void SConfig::SaveSettings() ini.Set("Core", "WiiSDCard", m_WiiSDCard); ini.Set("Core", "WiiKeyboard", m_WiiKeyboard); ini.Set("Core", "WiimoteReconnectOnLoad", m_WiimoteReconnectOnLoad); + ini.Set("Core", "WiimoteContinuousScanning", m_WiimoteContinuousScanning); ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer); ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient); ini.Set("Core", "FrameLimit", m_Framelimit); @@ -390,7 +391,8 @@ void SConfig::LoadSettings() ini.Get("Core", "WiiSDCard", &m_WiiSDCard, false); ini.Get("Core", "WiiKeyboard", &m_WiiKeyboard, false); - ini.Get("Core", "WiimoteReconnectOnLoad", &m_WiimoteReconnectOnLoad, true); + ini.Get("Core", "WiimoteReconnectOnLoad", &m_WiimoteReconnectOnLoad, true); + ini.Get("Core", "WiimoteContinuousScanning", &m_WiimoteContinuousScanning, true); ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false); diff --git a/Source/Core/Core/Src/ConfigManager.h b/Source/Core/Core/Src/ConfigManager.h index e3ad7b42a9..a633bded5c 100644 --- a/Source/Core/Core/Src/ConfigManager.h +++ b/Source/Core/Core/Src/ConfigManager.h @@ -42,6 +42,7 @@ struct SConfig : NonCopyable bool m_WiiSDCard; bool m_WiiKeyboard; bool m_WiimoteReconnectOnLoad; + bool m_WiimoteContinuousScanning; // name of the last used filename std::string m_LastFilename; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 7647698c63..4b3b737d36 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -24,6 +24,7 @@ #include "StringUtil.h" #include "Timer.h" #include "Host.h" +#include "ConfigManager.h" #include "WiimoteReal.h" @@ -303,9 +304,9 @@ void WiimoteScanner::WantWiimotes(bool do_want) void WiimoteScanner::StartScanning() { - m_run_thread = true; - if (IsReady()) + if (!m_run_thread && IsReady()) { + m_run_thread = true; m_scan_thread = std::thread(std::mem_fun(&WiimoteScanner::ThreadFunc), this); } } @@ -413,19 +414,23 @@ void LoadSettings() } } +// config dialog calls this when some settings change void Initialize() { + if (SConfig::GetInstance().m_WiimoteContinuousScanning) + g_wiimote_scanner.StartScanning(); + else + g_wiimote_scanner.StopScanning(); + std::lock_guard lk(g_refresh_lock); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + if (g_real_wiimotes_initialized) return; NOTICE_LOG(WIIMOTE, "WiimoteReal::Initialize"); - g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); - - g_wiimote_scanner.StartScanning(); - g_real_wiimotes_initialized = true; } @@ -534,7 +539,7 @@ void Refresh() HandleFoundWiimotes(found_wiimotes); } - g_wiimote_scanner.StartScanning(); + Initialize(); } void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index a4af2d5d9a..56b75531cf 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -60,14 +60,22 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin wxButton* const refresh_btn = new wxButton(this, -1, _("Refresh"), wxDefaultPosition); refresh_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::RefreshRealWiimotes, this); - // "Real wiimotes" layout wxStaticBoxSizer* const real_wiimotes_group = new wxStaticBoxSizer(wxVERTICAL, this, _("Real Wiimotes")); + wxBoxSizer* const real_wiimotes_sizer = new wxBoxSizer(wxHORIZONTAL); + if (!WiimoteReal::g_wiimote_scanner.IsReady()) real_wiimotes_group->Add(new wxStaticText(this, -1, _("A supported bluetooth device could not be found.\n" "You must manually pair your wiimotes.")), 0, wxALIGN_CENTER | wxALL, 5); + + wxCheckBox* const continuous_scanning = new wxCheckBox(this, wxID_ANY, _("Continuous Scanning")); + continuous_scanning->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnContinuousScanning, this); + continuous_scanning->SetValue(SConfig::GetInstance().m_WiimoteContinuousScanning); - real_wiimotes_group->Add(refresh_btn, 0, wxALIGN_CENTER); + real_wiimotes_sizer->Add(continuous_scanning, 0, wxALIGN_CENTER_VERTICAL); + real_wiimotes_sizer->AddStretchSpacer(1); + real_wiimotes_sizer->Add(refresh_btn, 0, wxALL | wxALIGN_CENTER, 5); + real_wiimotes_group->Add(real_wiimotes_sizer, 1, wxEXPAND); // "General Settings" controls const wxString str[] = { _("Bottom"), _("Top") }; diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h index 316d0d48bf..26d6660ee2 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h @@ -57,6 +57,12 @@ public: SConfig::GetInstance().m_WiimoteReconnectOnLoad = event.IsChecked(); event.Skip(); } + void OnContinuousScanning(wxCommandEvent& event) + { + SConfig::GetInstance().m_WiimoteContinuousScanning = event.IsChecked(); + WiimoteReal::Initialize(); + event.Skip(); + } private: void Cancel(wxCommandEvent& event); From a6461ca186c67592c1bd6bb4f6cd175c03ddcde3 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 11 Feb 2013 20:50:09 -0600 Subject: [PATCH 036/167] Improve wiimote reconnection on changing wiimote sources. --- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 48 +++++++++++++++---- .../Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 2 +- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 4b3b737d36..34fc7e92f5 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -38,6 +38,7 @@ namespace WiimoteReal void HandleFoundWiimotes(const std::vector&); void TryToConnectWiimote(Wiimote*); void HandleWiimoteDisconnect(int index); +void DoneWithWiimote(int index); bool g_real_wiimotes_initialized = false; @@ -382,6 +383,7 @@ void Wiimote::ThreadFunc() Common::SetCurrentThreadName("Wiimote Device Thread"); Host_ConnectWiimote(index, true); + NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", index + 1); // main loop while (m_run_thread && IsConnected()) @@ -453,15 +455,20 @@ void Shutdown(void) void ChangeWiimoteSource(unsigned int index, int source) { + { std::lock_guard lk(g_refresh_lock); - + g_wiimote_sources[index] = source; - - // source is emulated, kill any real connection - if (!(WIIMOTE_SRC_REAL & g_wiimote_sources[index])) - HandleWiimoteDisconnect(index); - g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + + // kill real connection (or swap to different slot) + DoneWithWiimote(index); + } + + // reconnect to emu + Host_ConnectWiimote(index, false); + if (WIIMOTE_SRC_EMU & source) + Host_ConnectWiimote(index, true); } void TryToConnectWiimote(Wiimote* wm) @@ -478,8 +485,6 @@ void TryToConnectWiimote(Wiimote* wm) g_wiimotes[i] = wm; wm->StartThread(); - - NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", i + 1); wm = NULL; break; @@ -491,6 +496,32 @@ void TryToConnectWiimote(Wiimote* wm) g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); } +void DoneWithWiimote(int index) +{ + std::lock_guard lk(g_refresh_lock); + + if (g_wiimotes[index]) + { + g_wiimotes[index]->StopThread(); + + // First see if we can use this real wiimote in another slot. + for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) + { + if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] + && !g_wiimotes[i] + && g_wiimotes[index]->Prepare(i)) + { + std::swap(g_wiimotes[i], g_wiimotes[index]); + g_wiimotes[i]->StartThread(); + break; + } + } + } + + // else, just disconnect the wiimote + HandleWiimoteDisconnect(index); +} + void HandleWiimoteDisconnect(int index) { std::lock_guard lk(g_refresh_lock); @@ -570,7 +601,6 @@ void Update(int _WiimoteNumber) // Wiimote::Update() may remove the wiimote if it was disconnected. if (!g_wiimotes[_WiimoteNumber]) { - NOTICE_LOG(WIIMOTE, "Emulating disconnect of wiimote %d.", _WiimoteNumber + 1); Host_ConnectWiimote(_WiimoteNumber, false); } } diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index 56b75531cf..3cd050a293 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -66,7 +66,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin if (!WiimoteReal::g_wiimote_scanner.IsReady()) real_wiimotes_group->Add(new wxStaticText(this, -1, _("A supported bluetooth device could not be found.\n" - "You must manually pair your wiimotes.")), 0, wxALIGN_CENTER | wxALL, 5); + "You must manually connect your wiimotes.")), 0, wxALIGN_CENTER | wxALL, 5); wxCheckBox* const continuous_scanning = new wxCheckBox(this, wxID_ANY, _("Continuous Scanning")); continuous_scanning->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnContinuousScanning, this); From da53ca8ee3127ff898f557212523b43d09207564 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 12 Feb 2013 00:19:27 -0600 Subject: [PATCH 037/167] "Wait for the wiimote to connect"? I think that's a horrible idea. --- Source/Core/DolphinWX/Src/FrameTools.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 56dde8e2ce..cb2750ade4 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -1355,10 +1355,6 @@ void CFrame::ConnectWiimote(int wm_idx, bool connect) wxString msg(wxString::Format(wxT("Wiimote %i %s"), wm_idx + 1, connect ? wxT("Connected") : wxT("Disconnected"))); Core::DisplayMessage(msg.ToAscii(), 3000); - - // Wait for the wiimote to connect - while (GetUsbPointer()->AccessWiiMote(wm_idx | 0x100)->IsConnected() != connect) - {} Host_UpdateMainFrame(); } } From 12674b3164f809814c6059b4bfdf9e800819da0c Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 12 Feb 2013 17:01:51 -0600 Subject: [PATCH 038/167] Possibly improve real wiimotes on Windows. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 3052f4b737..0f00d3fa5f 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -432,7 +432,7 @@ int Wiimote::IOWrite(const u8* buf, int len) } else { - ERROR_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); + WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); } } @@ -488,7 +488,7 @@ void ProcessWiimotes(bool new_scan, T& callback) srch.fReturnUnknown = true; srch.fIssueInquiry = new_scan; // multiple of 1.28 seconds - srch.cTimeoutMultiplier = 1; + srch.cTimeoutMultiplier = 2; BLUETOOTH_FIND_RADIO_PARAMS radioParam; radioParam.dwSize = sizeof(radioParam); From 7f305ba82288fa86fbe200036b26fd2cb219a293 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 12 Feb 2013 18:56:36 -0600 Subject: [PATCH 039/167] Fix sloppy connection logic. --- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 34fc7e92f5..ee685aae9b 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -478,15 +478,14 @@ void TryToConnectWiimote(Wiimote* wm) for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) { if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] - && !g_wiimotes[i] - && wm->Connect() - && wm->Prepare(i)) + && !g_wiimotes[i]) { - g_wiimotes[i] = wm; - - wm->StartThread(); - - wm = NULL; + if (wm->Connect() && wm->Prepare(i)) + { + g_wiimotes[i] = wm; + wm->StartThread(); + wm = NULL; + } break; } } @@ -508,11 +507,13 @@ void DoneWithWiimote(int index) for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) { if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] - && !g_wiimotes[i] - && g_wiimotes[index]->Prepare(i)) + && !g_wiimotes[i]) { - std::swap(g_wiimotes[i], g_wiimotes[index]); - g_wiimotes[i]->StartThread(); + if (g_wiimotes[index]->Prepare(i)) + { + std::swap(g_wiimotes[i], g_wiimotes[index]); + g_wiimotes[i]->StartThread(); + } break; } } From 77381a1af2d59b799afeb326bba122fbefff7287 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 12 Feb 2013 21:37:47 -0600 Subject: [PATCH 040/167] Futile attempts at fixing OS X. --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 51dcd17785..8c3a0f10b2 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -150,7 +150,8 @@ std::vector WiimoteScanner::FindWiimotes() [bti stop]; int found_devices = [[bti foundDevices] count]; - NOTICE_LOG(WIIMOTE, "Found %i bluetooth devices", found_devices); + if (found_devices) + NOTICE_LOG(WIIMOTE, "Found %i bluetooth devices", found_devices); en = [[bti foundDevices] objectEnumerator]; for (int i = 0; i < found_devices; i++) @@ -180,11 +181,11 @@ bool WiimoteScanner::IsReady() const // Connect to a wiimote with a known address. bool Wiimote::Connect() { - ConnectBT *cbt = [[ConnectBT alloc] init]; - if (IsConnected()) return false; + ConnectBT *cbt = [[ConnectBT alloc] init]; + [btd openL2CAPChannelSync: &cchan withPSM: kBluetoothL2CAPPSMHIDControl delegate: cbt]; [btd openL2CAPChannelSync: &ichan @@ -215,6 +216,9 @@ bool Wiimote::Connect() // Disconnect a wiimote. void Wiimote::Disconnect() { + if (!IsConnected()) + return; + NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i", index + 1); m_connected = false; From e57ff0613082c47a936ffef1c40a12780c489995 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 13 Feb 2013 14:00:15 -0600 Subject: [PATCH 041/167] Futile attempts at fixing Windows. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 109 ++++++++---------- 1 file changed, 50 insertions(+), 59 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 0f00d3fa5f..61abeffa2d 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include #include @@ -75,8 +76,7 @@ HINSTANCE bthprops_lib = NULL; static int initialized = 0; -std::mutex g_connected_devices_lock; -static std::unordered_set g_connected_devices; +std::unordered_map g_connect_times; inline void init_lib() { @@ -173,60 +173,50 @@ void WiimoteScanner::Update() // Returns the total number of found and connected wiimotes. std::vector WiimoteScanner::FindWiimotes() { - bool attached_some; - - ProcessWiimotes(true, [&](HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) + ProcessWiimotes(true, [](HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { ForgetWiimote(hRadio, btdi); - attached_some |= AttachWiimote(hRadio, btdi); + AttachWiimote(hRadio, btdi); }); - // Hacks... - if (attached_some) - SLEEP(2000); - - GUID device_id; - HDEVINFO device_info; - DWORD len; - SP_DEVICE_INTERFACE_DATA device_data; - PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; - - device_data.cbSize = sizeof(device_data); - // Get the device id + GUID device_id; HidD_GetHidGuid(&device_id); // Get all hid devices connected - device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); + HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); std::vector wiimotes; - for (int index = 0; true; ++index) + + SP_DEVICE_INTERFACE_DATA device_data; + device_data.cbSize = sizeof(device_data); + PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; + + for (int index = 0; SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data); ++index) { - free(detail_data); - detail_data = NULL; - - // Query the next hid device info - if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) - break; - // Get the size of the data block required + DWORD len; SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL); detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(len); detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Query the data for this device - if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) - continue; + if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) + { + auto const wm = new Wiimote; + wm->devicepath = detail_data->DevicePath; + wiimotes.push_back(wm); + } - auto const wm = new Wiimote; - wm->devicepath = detail_data->DevicePath; - wiimotes.push_back(wm); + free(detail_data); } - free(detail_data); - SetupDiDestroyDeviceInfoList(device_info); + // Don't mind me, just a random sleep to fix stuff on Windows + //if (!wiimotes.empty()) + // SLEEP(2000); + return wiimotes; } @@ -254,17 +244,14 @@ bool WiimoteScanner::IsReady() const // Connect to a wiimote with a known device path. bool Wiimote::Connect() { - std::lock_guard lk(g_connected_devices_lock); - - // This is where we disallow connecting to the same device twice - if (g_connected_devices.count(devicepath)) + if (IsConnected()) return false; dev_handle = CreateFile(devicepath.c_str(), - (GENERIC_READ | GENERIC_WRITE), - // TODO: Just do FILE_SHARE_READ and remove "g_connected_devices"? - // That is what "WiiYourself" does. - (FILE_SHARE_READ | FILE_SHARE_WRITE), + GENERIC_READ | GENERIC_WRITE, + // Having no FILE_SHARE_WRITE disallows us from connecting to the same wiimote twice. + // This is what "WiiYourself" does. + FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (dev_handle == INVALID_HANDLE_VALUE) @@ -299,15 +286,13 @@ bool Wiimote::Connect() ERROR_LOG(WIIMOTE, "Failed to set wiimote thread priority"); } */ - - g_connected_devices.insert(devicepath); return true; } void Wiimote::Disconnect() { - std::lock_guard lk(g_connected_devices_lock); - g_connected_devices.erase(devicepath); + if (!IsConnected()) + return; CloseHandle(dev_handle); dev_handle = 0; @@ -385,7 +370,7 @@ int Wiimote::IORead(u8* buf) if (bytes > 0) { // Move the data over one, so we can add back in data report indicator byte (here, 0xa1) - memmove(buf + 1, buf, MAX_PAYLOAD - 1); + std::copy_n(buf, MAX_PAYLOAD - 1, buf + 1); buf[0] = 0xa1; // TODO: is this really needed? @@ -408,11 +393,7 @@ int Wiimote::IOWrite(const u8* buf, int len) stack = MSBT_STACK_MS; if (IOWrite(buf, len)) - { - // Don't mind me, just a random sleep to fix stuff on Windows - SLEEP(1000); return 1; - } stack = MSBT_STACK_UNKNOWN; break; @@ -553,6 +534,8 @@ void RemoveWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { + // We don't want "remembered" devices. + // SetServiceState will just fail with them.. if (!btdi.fConnected && !btdi.fRemembered) { NOTICE_LOG(WIIMOTE, "Found wiimote. Enabling HID service."); @@ -561,6 +544,8 @@ bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) const DWORD hr = Bth_BluetoothSetServiceState(hRadio, &btdi, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE); + g_connect_times[btdi.Address.ullLong] = std::time(nullptr); + if (FAILED(hr)) ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr); else @@ -575,14 +560,20 @@ bool ForgetWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { if (!btdi.fConnected && btdi.fRemembered) { - // We don't want "remembered" devices. - // SetServiceState seems to just fail with them. - // Make Windows forget about them. - // This is also required to detect a disconnect for some reason.. - NOTICE_LOG(WIIMOTE, "Removing remembered wiimote."); - Bth_BluetoothRemoveDevice(&btdi.Address); + // Time to avoid RemoveDevice after SetServiceState. + // Sometimes SetServiceState takes a while.. + auto const avoid_forget_seconds = 5.0; - return true; + auto pair_time = g_connect_times.find(btdi.Address.ullLong); + if (pair_time == g_connect_times.end() + || std::difftime(time(nullptr), pair_time->second) >= avoid_forget_seconds) + { + // Make Windows forget about device so it will re-find it if visible. + // This is also required to detect a disconnect for some reason.. + NOTICE_LOG(WIIMOTE, "Removing remembered wiimote."); + Bth_BluetoothRemoveDevice(&btdi.Address); + return true; + } } return false; From 306e6b1d80c0426092001bb4653f93f217af152d Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 14 Feb 2013 14:02:51 -0600 Subject: [PATCH 042/167] Turn off continuous scanning by default. --- Source/Core/Core/Src/ConfigManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 282c369161..44a7591577 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -392,7 +392,7 @@ void SConfig::LoadSettings() ini.Get("Core", "WiiSDCard", &m_WiiSDCard, false); ini.Get("Core", "WiiKeyboard", &m_WiiKeyboard, false); ini.Get("Core", "WiimoteReconnectOnLoad", &m_WiimoteReconnectOnLoad, true); - ini.Get("Core", "WiimoteContinuousScanning", &m_WiimoteContinuousScanning, true); + ini.Get("Core", "WiimoteContinuousScanning", &m_WiimoteContinuousScanning, false); ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false); @@ -426,4 +426,4 @@ void SConfig::LoadSettings() } m_SYSCONF = new SysConf(); -} \ No newline at end of file +} From cda88a8c1ee3ac1b407b09e8e392262fd606f6ab Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 14 Feb 2013 18:41:31 -0600 Subject: [PATCH 043/167] Random improvements. --- .../Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 20 +++++++---- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 33 +++++++++++++++---- .../Core/Src/HW/WiimoteReal/WiimoteRealBase.h | 1 + 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 8c3a0f10b2..fda1d99462 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -216,19 +216,25 @@ bool Wiimote::Connect() // Disconnect a wiimote. void Wiimote::Disconnect() { + if (btd != NULL) + [btd closeConnection]; + + if (ichan != NULL) + [ichan release]; + + if (cchan != NULL) + [cchan release]; + + btd = NULL; + cchan = NULL; + ichan = NULL; + if (!IsConnected()) return; NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i", index + 1); m_connected = false; - - [btd closeConnection]; - [ichan release]; - [cchan release]; - btd = NULL; - cchan = NULL; - ichan = NULL; } bool Wiimote::IsConnected() const diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index ee685aae9b..311bf11de2 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -161,6 +161,18 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const _data, const { rpt.first[0] = WM_SET_REPORT | WM_BT_OUTPUT; } + + // Disallow games from turning off all of the LEDs. + // It makes wiimote connection status confusing. + if (rpt.first[1] == WM_LEDS) + { + auto& leds_rpt = *reinterpret_cast(&rpt.first[2]); + if (0 == leds_rpt.leds) + { + // Turn on ALL of the LEDs. + leds_rpt.leds = 0xf; + } + } m_write_reports.Push(rpt); } @@ -265,12 +277,15 @@ bool Wiimote::Prepare(int _index) // Turn off rumble u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_RUMBLE, 0}; - - // TODO: request status and check for sane response? + + // Request status report + u8 const req_status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0}; + // TODO: check for sane response? return (IOWrite(mode_report, sizeof(mode_report)) && IOWrite(led_report, sizeof(led_report)) - && (SLEEP(200), IOWrite(rumble_report, sizeof(rumble_report)))); + && (SLEEP(200), IOWrite(rumble_report, sizeof(rumble_report))) + && IOWrite(req_status_report, sizeof(req_status_report))); } void Wiimote::EmuStart() @@ -382,9 +397,6 @@ void Wiimote::ThreadFunc() { Common::SetCurrentThreadName("Wiimote Device Thread"); - Host_ConnectWiimote(index, true); - NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", index + 1); - // main loop while (m_run_thread && IsConnected()) { @@ -485,6 +497,8 @@ void TryToConnectWiimote(Wiimote* wm) g_wiimotes[i] = wm; wm->StartThread(); wm = NULL; + + Host_ConnectWiimote(i, true); } break; } @@ -513,6 +527,8 @@ void DoneWithWiimote(int index) { std::swap(g_wiimotes[i], g_wiimotes[index]); g_wiimotes[i]->StartThread(); + + Host_ConnectWiimote(i, true); } break; } @@ -563,9 +579,12 @@ void Refresh() // Brief rumble for already connected wiimotes. for (int i = 0; i != MAX_WIIMOTES; ++i) { - // kinda sloppy if (g_wiimotes[i]) + { + g_wiimotes[i]->StopThread(); g_wiimotes[i]->Prepare(i); + g_wiimotes[i]->StartThread(); + } } HandleFoundWiimotes(found_wiimotes); diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h index 15bbc2917f..1a1f6676cf 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h @@ -41,6 +41,7 @@ #define WM_SET_REPORT 0xA0 #endif +// TODO: duplicated in WiimoteHid.h // Commands #define WM_CMD_RUMBLE 0x10 #define WM_CMD_LED 0x11 From 891de527690a24a4e5c48ce04e85547905a694b9 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 14 Feb 2013 19:04:34 -0600 Subject: [PATCH 044/167] Don't need to hang dolphin when searching for wiimote with the refresh button. This code is getting pretty ugly. :/ --- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 311bf11de2..b628cf61fc 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -565,13 +565,15 @@ void Refresh() g_wiimote_scanner.StopScanning(); { - std::lock_guard lk(g_refresh_lock); - + std::unique_lock lk(g_refresh_lock); std::vector found_wiimotes; if (0 != CalculateWantedWiimotes()) { + // Don't hang dolphin when searching + lk.unlock(); found_wiimotes = g_wiimote_scanner.FindWiimotes(); + lk.lock(); } CheckForDisconnectedWiimotes(); From 1f20a24a04558d06f8584f0fcb35368c2a9c0f60 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 14 Feb 2013 21:02:41 -0600 Subject: [PATCH 045/167] Minor changes. --- .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index b628cf61fc..751b24ac38 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -336,7 +336,6 @@ void WiimoteScanner::StopScanning() } } - void CheckForDisconnectedWiimotes() { std::lock_guard lk(g_refresh_lock); @@ -485,7 +484,7 @@ void ChangeWiimoteSource(unsigned int index, int source) void TryToConnectWiimote(Wiimote* wm) { - std::lock_guard lk(g_refresh_lock); + std::unique_lock lk(g_refresh_lock); for (unsigned int i = 0; i != MAX_WIIMOTES; ++i) { @@ -494,9 +493,10 @@ void TryToConnectWiimote(Wiimote* wm) { if (wm->Connect() && wm->Prepare(i)) { - g_wiimotes[i] = wm; - wm->StartThread(); - wm = NULL; + NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", i + 1); + + std::swap(g_wiimotes[i], wm); + g_wiimotes[i]->StartThread(); Host_ConnectWiimote(i, true); } @@ -504,9 +504,11 @@ void TryToConnectWiimote(Wiimote* wm) } } - delete wm; - g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + + lk.unlock(); + + delete wm; } void DoneWithWiimote(int index) @@ -541,17 +543,19 @@ void DoneWithWiimote(int index) void HandleWiimoteDisconnect(int index) { - std::lock_guard lk(g_refresh_lock); - - if (g_wiimotes[index]) - { - delete g_wiimotes[index]; - g_wiimotes[index] = NULL; + Wiimote* wm = NULL; - NOTICE_LOG(WIIMOTE, "Disconnected wiimote %i.", index + 1); + { + std::lock_guard lk(g_refresh_lock); + std::swap(wm, g_wiimotes[index]); + g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); } - g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes()); + if (wm) + { + delete wm; + NOTICE_LOG(WIIMOTE, "Disconnected wiimote %i.", index + 1); + } } void HandleFoundWiimotes(const std::vector& wiimotes) From ef90b15f3ed032acd6b32b67b0a55e7a0df6a5b7 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 15 Feb 2013 03:00:31 -0600 Subject: [PATCH 046/167] Provide an option to not send speaker data. It can cause rumble lag even when the speaker is muted. --- Source/Core/Core/Src/ConfigManager.cpp | 2 ++ Source/Core/Core/Src/ConfigManager.h | 1 + Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 9 +++++++++ Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp | 8 +++++++- Source/Core/DolphinWX/Src/WiimoteConfigDiag.h | 5 +++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 44a7591577..85ecc7143f 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -242,6 +242,7 @@ void SConfig::SaveSettings() ini.Set("Core", "WiiKeyboard", m_WiiKeyboard); ini.Set("Core", "WiimoteReconnectOnLoad", m_WiimoteReconnectOnLoad); ini.Set("Core", "WiimoteContinuousScanning", m_WiimoteContinuousScanning); + ini.Set("Core", "WiimoteEnableSpeaker", m_WiimoteEnableSpeaker); ini.Set("Core", "RunCompareServer", m_LocalCoreStartupParameter.bRunCompareServer); ini.Set("Core", "RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient); ini.Set("Core", "FrameLimit", m_Framelimit); @@ -393,6 +394,7 @@ void SConfig::LoadSettings() ini.Get("Core", "WiiKeyboard", &m_WiiKeyboard, false); ini.Get("Core", "WiimoteReconnectOnLoad", &m_WiimoteReconnectOnLoad, true); ini.Get("Core", "WiimoteContinuousScanning", &m_WiimoteContinuousScanning, false); + ini.Get("Core", "WiimoteEnableSpeaker", &m_WiimoteEnableSpeaker, true); ini.Get("Core", "RunCompareServer", &m_LocalCoreStartupParameter.bRunCompareServer, false); ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false); diff --git a/Source/Core/Core/Src/ConfigManager.h b/Source/Core/Core/Src/ConfigManager.h index a633bded5c..0c4ceffa9f 100644 --- a/Source/Core/Core/Src/ConfigManager.h +++ b/Source/Core/Core/Src/ConfigManager.h @@ -43,6 +43,7 @@ struct SConfig : NonCopyable bool m_WiiKeyboard; bool m_WiimoteReconnectOnLoad; bool m_WiimoteContinuousScanning; + bool m_WiimoteEnableSpeaker; // name of the last used filename std::string m_LastFilename; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 751b24ac38..b5a1703527 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -173,6 +173,15 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const _data, const leds_rpt.leds = 0xf; } } + else if (rpt.first[1] == WM_WRITE_SPEAKER_DATA + && !SConfig::GetInstance().m_WiimoteEnableSpeaker) + { + // Translate speaker data reports into rumble reports. + rpt.first[1] = WM_CMD_RUMBLE; + // Keep only the rumble bit. + rpt.first[2] &= 0x1; + rpt.second = 3; + } m_write_reports.Push(rpt); } diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp index 3cd050a293..475718ed2e 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp @@ -71,11 +71,17 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin wxCheckBox* const continuous_scanning = new wxCheckBox(this, wxID_ANY, _("Continuous Scanning")); continuous_scanning->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnContinuousScanning, this); continuous_scanning->SetValue(SConfig::GetInstance().m_WiimoteContinuousScanning); + + auto wiimote_speaker = new wxCheckBox(this, wxID_ANY, _("Enable Speaker Data")); + wiimote_speaker->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnEnableSpeaker, this); + wiimote_speaker->SetValue(SConfig::GetInstance().m_WiimoteEnableSpeaker); real_wiimotes_sizer->Add(continuous_scanning, 0, wxALIGN_CENTER_VERTICAL); real_wiimotes_sizer->AddStretchSpacer(1); real_wiimotes_sizer->Add(refresh_btn, 0, wxALL | wxALIGN_CENTER, 5); - real_wiimotes_group->Add(real_wiimotes_sizer, 1, wxEXPAND); + + real_wiimotes_group->Add(wiimote_speaker, 0); + real_wiimotes_group->Add(real_wiimotes_sizer, 0, wxEXPAND); // "General Settings" controls const wxString str[] = { _("Bottom"), _("Top") }; diff --git a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h index 26d6660ee2..4c33661ca2 100644 --- a/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h +++ b/Source/Core/DolphinWX/Src/WiimoteConfigDiag.h @@ -63,6 +63,11 @@ public: WiimoteReal::Initialize(); event.Skip(); } + void OnEnableSpeaker(wxCommandEvent& event) + { + SConfig::GetInstance().m_WiimoteEnableSpeaker = event.IsChecked(); + event.Skip(); + } private: void Cancel(wxCommandEvent& event); From 53aec6c476b0ec9db4d301eaafedbb26eb3697f4 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 16 Feb 2013 17:50:40 -0600 Subject: [PATCH 047/167] Fix OGL perf queries and make them not slow! --- Source/Core/Common/Src/VideoBackendBase.h | 6 +- Source/Core/VideoCommon/Src/MainBase.cpp | 43 +++++++ Source/Core/VideoCommon/Src/PerfQueryBase.h | 2 + Source/Core/VideoCommon/Src/PixelEngine.cpp | 25 ++-- .../Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp | 111 +++++++++++++----- .../Plugins/Plugin_VideoOGL/Src/PerfQuery.h | 24 ++++ .../Plugin_VideoOGL/Src/VertexManager.cpp | 2 +- .../Plugin_VideoSoftware/Src/SWmain.cpp | 6 + .../Plugin_VideoSoftware/Src/VideoBackend.h | 2 + 9 files changed, 178 insertions(+), 43 deletions(-) diff --git a/Source/Core/Common/Src/VideoBackendBase.h b/Source/Core/Common/Src/VideoBackendBase.h index d09288ebc7..4e602526d2 100644 --- a/Source/Core/Common/Src/VideoBackendBase.h +++ b/Source/Core/Common/Src/VideoBackendBase.h @@ -22,6 +22,7 @@ #include #include "ChunkFile.h" +#include "PerfQueryBase.h" typedef void (*writeFn16)(const u16,const u32); typedef void (*writeFn32)(const u32,const u32); @@ -107,6 +108,7 @@ public: virtual void Video_EndField() = 0; virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0; + virtual u32 Video_GetQueryResult(PerfQueryType type) = 0; virtual void Video_AddMessage(const char* pstr, unsigned int milliseconds) = 0; virtual void Video_ClearMessages() = 0; @@ -154,8 +156,10 @@ class VideoBackendHardware : public VideoBackend void Video_ExitLoop(); void Video_BeginField(u32, FieldType, u32, u32); void Video_EndField(); - u32 Video_AccessEFB(EFBAccessType, u32, u32, u32); + u32 Video_AccessEFB(EFBAccessType, u32, u32, u32); + u32 Video_GetQueryResult(PerfQueryType type); + void Video_AddMessage(const char* pstr, unsigned int milliseconds); void Video_ClearMessages(); bool Video_Screenshot(const char* filename); diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index cb6dc7ae5b..e8de52addb 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -21,6 +21,10 @@ volatile u32 s_swapRequested = false; u32 s_efbAccessRequested = false; volatile u32 s_FifoShuttingDown = false; +std::condition_variable s_perf_query_cond; +std::mutex s_perf_query_lock; +static volatile bool s_perf_query_requested; + static volatile struct { u32 xfbAddr; @@ -169,6 +173,43 @@ u32 VideoBackendHardware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 return 0; } +static bool QueryResultIsReady() +{ + return !s_perf_query_requested || s_FifoShuttingDown; +} + +void VideoFifo_CheckPerfQueryRequest() +{ + if (s_perf_query_requested) + { + g_perf_query->FlushResults(); + + { + std::lock_guard lk(s_perf_query_lock); + s_perf_query_requested = false; + } + + s_perf_query_cond.notify_one(); + } +} + +u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type) +{ + // Is this check sane? + if (!g_perf_query->IsFlushed()) + { + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) + { + s_perf_query_requested = true; + std::unique_lock lk(s_perf_query_lock); + s_perf_query_cond.wait(lk, QueryResultIsReady); + } + else + g_perf_query->FlushResults(); + } + + return g_perf_query->GetQueryResult(type); +} void VideoBackendHardware::InitializeShared() { @@ -176,6 +217,7 @@ void VideoBackendHardware::InitializeShared() s_swapRequested = 0; s_efbAccessRequested = 0; + s_perf_query_requested = false; s_FifoShuttingDown = 0; memset((void*)&s_beginFieldArgs, 0, sizeof(s_beginFieldArgs)); memset(&s_accessEFBArgs, 0, sizeof(s_accessEFBArgs)); @@ -223,6 +265,7 @@ void VideoFifo_CheckAsyncRequest() { VideoFifo_CheckSwapRequest(); VideoFifo_CheckEFBAccess(); + VideoFifo_CheckPerfQueryRequest(); } void VideoBackendHardware::Video_GatherPipeBursted() diff --git a/Source/Core/VideoCommon/Src/PerfQueryBase.h b/Source/Core/VideoCommon/Src/PerfQueryBase.h index 0520e9244c..2643482379 100644 --- a/Source/Core/VideoCommon/Src/PerfQueryBase.h +++ b/Source/Core/VideoCommon/Src/PerfQueryBase.h @@ -32,6 +32,8 @@ public: virtual void DisableQuery(PerfQueryGroup type) {} virtual void ResetQuery() {} virtual u32 GetQueryResult(PerfQueryType type) { return 0; } + virtual void FlushResults() {} + virtual bool IsFlushed() const { return true; } }; extern PerfQueryBase* g_perf_query; diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index 005468f63c..2d6275096c 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -260,35 +260,35 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) // NOTE(neobrain): only PE_PERF_ZCOMP_OUTPUT is implemented in D3D11, but the other values shouldn't be contradictionary to the value of that register (i.e. INPUT registers should always be greater or equal to their corresponding OUTPUT registers). case PE_PERF_ZCOMP_INPUT_ZCOMPLOC_L: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT_ZCOMPLOC) & 0xFFFF; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_INPUT_ZCOMPLOC) & 0xFFFF; break; case PE_PERF_ZCOMP_INPUT_ZCOMPLOC_H: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT_ZCOMPLOC) >> 16; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_INPUT_ZCOMPLOC) >> 16; break; case PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_L: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT_ZCOMPLOC) & 0xFFFF; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_OUTPUT_ZCOMPLOC) & 0xFFFF; break; case PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_H: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT_ZCOMPLOC) >> 16; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_OUTPUT_ZCOMPLOC) >> 16; break; case PE_PERF_ZCOMP_INPUT_L: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT) & 0xFFFF; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_INPUT) & 0xFFFF; break; case PE_PERF_ZCOMP_INPUT_H: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_INPUT) >> 16; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_INPUT) >> 16; break; case PE_PERF_ZCOMP_OUTPUT_L: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT) & 0xFFFF; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_OUTPUT) & 0xFFFF; break; case PE_PERF_ZCOMP_OUTPUT_H: - _uReturnValue = g_perf_query->GetQueryResult(PQ_ZCOMP_OUTPUT) >> 16; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_ZCOMP_OUTPUT) >> 16; break; case PE_PERF_BLEND_INPUT_L: @@ -298,19 +298,20 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) // In very old builds, Dolphin only returned 0. That caused the challenge to be immediately finished without any goop being cleaned (the timer just didn't even start counting from 3:00:00). // Later builds returned 1 for the high register. That caused the timer to actually count down, but made the challenge unbeatable because the game always thought you didn't clear any goop at all. // Note that currently this functionality is only implemented in the D3D11 backend. - _uReturnValue = g_perf_query->GetQueryResult(PQ_BLEND_INPUT) & 0xFFFF; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_BLEND_INPUT) & 0xFFFF; + //ERROR_LOG(VIDEO, "PQ_BLEND_INPUT: %d", g_video_backend->Video_GetQueryResult(PQ_BLEND_INPUT)); break; case PE_PERF_BLEND_INPUT_H: - _uReturnValue = g_perf_query->GetQueryResult(PQ_BLEND_INPUT) >> 16; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_BLEND_INPUT) >> 16; break; case PE_PERF_EFB_COPY_CLOCKS_L: - _uReturnValue = g_perf_query->GetQueryResult(PQ_EFB_COPY_CLOCKS) & 0xFFFF; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_EFB_COPY_CLOCKS) & 0xFFFF; break; case PE_PERF_EFB_COPY_CLOCKS_H: - _uReturnValue = g_perf_query->GetQueryResult(PQ_EFB_COPY_CLOCKS) >> 16; + _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_EFB_COPY_CLOCKS) >> 16; break; default: diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp index cb659e6921..8cee426e98 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp @@ -1,31 +1,47 @@ #include "GLUtil.h" #include "PerfQuery.h" -namespace OGL { - -u32 results[PQG_NUM_MEMBERS] = { 0 }; -GLuint query_id; - -PerfQueryGroup active_query; +namespace OGL +{ PerfQuery::PerfQuery() + : m_query_read_pos() + , m_query_count() { - glGenQueries(1, &query_id); + for (int i = 0; i != ARRAYSIZE(m_query_buffer); ++i) + glGenQueries(1, &m_query_buffer[i].query_id); + + ResetQuery(); } PerfQuery::~PerfQuery() { - glDeleteQueries(1, &query_id); + for (int i = 0; i != ARRAYSIZE(m_query_buffer); ++i) + glDeleteQueries(1, &m_query_buffer[i].query_id); } void PerfQuery::EnableQuery(PerfQueryGroup type) { + // Is this sane? + if (m_query_count > ARRAYSIZE(m_query_buffer) / 2) + WeakFlush(); + + if (ARRAYSIZE(m_query_buffer) == m_query_count) + { + FlushOne(); + //ERROR_LOG(VIDEO, "flushed query buffer early!"); + } + // start query if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) { - glBeginQuery(GL_SAMPLES_PASSED, query_id); + auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % ARRAYSIZE(m_query_buffer)]; + + glBeginQuery(GL_SAMPLES_PASSED, entry.query_id); + entry.query_type = type; + + ++m_query_count; } - active_query = type; } void PerfQuery::DisableQuery(PerfQueryGroup type) @@ -34,45 +50,82 @@ void PerfQuery::DisableQuery(PerfQueryGroup type) if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) { glEndQuery(GL_SAMPLES_PASSED); + } +} - GLuint query_result = GL_FALSE; - while (query_result != GL_TRUE) +bool PerfQuery::IsFlushed() const +{ + return 0 == m_query_count; +} + +void PerfQuery::FlushOne() +{ + auto& entry = m_query_buffer[m_query_read_pos]; + + GLuint result = 0; + glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result); + + m_results[entry.query_type] += result; + + m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); + --m_query_count; +} + +// TODO: could selectively flush things, but I don't think that will do much +void PerfQuery::FlushResults() +{ + while (!IsFlushed()) + FlushOne(); +} + +void PerfQuery::WeakFlush() +{ + while (!IsFlushed()) + { + auto& entry = m_query_buffer[m_query_read_pos]; + + GLuint result = GL_FALSE; + glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT_AVAILABLE, &result); + + if (GL_TRUE == result) { - glGetQueryObjectuiv(query_id, GL_QUERY_RESULT_AVAILABLE, &query_result); + FlushOne(); + } + else + { + break; } - - glGetQueryObjectuiv(query_id, GL_QUERY_RESULT, &query_result); - - results[active_query] += query_result; } } void PerfQuery::ResetQuery() { - memset(results, 0, sizeof(results)); + m_query_count = 0; + std::fill_n(m_results, ARRAYSIZE(m_results), 0); } u32 PerfQuery::GetQueryResult(PerfQueryType type) { - if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC || type == PQ_BLEND_INPUT) + u32 result = 0; + + if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC) { - + result = m_results[PQG_ZCOMP_ZCOMPLOC]; } - if (type == PQ_ZCOMP_INPUT || type == PQ_ZCOMP_OUTPUT || type == PQ_BLEND_INPUT) + else if (type == PQ_ZCOMP_INPUT || type == PQ_ZCOMP_OUTPUT) { - + result = m_results[PQG_ZCOMP]; } - if (type == PQ_BLEND_INPUT) + else if (type == PQ_BLEND_INPUT) { - results[PQ_BLEND_INPUT] = results[PQ_ZCOMP_OUTPUT] + results[PQ_ZCOMP_OUTPUT_ZCOMPLOC]; + result = m_results[PQG_ZCOMP] + m_results[PQG_ZCOMP_ZCOMPLOC]; } - - if (type == PQ_EFB_COPY_CLOCKS) + else if (type == PQ_EFB_COPY_CLOCKS) { - // TODO + result = m_results[PQG_EFB_COPY_CLOCKS]; } - - return results[type]; + + return result / 4; } } // namespace diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h index 776c576e2d..76040272e3 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h @@ -15,6 +15,30 @@ public: void DisableQuery(PerfQueryGroup type); void ResetQuery(); u32 GetQueryResult(PerfQueryType type); + void FlushResults(); + bool IsFlushed() const; + +private: + struct ActiveQuery + { + GLuint query_id; + PerfQueryGroup query_type; + }; + + // when testing in SMS: 64 was too small, 128 was ok + static const int PERF_QUERY_BUFFER_SIZE = 512; + + void WeakFlush(); + // Only use when non-empty + void FlushOne(); + + // This contains gl query objects with unretrieved results. + ActiveQuery m_query_buffer[PERF_QUERY_BUFFER_SIZE]; + int m_query_read_pos; + + // TODO: sloppy + volatile int m_query_count; + volatile u32 m_results[PQG_NUM_MEMBERS]; }; } // namespace diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index b2f55adec5..85a23e1c1d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -211,7 +211,7 @@ void VertexManager::vFlush() g_perf_query->EnableQuery(bpmem.zcontrol.zcomploc ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); Draw(); g_perf_query->DisableQuery(bpmem.zcontrol.zcomploc ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - ERROR_LOG(VIDEO, "PerfQuery result: %d", g_perf_query->GetQueryResult(bpmem.zcontrol.zcomploc ? PQ_ZCOMP_OUTPUT_ZCOMPLOC : PQ_ZCOMP_OUTPUT)); + //ERROR_LOG(VIDEO, "PerfQuery result: %d", g_perf_query->GetQueryResult(bpmem.zcontrol.zcomploc ? PQ_ZCOMP_OUTPUT_ZCOMPLOC : PQ_ZCOMP_OUTPUT)); // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 3c6fdcca38..100ff55bf4 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -176,6 +176,12 @@ u32 VideoSoftware::Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputDa return value; } +u32 VideoSoftware::Video_GetQueryResult(PerfQueryType type) +{ + // TODO: + return 0; +} + bool VideoSoftware::Video_Screenshot(const char *_szFilename) { return false; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h index c0309c95c1..2ba282788b 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h @@ -26,7 +26,9 @@ class VideoSoftware : public VideoBackend void Video_ExitLoop(); void Video_BeginField(u32, FieldType, u32, u32); void Video_EndField(); + u32 Video_AccessEFB(EFBAccessType, u32, u32, u32); + u32 Video_GetQueryResult(PerfQueryType type); void Video_AddMessage(const char* pstr, unsigned int milliseconds); void Video_ClearMessages(); From 0f617183a8a74f066d1d01a3ed50042cc9824bf8 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 18 Feb 2013 14:54:24 +0000 Subject: [PATCH 048/167] Add a possible TODO. Dunno if the hardware behaves like this, but it likely does. --- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index f10634ba18..19f18ae855 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1464,6 +1464,7 @@ void Renderer::SetDepthMode() else { // if the test is disabled write is disabled too + // TODO: When PE performance metrics are being emulated via occlusion queries, we should (probably?) enable depth test with depth function ALWAYS here glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); } From 19ab5bf50d511f9e73a896c9c610e8521fe7b583 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 18 Feb 2013 17:14:56 +0100 Subject: [PATCH 049/167] TextureCache: Fix D3D backends crashing when a game uses multiple 1x1-sized LODs. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 11 ++++++++--- Source/Core/VideoCommon/Src/VideoConfig.cpp | 1 + Source/Core/VideoCommon/Src/VideoConfig.h | 1 + Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 1 + Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 1 + Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 1 + 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index d77caa94b3..fd935de342 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -318,7 +318,7 @@ static TextureCache::TCacheEntryBase* ReturnEntry(unsigned int stage, TextureCac TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, u32 const address, unsigned int width, unsigned int height, int const texformat, - unsigned int const tlutaddr, int const tlutfmt, bool const use_mipmaps, unsigned int const maxlevel, bool const from_tmem) + unsigned int const tlutaddr, int const tlutfmt, bool const use_mipmaps, unsigned int maxlevel, bool const from_tmem) { if (0 == address) return NULL; @@ -345,7 +345,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, full_format = texformat | (tlutfmt << 16); const u32 texture_size = TexDecoder_GetTextureSizeInBytes(expandedWidth, expandedHeight, texformat); - + const u8* src_data; if (from_tmem) src_data = &texMem[bpmem.tex[stage / 4].texImage1[stage % 4].tmem_even * TMEM_LINE_SIZE]; @@ -372,6 +372,11 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, tex_hash ^= tlut_hash; } + // D3D doesn't like when the specified mipmap count would require more than one 1x1-sized LOD in the mipmap chain + // e.g. 64x64 with 7 LODs would have the mipmap chain 64x64,32x32,16x16,8x8,4x4,2x2,1x1,1x1, so we limit the mipmap count to 6 there + while (g_ActiveConfig.backend_info.bUseMinimalMipCount && max(expandedWidth, expandedHeight) >> maxlevel == 0) + --maxlevel; + TCacheEntryBase *entry = textures[texID]; if (entry) { @@ -456,7 +461,7 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, const bool using_custom_lods = using_custom_texture && CheckForCustomTextureLODs(tex_hash, texformat, texLevels); // Only load native mips if their dimensions fit to our virtual texture dimensions const bool use_native_mips = use_mipmaps && !using_custom_lods && (width == nativeW && height == nativeH); - texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1; + texLevels = (use_native_mips || using_custom_lods) ? texLevels : 1; // TODO: Should be forced to 1 for non-pow2 textures (e.g. efb copies with automatically adjusted IR) // create the entry/texture if (NULL == entry) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 7418d60741..a76514a10c 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -42,6 +42,7 @@ VideoConfig::VideoConfig() // disable all features by default backend_info.APIType = API_NONE; backend_info.bUseRGBATextures = false; + backend_info.bUseMinimalMipCount = false; backend_info.bSupports3DVision = false; } diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 4364bea6ea..183fcf784c 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -157,6 +157,7 @@ struct VideoConfig std::vector PPShaders; // post-processing shaders bool bUseRGBATextures; // used for D3D11 in TextureCache + bool bUseMinimalMipCount; bool bSupports3DVision; bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL bool bSupportsFormatReinterpretation; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index cb348b8684..b7dd9101d3 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -90,6 +90,7 @@ void InitBackendInfo() g_Config.backend_info.APIType = API_D3D11; g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats + g_Config.backend_info.bUseMinimalMipCount = true; g_Config.backend_info.bSupports3DVision = false; g_Config.backend_info.bSupportsDualSourceBlend = true; g_Config.backend_info.bSupportsFormatReinterpretation = true; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 5a80100a08..3c00e1d619 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -93,6 +93,7 @@ void InitBackendInfo() const int maxConstants = (shaderModel < 3) ? 32 : ((shaderModel < 4) ? 224 : 65536); g_Config.backend_info.APIType = shaderModel < 3 ? API_D3D9_SM20 :API_D3D9_SM30; g_Config.backend_info.bUseRGBATextures = false; + g_Config.backend_info.bUseMinimalMipCount = true; g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupportsDualSourceBlend = false; g_Config.backend_info.bSupportsFormatReinterpretation = true; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index e57e3e210a..05f21beed1 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -130,6 +130,7 @@ void InitBackendInfo() { g_Config.backend_info.APIType = API_OPENGL; g_Config.backend_info.bUseRGBATextures = false; + g_Config.backend_info.bUseMinimalMipCount = false; g_Config.backend_info.bSupports3DVision = false; g_Config.backend_info.bSupportsDualSourceBlend = false; // supported, but broken g_Config.backend_info.bSupportsFormatReinterpretation = false; From 718a1b5dedd7e2d3c9905b72a40080addd14b16e Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 19 Feb 2013 23:18:13 +1100 Subject: [PATCH 050/167] Fixed a buffer overflow in the OpenAL buffer. --- Source/Core/AudioCommon/Src/OpenALStream.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/Core/AudioCommon/Src/OpenALStream.cpp b/Source/Core/AudioCommon/Src/OpenALStream.cpp index 6b239a584c..7d1c45175b 100644 --- a/Source/Core/AudioCommon/Src/OpenALStream.cpp +++ b/Source/Core/AudioCommon/Src/OpenALStream.cpp @@ -200,6 +200,7 @@ void OpenALStream::SoundLoop() u64 num_samples_to_render = (audio_dma_period * ais_samples_per_second) / SystemTimers::GetTicksPerSecond(); unsigned int numSamples = (unsigned int)num_samples_to_render; + unsigned int minSamples = surround_capable ? 240 : 0; // DPL2 accepts 240 samples minimum (FWRDURATION) numSamples = (numSamples > OAL_MAX_SAMPLES) ? OAL_MAX_SAMPLES : numSamples; numSamples = m_mixer->Mix(realtimeBuffer, numSamples); @@ -236,9 +237,15 @@ void OpenALStream::SoundLoop() // Adjust SETTING_SEQUENCE_MS to balance between lag vs hollow audio soundTouch.setSetting(SETTING_SEQUENCE_MS, (int)(1 / (rate * rate))); soundTouch.setTempo(rate); + if (rate > 10) + { + soundTouch.clear(); + } } - unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * SURROUND_CHANNELS * OAL_MAX_BUFFERS); - if (nSamples > 0) + + unsigned int nSamples = soundTouch.receiveSamples(sampleBuffer, OAL_MAX_SAMPLES * SIZE_FLOAT * OAL_MAX_BUFFERS); + + if (nSamples > minSamples) { // Remove the Buffer from the Queue. (uiBuffer contains the Buffer ID for the unqueued Buffer) if (iBuffersFilled == 0) From 294cb165ba3449cc4fd96eabb5272e2984a58eb8 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 19 Feb 2013 22:39:28 -0600 Subject: [PATCH 051/167] Don't load level 0 twice for 1-level textures in DX11. --- Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index 844cf24b47..ba05dc83d2 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -70,24 +70,19 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, { D3D11_USAGE usage = D3D11_USAGE_DEFAULT; D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0; - D3D11_SUBRESOURCE_DATA srdata, *data = NULL; + // This is just an optimization apparently? if (tex_levels == 1) { usage = D3D11_USAGE_DYNAMIC; cpu_access = D3D11_CPU_ACCESS_WRITE; - - srdata.pSysMem = TextureCache::temp; - srdata.SysMemPitch = 4 * expanded_width; - - data = &srdata; } const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access); ID3D11Texture2D *pTexture; - const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, data, &pTexture); + const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, NULL, &pTexture); CHECK(SUCCEEDED(hr), "Create texture of the TextureCache"); TCacheEntry* const entry = new TCacheEntry(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE)); From 6e6d8af6ddaddeeaf89be2f8b6920b913488f0c6 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 05:37:01 -0600 Subject: [PATCH 052/167] Revert "Don't load level 0 twice for 1-level textures in DX11." and fix it properly. All backend TextureCaches now load level 0 in CreateTexture. This reverts commit 294cb165ba3449cc4fd96eabb5272e2984a58eb8. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 15 ++++++++++----- .../Plugins/Plugin_VideoDX11/Src/TextureCache.cpp | 9 +++++++-- .../Plugins/Plugin_VideoDX9/Src/TextureCache.cpp | 2 ++ .../Plugins/Plugin_VideoOGL/Src/TextureCache.cpp | 2 ++ 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index fd935de342..fda4f21a7e 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -481,15 +481,20 @@ TextureCache::TCacheEntryBase* TextureCache::Load(unsigned int const stage, GFX_DEBUGGER_PAUSE_AT(NEXT_NEW_TEXTURE, true); } + else + { + // load texture (CreateTexture also loads level 0) + entry->Load(width, height, expandedWidth, 0); + } entry->SetGeneralParameters(address, texture_size, full_format, entry->num_mipmaps); entry->SetDimensions(nativeW, nativeH, width, height); entry->hash = tex_hash; - if (entry->IsEfbCopy() && !g_ActiveConfig.bCopyEFBToTexture) entry->type = TCET_EC_DYNAMIC; - else entry->type = TCET_NORMAL; - - // load texture - entry->Load(width, height, expandedWidth, 0); + + if (entry->IsEfbCopy() && !g_ActiveConfig.bCopyEFBToTexture) + entry->type = TCET_EC_DYNAMIC; + else + entry->type = TCET_NORMAL; if (g_ActiveConfig.bDumpTextures && !using_custom_texture) DumpTexture(entry, 0); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index ba05dc83d2..844cf24b47 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -70,19 +70,24 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, { D3D11_USAGE usage = D3D11_USAGE_DEFAULT; D3D11_CPU_ACCESS_FLAG cpu_access = (D3D11_CPU_ACCESS_FLAG)0; + D3D11_SUBRESOURCE_DATA srdata, *data = NULL; - // This is just an optimization apparently? if (tex_levels == 1) { usage = D3D11_USAGE_DYNAMIC; cpu_access = D3D11_CPU_ACCESS_WRITE; + + srdata.pSysMem = TextureCache::temp; + srdata.SysMemPitch = 4 * expanded_width; + + data = &srdata; } const D3D11_TEXTURE2D_DESC texdesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8G8B8A8_UNORM, width, height, 1, tex_levels, D3D11_BIND_SHADER_RESOURCE, usage, cpu_access); ID3D11Texture2D *pTexture; - const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, NULL, &pTexture); + const HRESULT hr = D3D::device->CreateTexture2D(&texdesc, data, &pTexture); CHECK(SUCCEEDED(hr), "Create texture of the TextureCache"); TCacheEntry* const entry = new TCacheEntry(new D3DTexture2D(pTexture, D3D11_BIND_SHADER_RESOURCE)); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp index 660fad7379..f105d0f774 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp @@ -226,6 +226,8 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, u TCacheEntry* entry = new TCacheEntry(D3D::CreateTexture2D(temp, width, height, expanded_width, d3d_fmt, swap_r_b, tex_levels)); entry->swap_r_b = swap_r_b; entry->d3d_fmt = d3d_fmt; + + entry->Load(width, height, expanded_width, 0); return entry; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp index bf6f6d1ef2..ee918ee6c0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureCache.cpp @@ -178,6 +178,8 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, entry.pcfmt = pcfmt; entry.bHaveMipMaps = tex_levels != 1; + + entry.Load(width, height, expanded_width, 0); return &entry; } From b7fae1febb77629032122c710ac3a882c309ffdf Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 14:18:21 -0600 Subject: [PATCH 053/167] Fix my DX11 texture-related failure.. Fixes issue 6026. (probably) --- Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp index 844cf24b47..c0474e5c67 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/TextureCache.cpp @@ -98,6 +98,9 @@ TextureCache::TCacheEntryBase* TextureCache::CreateTexture(unsigned int width, D3D::SetDebugObjectName((ID3D11DeviceChild*)entry->texture->GetSRV(), "shader resource view of a texture of the TextureCache"); SAFE_RELEASE(pTexture); + + if (tex_levels != 1) + entry->Load(width, height, expanded_width, 0); return entry; } From f3e91bc10de42648f5f8c515b013f22218e14cd4 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 17:30:34 -0600 Subject: [PATCH 054/167] Hopefully kill a stupid warning on Windows. --- Source/Core/Common/Src/FileUtil.cpp | 4 ++-- Source/Core/Common/Src/FileUtil.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp index d6ab33962a..a2bd694438 100644 --- a/Source/Core/Common/Src/FileUtil.cpp +++ b/Source/Core/Common/Src/FileUtil.cpp @@ -781,9 +781,9 @@ IOFile::IOFile(IOFile&& other) Swap(other); } -IOFile& IOFile::operator=(IOFile other) +IOFile& IOFile::operator=(IOFile&& other) { - Swap(other); + IOFile(std::move(other)).Swap(*this); return *this; } diff --git a/Source/Core/Common/Src/FileUtil.h b/Source/Core/Common/Src/FileUtil.h index 2c8bf8f64b..b8e8d9c17c 100644 --- a/Source/Core/Common/Src/FileUtil.h +++ b/Source/Core/Common/Src/FileUtil.h @@ -160,7 +160,7 @@ public: ~IOFile(); IOFile(IOFile&& other); - IOFile& operator=(IOFile other); + IOFile& operator=(IOFile&& other); void Swap(IOFile& other); From e9232280c43174b4349eef8f7abbb551c120ac53 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 17:35:01 -0600 Subject: [PATCH 055/167] Fix OSX! --- Source/Core/Common/Src/FileUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp index a2bd694438..491db88e41 100644 --- a/Source/Core/Common/Src/FileUtil.cpp +++ b/Source/Core/Common/Src/FileUtil.cpp @@ -783,7 +783,7 @@ IOFile::IOFile(IOFile&& other) IOFile& IOFile::operator=(IOFile&& other) { - IOFile(std::move(other)).Swap(*this); + IOFile((IOFile&&)other).Swap(*this); return *this; } From 6a13a4e5ed10aac3b80e996f5c9e94d000f484b2 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 20:20:53 -0600 Subject: [PATCH 056/167] Add template "swap" function to CommonFuncs. --- Source/Core/Common/Src/CommonFuncs.h | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Source/Core/Common/Src/CommonFuncs.h b/Source/Core/Common/Src/CommonFuncs.h index 585fe0999a..18dc40e8c8 100644 --- a/Source/Core/Common/Src/CommonFuncs.h +++ b/Source/Core/Common/Src/CommonFuncs.h @@ -162,6 +162,40 @@ inline u16 swap16(const u8* _pData) {return swap16(*(const u16*)_pData);} inline u32 swap32(const u8* _pData) {return swap32(*(const u32*)_pData);} inline u64 swap64(const u8* _pData) {return swap64(*(const u64*)_pData);} +template +void swap(u8*); + +template <> +inline void swap<1>(u8* data) +{} + +template <> +inline void swap<2>(u8* data) +{ + *reinterpret_cast(data) = swap16(data); +} + +template <> +inline void swap<4>(u8* data) +{ + *reinterpret_cast(data) = swap32(data); +} + +template <> +inline void swap<8>(u8* data) +{ + *reinterpret_cast(data) = swap64(data); +} + +template +inline T FromBigEndian(T data) +{ + //static_assert(std::is_arithmetic::value, "function only makes sense with arithmetic types"); + + swap(reinterpret_cast(&data)); + return data; +} + } // Namespace Common #endif // _COMMONFUNCS_H_ From 8f256237a38e97db13d15ec8a761243755587714 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 20:21:25 -0600 Subject: [PATCH 057/167] Templatify DataReader a bit. --- Source/Core/VideoCommon/Src/DataReader.h | 91 ++++++++---------------- 1 file changed, 31 insertions(+), 60 deletions(-) diff --git a/Source/Core/VideoCommon/Src/DataReader.h b/Source/Core/VideoCommon/Src/DataReader.h index 06668f8bbc..00dca77134 100644 --- a/Source/Core/VideoCommon/Src/DataReader.h +++ b/Source/Core/VideoCommon/Src/DataReader.h @@ -31,43 +31,63 @@ __forceinline void DataSkip(u32 skip) g_pVideoData += skip; } +// probably unnecessary +template +__forceinline void DataSkip() +{ + g_pVideoData += count; +} + +template +__forceinline T DataPeek(int _uOffset) +{ + auto const result = Common::FromBigEndian(*reinterpret_cast(g_pVideoData + _uOffset)); + return result; +} + +// TODO: kill these __forceinline u8 DataPeek8(int _uOffset) { - return g_pVideoData[_uOffset]; + return DataPeek(_uOffset); } __forceinline u16 DataPeek16(int _uOffset) { - return Common::swap16(*(u16*)&g_pVideoData[_uOffset]); + return DataPeek(_uOffset); } __forceinline u32 DataPeek32(int _uOffset) { - return Common::swap32(*(u32*)&g_pVideoData[_uOffset]); + return DataPeek(_uOffset); } +template +__forceinline T DataRead() +{ + auto const result = DataPeek(0); + DataSkip(); + return result; +} + +// TODO: kill these __forceinline u8 DataReadU8() { - return *g_pVideoData++; + return DataRead(); } __forceinline s8 DataReadS8() { - return (s8)(*g_pVideoData++); + return DataRead(); } __forceinline u16 DataReadU16() { - u16 tmp = Common::swap16(*(u16*)g_pVideoData); - g_pVideoData += 2; - return tmp; + return DataRead(); } __forceinline u32 DataReadU32() { - u32 tmp = Common::swap32(*(u32*)g_pVideoData); - g_pVideoData += 4; - return tmp; + return DataRead(); } typedef void (*DataReadU32xNfunc)(u32 *buf); @@ -120,55 +140,6 @@ __forceinline u32 DataReadU32Unswapped() return tmp; } -template -__forceinline T DataRead() -{ - T tmp = *(T*)g_pVideoData; - g_pVideoData += sizeof(T); - return tmp; -} - -template <> -__forceinline u16 DataRead() -{ - u16 tmp = Common::swap16(*(u16*)g_pVideoData); - g_pVideoData += 2; - return tmp; -} - -template <> -__forceinline s16 DataRead() -{ - s16 tmp = (s16)Common::swap16(*(u16*)g_pVideoData); - g_pVideoData += 2; - return tmp; -} - -template <> -__forceinline u32 DataRead() -{ - u32 tmp = (u32)Common::swap32(*(u32*)g_pVideoData); - g_pVideoData += 4; - return tmp; -} - -template <> -__forceinline s32 DataRead() -{ - s32 tmp = (s32)Common::swap32(*(u32*)g_pVideoData); - g_pVideoData += 4; - return tmp; -} - -__forceinline float DataReadF32() -{ - union {u32 i; float f;} temp; - temp.i = Common::swap32(*(u32*)g_pVideoData); - g_pVideoData += 4; - float tmp = temp.f; - return tmp; -} - __forceinline u8* DataGetPosition() { return g_pVideoData; From 5e78f8a176ceda4255164713ff62c08adfded2ca Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 20:43:53 -0600 Subject: [PATCH 058/167] Templatify TextCord Loader functions. --- .../Src/VertexLoader_TextCoord.cpp | 356 ++---------------- 1 file changed, 40 insertions(+), 316 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp index ba3bb73f43..5db2242d1b 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp @@ -39,275 +39,36 @@ void LOADERDECL TexCoord_Read_Dummy() tcIndex++; } -void LOADERDECL TexCoord_ReadDirect_UByte1() +template +void LOADERDECL TexCoord_ReadDirect() { - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)DataReadU8() * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadDirect_UByte2() -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)DataReadU8() * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)DataReadU8() * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; + reinterpret_cast(VertexManager::s_pCurBufferPointer)[0] = DataRead() * tcScale[tcIndex]; + if (N >= 1) + reinterpret_cast(VertexManager::s_pCurBufferPointer)[1] = DataRead() * tcScale[tcIndex]; + //LOG_TEX1(); + //LOG_TEX2(); + VertexManager::s_pCurBufferPointer += sizeof(float) * N; + ++tcIndex; } -void LOADERDECL TexCoord_ReadDirect_Byte1() +template +void LOADERDECL TexCoord_ReadIndex() { - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s8)DataReadU8() * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadDirect_Byte2() -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s8)DataReadU8() * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s8)DataReadU8() * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadDirect_UShort1() -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)DataReadU16() * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadDirect_UShort2() -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)DataReadU16() * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)DataReadU16() * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadDirect_Short1() -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s16)DataReadU16() * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadDirect_Short2() -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s16)DataReadU16() * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s16)DataReadU16() * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadDirect_Float1() -{ - ((u32*)VertexManager::s_pCurBufferPointer)[0] = DataReadU32(); - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadDirect_Float2() -{ - ((u32*)VertexManager::s_pCurBufferPointer)[0] = DataReadU32(); - ((u32*)VertexManager::s_pCurBufferPointer)[1] = DataReadU32(); - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -// ================================================================================== -void LOADERDECL TexCoord_ReadIndex8_UByte1() -{ - u8 Index = DataReadU8(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(*pData) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex8_UByte2() -{ - u8 Index = DataReadU8(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(u8)(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(u8)(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex8_Byte1() -{ - u8 Index = DataReadU8(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s8)(*pData) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex8_Byte2() -{ - u8 Index = DataReadU8(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s8)(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s8)(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex8_UShort1() -{ - u8 Index = DataReadU8(); - const u16 *pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(u16)Common::swap16(*pData) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex8_UShort2() -{ - u8 Index = DataReadU8(); - const u16 *pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(u16)Common::swap16(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(u16)Common::swap16(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex8_Short1() -{ - u8 Index = DataReadU8(); - const u16 *pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s16)Common::swap16(pData[0]) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex8_Short2() -{ - u8 Index = DataReadU8(); - const u16 *pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s16)Common::swap16(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s16)Common::swap16(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex8_Float1() -{ - u16 Index = DataReadU8(); - const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(pData[0]); - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex8_Float2() -{ - u16 Index = DataReadU8(); - const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(pData[0]); - ((u32*)VertexManager::s_pCurBufferPointer)[1] = Common::swap32(pData[1]); - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -// ================================================================================== -void LOADERDECL TexCoord_ReadIndex16_UByte1() -{ - u16 Index = DataReadU16(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(u8)(pData[0]) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex16_UByte2() -{ - u16 Index = DataReadU16(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(u8)(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(u8)(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex16_Byte1() -{ - u16 Index = DataReadU16(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s8)(pData[0]) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex16_Byte2() -{ - u16 Index = DataReadU16(); - const u8 *pData = cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s8)(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s8)(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex16_UShort1() -{ - u16 Index = DataReadU16(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(u16)Common::swap16(pData[0]) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} -void LOADERDECL TexCoord_ReadIndex16_UShort2() -{ - u16 Index = DataReadU16(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(u16)Common::swap16(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(u16)Common::swap16(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex16_Short1() -{ - u16 Index = DataReadU16(); - const u16 *pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s16)Common::swap16(*pData) * tcScale[tcIndex]; - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex16_Short2() -{ - // Heavy in ZWW - u16 Index = DataReadU16(); - const u16 *pData = (const u16 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(s16)Common::swap16(pData[0]) * tcScale[tcIndex]; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(s16)Common::swap16(pData[1]) * tcScale[tcIndex]; - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; + auto const index = DataRead(); + auto const data = reinterpret_cast(cached_arraybases[ARRAY_TEXCOORD0 + tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0 + tcIndex])); + reinterpret_cast(VertexManager::s_pCurBufferPointer)[0] = Common::FromBigEndian(data[0]) * tcScale[tcIndex]; + if (N >= 1) + reinterpret_cast(VertexManager::s_pCurBufferPointer)[1] = Common::FromBigEndian(data[1]) * tcScale[tcIndex]; + //LOG_TEX1(); + //LOG_TEX2(); + VertexManager::s_pCurBufferPointer += sizeof(float) * N; + ++tcIndex; } #if _M_SSE >= 0x401 static const __m128i kMaskSwap16_2 = _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x02030001L); -void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() +void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() { // Heavy in ZWW u16 Index = DataReadU16(); @@ -325,27 +86,6 @@ void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() } #endif -void LOADERDECL TexCoord_ReadIndex16_Float1() -{ - u16 Index = DataReadU16(); - const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(pData[0]); - LOG_TEX1(); - VertexManager::s_pCurBufferPointer += 4; - tcIndex++; -} - -void LOADERDECL TexCoord_ReadIndex16_Float2() -{ - u16 Index = DataReadU16(); - const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); - ((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(pData[0]); - ((u32*)VertexManager::s_pCurBufferPointer)[1] = Common::swap32(pData[1]); - LOG_TEX2(); - VertexManager::s_pCurBufferPointer += 8; - tcIndex++; -} - #if _M_SSE >= 0x301 static const __m128i kMaskSwap32 = _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L); @@ -373,56 +113,40 @@ static TPipelineFunction tableReadTexCoord[4][8][2] = { {NULL, NULL,}, }, { - {TexCoord_ReadDirect_UByte1, TexCoord_ReadDirect_UByte2,}, - {TexCoord_ReadDirect_Byte1, TexCoord_ReadDirect_Byte2,}, - {TexCoord_ReadDirect_UShort1, TexCoord_ReadDirect_UShort2,}, - {TexCoord_ReadDirect_Short1, TexCoord_ReadDirect_Short2,}, - {TexCoord_ReadDirect_Float1, TexCoord_ReadDirect_Float2,}, + {TexCoord_ReadDirect, TexCoord_ReadDirect,}, + {TexCoord_ReadDirect, TexCoord_ReadDirect,}, + {TexCoord_ReadDirect, TexCoord_ReadDirect,}, + {TexCoord_ReadDirect, TexCoord_ReadDirect,}, + {TexCoord_ReadDirect, TexCoord_ReadDirect,}, }, { - {TexCoord_ReadIndex8_UByte1, TexCoord_ReadIndex8_UByte2,}, - {TexCoord_ReadIndex8_Byte1, TexCoord_ReadIndex8_Byte2,}, - {TexCoord_ReadIndex8_UShort1, TexCoord_ReadIndex8_UShort2,}, - {TexCoord_ReadIndex8_Short1, TexCoord_ReadIndex8_Short2,}, - {TexCoord_ReadIndex8_Float1, TexCoord_ReadIndex8_Float2,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, }, { - {TexCoord_ReadIndex16_UByte1, TexCoord_ReadIndex16_UByte2,}, - {TexCoord_ReadIndex16_Byte1, TexCoord_ReadIndex16_Byte2,}, - {TexCoord_ReadIndex16_UShort1, TexCoord_ReadIndex16_UShort2,}, - {TexCoord_ReadIndex16_Short1, TexCoord_ReadIndex16_Short2,}, - {TexCoord_ReadIndex16_Float1, TexCoord_ReadIndex16_Float2,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, + {TexCoord_ReadIndex, TexCoord_ReadIndex,}, }, }; static int tableReadTexCoordVertexSize[4][8][2] = { { - {0, 0,}, - {0, 0,}, - {0, 0,}, - {0, 0,}, - {0, 0,}, + {0, 0,}, {0, 0,}, {0, 0,}, {0, 0,}, {0, 0,}, }, { - {1, 2,}, - {1, 2,}, - {2, 4,}, - {2, 4,}, - {4, 8,}, + {1, 2,}, {1, 2,}, {2, 4,}, {2, 4,}, {4, 8,}, }, { - {1, 1,}, - {1, 1,}, - {1, 1,}, - {1, 1,}, - {1, 1,}, + {1, 1,}, {1, 1,}, {1, 1,}, {1, 1,}, {1, 1,}, }, { - {2, 2,}, - {2, 2,}, - {2, 2,}, - {2, 2,}, - {2, 2,}, + {2, 2,}, {2, 2,}, {2, 2,}, {2, 2,}, {2, 2,}, }, }; From 5b63472ad7ec1dc93fc9efac39e55e636f5f0fc0 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 22:22:41 -0600 Subject: [PATCH 059/167] Templatify Normal Loader functions. --- .../VideoCommon/Src/VertexLoader_Normal.cpp | 499 +++++------------- .../VideoCommon/Src/VertexLoader_Normal.h | 30 -- .../Src/VertexLoader_TextCoord.cpp | 2 + 3 files changed, 132 insertions(+), 399 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp index 830bd3de13..a53425b1ec 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp @@ -22,6 +22,7 @@ #include "VertexManagerBase.h" #include "CPUDetect.h" #include +#include #if _M_SSE >= 0x401 #include @@ -34,74 +35,143 @@ VertexLoader_Normal::Set VertexLoader_Normal::m_Table[NUM_NRM_TYPE][NUM_NRM_INDICES][NUM_NRM_ELEMENTS][NUM_NRM_FORMAT]; +namespace +{ + +template +float FracAdjust(T val) +{ + //auto const S8FRAC = 1.f / (1u << 6); + //auto const U8FRAC = 1.f / (1u << 7); + //auto const S16FRAC = 1.f / (1u << 14); + //auto const U16FRAC = 1.f / (1u << 15); + + return val / float(1u << (sizeof(T) * 8 - std::numeric_limits::is_signed - 1)); +} + +template <> +float FracAdjust(float val) +{ return val; } + +template +inline void ReadIndirect(const T* data) +{ + static_assert(3 == N || 9 == N, "N is only sane as 3 or 9!"); + + auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); + + for (int i = 0; i != N; ++i) + { + dest[i] = FracAdjust(Common::FromBigEndian(data[i])); + LOG_NORM(); + } + + VertexManager::s_pCurBufferPointer += sizeof(float) * N; +} + +template +void LOADERDECL Normal_Direct() +{ + auto const source = reinterpret_cast(DataGetPosition()); + ReadIndirect(source); + DataSkip(); +} + +template +inline void Normal_Index_Offset() +{ + static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); + + auto const index = DataRead(); + auto const data = reinterpret_cast(cached_arraybases[ARRAY_NORMAL] + + (index * arraystrides[ARRAY_NORMAL]) + sizeof(T) * 3 * Offset); + ReadIndirect(data); +} + +template +void LOADERDECL Normal_Index() +{ + Normal_Index_Offset(); +} + +template +void LOADERDECL Normal_Index_Indices3() +{ + Normal_Index_Offset(); + Normal_Index_Offset(); + Normal_Index_Offset(); +} + +} + void VertexLoader_Normal::Init(void) { // HACK is for signed instead of unsigned to prevent crashes. - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_DirectByte); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_DirectByte); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_DirectShort); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_DirectShort); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_DirectFloat); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_DirectByte3); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_DirectByte3); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_DirectShort3); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_DirectShort3); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_DirectFloat3); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_DirectByte); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_DirectByte); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_DirectShort); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_DirectShort); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_DirectFloat); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_DirectByte3); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_DirectByte3); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_DirectShort3); //HACK - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_DirectShort3); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_DirectFloat3); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_Direct); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_Direct); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index8_Byte); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index8_Byte); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index8_Short); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index8_Short); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index8_Float); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(1, Normal_Index8_Byte3_Indices1); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(1, Normal_Index8_Byte3_Indices1); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(1, Normal_Index8_Short3_Indices1); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(1, Normal_Index8_Short3_Indices1); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(1, Normal_Index8_Float3_Indices1); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index8_Byte); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index8_Byte); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index8_Short); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index8_Short); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index8_Float); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(3, Normal_Index8_Byte3_Indices3); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(3, Normal_Index8_Byte3_Indices3); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(3, Normal_Index8_Short3_Indices3); //HACK - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(3, Normal_Index8_Short3_Indices3); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(3, Normal_Index8_Float3_Indices3); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(3, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(3, Normal_Index_Indices3); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(3, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(3, Normal_Index_Indices3); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(3, Normal_Index_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index16_Byte); //HACK - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index16_Byte); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index16_Short); //HACK - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index16_Short); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index16_Float); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(2, Normal_Index16_Byte3_Indices1); //HACK - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(2, Normal_Index16_Byte3_Indices1); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(2, Normal_Index16_Short3_Indices1); //HACK - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(2, Normal_Index16_Short3_Indices1); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(2, Normal_Index16_Float3_Indices1); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index16_Byte); //HACK - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index16_Byte); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index16_Short); //HACK - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index16_Short); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index16_Float); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(6, Normal_Index16_Byte3_Indices3); //HACK - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(6, Normal_Index16_Byte3_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(6, Normal_Index16_Short3_Indices3); //HACK - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(6, Normal_Index16_Short3_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(6, Normal_Index16_Float3_Indices3); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(6, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(6, Normal_Index_Indices3); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(6, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(6, Normal_Index_Indices3); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(6, Normal_Index_Indices3); } unsigned int VertexLoader_Normal::GetSize(unsigned int _type, @@ -116,312 +186,3 @@ TPipelineFunction VertexLoader_Normal::GetFunction(unsigned int _type, TPipelineFunction pFunc = m_Table[_type][_index3][_elements][_format].function; return pFunc; } - -// This fracs are fixed acording to format -#define S8FRAC 0.015625f; // 1.0f / (1U << 6) -#define S16FRAC 0.00006103515625f; // 1.0f / (1U << 14) -// --- Direct --- - -inline void ReadIndirectS8x3(const s8* pData) -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = pData[0] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[1] = pData[1] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[2] = pData[2] * S8FRAC; - VertexManager::s_pCurBufferPointer += 12; - LOG_NORM(); -} - -inline void ReadIndirectS8x9(const s8* pData) -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = pData[0] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[1] = pData[1] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[2] = pData[2] * S8FRAC; - LOG_NORM(); - ((float*)VertexManager::s_pCurBufferPointer)[3] = pData[3] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[4] = pData[4] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[5] = pData[5] * S8FRAC; - LOG_NORM(); - ((float*)VertexManager::s_pCurBufferPointer)[6] = pData[6] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[7] = pData[7] * S8FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[8] = pData[8] * S8FRAC; - LOG_NORM(); - VertexManager::s_pCurBufferPointer += 36; -} - -inline void ReadIndirectS16x3(const u16* pData) -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = ((s16)Common::swap16(pData[0])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[1] = ((s16)Common::swap16(pData[1])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[2] = ((s16)Common::swap16(pData[2])) * S16FRAC; - VertexManager::s_pCurBufferPointer += 12; - LOG_NORM() -} - -inline void ReadIndirectS16x9(const u16* pData) -{ - ((float*)VertexManager::s_pCurBufferPointer)[0] = ((s16)Common::swap16(pData[0])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[1] = ((s16)Common::swap16(pData[1])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[2] = ((s16)Common::swap16(pData[2])) * S16FRAC; - LOG_NORM() - ((float*)VertexManager::s_pCurBufferPointer)[3] = ((s16)Common::swap16(pData[3])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[4] = ((s16)Common::swap16(pData[4])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[5] = ((s16)Common::swap16(pData[5])) * S16FRAC; - LOG_NORM() - ((float*)VertexManager::s_pCurBufferPointer)[6] = ((s16)Common::swap16(pData[6])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[7] = ((s16)Common::swap16(pData[7])) * S16FRAC; - ((float*)VertexManager::s_pCurBufferPointer)[8] = ((s16)Common::swap16(pData[8])) * S16FRAC; - LOG_NORM() - VertexManager::s_pCurBufferPointer += 36; -} - -inline void ReadIndirectFloatx3(const u32* pData) -{ - ((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(pData[0]); - ((u32*)VertexManager::s_pCurBufferPointer)[1] = Common::swap32(pData[1]); - ((u32*)VertexManager::s_pCurBufferPointer)[2] = Common::swap32(pData[2]); - VertexManager::s_pCurBufferPointer += 12; - LOG_NORM(); -} - -inline void ReadIndirectFloatx9(const u32* pData) -{ - ((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(pData[0]); - ((u32*)VertexManager::s_pCurBufferPointer)[1] = Common::swap32(pData[1]); - ((u32*)VertexManager::s_pCurBufferPointer)[2] = Common::swap32(pData[2]); - LOG_NORM(); - ((u32*)VertexManager::s_pCurBufferPointer)[3] = Common::swap32(pData[3]); - ((u32*)VertexManager::s_pCurBufferPointer)[4] = Common::swap32(pData[4]); - ((u32*)VertexManager::s_pCurBufferPointer)[5] = Common::swap32(pData[5]); - LOG_NORM(); - ((u32*)VertexManager::s_pCurBufferPointer)[6] = Common::swap32(pData[6]); - ((u32*)VertexManager::s_pCurBufferPointer)[7] = Common::swap32(pData[7]); - ((u32*)VertexManager::s_pCurBufferPointer)[8] = Common::swap32(pData[8]); - LOG_NORM(); - VertexManager::s_pCurBufferPointer += 36; -} - -inline void ReadDirectS8x3() -{ - const s8* Source = (const s8*)DataGetPosition(); - ReadIndirectS8x3(Source); - DataSkip(3); -} - -inline void ReadDirectS8x9() -{ - const s8* Source = (const s8*)DataGetPosition(); - ReadIndirectS8x9(Source); - DataSkip(9); -} - -inline void ReadDirectS16x3() -{ - const u16* Source = (const u16*)DataGetPosition(); - ReadIndirectS16x3(Source); - DataSkip(6); -} - -inline void ReadDirectS16x9() -{ - const u16* Source = (const u16*)DataGetPosition(); - ReadIndirectS16x9(Source); - DataSkip(18); -} - -inline void ReadDirectFloatx3() -{ - const u32* Source = (const u32*)DataGetPosition(); - ReadIndirectFloatx3(Source); - DataSkip(12); -} - -inline void ReadDirectFloatx9() -{ - const u32* Source = (const u32*)DataGetPosition(); - ReadIndirectFloatx9(Source); - DataSkip(36); -} - - - -void LOADERDECL VertexLoader_Normal::Normal_DirectByte() -{ - ReadDirectS8x3(); -} - -void LOADERDECL VertexLoader_Normal::Normal_DirectShort() -{ - ReadDirectS16x3(); -} - -void LOADERDECL VertexLoader_Normal::Normal_DirectFloat() -{ - ReadDirectFloatx3(); -} - -void LOADERDECL VertexLoader_Normal::Normal_DirectByte3() -{ - ReadDirectS8x9(); -} - -void LOADERDECL VertexLoader_Normal::Normal_DirectShort3() -{ - ReadDirectS16x9(); -} - -void LOADERDECL VertexLoader_Normal::Normal_DirectFloat3() -{ - ReadDirectFloatx9(); -} - - -// --- Index8 --- - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Byte() -{ - u8 Index = DataReadU8(); - const s8* pData = (const s8 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS8x3(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Short() -{ - u8 Index = DataReadU8(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS16x3(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Float() -{ - u8 Index = DataReadU8(); - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectFloatx3(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Byte3_Indices1() -{ - u8 Index = DataReadU8(); - const s8* pData = (const s8 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS8x9(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Short3_Indices1() -{ - u8 Index = DataReadU8(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS16x9(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Float3_Indices1() -{ - u8 Index = DataReadU8(); - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectFloatx9(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Byte3_Indices3() -{ - for (int i = 0; i < 3; i++) - { - u8 Index = DataReadU8(); - const s8* pData = (const s8*)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i); - ReadIndirectS8x3(pData); - } -} - - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Short3_Indices3() -{ - for (int i = 0; i < 3; i++) - { - u8 Index = DataReadU8(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i); - ReadIndirectS16x3(pData); - } -} - -void LOADERDECL VertexLoader_Normal::Normal_Index8_Float3_Indices3() -{ - for (int i = 0; i < 3; i++) - { - u8 Index = DataReadU8(); - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i); - ReadIndirectFloatx3(pData); - } -} - - -// --- Index16 --- - - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Byte() -{ - u16 Index = DataReadU16(); - const s8* pData = (const s8 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS8x3(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Short() -{ - u16 Index = DataReadU16(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS16x3(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Float() -{ - u16 Index = DataReadU16(); - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectFloatx3(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Byte3_Indices1() -{ - u16 Index = DataReadU16(); - const s8* pData = (const s8 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS8x9(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Short3_Indices1() -{ - u16 Index = DataReadU16(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectS16x9(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Float3_Indices1() -{ - u16 Index = DataReadU16(); - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL])); - ReadIndirectFloatx9(pData); -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Byte3_Indices3() -{ - for (int i = 0; i < 3; i++) - { - u16 Index = DataReadU16(); - const s8* pData = (const s8*)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i); - ReadIndirectS8x3(pData); - } -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Short3_Indices3() -{ - for (int i = 0; i < 3; i++) - { - u16 Index = DataReadU16(); - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i); - ReadIndirectS16x3(pData); - } -} - -void LOADERDECL VertexLoader_Normal::Normal_Index16_Float3_Indices3() -{ - for (int i = 0; i < 3; i++) - { - u16 Index = DataReadU16(); - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i); - ReadIndirectFloatx3(pData); - } -} diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Normal.h b/Source/Core/VideoCommon/Src/VertexLoader_Normal.h index 934cd1ec43..71d4387ff0 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Normal.h +++ b/Source/Core/VideoCommon/Src/VertexLoader_Normal.h @@ -79,36 +79,6 @@ private: }; static Set m_Table[NUM_NRM_TYPE][NUM_NRM_INDICES][NUM_NRM_ELEMENTS][NUM_NRM_FORMAT]; - - // direct - static void LOADERDECL Normal_DirectByte(); - static void LOADERDECL Normal_DirectShort(); - static void LOADERDECL Normal_DirectFloat(); - static void LOADERDECL Normal_DirectByte3(); - static void LOADERDECL Normal_DirectShort3(); - static void LOADERDECL Normal_DirectFloat3(); - - // index8 - static void LOADERDECL Normal_Index8_Byte(); - static void LOADERDECL Normal_Index8_Short(); - static void LOADERDECL Normal_Index8_Float(); - static void LOADERDECL Normal_Index8_Byte3_Indices1(); - static void LOADERDECL Normal_Index8_Short3_Indices1(); - static void LOADERDECL Normal_Index8_Float3_Indices1(); - static void LOADERDECL Normal_Index8_Byte3_Indices3(); - static void LOADERDECL Normal_Index8_Short3_Indices3(); - static void LOADERDECL Normal_Index8_Float3_Indices3(); - - // index16 - static void LOADERDECL Normal_Index16_Byte(); - static void LOADERDECL Normal_Index16_Short(); - static void LOADERDECL Normal_Index16_Float(); - static void LOADERDECL Normal_Index16_Byte3_Indices1(); - static void LOADERDECL Normal_Index16_Short3_Indices1(); - static void LOADERDECL Normal_Index16_Float3_Indices1(); - static void LOADERDECL Normal_Index16_Byte3_Indices3(); - static void LOADERDECL Normal_Index16_Short3_Indices3(); - static void LOADERDECL Normal_Index16_Float3_Indices3(); }; #endif diff --git a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp index 5db2242d1b..8bbd1197d5 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp @@ -54,6 +54,8 @@ void LOADERDECL TexCoord_ReadDirect() template void LOADERDECL TexCoord_ReadIndex() { + static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); + auto const index = DataRead(); auto const data = reinterpret_cast(cached_arraybases[ARRAY_TEXCOORD0 + tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0 + tcIndex])); reinterpret_cast(VertexManager::s_pCurBufferPointer)[0] = Common::FromBigEndian(data[0]) * tcScale[tcIndex]; From 3938d3713b23d264e78a19b5bc1cb751630ee9ba Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 00:40:22 -0600 Subject: [PATCH 060/167] Fix what I broke. --- .../Src/VertexLoader_TextCoord.cpp | 54 ++++++++++++++----- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp index 8bbd1197d5..b5e7d890ff 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp @@ -28,8 +28,20 @@ #include #endif -#define LOG_TEX1() // PRIM_LOG("tex: %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0]); -#define LOG_TEX2() // PRIM_LOG("tex: %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0], ((float*)VertexManager::s_pCurBufferPointer)[1]); +template +void LOG_TEX(); + +template <> +__forceinline void LOG_TEX<1>() +{ + // PRIM_LOG("tex: %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0]); +} + +template <> +__forceinline void LOG_TEX<2>() +{ + // PRIM_LOG("tex: %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0], ((float*)VertexManager::s_pCurBufferPointer)[1]); +} extern int tcIndex; extern float tcScale[8]; @@ -39,14 +51,26 @@ void LOADERDECL TexCoord_Read_Dummy() tcIndex++; } +template +float TCScale(T val) +{ + return val * tcScale[tcIndex]; +} + +template <> +float TCScale(float val) +{ return val; } + template void LOADERDECL TexCoord_ReadDirect() { - reinterpret_cast(VertexManager::s_pCurBufferPointer)[0] = DataRead() * tcScale[tcIndex]; - if (N >= 1) - reinterpret_cast(VertexManager::s_pCurBufferPointer)[1] = DataRead() * tcScale[tcIndex]; - //LOG_TEX1(); - //LOG_TEX2(); + auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); + + for (int i = 0; i != N; ++i) + dest[i] = TCScale(DataRead()); + + LOG_TEX(); + VertexManager::s_pCurBufferPointer += sizeof(float) * N; ++tcIndex; } @@ -57,12 +81,16 @@ void LOADERDECL TexCoord_ReadIndex() static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); auto const index = DataRead(); - auto const data = reinterpret_cast(cached_arraybases[ARRAY_TEXCOORD0 + tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0 + tcIndex])); - reinterpret_cast(VertexManager::s_pCurBufferPointer)[0] = Common::FromBigEndian(data[0]) * tcScale[tcIndex]; - if (N >= 1) - reinterpret_cast(VertexManager::s_pCurBufferPointer)[1] = Common::FromBigEndian(data[1]) * tcScale[tcIndex]; - //LOG_TEX1(); - //LOG_TEX2(); + auto const data = reinterpret_cast(cached_arraybases[ARRAY_TEXCOORD0 + tcIndex] + + (index * arraystrides[ARRAY_TEXCOORD0 + tcIndex])); + + auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); + + for (int i = 0; i != N; ++i) + dest[i] = TCScale(Common::FromBigEndian(data[i])); + + LOG_TEX(); + VertexManager::s_pCurBufferPointer += sizeof(float) * N; ++tcIndex; } From 5efdcef34ad06a94c36a7cf7c1e84bbaee26d215 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 00:49:47 -0600 Subject: [PATCH 061/167] No longer have the signed/unsigned hack I guess. --- .../VideoCommon/Src/VertexLoader_Normal.cpp | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp index a53425b1ec..34a3190eff 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp @@ -46,6 +46,7 @@ float FracAdjust(T val) //auto const S16FRAC = 1.f / (1u << 14); //auto const U16FRAC = 1.f / (1u << 15); + // TODO: is this right? return val / float(1u << (sizeof(T) * 8 - std::numeric_limits::is_signed - 1)); } @@ -106,70 +107,69 @@ void LOADERDECL Normal_Index_Indices3() void VertexLoader_Normal::Init(void) { - // HACK is for signed instead of unsigned to prevent crashes. - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); //HACK + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_Direct); m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_Direct); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index); m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(3, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(3, Normal_Index_Indices3); m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(3, Normal_Index_Indices3); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(3, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(3, Normal_Index_Indices3); m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(3, Normal_Index_Indices3); m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(3, Normal_Index_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index); m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(6, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(6, Normal_Index_Indices3); m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(6, Normal_Index_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(6, Normal_Index_Indices3); //HACK + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(6, Normal_Index_Indices3); m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(6, Normal_Index_Indices3); m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(6, Normal_Index_Indices3); } From 660fc129275dc92e4f6f99bb497f83b2da58992a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 02:00:27 -0600 Subject: [PATCH 062/167] Cleanup Position loader functions. --- .../VideoCommon/Src/VertexLoader_Position.cpp | 266 +++++------------- 1 file changed, 69 insertions(+), 197 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp index 06481f9ddf..3fa74fb747 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp @@ -15,6 +15,8 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include + #include "Common.h" #include "VideoCommon.h" #include "VertexLoader.h" @@ -71,101 +73,52 @@ MOVUPS(MOffset(EDI, 0), XMM0); */ -// ============================================================================== -// Direct -// ============================================================================== - -template -void Pos_ReadDirect() +template +float PosScale(T val) { - ((float*)VertexManager::s_pCurBufferPointer)[0] = (float)(T)DataRead() * posScale; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)(T)DataRead() * posScale; - if (three) - ((float*)VertexManager::s_pCurBufferPointer)[2] = (float)(T)DataRead() * posScale; - else - ((float*)VertexManager::s_pCurBufferPointer)[2] = 0.0f; + return val * posScale; +} + +template <> +float PosScale(float val) +{ return val; } + +template +LOADERDECL void Pos_ReadDirect() +{ + static_assert(N <= 3, "N > 3 is not sane!"); + + auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); + for (int i = 0; i != N; ++i) + dest[i] = PosScale(DataRead()); + + for (int i = N; i != 3; ++i) + dest[i] = 0.f; + LOG_VTX(); - VertexManager::s_pCurBufferPointer += 12; + VertexManager::s_pCurBufferPointer += sizeof(float) * 3; } -void LOADERDECL Pos_ReadDirect_UByte3() { Pos_ReadDirect(); } -void LOADERDECL Pos_ReadDirect_Byte3() { Pos_ReadDirect(); } -void LOADERDECL Pos_ReadDirect_UShort3() { Pos_ReadDirect(); } -void LOADERDECL Pos_ReadDirect_Short3() { Pos_ReadDirect(); } -void LOADERDECL Pos_ReadDirect_UByte2() { Pos_ReadDirect(); } -void LOADERDECL Pos_ReadDirect_Byte2() { Pos_ReadDirect(); } -void LOADERDECL Pos_ReadDirect_UShort2() { Pos_ReadDirect(); } -void LOADERDECL Pos_ReadDirect_Short2() { Pos_ReadDirect(); } - -void LOADERDECL Pos_ReadDirect_Float3() +template +LOADERDECL void Pos_ReadIndex() { - // No need to use floating point here. - ((u32 *)VertexManager::s_pCurBufferPointer)[0] = DataReadU32(); - ((u32 *)VertexManager::s_pCurBufferPointer)[1] = DataReadU32(); - ((u32 *)VertexManager::s_pCurBufferPointer)[2] = DataReadU32(); - LOG_VTX(); - VertexManager::s_pCurBufferPointer += 12; -} - -void LOADERDECL Pos_ReadDirect_Float2() -{ - // No need to use floating point here. - ((u32 *)VertexManager::s_pCurBufferPointer)[0] = DataReadU32(); - ((u32 *)VertexManager::s_pCurBufferPointer)[1] = DataReadU32(); - ((u32 *)VertexManager::s_pCurBufferPointer)[2] = 0; - LOG_VTX(); - VertexManager::s_pCurBufferPointer += 12; -} - - -template -inline void Pos_ReadIndex_Byte(int Index) -{ - if(Index < MaxSize) + static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); + static_assert(N <= 3, "N > 3 is not sane!"); + + auto const index = DataRead(); + if (index < std::numeric_limits::max()) { - const u8* pData = cached_arraybases[ARRAY_POSITION] + ((u32)Index * arraystrides[ARRAY_POSITION]); - ((float*)VertexManager::s_pCurBufferPointer)[0] = ((float)(T)(pData[0])) * posScale; - ((float*)VertexManager::s_pCurBufferPointer)[1] = ((float)(T)(pData[1])) * posScale; - if (three) - ((float*)VertexManager::s_pCurBufferPointer)[2] = ((float)(T)(pData[2])) * posScale; - else - ((float*)VertexManager::s_pCurBufferPointer)[2] = 0.0f; + auto const data = reinterpret_cast(cached_arraybases[ARRAY_POSITION] + (index * arraystrides[ARRAY_POSITION])); + auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); + + for (int i = 0; i != N; ++i) + dest[i] = PosScale(Common::FromBigEndian(data[i])); + + for (int i = N; i != 3; ++i) + dest[i] = 0.f + LOG_VTX(); - VertexManager::s_pCurBufferPointer += 12; - } -} - -template -inline void Pos_ReadIndex_Short(int Index) -{ - if(Index < MaxSize) - { - const u16* pData = (const u16 *)(cached_arraybases[ARRAY_POSITION] + ((u32)Index * arraystrides[ARRAY_POSITION])); - ((float*)VertexManager::s_pCurBufferPointer)[0] = ((float)(T)Common::swap16(pData[0])) * posScale; - ((float*)VertexManager::s_pCurBufferPointer)[1] = ((float)(T)Common::swap16(pData[1])) * posScale; - if (three) - ((float*)VertexManager::s_pCurBufferPointer)[2] = ((float)(T)Common::swap16(pData[2])) * posScale; - else - ((float*)VertexManager::s_pCurBufferPointer)[2] = 0.0f; - LOG_VTX(); - VertexManager::s_pCurBufferPointer += 12; - } -} - -template -void Pos_ReadIndex_Float(int Index) -{ - if(Index < MaxSize) - { - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION])); - ((u32*)VertexManager::s_pCurBufferPointer)[0] = Common::swap32(pData[0]); - ((u32*)VertexManager::s_pCurBufferPointer)[1] = Common::swap32(pData[1]); - if (three) - ((u32*)VertexManager::s_pCurBufferPointer)[2] = Common::swap32(pData[2]); - else - ((float*)VertexManager::s_pCurBufferPointer)[2] = 0.0f; - LOG_VTX(); - VertexManager::s_pCurBufferPointer += 12; + VertexManager::s_pCurBufferPointer += sizeof(float) * 3; } } @@ -173,87 +126,22 @@ void Pos_ReadIndex_Float(int Index) static const __m128i kMaskSwap32_3 = _mm_set_epi32(0xFFFFFFFFL, 0x08090A0BL, 0x04050607L, 0x00010203L); static const __m128i kMaskSwap32_2 = _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L); -template -void Pos_ReadIndex_Float_SSSE3(int Index) +template +LOADERDECL void Pos_ReadIndex_Float_SSSE3() { - if(Index < MaxSize) + auto const index = DataRead(); + if (index < std::numeric_limits::max()) { const u32* pData = (const u32 *)(cached_arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION])); GC_ALIGNED128(const __m128i a = _mm_loadu_si128((__m128i*)pData)); GC_ALIGNED128(__m128i b = _mm_shuffle_epi8(a, three ? kMaskSwap32_3 : kMaskSwap32_2)); _mm_storeu_si128((__m128i*)VertexManager::s_pCurBufferPointer, b); LOG_VTX(); - VertexManager::s_pCurBufferPointer += 12; + VertexManager::s_pCurBufferPointer += sizeof(float) * 3; } } #endif -// Explicitly instantiate these functions to decrease the possibility of -// symbol binding problems when (only) calling them from JIT compiled code. -template void Pos_ReadDirect(); -template void Pos_ReadDirect(); -template void Pos_ReadDirect(); -template void Pos_ReadDirect(); -template void Pos_ReadDirect(); -template void Pos_ReadDirect(); -template void Pos_ReadDirect(); -template void Pos_ReadDirect(); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Float(int Index); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Float(int Index); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Float(int Index); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Byte(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Short(int Index); -template void Pos_ReadIndex_Float(int Index); - -// ============================================================================== -// Index 8 -// ============================================================================== -void LOADERDECL Pos_ReadIndex8_UByte3() {Pos_ReadIndex_Byte (DataReadU8());} -void LOADERDECL Pos_ReadIndex8_Byte3() {Pos_ReadIndex_Byte (DataReadU8());} -void LOADERDECL Pos_ReadIndex8_UShort3() {Pos_ReadIndex_Short (DataReadU8());} -void LOADERDECL Pos_ReadIndex8_Short3() {Pos_ReadIndex_Short (DataReadU8());} -void LOADERDECL Pos_ReadIndex8_Float3() {Pos_ReadIndex_Float (DataReadU8());} -void LOADERDECL Pos_ReadIndex8_UByte2() {Pos_ReadIndex_Byte(DataReadU8());} -void LOADERDECL Pos_ReadIndex8_Byte2() {Pos_ReadIndex_Byte(DataReadU8());} -void LOADERDECL Pos_ReadIndex8_UShort2() {Pos_ReadIndex_Short(DataReadU8());} -void LOADERDECL Pos_ReadIndex8_Short2() {Pos_ReadIndex_Short(DataReadU8());} -void LOADERDECL Pos_ReadIndex8_Float2() {Pos_ReadIndex_Float (DataReadU8());} - -// ============================================================================== -// Index 16 -// ============================================================================== -void LOADERDECL Pos_ReadIndex16_UByte3() {Pos_ReadIndex_Byte (DataReadU16());} -void LOADERDECL Pos_ReadIndex16_Byte3() {Pos_ReadIndex_Byte (DataReadU16());} -void LOADERDECL Pos_ReadIndex16_UShort3() {Pos_ReadIndex_Short (DataReadU16());} -void LOADERDECL Pos_ReadIndex16_Short3() {Pos_ReadIndex_Short (DataReadU16());} -void LOADERDECL Pos_ReadIndex16_Float3() {Pos_ReadIndex_Float (DataReadU16());} -void LOADERDECL Pos_ReadIndex16_UByte2() {Pos_ReadIndex_Byte(DataReadU16());} -void LOADERDECL Pos_ReadIndex16_Byte2() {Pos_ReadIndex_Byte(DataReadU16());} -void LOADERDECL Pos_ReadIndex16_UShort2() {Pos_ReadIndex_Short(DataReadU16());} -void LOADERDECL Pos_ReadIndex16_Short2() {Pos_ReadIndex_Short(DataReadU16());} -void LOADERDECL Pos_ReadIndex16_Float2() {Pos_ReadIndex_Float (DataReadU16());} - -#if _M_SSE >= 0x301 -void LOADERDECL Pos_ReadIndex8_Float3_SSSE3() {Pos_ReadIndex_Float_SSSE3 (DataReadU8());} -void LOADERDECL Pos_ReadIndex8_Float2_SSSE3() {Pos_ReadIndex_Float_SSSE3 (DataReadU8());} -void LOADERDECL Pos_ReadIndex16_Float3_SSSE3() {Pos_ReadIndex_Float_SSSE3 (DataReadU16());} -void LOADERDECL Pos_ReadIndex16_Float2_SSSE3() {Pos_ReadIndex_Float_SSSE3 (DataReadU16());} -#endif - static TPipelineFunction tableReadPosition[4][8][2] = { { {NULL, NULL,}, @@ -263,56 +151,40 @@ static TPipelineFunction tableReadPosition[4][8][2] = { {NULL, NULL,}, }, { - {Pos_ReadDirect_UByte2, Pos_ReadDirect_UByte3,}, - {Pos_ReadDirect_Byte2, Pos_ReadDirect_Byte3,}, - {Pos_ReadDirect_UShort2, Pos_ReadDirect_UShort3,}, - {Pos_ReadDirect_Short2, Pos_ReadDirect_Short3,}, - {Pos_ReadDirect_Float2, Pos_ReadDirect_Float3,}, + {Pos_ReadDirect, Pos_ReadDirect,}, + {Pos_ReadDirect, Pos_ReadDirect,}, + {Pos_ReadDirect, Pos_ReadDirect,}, + {Pos_ReadDirect, Pos_ReadDirect,}, + {Pos_ReadDirect, Pos_ReadDirect,}, }, { - {Pos_ReadIndex8_UByte2, Pos_ReadIndex8_UByte3,}, - {Pos_ReadIndex8_Byte2, Pos_ReadIndex8_Byte3,}, - {Pos_ReadIndex8_UShort2, Pos_ReadIndex8_UShort3,}, - {Pos_ReadIndex8_Short2, Pos_ReadIndex8_Short3,}, - {Pos_ReadIndex8_Float2, Pos_ReadIndex8_Float3,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, }, { - {Pos_ReadIndex16_UByte2, Pos_ReadIndex16_UByte3,}, - {Pos_ReadIndex16_Byte2, Pos_ReadIndex16_Byte3,}, - {Pos_ReadIndex16_UShort2, Pos_ReadIndex16_UShort3,}, - {Pos_ReadIndex16_Short2, Pos_ReadIndex16_Short3,}, - {Pos_ReadIndex16_Float2, Pos_ReadIndex16_Float3,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, + {Pos_ReadIndex, Pos_ReadIndex,}, }, }; static int tableReadPositionVertexSize[4][8][2] = { { - {0, 0,}, - {0, 0,}, - {0, 0,}, - {0, 0,}, - {0, 0,}, + {0, 0,}, {0, 0,}, {0, 0,}, {0, 0,}, {0, 0,}, }, { - {2, 3,}, - {2, 3,}, - {4, 6,}, - {4, 6,}, - {8, 12,}, + {2, 3,}, {2, 3,}, {4, 6,}, {4, 6,}, {8, 12,}, }, { - {1, 1,}, - {1, 1,}, - {1, 1,}, - {1, 1,}, - {1, 1,}, + {1, 1,}, {1, 1,}, {1, 1,}, {1, 1,}, {1, 1,}, }, { - {2, 2,}, - {2, 2,}, - {2, 2,}, - {2, 2,}, - {2, 2,}, + {2, 2,}, {2, 2,}, {2, 2,}, {2, 2,}, {2, 2,}, }, }; @@ -322,10 +194,10 @@ void VertexLoader_Position::Init(void) { #if _M_SSE >= 0x301 if (cpu_info.bSSSE3) { - tableReadPosition[2][4][0] = Pos_ReadIndex8_Float2_SSSE3; - tableReadPosition[2][4][1] = Pos_ReadIndex8_Float3_SSSE3; - tableReadPosition[3][4][0] = Pos_ReadIndex16_Float2_SSSE3; - tableReadPosition[3][4][1] = Pos_ReadIndex16_Float3_SSSE3; + tableReadPosition[2][4][0] = Pos_ReadIndex_Float_SSSE3; + tableReadPosition[2][4][1] = Pos_ReadIndex_Float_SSSE3; + tableReadPosition[3][4][0] = Pos_ReadIndex_Float_SSSE3; + tableReadPosition[3][4][1] = Pos_ReadIndex_Float_SSSE3; } #endif From dc776a19a01f730f2d21496a1403fbdda35cbc7e Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 02:49:17 -0600 Subject: [PATCH 063/167] Cleanup VertexLoader's Color functions a bit. --- .../VideoCommon/Src/VertexLoader_Color.cpp | 92 ++++++++----------- 1 file changed, 37 insertions(+), 55 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp index 9cfa5efc31..ce2c970fb9 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp @@ -15,9 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#ifndef _VERTEXLOADERCOLOR_H -#define _VERTEXLOADERCOLOR_H - #include "Common.h" #include "VideoCommon.h" #include "LookUpTables.h" @@ -132,80 +129,65 @@ void LOADERDECL Color_ReadDirect_32b_8888() _SetCol(col); } - - -void LOADERDECL Color_ReadIndex8_16b_565() +template +void Color_ReadIndex_16b_565() { - u8 Index = DataReadU8(); + auto const Index = DataRead(); u16 val = Common::swap16(*(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]))); _SetCol565(val); } -void LOADERDECL Color_ReadIndex8_24b_888() + +template +void Color_ReadIndex_24b_888() { - u8 Index = DataReadU8(); + auto const Index = DataRead(); const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); _SetCol(_Read24(iAddress)); } -void LOADERDECL Color_ReadIndex8_32b_888x() + +template +void Color_ReadIndex_32b_888x() { - u8 Index = DataReadU8(); + auto const Index = DataRead(); const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); _SetCol(_Read24(iAddress)); } -void LOADERDECL Color_ReadIndex8_16b_4444() + +template +void Color_ReadIndex_16b_4444() { - u8 Index = DataReadU8(); + auto const Index = DataRead(); u16 val = *(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex])); _SetCol4444(val); } -void LOADERDECL Color_ReadIndex8_24b_6666() + +template +void Color_ReadIndex_24b_6666() { - u8 Index = DataReadU8(); + auto const Index = DataRead(); const u8* pData = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]) - 1; u32 val = Common::swap32(pData); _SetCol6666(val); } -void LOADERDECL Color_ReadIndex8_32b_8888() + +template +void Color_ReadIndex_32b_8888() { - u8 Index = DataReadU8(); + auto const Index = DataRead(); const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); _SetCol(_Read32(iAddress)); } -void LOADERDECL Color_ReadIndex16_16b_565() -{ - u16 Index = DataReadU16(); - u16 val = Common::swap16(*(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]))); - _SetCol565(val); -} -void LOADERDECL Color_ReadIndex16_24b_888() -{ - u16 Index = DataReadU16(); - const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); - _SetCol(_Read24(iAddress)); -} -void LOADERDECL Color_ReadIndex16_32b_888x() -{ - u16 Index = DataReadU16(); - const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); - _SetCol(_Read24(iAddress)); -} -void LOADERDECL Color_ReadIndex16_16b_4444() -{ - u16 Index = DataReadU16(); - u16 val = *(const u16 *)(cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex])); - _SetCol4444(val); -} -void LOADERDECL Color_ReadIndex16_24b_6666() -{ - u16 Index = DataReadU16(); - const u8 *pData = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]) - 1; - u32 val = Common::swap32(pData); - _SetCol6666(val); -} -void LOADERDECL Color_ReadIndex16_32b_8888() -{ - u16 Index = DataReadU16(); - const u8 *iAddress = cached_arraybases[ARRAY_COLOR+colIndex] + (Index * arraystrides[ARRAY_COLOR+colIndex]); - _SetCol(_Read32(iAddress)); -} -#endif + +void LOADERDECL Color_ReadIndex8_16b_565() { Color_ReadIndex_16b_565(); } +void LOADERDECL Color_ReadIndex8_24b_888() { Color_ReadIndex_24b_888(); } +void LOADERDECL Color_ReadIndex8_32b_888x() { Color_ReadIndex_32b_888x(); } +void LOADERDECL Color_ReadIndex8_16b_4444() { Color_ReadIndex_16b_4444(); } +void LOADERDECL Color_ReadIndex8_24b_6666() { Color_ReadIndex_24b_6666(); } +void LOADERDECL Color_ReadIndex8_32b_8888() { Color_ReadIndex_32b_8888(); } + +void LOADERDECL Color_ReadIndex16_16b_565() { Color_ReadIndex_16b_565(); } +void LOADERDECL Color_ReadIndex16_24b_888() { Color_ReadIndex_24b_888(); } +void LOADERDECL Color_ReadIndex16_32b_888x() { Color_ReadIndex_32b_888x(); } +void LOADERDECL Color_ReadIndex16_16b_4444() { Color_ReadIndex_16b_4444(); } +void LOADERDECL Color_ReadIndex16_24b_6666() { Color_ReadIndex_24b_6666(); } +void LOADERDECL Color_ReadIndex16_32b_8888() { Color_ReadIndex_32b_8888(); } From 7a89faf13f1d02f9f5d2b01ffa33fe6e8b2c6d99 Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 21 Feb 2013 11:36:10 +0100 Subject: [PATCH 064/167] converting the last vertices again instead of copying from buffer on buffer split for mapping, this buffer must be write only, so we cannot copy anthing. converting again needs more cpu, but should happen rarely --- Source/Core/VideoCommon/Src/VertexLoader.cpp | 63 +++++++++++--------- Source/Core/VideoCommon/Src/VertexLoader.h | 1 + 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index 5bffab8ee7..7eb410fc43 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -571,7 +571,6 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) if (remainingVerts < granularity) { INCSTAT(stats.thisFrame.numBufferSplits); // This buffer full - break current primitive and flush, to switch to the next buffer. - u8* plastptr = VertexManager::s_pCurBufferPointer; if (v - startv > 0) VertexManager::AddVertices(primitive, v - startv + extraverts); VertexManager::Flush(); @@ -581,27 +580,28 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) case 3: // triangle strip, copy last two vertices // a little trick since we have to keep track of signs if (v & 1) { - memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-2*native_stride, native_stride); - memcpy_gc(VertexManager::s_pCurBufferPointer+native_stride, plastptr-native_stride*2, 2*native_stride); - VertexManager::s_pCurBufferPointer += native_stride*3; + g_pVideoData -= m_VertexSize*2; + ConvertVertices(1); + g_pVideoData -= m_VertexSize; + ConvertVertices(2); extraverts = 3; } else { - memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-native_stride*2, native_stride*2); - VertexManager::s_pCurBufferPointer += native_stride*2; + g_pVideoData -= m_VertexSize*2; + ConvertVertices(2); extraverts = 2; } break; case 4: // tri fan, copy first and last vert - memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-native_stride*(v-startv+extraverts), native_stride); - VertexManager::s_pCurBufferPointer += native_stride; - memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-native_stride, native_stride); - VertexManager::s_pCurBufferPointer += native_stride; + g_pVideoData -= m_VertexSize*(v-startv+extraverts); + ConvertVertices(1); + g_pVideoData += m_VertexSize*(v-startv+extraverts-2); + ConvertVertices(1); extraverts = 2; break; case 6: // line strip - memcpy_gc(VertexManager::s_pCurBufferPointer, plastptr-native_stride, native_stride); - VertexManager::s_pCurBufferPointer += native_stride; + g_pVideoData -= m_VertexSize*1; + ConvertVertices(1); extraverts = 1; break; default: @@ -615,22 +615,8 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) if (count - v < remainingVerts) remainingVerts = count - v; - #ifdef USE_JIT - if (remainingVerts > 0) { - loop_counter = remainingVerts; - ((void (*)())(void*)m_compiledCode)(); - } - #else - for (int s = 0; s < remainingVerts; s++) - { - tcIndex = 0; - colIndex = 0; - s_texmtxwrite = s_texmtxread = 0; - for (int i = 0; i < m_numPipelineStages; i++) - m_PipelineStages[i](); - PRIM_LOG("\n"); - } - #endif + ConvertVertices(remainingVerts); + v += remainingVerts; } @@ -639,6 +625,27 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) } +void VertexLoader::ConvertVertices ( int count ) +{ +#ifdef USE_JIT + if (count > 0) { + loop_counter = count; + ((void (*)())(void*)m_compiledCode)(); + } +#else + for (int s = 0; s < count; s++) + { + tcIndex = 0; + colIndex = 0; + s_texmtxwrite = s_texmtxread = 0; + for (int i = 0; i < m_numPipelineStages; i++) + m_PipelineStages[i](); + PRIM_LOG("\n"); + } +#endif +} + + void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int count, u8* Data) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.h b/Source/Core/VideoCommon/Src/VertexLoader.h index 98a57cb9ff..4f4fc19e99 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.h +++ b/Source/Core/VideoCommon/Src/VertexLoader.h @@ -119,6 +119,7 @@ private: void SetVAT(u32 _group0, u32 _group1, u32 _group2); void CompileVertexTranslator(); + void ConvertVertices(int count); void WriteCall(TPipelineFunction); From 0d33e200260978ebeb159e84fbf6a792363b2574 Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 21 Feb 2013 11:41:14 +0100 Subject: [PATCH 065/167] bbox: replace s_pCurBufferPointer with locale buffer, so it can be read without read from the writeonly buffer --- Source/Core/VideoCommon/Src/VertexLoader.cpp | 40 +++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index 7eb410fc43..23064dec9a 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -72,6 +72,10 @@ int colElements[2]; float posScale; float tcScale[8]; +// bbox must read vertex position, so convert it to this buffer +static float s_bbox_vertex_buffer[3]; +static u8 *s_bbox_pCurBufferPointer_orig; + static const float fractionTable[32] = { 1.0f / (1U << 0), 1.0f / (1U << 1), 1.0f / (1U << 2), 1.0f / (1U << 3), 1.0f / (1U << 4), 1.0f / (1U << 5), 1.0f / (1U << 6), 1.0f / (1U << 7), @@ -99,17 +103,32 @@ void LOADERDECL PosMtx_Write() *VertexManager::s_pCurBufferPointer++ = 0; } +void LOADERDECL UpdateBoundingBoxPrepare() +{ + if (!PixelEngine::bbox_active) + return; + + // set our buffer as videodata buffer, so we will get a copy of the vertex positions + // this is a big hack, but so we can use the same converting function then without bbox + s_bbox_pCurBufferPointer_orig = VertexManager::s_pCurBufferPointer; + VertexManager::s_pCurBufferPointer = (u8*)s_bbox_vertex_buffer; +} + void LOADERDECL UpdateBoundingBox() { if (!PixelEngine::bbox_active) return; + + // reset videodata pointer + VertexManager::s_pCurBufferPointer = s_bbox_pCurBufferPointer_orig; + + // copy vertex pointers + memcpy(VertexManager::s_pCurBufferPointer, s_bbox_vertex_buffer, 12); + VertexManager::s_pCurBufferPointer += 12; - // Truly evil hack, reading backwards from the write pointer. If we were writing to write-only - // memory like we might have been with a D3D vertex buffer, this would have been a bad idea. - float *data = (float *)(VertexManager::s_pCurBufferPointer - 12); // We must transform the just loaded point by the current world and projection matrix - in software. // Then convert to screen space and update the bounding box. - float p[3] = {data[0], data[1], data[2]}; + float p[3] = {s_bbox_vertex_buffer[0], s_bbox_vertex_buffer[1], s_bbox_vertex_buffer[2]}; const float *world_matrix = (float*)xfmem + MatrixIndexA.PosNormalMtxIdx * 4; const float *proj_matrix = &g_fProjectionMatrix[0]; @@ -267,15 +286,16 @@ void VertexLoader::CompileVertexTranslator() if (m_VtxDesc.Tex7MatIdx) {m_VertexSize += 1; m_NativeFmt->m_components |= VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); } // Write vertex position loader - WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements)); + if(g_ActiveConfig.bUseBBox) { + WriteCall(UpdateBoundingBoxPrepare); + WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements)); + WriteCall(UpdateBoundingBox); + } else { + WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements)); + } m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.Position, m_VtxAttr.PosFormat, m_VtxAttr.PosElements); nat_offset += 12; - // OK, so we just got a point. Let's go back and read it for the bounding box. - - if(g_ActiveConfig.bUseBBox) - WriteCall(UpdateBoundingBox); - // Normals vtx_decl.num_normals = 0; if (m_VtxDesc.Normal != NOT_PRESENT) From 66d0c1c301c1a40414a0135d94525dab5198a8eb Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 21 Feb 2013 11:45:29 +0100 Subject: [PATCH 066/167] small cleanups of s_pCurBufferPointer --- Source/Core/VideoCommon/Src/DLCache.cpp | 3 +-- Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp | 1 + Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp | 7 +++---- Source/Core/VideoCommon/Src/VideoCommon.h | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Source/Core/VideoCommon/Src/DLCache.cpp b/Source/Core/VideoCommon/Src/DLCache.cpp index c828ea3a03..86d321114c 100644 --- a/Source/Core/VideoCommon/Src/DLCache.cpp +++ b/Source/Core/VideoCommon/Src/DLCache.cpp @@ -550,8 +550,7 @@ void CompileAndRunDisplayList(u32 address, u32 size, CachedDisplayList *dl) cmd_byte & GX_VAT_MASK, // Vertex loader index (0 - 7) (cmd_byte & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT, numVertices); - u8* EndAddress = VertexManager::s_pCurBufferPointer; - u32 Vdatasize = (u32)(EndAddress - StartAddress); + u32 Vdatasize = (u32)(VertexManager::s_pCurBufferPointer - StartAddress); if (Vdatasize > 0) { // Compile diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp index 830bd3de13..82d04f5ea2 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp @@ -30,6 +30,7 @@ #include #endif +// warning: mapping buffer should be disabled to use this #define LOG_NORM() // PRIM_LOG("norm: %f %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[-3], ((float*)VertexManager::s_pCurBufferPointer)[-2], ((float*)VertexManager::s_pCurBufferPointer)[-1]); VertexLoader_Normal::Set VertexLoader_Normal::m_Table[NUM_NRM_TYPE][NUM_NRM_INDICES][NUM_NRM_ELEMENTS][NUM_NRM_FORMAT]; diff --git a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp index ba3bb73f43..fd6f191ae3 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp @@ -28,6 +28,7 @@ #include #endif +// warning: mapping buffer should be disabled to use this #define LOG_TEX1() // PRIM_LOG("tex: %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0]); #define LOG_TEX2() // PRIM_LOG("tex: %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0], ((float*)VertexManager::s_pCurBufferPointer)[1]); @@ -355,11 +356,9 @@ void LOADERDECL TexCoord_ReadIndex16_Float2_SSSE3() const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); GC_ALIGNED128(const __m128i a = _mm_loadl_epi64((__m128i*)pData)); GC_ALIGNED128(const __m128i b = _mm_shuffle_epi8(a, kMaskSwap32)); - u8* p = VertexManager::s_pCurBufferPointer; - _mm_storel_epi64((__m128i*)p, b); + _mm_storel_epi64((__m128i*)VertexManager::s_pCurBufferPointer, b); LOG_TEX2(); - p += 8; - VertexManager::s_pCurBufferPointer = p; + VertexManager::s_pCurBufferPointer += 8; tcIndex++; } #endif diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index 1eeed20b82..7681d8ba82 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -90,7 +90,7 @@ struct TargetRectangle : public MathUtil::Rectangle #define PRIM_LOG(...) DEBUG_LOG(VIDEO, ##__VA_ARGS__) #endif - +// warning: mapping buffer should be disabled to use this // #define LOG_VTX() DEBUG_LOG(VIDEO, "vtx: %f %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0], ((float*)VertexManager::s_pCurBufferPointer)[1], ((float*)VertexManager::s_pCurBufferPointer)[2]); #define LOG_VTX() From 76e6085e31920b2521074ea871efd6a4129b3614 Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 21 Feb 2013 12:36:29 +0100 Subject: [PATCH 067/167] consistently usage of buffer pointers --- Source/Core/VideoCommon/Src/VertexManagerBase.cpp | 10 ++++++---- Source/Core/VideoCommon/Src/VertexManagerBase.h | 8 +++++--- Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp | 6 +++--- Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp | 10 +++++----- Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp | 6 +++--- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index cd5a01c6b3..6fd1898db6 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -16,8 +16,9 @@ VertexManager *g_vertex_manager; -u8 *VertexManager::s_pCurBufferPointer; u8 *VertexManager::s_pBaseBufferPointer; +u8 *VertexManager::s_pCurBufferPointer; +u8 *VertexManager::s_pEndBufferPointer; u8 *VertexManager::LocalVBuffer; u16 *VertexManager::TIBuffer; @@ -32,6 +33,7 @@ VertexManager::VertexManager() LocalVBuffer = new u8[MAXVBUFFERSIZE]; s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer; + s_pEndBufferPointer = s_pBaseBufferPointer + MAXVBUFFERSIZE; TIBuffer = new u16[MAXIBUFFERSIZE]; LIBuffer = new u16[MAXIBUFFERSIZE]; @@ -42,7 +44,7 @@ VertexManager::VertexManager() void VertexManager::ResetBuffer() { - s_pCurBufferPointer = LocalVBuffer; + s_pCurBufferPointer = s_pBaseBufferPointer; } VertexManager::~VertexManager() @@ -87,7 +89,7 @@ void VertexManager::AddIndices(int primitive, int numVertices) int VertexManager::GetRemainingSize() { - return MAXVBUFFERSIZE - (int)(s_pCurBufferPointer - LocalVBuffer); + return (int)(s_pEndBufferPointer - s_pCurBufferPointer); } int VertexManager::GetRemainingVertices(int primitive) @@ -170,7 +172,7 @@ void VertexManager::Flush() #if (0) void VertexManager::Flush() { - if (LocalVBuffer == s_pCurBufferPointer || Flushed) + if (s_pBaseBufferPointer == s_pCurBufferPointer || Flushed) return; Flushed = true; diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h index f3a4aa72e3..d4608630ca 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.h +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h @@ -30,8 +30,9 @@ public: static void AddVertices(int _primitive, int _numVertices); // TODO: protected? - static u8 *s_pCurBufferPointer; static u8 *s_pBaseBufferPointer; + static u8 *s_pCurBufferPointer; + static u8 *s_pEndBufferPointer; static int GetRemainingSize(); static int GetRemainingVertices(int primitive); @@ -43,7 +44,7 @@ public: static u16* GetTriangleIndexBuffer() { return TIBuffer; } static u16* GetLineIndexBuffer() { return LIBuffer; } static u16* GetPointIndexBuffer() { return PIBuffer; } - static u8* GetVertexBuffer() { return LocalVBuffer; } + static u8* GetVertexBuffer() { return s_pBaseBufferPointer; } static void DoState(PointerWrap& p); virtual void CreateDeviceObjects(){}; @@ -52,7 +53,6 @@ protected: // TODO: make private after Flush() is merged static void ResetBuffer(); - static u8 *LocalVBuffer; static u16 *TIBuffer; static u16 *LIBuffer; static u16 *PIBuffer; @@ -67,6 +67,8 @@ private: //virtual void Draw(u32 stride, bool alphapass) = 0; // temp virtual void vFlush() = 0; + + static u8 *LocalVBuffer; }; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index ab8ed68654..b227a4d27b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -104,7 +104,7 @@ void VertexManager::LoadBuffers() { D3D11_MAPPED_SUBRESOURCE map; - UINT vSize = UINT(s_pCurBufferPointer - LocalVBuffer); + UINT vSize = UINT(s_pCurBufferPointer - s_pBaseBufferPointer); D3D11_MAP MapType = D3D11_MAP_WRITE_NO_OVERWRITE; if (m_vertexBufferCursor + vSize >= VBUFFER_SIZE) { @@ -116,7 +116,7 @@ void VertexManager::LoadBuffers() D3D::context->Map(m_vertexBuffers[m_activeVertexBuffer], 0, MapType, 0, &map); - memcpy((u8*)map.pData + m_vertexBufferCursor, LocalVBuffer, vSize); + memcpy((u8*)map.pData + m_vertexBufferCursor, s_pBaseBufferPointer, vSize); D3D::context->Unmap(m_vertexBuffers[m_activeVertexBuffer], 0); m_vertexDrawOffset = m_vertexBufferCursor; m_vertexBufferCursor += vSize; @@ -211,7 +211,7 @@ void VertexManager::Draw(UINT stride) void VertexManager::vFlush() { - if (LocalVBuffer == s_pCurBufferPointer) return; + if (s_pBaseBufferPointer == s_pCurBufferPointer) return; if (Flushed) return; Flushed=true; VideoFifo_CheckEFBAccess(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 661cf36e76..5ca6018fb1 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -173,7 +173,7 @@ void VertexManager::PrepareVBuffers(int stride) DestroyDeviceObjects(); return; } - memcpy(pVertices, LocalVBuffer, datasize); + memcpy(pVertices, s_pBaseBufferPointer, datasize); VBuffers[CurrentVBuffer]->Unlock(); LockMode = D3DLOCK_NOOVERWRITE; @@ -268,7 +268,7 @@ void VertexManager::DrawVA(int stride) 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), TIBuffer, D3DFMT_INDEX16, - LocalVBuffer, + s_pBaseBufferPointer, stride))) { DumpBadShaders(); @@ -282,7 +282,7 @@ void VertexManager::DrawVA(int stride) 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), LIBuffer, D3DFMT_INDEX16, - LocalVBuffer, + s_pBaseBufferPointer, stride))) { DumpBadShaders(); @@ -296,7 +296,7 @@ void VertexManager::DrawVA(int stride) 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), PIBuffer, D3DFMT_INDEX16, - LocalVBuffer, + s_pBaseBufferPointer, stride))) { DumpBadShaders(); @@ -307,7 +307,7 @@ void VertexManager::DrawVA(int stride) void VertexManager::vFlush() { - if (LocalVBuffer == s_pCurBufferPointer) return; + if (s_pBaseBufferPointer == s_pCurBufferPointer) return; if (Flushed) return; Flushed = true; VideoFifo_CheckEFBAccess(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 6ea10fc077..5a07f42662 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -100,7 +100,7 @@ void VertexManager::Draw() void VertexManager::vFlush() { - if (LocalVBuffer == s_pCurBufferPointer) return; + if (s_pBaseBufferPointer == s_pCurBufferPointer) return; if (Flushed) return; Flushed=true; VideoFifo_CheckEFBAccess(); @@ -135,7 +135,7 @@ void VertexManager::vFlush() (void)GL_REPORT_ERROR(); //glBindBuffer(GL_ARRAY_BUFFER, s_vboBuffers[s_nCurVBOIndex]); - //glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - LocalVBuffer, LocalVBuffer, GL_STREAM_DRAW); + //glBufferData(GL_ARRAY_BUFFER, s_pCurBufferPointer - s_pBaseBufferPointer, s_pBaseBufferPointer, GL_STREAM_DRAW); GL_REPORT_ERRORD(); // setup the pointers @@ -240,7 +240,7 @@ void VertexManager::vFlush() GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); //s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers); - s_pCurBufferPointer = LocalVBuffer; + s_pCurBufferPointer = s_pBaseBufferPointer; IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer); #if defined(_DEBUG) || defined(DEBUGFAST) From 4b4dce1bd9bba3d1d12d23343d58c4040ae09c3a Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 21 Feb 2013 13:00:19 +0100 Subject: [PATCH 068/167] build fix --- Source/Core/VideoCommon/Src/VertexLoader_Position.cpp | 8 ++++---- Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp index 3fa74fb747..14f2819260 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp @@ -84,7 +84,7 @@ float PosScale(float val) { return val; } template -LOADERDECL void Pos_ReadDirect() +void LOADERDECL Pos_ReadDirect() { static_assert(N <= 3, "N > 3 is not sane!"); @@ -100,7 +100,7 @@ LOADERDECL void Pos_ReadDirect() } template -LOADERDECL void Pos_ReadIndex() +void LOADERDECL Pos_ReadIndex() { static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); static_assert(N <= 3, "N > 3 is not sane!"); @@ -127,12 +127,12 @@ static const __m128i kMaskSwap32_3 = _mm_set_epi32(0xFFFFFFFFL, 0x08090A0BL, 0x0 static const __m128i kMaskSwap32_2 = _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L); template -LOADERDECL void Pos_ReadIndex_Float_SSSE3() +void LOADERDECL Pos_ReadIndex_Float_SSSE3() { auto const index = DataRead(); if (index < std::numeric_limits::max()) { - const u32* pData = (const u32 *)(cached_arraybases[ARRAY_POSITION] + (Index * arraystrides[ARRAY_POSITION])); + const u32* pData = (const u32 *)(cached_arraybases[ARRAY_POSITION] + (index * arraystrides[ARRAY_POSITION])); GC_ALIGNED128(const __m128i a = _mm_loadu_si128((__m128i*)pData)); GC_ALIGNED128(__m128i b = _mm_shuffle_epi8(a, three ? kMaskSwap32_3 : kMaskSwap32_2)); _mm_storeu_si128((__m128i*)VertexManager::s_pCurBufferPointer, b); diff --git a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp index 33efe33bdf..52f9d26ad3 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp @@ -112,7 +112,7 @@ void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() const __m128 e = _mm_load1_ps(&tcScale[tcIndex]); const __m128 f = _mm_mul_ps(d, e); _mm_storeu_ps((float*)VertexManager::s_pCurBufferPointer, f); - LOG_TEX2(); + LOG_TEX<2>(); VertexManager::s_pCurBufferPointer += 8; tcIndex++; } @@ -128,7 +128,7 @@ void LOADERDECL TexCoord_ReadIndex16_Float2_SSSE3() GC_ALIGNED128(const __m128i a = _mm_loadl_epi64((__m128i*)pData)); GC_ALIGNED128(const __m128i b = _mm_shuffle_epi8(a, kMaskSwap32)); _mm_storel_epi64((__m128i*)VertexManager::s_pCurBufferPointer, b); - LOG_TEX2(); + LOG_TEX<2>(); VertexManager::s_pCurBufferPointer += 8; tcIndex++; } From c7f4d6b9ac9860532b8c84d6fde5ba4b80dca08d Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 21 Feb 2013 13:45:48 +0100 Subject: [PATCH 069/167] wrapper for s_pCurBufferPointer --- Source/Core/VideoCommon/Src/DataReader.h | 9 +++++++++ .../VideoCommon/Src/VertexLoader_Color.cpp | 3 +-- .../VideoCommon/Src/VertexLoader_Normal.cpp | 7 ++----- .../VideoCommon/Src/VertexLoader_Position.cpp | 20 +++++-------------- .../Src/VertexLoader_TextCoord.cpp | 19 ++++++------------ Source/Core/VideoCommon/Src/VideoCommon.h | 2 +- 6 files changed, 24 insertions(+), 36 deletions(-) diff --git a/Source/Core/VideoCommon/Src/DataReader.h b/Source/Core/VideoCommon/Src/DataReader.h index 00dca77134..03061229c0 100644 --- a/Source/Core/VideoCommon/Src/DataReader.h +++ b/Source/Core/VideoCommon/Src/DataReader.h @@ -20,6 +20,8 @@ #ifndef _DATAREADER_H #define _DATAREADER_H +#include "VertexManagerBase.h" + extern u8* g_pVideoData; #if _M_SSE >= 0x301 && !(defined __GNUC__ && !defined __SSSE3__) @@ -145,4 +147,11 @@ __forceinline u8* DataGetPosition() return g_pVideoData; } +template +__forceinline void DataWrite(T data) +{ + *(T*)VertexManager::s_pCurBufferPointer = data; + VertexManager::s_pCurBufferPointer += sizeof(T); +} + #endif diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp index ce2c970fb9..fa1ecbe973 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Color.cpp @@ -34,8 +34,7 @@ extern int colElements[2]; __forceinline void _SetCol(u32 val) { - *(u32*)VertexManager::s_pCurBufferPointer = val; - VertexManager::s_pCurBufferPointer += 4; + DataWrite(val); colIndex++; } diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp index 4102fdff69..0b7a37926e 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp @@ -59,16 +59,13 @@ template inline void ReadIndirect(const T* data) { static_assert(3 == N || 9 == N, "N is only sane as 3 or 9!"); - - auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); for (int i = 0; i != N; ++i) { - dest[i] = FracAdjust(Common::FromBigEndian(data[i])); - LOG_NORM(); + DataWrite(FracAdjust(Common::FromBigEndian(data[i]))); } - VertexManager::s_pCurBufferPointer += sizeof(float) * N; + LOG_NORM(); } template diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp index 14f2819260..ce7a38b8c3 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Position.cpp @@ -88,15 +88,10 @@ void LOADERDECL Pos_ReadDirect() { static_assert(N <= 3, "N > 3 is not sane!"); - auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); - for (int i = 0; i != N; ++i) - dest[i] = PosScale(DataRead()); - - for (int i = N; i != 3; ++i) - dest[i] = 0.f; + for (int i = 0; i < 3; ++i) + DataWrite(i()) : 0.f); LOG_VTX(); - VertexManager::s_pCurBufferPointer += sizeof(float) * 3; } template @@ -109,16 +104,11 @@ void LOADERDECL Pos_ReadIndex() if (index < std::numeric_limits::max()) { auto const data = reinterpret_cast(cached_arraybases[ARRAY_POSITION] + (index * arraystrides[ARRAY_POSITION])); - auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); - for (int i = 0; i != N; ++i) - dest[i] = PosScale(Common::FromBigEndian(data[i])); - - for (int i = N; i != 3; ++i) - dest[i] = 0.f + for (int i = 0; i < 3; ++i) + DataWrite(i __forceinline void LOG_TEX<1>() { // warning: mapping buffer should be disabled to use this - // PRIM_LOG("tex: %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0]); + // PRIM_LOG("tex: %f, ", ((float*)VertexManager::s_pCurBufferPointer)[-1]); } template <> __forceinline void LOG_TEX<2>() { // warning: mapping buffer should be disabled to use this - // PRIM_LOG("tex: %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0], ((float*)VertexManager::s_pCurBufferPointer)[1]); + // PRIM_LOG("tex: %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[-2], ((float*)VertexManager::s_pCurBufferPointer)[-1]); } extern int tcIndex; @@ -66,14 +66,11 @@ float TCScale(float val) template void LOADERDECL TexCoord_ReadDirect() { - auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); - for (int i = 0; i != N; ++i) - dest[i] = TCScale(DataRead()); + DataWrite(TCScale(DataRead())); LOG_TEX(); - VertexManager::s_pCurBufferPointer += sizeof(float) * N; ++tcIndex; } @@ -86,14 +83,10 @@ void LOADERDECL TexCoord_ReadIndex() auto const data = reinterpret_cast(cached_arraybases[ARRAY_TEXCOORD0 + tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0 + tcIndex])); - auto const dest = reinterpret_cast(VertexManager::s_pCurBufferPointer); - for (int i = 0; i != N; ++i) - dest[i] = TCScale(Common::FromBigEndian(data[i])); + DataWrite(TCScale(Common::FromBigEndian(data[i]))); LOG_TEX(); - - VertexManager::s_pCurBufferPointer += sizeof(float) * N; ++tcIndex; } @@ -112,8 +105,8 @@ void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() const __m128 e = _mm_load1_ps(&tcScale[tcIndex]); const __m128 f = _mm_mul_ps(d, e); _mm_storeu_ps((float*)VertexManager::s_pCurBufferPointer, f); - LOG_TEX<2>(); VertexManager::s_pCurBufferPointer += 8; + LOG_TEX<2>(); tcIndex++; } #endif @@ -128,8 +121,8 @@ void LOADERDECL TexCoord_ReadIndex16_Float2_SSSE3() GC_ALIGNED128(const __m128i a = _mm_loadl_epi64((__m128i*)pData)); GC_ALIGNED128(const __m128i b = _mm_shuffle_epi8(a, kMaskSwap32)); _mm_storel_epi64((__m128i*)VertexManager::s_pCurBufferPointer, b); - LOG_TEX<2>(); VertexManager::s_pCurBufferPointer += 8; + LOG_TEX<2>(); tcIndex++; } #endif diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index 7681d8ba82..b15d539611 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -91,7 +91,7 @@ struct TargetRectangle : public MathUtil::Rectangle #endif // warning: mapping buffer should be disabled to use this -// #define LOG_VTX() DEBUG_LOG(VIDEO, "vtx: %f %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[0], ((float*)VertexManager::s_pCurBufferPointer)[1], ((float*)VertexManager::s_pCurBufferPointer)[2]); +// #define LOG_VTX() DEBUG_LOG(VIDEO, "vtx: %f %f %f, ", ((float*)VertexManager::s_pCurBufferPointer)[-3], ((float*)VertexManager::s_pCurBufferPointer)[-2], ((float*)VertexManager::s_pCurBufferPointer)[-1]); #define LOG_VTX() From 29d43ef897275bd200cee0ec4492b1c2052902f3 Mon Sep 17 00:00:00 2001 From: "kostamarino@hotmail.com" Date: Thu, 21 Feb 2013 20:34:45 +0200 Subject: [PATCH 070/167] Gameini database update. Update/additions of Fifa Street and Open Season (fixes issue 5438). Cleanup of DisableWiimoteSpeaker = 1 (aka Alternate wiimote timing) from the database since it is no longer used. Edit the tales of symphonia projection hack. --- Data/User/GameConfig/GF8E69.ini | 8 +- Data/User/GameConfig/GF8P69.ini | 16 ++++ Data/User/GameConfig/GOSE41.ini | 8 +- Data/User/GameConfig/GOSP41.ini | 8 +- Data/User/GameConfig/GOSX41.ini | 8 +- Data/User/GameConfig/PH_PRESETS.ini | 2 +- Data/User/GameConfig/R22E01.ini | 3 +- Data/User/GameConfig/R22J01.ini | 3 +- Data/User/GameConfig/R22P01.ini | 3 +- Data/User/GameConfig/R3ME01.ini | 39 ++++---- Data/User/GameConfig/R3MP01.ini | 39 ++++---- Data/User/GameConfig/R4QE01.ini | 39 ++++---- Data/User/GameConfig/R4QJ01.ini | 39 ++++---- Data/User/GameConfig/R4QK01.ini | 39 ++++---- Data/User/GameConfig/R4QP01.ini | 39 ++++---- Data/User/GameConfig/R5WEA4.ini | 3 +- Data/User/GameConfig/R5WJA4.ini | 3 +- Data/User/GameConfig/R7PE01.ini | 37 ++++---- Data/User/GameConfig/R7PP01.ini | 25 +++-- Data/User/GameConfig/RBWE01.ini | 35 ++++--- Data/User/GameConfig/RBWJ01.ini | 35 ++++--- Data/User/GameConfig/RBWP01.ini | 35 ++++--- Data/User/GameConfig/RCJE8P.ini | 1 - Data/User/GameConfig/RCJP8P.ini | 1 - Data/User/GameConfig/RD2E41.ini | 33 ++++--- Data/User/GameConfig/RD2J41.ini | 33 ++++--- Data/User/GameConfig/RD2K41.ini | 33 ++++--- Data/User/GameConfig/RD2P41.ini | 33 ++++--- Data/User/GameConfig/RD2X41.ini | 33 ++++--- Data/User/GameConfig/RHDE8P.ini | 39 ++++---- Data/User/GameConfig/RHDJ8P.ini | 39 ++++---- Data/User/GameConfig/RHDP8P.ini | 39 ++++---- Data/User/GameConfig/RHOE8P.ini | 77 ++++++++------- Data/User/GameConfig/RHOJ8P.ini | 23 +++-- Data/User/GameConfig/RHOP8P.ini | 23 +++-- Data/User/GameConfig/RLGE64.ini | 1 - Data/User/GameConfig/RLGJ52.ini | 1 - Data/User/GameConfig/RLGP64.ini | 1 - Data/User/GameConfig/RM3E01.ini | 1 - Data/User/GameConfig/RM3J01.ini | 1 - Data/User/GameConfig/RM3P01.ini | 1 - Data/User/GameConfig/RQREXJ.ini | 3 +- Data/User/GameConfig/RQRJAF.ini | 3 +- Data/User/GameConfig/RQRPAF.ini | 3 +- Data/User/GameConfig/RRKE70.ini | 3 +- Data/User/GameConfig/RRKP70.ini | 3 +- Data/User/GameConfig/RTZE08.ini | 39 ++++---- Data/User/GameConfig/RTZJ08.ini | 39 ++++---- Data/User/GameConfig/RTZK08.ini | 39 ++++---- Data/User/GameConfig/RTZP08.ini | 39 ++++---- Data/User/GameConfig/RZJD69.ini | 3 +- Data/User/GameConfig/RZJE69.ini | 3 +- Data/User/GameConfig/RZJJ13.ini | 3 +- Data/User/GameConfig/RZJP69.ini | 3 +- Data/User/GameConfig/RZZE8P.ini | 33 ++++--- Data/User/GameConfig/RZZJEL.ini | 33 ++++--- Data/User/GameConfig/RZZP8P.ini | 33 ++++--- Data/User/GameConfig/SC2E8P.ini | 41 ++++---- Data/User/GameConfig/SC2P8P.ini | 139 ++++++++++++++-------------- Data/User/GameConfig/SD2E41.ini | 3 +- Data/User/GameConfig/SD2J01.ini | 3 +- Data/User/GameConfig/SD2P41.ini | 3 +- Data/User/GameConfig/SD2Y41.ini | 3 +- Data/User/GameConfig/SEME4Q.ini | 3 +- Data/User/GameConfig/SEMJ01.ini | 3 +- Data/User/GameConfig/SEMP4Q.ini | 3 +- Data/User/GameConfig/SEMX4Q.ini | 3 +- Data/User/GameConfig/SEMY4Q.ini | 3 +- Data/User/GameConfig/SEMZ4Q.ini | 3 +- Data/User/GameConfig/SERE4Q.ini | 3 +- Data/User/GameConfig/SERF4Q.ini | 3 +- Data/User/GameConfig/SERP4Q.ini | 3 +- Data/User/GameConfig/SF8E01.ini | 3 +- Data/User/GameConfig/SF8J01.ini | 3 +- Data/User/GameConfig/SF8P01.ini | 3 +- Data/User/GameConfig/SFIE01.ini | 1 - Data/User/GameConfig/SFIP01.ini | 1 - Data/User/GameConfig/SHLPA4.ini | 3 +- Data/User/GameConfig/SJDE41.ini | 1 - Data/User/GameConfig/SJDP41.ini | 1 - Data/User/GameConfig/SJDY41.ini | 1 - Data/User/GameConfig/SJDZ41.ini | 1 - Data/User/GameConfig/SMOE41.ini | 41 ++++---- Data/User/GameConfig/SMOP41.ini | 41 ++++---- Data/User/GameConfig/SMOX41.ini | 41 ++++---- Data/User/GameConfig/SO3EE9.ini | 1 - Data/User/GameConfig/SO3J99.ini | 1 - Data/User/GameConfig/SOJE41.ini | 33 ++++--- Data/User/GameConfig/SOJP41.ini | 33 ++++--- Data/User/GameConfig/SOUE01.ini | 1 - Data/User/GameConfig/SOUJ01.ini | 1 - Data/User/GameConfig/SOUK01.ini | 1 - Data/User/GameConfig/SOUP01.ini | 1 - Data/User/GameConfig/SRQE41.ini | 1 - Data/User/GameConfig/SRQP41.ini | 1 - Data/User/GameConfig/SX3J01.ini | 3 +- Data/User/GameConfig/SX3P01.ini | 3 +- 97 files changed, 769 insertions(+), 832 deletions(-) create mode 100644 Data/User/GameConfig/GF8P69.ini diff --git a/Data/User/GameConfig/GF8E69.ini b/Data/User/GameConfig/GF8E69.ini index 858a62d3d8..5fa4328270 100644 --- a/Data/User/GameConfig/GF8E69.ini +++ b/Data/User/GameConfig/GF8E69.ini @@ -3,7 +3,7 @@ TLBHack = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = +EmulationIssues = The videos are messed up, skip them. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. $Master Code @@ -40,3 +40,9 @@ $Away Team Never Scores 00416F8C 00000000 [Video] ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GF8P69.ini b/Data/User/GameConfig/GF8P69.ini new file mode 100644 index 0000000000..3d6f730434 --- /dev/null +++ b/Data/User/GameConfig/GF8P69.ini @@ -0,0 +1,16 @@ +# GF8P69 - FIFA Street +[Core] Values set here will override the main dolphin settings. +TLBHack = 1 +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = The videos are messed up, skip them. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] diff --git a/Data/User/GameConfig/GOSE41.ini b/Data/User/GameConfig/GOSE41.ini index 4682f2275c..adc124119f 100644 --- a/Data/User/GameConfig/GOSE41.ini +++ b/Data/User/GameConfig/GOSE41.ini @@ -1,9 +1,11 @@ # GOSE41 - Open Season [Core] Values set here will override the main dolphin settings. -TLBHack = 1 +MMU = 1 +FastDiscSpeed = 1 +BlockMerging = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 2 -EmulationIssues = Severe graphic issues. +EmulationStateId = 4 +EmulationIssues = Needs MMU (Slow). [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Video] diff --git a/Data/User/GameConfig/GOSP41.ini b/Data/User/GameConfig/GOSP41.ini index 40fc6ad1f1..cb12055384 100644 --- a/Data/User/GameConfig/GOSP41.ini +++ b/Data/User/GameConfig/GOSP41.ini @@ -1,9 +1,11 @@ # GOSP41 - Open Season [Core] Values set here will override the main dolphin settings. -TLBHack = 1 +MMU = 1 +FastDiscSpeed = 1 +BlockMerging = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 2 -EmulationIssues = Severe graphic issues. +EmulationStateId = 4 +EmulationIssues = Needs MMU (Slow). [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Video] diff --git a/Data/User/GameConfig/GOSX41.ini b/Data/User/GameConfig/GOSX41.ini index 92662f0a4c..8790cdfd8c 100644 --- a/Data/User/GameConfig/GOSX41.ini +++ b/Data/User/GameConfig/GOSX41.ini @@ -1,9 +1,11 @@ # GOSX41 - Open Season [Core] Values set here will override the main dolphin settings. -TLBHack = 1 +MMU = 1 +FastDiscSpeed = 1 +BlockMerging = 1 [EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 2 -EmulationIssues = Severe graphic issues. +EmulationStateId = 4 +EmulationIssues = Needs MMU (Slow). [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Video] diff --git a/Data/User/GameConfig/PH_PRESETS.ini b/Data/User/GameConfig/PH_PRESETS.ini index 8d82d00790..f5e7a4aacf 100644 --- a/Data/User/GameConfig/PH_PRESETS.ini +++ b/Data/User/GameConfig/PH_PRESETS.ini @@ -33,7 +33,7 @@ PH_ExtraParam = 1 [5] Title = Tales of Symphonia GC -PH_ZNear = 0.0002 +PH_ZNear = 0.00026 # --------------------------------------------------- diff --git a/Data/User/GameConfig/R22E01.ini b/Data/User/GameConfig/R22E01.ini index dfe3542671..c494ee5e12 100644 --- a/Data/User/GameConfig/R22E01.ini +++ b/Data/User/GameConfig/R22E01.ini @@ -17,5 +17,4 @@ PH_ZFar = SafeTextureCacheColorSamples = 512 [Video_Hacks] EFBEmulateFormatChanges = True -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/R22J01.ini b/Data/User/GameConfig/R22J01.ini index c38ff20966..94aeac02f3 100644 --- a/Data/User/GameConfig/R22J01.ini +++ b/Data/User/GameConfig/R22J01.ini @@ -17,5 +17,4 @@ PH_ZFar = SafeTextureCacheColorSamples = 512 [Video_Hacks] EFBEmulateFormatChanges = True -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/R22P01.ini b/Data/User/GameConfig/R22P01.ini index 6153cb0d06..8fb637216f 100644 --- a/Data/User/GameConfig/R22P01.ini +++ b/Data/User/GameConfig/R22P01.ini @@ -17,5 +17,4 @@ PH_ZFar = SafeTextureCacheColorSamples = 512 [Video_Hacks] EFBEmulateFormatChanges = True -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/R3ME01.ini b/Data/User/GameConfig/R3ME01.ini index 312d6a15f1..4c891c14b1 100644 --- a/Data/User/GameConfig/R3ME01.ini +++ b/Data/User/GameConfig/R3ME01.ini @@ -1,20 +1,19 @@ -# R3ME01 - Metroid Prime Trilogy -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Disable EuRGB60(PAL60) to avoid a black bar appearing. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Hacks] -EFBToTextureEnable = False -EFBCopyEnable = True -[Wii] -DisableWiimoteSpeaker = 1 +# R3ME01 - Metroid Prime Trilogy +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Disable EuRGB60(PAL60) to avoid a black bar appearing. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True +[Wii] diff --git a/Data/User/GameConfig/R3MP01.ini b/Data/User/GameConfig/R3MP01.ini index 291ac8df38..71938b821a 100644 --- a/Data/User/GameConfig/R3MP01.ini +++ b/Data/User/GameConfig/R3MP01.ini @@ -1,20 +1,19 @@ -# R3MP01 - Metroid Prime Trilogy -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Disable EuRGB60(PAL60) to avoid a black bar appearing. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Hacks] -EFBToTextureEnable = False -EFBCopyEnable = True -[Wii] -DisableWiimoteSpeaker = 1 +# R3MP01 - Metroid Prime Trilogy +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Disable EuRGB60(PAL60) to avoid a black bar appearing. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Hacks] +EFBToTextureEnable = False +EFBCopyEnable = True +[Wii] diff --git a/Data/User/GameConfig/R4QE01.ini b/Data/User/GameConfig/R4QE01.ini index 3ae6cb283a..e822d53161 100644 --- a/Data/User/GameConfig/R4QE01.ini +++ b/Data/User/GameConfig/R4QE01.ini @@ -1,20 +1,19 @@ -# R4QE01 - Mario Strikers Charged -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 5 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Enhancements] -[Video_Hacks] -DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +# R4QE01 - Mario Strikers Charged +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 5 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Enhancements] +[Video_Hacks] +DlistCachingEnable = False +[Wii] diff --git a/Data/User/GameConfig/R4QJ01.ini b/Data/User/GameConfig/R4QJ01.ini index d97cc37c84..14bef2a3e5 100644 --- a/Data/User/GameConfig/R4QJ01.ini +++ b/Data/User/GameConfig/R4QJ01.ini @@ -1,20 +1,19 @@ -# R4QJ01 - Mario Strikers Charged -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 5 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Enhancements] -[Video_Hacks] -DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +# R4QJ01 - Mario Strikers Charged +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 5 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Enhancements] +[Video_Hacks] +DlistCachingEnable = False +[Wii] diff --git a/Data/User/GameConfig/R4QK01.ini b/Data/User/GameConfig/R4QK01.ini index 2c45a961a0..2fb7675fd4 100644 --- a/Data/User/GameConfig/R4QK01.ini +++ b/Data/User/GameConfig/R4QK01.ini @@ -1,20 +1,19 @@ -# R4QK01 - Mario Power Soccer -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 5 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Enhancements] -[Video_Hacks] -DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +# R4QK01 - Mario Power Soccer +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 5 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Enhancements] +[Video_Hacks] +DlistCachingEnable = False +[Wii] diff --git a/Data/User/GameConfig/R4QP01.ini b/Data/User/GameConfig/R4QP01.ini index 8ec96e8cf3..54fa2ec234 100644 --- a/Data/User/GameConfig/R4QP01.ini +++ b/Data/User/GameConfig/R4QP01.ini @@ -1,20 +1,19 @@ -# R4QP01 - Mario Strikers Charged -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 5 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Enhancements] -[Video_Hacks] -DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +# R4QP01 - Mario Strikers Charged +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 5 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Enhancements] +[Video_Hacks] +DlistCachingEnable = False +[Wii] diff --git a/Data/User/GameConfig/R5WEA4.ini b/Data/User/GameConfig/R5WEA4.ini index 315f7f340a..48b1c5cd12 100644 --- a/Data/User/GameConfig/R5WEA4.ini +++ b/Data/User/GameConfig/R5WEA4.ini @@ -15,5 +15,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 512 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/R5WJA4.ini b/Data/User/GameConfig/R5WJA4.ini index 30a983b648..25d6076a05 100644 --- a/Data/User/GameConfig/R5WJA4.ini +++ b/Data/User/GameConfig/R5WJA4.ini @@ -15,5 +15,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 512 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/R7PE01.ini b/Data/User/GameConfig/R7PE01.ini index 1a052239ae..244ccc1db3 100644 --- a/Data/User/GameConfig/R7PE01.ini +++ b/Data/User/GameConfig/R7PE01.ini @@ -1,19 +1,18 @@ -# R7PE01 - Punch Out -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Disable "Use EuRGB60 (PAL60) mode" in the wii configuration tab for the game to run -[OnFrame] Add memory patches to be applied every frame here. -+$Patch -0x8011E0F8:dword:0x4E800020 -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# R7PE01 - Punch Out +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Disable "Use EuRGB60 (PAL60) mode" in the wii configuration tab for the game to run +[OnFrame] Add memory patches to be applied every frame here. ++$Patch +0x8011E0F8:dword:0x4E800020 +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/R7PP01.ini b/Data/User/GameConfig/R7PP01.ini index 302bd1e965..a0113b7415 100644 --- a/Data/User/GameConfig/R7PP01.ini +++ b/Data/User/GameConfig/R7PP01.ini @@ -1,13 +1,12 @@ -# R7PP01 - Punch Out -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = -EmulationStateId = 5 -[OnFrame] Add memory patches to be applied every frame here. -+$Patch -0x8011F1CC:dword:0x4E800020 -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -[Wii] -DisableWiimoteSpeaker = 1 +# R7PP01 - Punch Out +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 5 +[OnFrame] Add memory patches to be applied every frame here. ++$Patch +0x8011F1CC:dword:0x4E800020 +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +[Wii] diff --git a/Data/User/GameConfig/RBWE01.ini b/Data/User/GameConfig/RBWE01.ini index 9e8d586cf4..a2cad6ff7d 100644 --- a/Data/User/GameConfig/RBWE01.ini +++ b/Data/User/GameConfig/RBWE01.ini @@ -1,18 +1,17 @@ -# RBWE01 - Battalion Wars 2 -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs LLE audio for proper sound. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Enhancements] -[Wii] -DisableWiimoteSpeaker = 1 +# RBWE01 - Battalion Wars 2 +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs LLE audio for proper sound. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Enhancements] +[Wii] diff --git a/Data/User/GameConfig/RBWJ01.ini b/Data/User/GameConfig/RBWJ01.ini index bf95ff65c8..0d799c74fa 100644 --- a/Data/User/GameConfig/RBWJ01.ini +++ b/Data/User/GameConfig/RBWJ01.ini @@ -1,18 +1,17 @@ -# RBWJ01 - Totsugeki Famicom Wars vs. -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs LLE audio for proper sound. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Enhancements] -[Wii] -DisableWiimoteSpeaker = 1 +# RBWJ01 - Totsugeki Famicom Wars vs. +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs LLE audio for proper sound. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Enhancements] +[Wii] diff --git a/Data/User/GameConfig/RBWP01.ini b/Data/User/GameConfig/RBWP01.ini index f6282130a5..5422388866 100644 --- a/Data/User/GameConfig/RBWP01.ini +++ b/Data/User/GameConfig/RBWP01.ini @@ -1,18 +1,17 @@ -# RBWP01 - Battalion Wars 2 -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs LLE audio for proper sound. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Enhancements] -[Wii] -DisableWiimoteSpeaker = 1 +# RBWP01 - Battalion Wars 2 +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs LLE audio for proper sound. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Enhancements] +[Wii] diff --git a/Data/User/GameConfig/RCJE8P.ini b/Data/User/GameConfig/RCJE8P.ini index 845f08de77..79280a5609 100644 --- a/Data/User/GameConfig/RCJE8P.ini +++ b/Data/User/GameConfig/RCJE8P.ini @@ -24,6 +24,5 @@ PH_ZFar = [Video_Enhancements] ForceFiltering = False [Wii] -DisableWiimoteSpeaker = 1 [Video_Hacks] DlistCachingEnable = False diff --git a/Data/User/GameConfig/RCJP8P.ini b/Data/User/GameConfig/RCJP8P.ini index 6d82c897e5..5a242b5e4e 100644 --- a/Data/User/GameConfig/RCJP8P.ini +++ b/Data/User/GameConfig/RCJP8P.ini @@ -18,6 +18,5 @@ PH_ZFar = [Video_Enhancements] ForceFiltering = False [Wii] -DisableWiimoteSpeaker = 1 [Video_Hacks] DlistCachingEnable = False diff --git a/Data/User/GameConfig/RD2E41.ini b/Data/User/GameConfig/RD2E41.ini index a93f6359e6..92ca3f53b5 100644 --- a/Data/User/GameConfig/RD2E41.ini +++ b/Data/User/GameConfig/RD2E41.ini @@ -1,17 +1,16 @@ -# RD2E41 - Red Steel 2 -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs real wiimote and motion plus. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RD2E41 - Red Steel 2 +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs real wiimote and motion plus. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RD2J41.ini b/Data/User/GameConfig/RD2J41.ini index 8fccc41c35..2042a71430 100644 --- a/Data/User/GameConfig/RD2J41.ini +++ b/Data/User/GameConfig/RD2J41.ini @@ -1,17 +1,16 @@ -# RD2J41 - Red Steel 2 -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs real wiimote and motion plus. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RD2J41 - Red Steel 2 +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs real wiimote and motion plus. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RD2K41.ini b/Data/User/GameConfig/RD2K41.ini index aa0e90f2b2..93123fa871 100644 --- a/Data/User/GameConfig/RD2K41.ini +++ b/Data/User/GameConfig/RD2K41.ini @@ -1,17 +1,16 @@ -# RD2K41 - Red Steel 2 -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs real wiimote and motion plus. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RD2K41 - Red Steel 2 +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs real wiimote and motion plus. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RD2P41.ini b/Data/User/GameConfig/RD2P41.ini index 7cbf91b22d..8a7e5f7541 100644 --- a/Data/User/GameConfig/RD2P41.ini +++ b/Data/User/GameConfig/RD2P41.ini @@ -1,17 +1,16 @@ -# RD2P41 - Red Steel 2 -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs real wiimote and motion plus. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RD2P41 - Red Steel 2 +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs real wiimote and motion plus. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RD2X41.ini b/Data/User/GameConfig/RD2X41.ini index 6748136cad..53f0716869 100644 --- a/Data/User/GameConfig/RD2X41.ini +++ b/Data/User/GameConfig/RD2X41.ini @@ -1,17 +1,16 @@ -# RD2X41 - Red Steel 2 -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Needs real wiimote and motion plus. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RD2X41 - Red Steel 2 +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Needs real wiimote and motion plus. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RHDE8P.ini b/Data/User/GameConfig/RHDE8P.ini index b49ec93cb8..31d7a2f620 100644 --- a/Data/User/GameConfig/RHDE8P.ini +++ b/Data/User/GameConfig/RHDE8P.ini @@ -1,20 +1,19 @@ -# RHDE8P - THE HOUSE OF THE DEAD 2 AND 3 RETURN -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Settings] -UseXFB = True -UseRealXFB = False -[Wii] -DisableWiimoteSpeaker = 1 +# RHDE8P - THE HOUSE OF THE DEAD 2 AND 3 RETURN +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = False +[Wii] diff --git a/Data/User/GameConfig/RHDJ8P.ini b/Data/User/GameConfig/RHDJ8P.ini index 63e818f737..014c94aaba 100644 --- a/Data/User/GameConfig/RHDJ8P.ini +++ b/Data/User/GameConfig/RHDJ8P.ini @@ -1,20 +1,19 @@ -# RHDJ8P - THE HOUSE OF THE DEAD 2 AND 3 RETURN -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Settings] -UseXFB = True -UseRealXFB = False -[Wii] -DisableWiimoteSpeaker = 1 +# RHDJ8P - THE HOUSE OF THE DEAD 2 AND 3 RETURN +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = False +[Wii] diff --git a/Data/User/GameConfig/RHDP8P.ini b/Data/User/GameConfig/RHDP8P.ini index e932c173fb..6183ad8422 100644 --- a/Data/User/GameConfig/RHDP8P.ini +++ b/Data/User/GameConfig/RHDP8P.ini @@ -1,20 +1,19 @@ -# RHDP8P - THE HOUSE OF THE DEAD 2 AND 3 RETURN -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Settings] -UseXFB = True -UseRealXFB = False -[Wii] -DisableWiimoteSpeaker = 1 +# RHDP8P - THE HOUSE OF THE DEAD 2 AND 3 RETURN +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = False +[Wii] diff --git a/Data/User/GameConfig/RHOE8P.ini b/Data/User/GameConfig/RHOE8P.ini index c28f341fb6..55d697ca52 100644 --- a/Data/User/GameConfig/RHOE8P.ini +++ b/Data/User/GameConfig/RHOE8P.ini @@ -1,39 +1,38 @@ -# RHOE8P - House Of The Dead: OVERKILL -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Use dx11 plugin (r6945) -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -$Infinte Bomb Usage after Getting 1 [g6flavor] -04159D1C 60000000 -$If Score Increase, MAX [ZiT] -C2142134 00000002 -3CA03B9B 38A5C9FF -90A60178 00000000 -$Infinite LIFE [ZiT] -04130ED4 60000000 -$Infinite Bullet [ZiT] -04159FAC 907D0720 -$CASH MAX [ZiT] -C214B118 00000002 -3CA03B9B 38A5C9FF -90A300D8 00000000 -$CASH MAX [ZiT] -C214B110 00000002 -3CA03B9B 38A5C9FF -90A300DC 00000000 -$If Score Increase, MAX [ZiT] -C2152674 00000002 -3CA03B9B 38A5C9FF -90B60178 00000000 -[Wii] -DisableWiimoteSpeaker = 1 +# RHOE8P - House Of The Dead: OVERKILL +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Use dx11 plugin (r6945) +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +$Infinte Bomb Usage after Getting 1 [g6flavor] +04159D1C 60000000 +$If Score Increase, MAX [ZiT] +C2142134 00000002 +3CA03B9B 38A5C9FF +90A60178 00000000 +$Infinite LIFE [ZiT] +04130ED4 60000000 +$Infinite Bullet [ZiT] +04159FAC 907D0720 +$CASH MAX [ZiT] +C214B118 00000002 +3CA03B9B 38A5C9FF +90A300D8 00000000 +$CASH MAX [ZiT] +C214B110 00000002 +3CA03B9B 38A5C9FF +90A300DC 00000000 +$If Score Increase, MAX [ZiT] +C2152674 00000002 +3CA03B9B 38A5C9FF +90B60178 00000000 +[Wii] diff --git a/Data/User/GameConfig/RHOJ8P.ini b/Data/User/GameConfig/RHOJ8P.ini index 3e23f6605c..2eb65c9fc9 100644 --- a/Data/User/GameConfig/RHOJ8P.ini +++ b/Data/User/GameConfig/RHOJ8P.ini @@ -1,12 +1,11 @@ -# RHOJ8P - House Of The Dead: OVERKILL -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Use dx11 plugin (r6945) -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RHOJ8P - House Of The Dead: OVERKILL +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Use dx11 plugin (r6945) +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RHOP8P.ini b/Data/User/GameConfig/RHOP8P.ini index 8e9d0e879d..85a8e2770a 100644 --- a/Data/User/GameConfig/RHOP8P.ini +++ b/Data/User/GameConfig/RHOP8P.ini @@ -1,12 +1,11 @@ -# RHOP8P - House Of The Dead: OVERKILL -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Use dx11 plugin (r6945) -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RHOP8P - House Of The Dead: OVERKILL +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Use dx11 plugin (r6945) +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RLGE64.ini b/Data/User/GameConfig/RLGE64.ini index 505df3c17d..5e66cda379 100644 --- a/Data/User/GameConfig/RLGE64.ini +++ b/Data/User/GameConfig/RLGE64.ini @@ -6,7 +6,6 @@ EmulationIssues = [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/RLGJ52.ini b/Data/User/GameConfig/RLGJ52.ini index 52b8648072..37b4f728d1 100644 --- a/Data/User/GameConfig/RLGJ52.ini +++ b/Data/User/GameConfig/RLGJ52.ini @@ -6,7 +6,6 @@ EmulationIssues = [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/RLGP64.ini b/Data/User/GameConfig/RLGP64.ini index f82d202584..6404bf0a77 100644 --- a/Data/User/GameConfig/RLGP64.ini +++ b/Data/User/GameConfig/RLGP64.ini @@ -6,7 +6,6 @@ EmulationIssues = [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/RM3E01.ini b/Data/User/GameConfig/RM3E01.ini index cb87db9070..182660bd97 100644 --- a/Data/User/GameConfig/RM3E01.ini +++ b/Data/User/GameConfig/RM3E01.ini @@ -21,6 +21,5 @@ SafeTextureCacheColorSamples = 512 EFBToTextureEnable = False EFBCopyEnable = True [Wii] -DisableWiimoteSpeaker = 1 [Video_Hacks] EFBEmulateFormatChanges = True diff --git a/Data/User/GameConfig/RM3J01.ini b/Data/User/GameConfig/RM3J01.ini index 97a88c4c69..50c84d87a9 100644 --- a/Data/User/GameConfig/RM3J01.ini +++ b/Data/User/GameConfig/RM3J01.ini @@ -21,6 +21,5 @@ SafeTextureCacheColorSamples = 512 EFBToTextureEnable = False EFBCopyEnable = True [Wii] -DisableWiimoteSpeaker = 1 [Video_Hacks] EFBEmulateFormatChanges = True diff --git a/Data/User/GameConfig/RM3P01.ini b/Data/User/GameConfig/RM3P01.ini index 093afc15db..0832325938 100644 --- a/Data/User/GameConfig/RM3P01.ini +++ b/Data/User/GameConfig/RM3P01.ini @@ -23,6 +23,5 @@ SafeTextureCacheColorSamples = 512 EFBToTextureEnable = False EFBCopyEnable = True [Wii] -DisableWiimoteSpeaker = 1 [Video_Hacks] EFBEmulateFormatChanges = True diff --git a/Data/User/GameConfig/RQREXJ.ini b/Data/User/GameConfig/RQREXJ.ini index 91a35e540d..48d52b4320 100644 --- a/Data/User/GameConfig/RQREXJ.ini +++ b/Data/User/GameConfig/RQREXJ.ini @@ -16,5 +16,4 @@ EmulationIssues = Needs single core to run properly(r7436). [OnFrame] [ActionReplay] [Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RQRJAF.ini b/Data/User/GameConfig/RQRJAF.ini index c647c4acee..7ae768c3b4 100644 --- a/Data/User/GameConfig/RQRJAF.ini +++ b/Data/User/GameConfig/RQRJAF.ini @@ -16,5 +16,4 @@ EmulationIssues = Needs single core to run properly(r7436). [OnFrame] [ActionReplay] [Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RQRPAF.ini b/Data/User/GameConfig/RQRPAF.ini index 8052e6084b..752c0fa2bd 100644 --- a/Data/User/GameConfig/RQRPAF.ini +++ b/Data/User/GameConfig/RQRPAF.ini @@ -16,5 +16,4 @@ EmulationIssues = Needs single core to run properly(r7436). [OnFrame] [ActionReplay] [Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RRKE70.ini b/Data/User/GameConfig/RRKE70.ini index 621b0dfd09..ebb3188d0b 100644 --- a/Data/User/GameConfig/RRKE70.ini +++ b/Data/User/GameConfig/RRKE70.ini @@ -16,5 +16,4 @@ EmulationIssues = [Gecko] [Video_Hacks] EFBEmulateFormatChanges = True -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RRKP70.ini b/Data/User/GameConfig/RRKP70.ini index c5fc07ede3..e69e07f92e 100644 --- a/Data/User/GameConfig/RRKP70.ini +++ b/Data/User/GameConfig/RRKP70.ini @@ -16,5 +16,4 @@ EmulationIssues = [Gecko] [Video_Hacks] EFBEmulateFormatChanges = True -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RTZE08.ini b/Data/User/GameConfig/RTZE08.ini index ff41b71a06..27524e8236 100644 --- a/Data/User/GameConfig/RTZE08.ini +++ b/Data/User/GameConfig/RTZE08.ini @@ -1,20 +1,19 @@ -# RTZE08 - Zack and Wiki: Quest for Barbaros' Treasure -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = -EmulationStateId = 4 -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Settings] -UseXFB = True -UseRealXFB = False -[Wii] -DisableWiimoteSpeaker = 1 +# RTZE08 - Zack and Wiki: Quest for Barbaros' Treasure +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 4 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = False +[Wii] diff --git a/Data/User/GameConfig/RTZJ08.ini b/Data/User/GameConfig/RTZJ08.ini index 5a62e2c8ca..6a5aa8d6ee 100644 --- a/Data/User/GameConfig/RTZJ08.ini +++ b/Data/User/GameConfig/RTZJ08.ini @@ -1,20 +1,19 @@ -# RTZJ08 - Zack and Wiki: Quest for Barbaros' Treasure -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = -EmulationStateId = 4 -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Settings] -UseXFB = True -UseRealXFB = False -[Wii] -DisableWiimoteSpeaker = 1 +# RTZJ08 - Zack and Wiki: Quest for Barbaros' Treasure +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 4 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = False +[Wii] diff --git a/Data/User/GameConfig/RTZK08.ini b/Data/User/GameConfig/RTZK08.ini index 6a7d00e753..ec333d6bce 100644 --- a/Data/User/GameConfig/RTZK08.ini +++ b/Data/User/GameConfig/RTZK08.ini @@ -1,20 +1,19 @@ -# RTZK08 - Zack and Wiki: Quest for Barbaros' Treasure -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = -EmulationStateId = 4 -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Settings] -UseXFB = True -UseRealXFB = False -[Wii] -DisableWiimoteSpeaker = 1 +# RTZK08 - Zack and Wiki: Quest for Barbaros' Treasure +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 4 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = False +[Wii] diff --git a/Data/User/GameConfig/RTZP08.ini b/Data/User/GameConfig/RTZP08.ini index 8add9d2869..f3b0834049 100644 --- a/Data/User/GameConfig/RTZP08.ini +++ b/Data/User/GameConfig/RTZP08.ini @@ -1,20 +1,19 @@ -# RTZP08 - Zack and Wiki: Quest for Barbaros' Treasure -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = -EmulationStateId = 4 -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Settings] -UseXFB = True -UseRealXFB = False -[Wii] -DisableWiimoteSpeaker = 1 +# RTZP08 - Zack and Wiki: Quest for Barbaros' Treasure +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = +EmulationStateId = 4 +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Settings] +UseXFB = True +UseRealXFB = False +[Wii] diff --git a/Data/User/GameConfig/RZJD69.ini b/Data/User/GameConfig/RZJD69.ini index 671318fd38..848dcba860 100644 --- a/Data/User/GameConfig/RZJD69.ini +++ b/Data/User/GameConfig/RZJD69.ini @@ -17,5 +17,4 @@ PH_ZFar = [Video_Settings] SafeTextureCacheColorSamples = 512 [Video_Enhancements] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RZJE69.ini b/Data/User/GameConfig/RZJE69.ini index a37d3f9223..c48c837a27 100644 --- a/Data/User/GameConfig/RZJE69.ini +++ b/Data/User/GameConfig/RZJE69.ini @@ -17,5 +17,4 @@ PH_ZFar = [Video_Settings] SafeTextureCacheColorSamples = 512 [Video_Enhancements] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RZJJ13.ini b/Data/User/GameConfig/RZJJ13.ini index d109d22a98..24aa98035b 100644 --- a/Data/User/GameConfig/RZJJ13.ini +++ b/Data/User/GameConfig/RZJJ13.ini @@ -17,5 +17,4 @@ PH_ZFar = [Video_Settings] SafeTextureCacheColorSamples = 512 [Video_Enhancements] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RZJP69.ini b/Data/User/GameConfig/RZJP69.ini index 63b230b1da..9fa88eb843 100644 --- a/Data/User/GameConfig/RZJP69.ini +++ b/Data/User/GameConfig/RZJP69.ini @@ -31,6 +31,5 @@ $Rapid Fire [TNTkryzt] [Video_Settings] SafeTextureCacheColorSamples = 512 [Video_Enhancements] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/RZZE8P.ini b/Data/User/GameConfig/RZZE8P.ini index 31859ef891..9c74320a0b 100644 --- a/Data/User/GameConfig/RZZE8P.ini +++ b/Data/User/GameConfig/RZZE8P.ini @@ -1,17 +1,16 @@ -# RZZE8P - MADWORLD -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 5 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RZZE8P - MADWORLD +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 5 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RZZJEL.ini b/Data/User/GameConfig/RZZJEL.ini index 0e6a08334a..6ace0cb90c 100644 --- a/Data/User/GameConfig/RZZJEL.ini +++ b/Data/User/GameConfig/RZZJEL.ini @@ -1,17 +1,16 @@ -# RZZJEL - MADWORLD -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 5 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RZZJEL - MADWORLD +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 5 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/RZZP8P.ini b/Data/User/GameConfig/RZZP8P.ini index 6dc117c26f..ac5bed9812 100644 --- a/Data/User/GameConfig/RZZP8P.ini +++ b/Data/User/GameConfig/RZZP8P.ini @@ -1,17 +1,16 @@ -# RZZP8P - MADWORLD -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 5 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# RZZP8P - MADWORLD +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 5 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/SC2E8P.ini b/Data/User/GameConfig/SC2E8P.ini index ff46b91be8..998d51859d 100644 --- a/Data/User/GameConfig/SC2E8P.ini +++ b/Data/User/GameConfig/SC2E8P.ini @@ -1,21 +1,20 @@ -# SC2E8P - Conduit 2 -[Core] -BlockMerging = 1 -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[EmuState] -EmulationStateId = 4 -EmulationIssues = -[OnFrame] -[ActionReplay] -[Gecko] -[Video_Hacks] -DlistCachingEnable = False -[Video_Settings] -[Wii] -DisableWiimoteSpeaker = 1 +# SC2E8P - Conduit 2 +[Core] +BlockMerging = 1 +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[EmuState] +EmulationStateId = 4 +EmulationIssues = +[OnFrame] +[ActionReplay] +[Gecko] +[Video_Hacks] +DlistCachingEnable = False +[Video_Settings] +[Wii] diff --git a/Data/User/GameConfig/SC2P8P.ini b/Data/User/GameConfig/SC2P8P.ini index a065f8a096..b9f5c5989c 100644 --- a/Data/User/GameConfig/SC2P8P.ini +++ b/Data/User/GameConfig/SC2P8P.ini @@ -1,70 +1,69 @@ -# SC2P8P - Conduit 2 -[Core] -BlockMerging = 1 -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[EmuState] -EmulationStateId = 4 -EmulationIssues = -[OnFrame] -[ActionReplay] -[Gecko] -$Undead Invincibility Mode [Bully@Wiiplaza] -F6000001 80008100 -8001002C 90180000 -D200000C 00000006 -2C110035 40820020 -2C0800F4 40820018 -2C0300A0 40820010 -3C007FFF 6000FFFF -90040000 80040000 -60000000 00000000 -E0000000 80008000 -**Offline Only* -**You are completely untouchable* -*Picture -> http://imageshack.us/photo/my-images/684/sc2p8p008.png/ -$Inf. Ammo [Bully@Wiiplaza] -F6000001 80008100 -80640000 80050000 -D2000008 00000003 -2C110021 4082000C -38600000 7C030050 -60000000 00000000 -E0000000 80008000 -**Offline Only* -$No Flashwhite [Bully@Wiiplaza] -F6000001 80008100 -EC210032 93C10008 -14000114 60000000 -E0000000 80008000 -$Inf. Money [Bully@Wiiplaza] -F6000001 80008100 -7C003A14 38E70001 -D2000010 00000004 -2C11002F 40820014 -2C0401A8 4082000C -3D807FFF 7D84012E -7C04002E 00000000 -E0000000 80008000 -$Profile One Name Changer Jedi Hack & [Mitch] -0487E2D4 XXXXXXXX -0487E2D8 XXXXXXXX -0487E2DC XXXXXXXX -$Profile Two Name Changer Jedi Hack & [Mitch] -0487E320 0000XXXX -0487E324 XXXXXXXX -0487E328 XXXXXXXX -0487E32C XXXX0000 -$Profile Three Name Changer Jedi Hack & [Mitch] -0487E370 XXXXXXXX -0487E374 XXXXXXXX -[Video_Hacks] -DlistCachingEnable = False -[Video_Settings] -[Wii] -DisableWiimoteSpeaker = 1 +# SC2P8P - Conduit 2 +[Core] +BlockMerging = 1 +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[EmuState] +EmulationStateId = 4 +EmulationIssues = +[OnFrame] +[ActionReplay] +[Gecko] +$Undead Invincibility Mode [Bully@Wiiplaza] +F6000001 80008100 +8001002C 90180000 +D200000C 00000006 +2C110035 40820020 +2C0800F4 40820018 +2C0300A0 40820010 +3C007FFF 6000FFFF +90040000 80040000 +60000000 00000000 +E0000000 80008000 +**Offline Only* +**You are completely untouchable* +*Picture -> http://imageshack.us/photo/my-images/684/sc2p8p008.png/ +$Inf. Ammo [Bully@Wiiplaza] +F6000001 80008100 +80640000 80050000 +D2000008 00000003 +2C110021 4082000C +38600000 7C030050 +60000000 00000000 +E0000000 80008000 +**Offline Only* +$No Flashwhite [Bully@Wiiplaza] +F6000001 80008100 +EC210032 93C10008 +14000114 60000000 +E0000000 80008000 +$Inf. Money [Bully@Wiiplaza] +F6000001 80008100 +7C003A14 38E70001 +D2000010 00000004 +2C11002F 40820014 +2C0401A8 4082000C +3D807FFF 7D84012E +7C04002E 00000000 +E0000000 80008000 +$Profile One Name Changer Jedi Hack & [Mitch] +0487E2D4 XXXXXXXX +0487E2D8 XXXXXXXX +0487E2DC XXXXXXXX +$Profile Two Name Changer Jedi Hack & [Mitch] +0487E320 0000XXXX +0487E324 XXXXXXXX +0487E328 XXXXXXXX +0487E32C XXXX0000 +$Profile Three Name Changer Jedi Hack & [Mitch] +0487E370 XXXXXXXX +0487E374 XXXXXXXX +[Video_Hacks] +DlistCachingEnable = False +[Video_Settings] +[Wii] diff --git a/Data/User/GameConfig/SD2E41.ini b/Data/User/GameConfig/SD2E41.ini index 179c13afb9..ae90ff5196 100644 --- a/Data/User/GameConfig/SD2E41.ini +++ b/Data/User/GameConfig/SD2E41.ini @@ -16,5 +16,4 @@ EmulationIssues = [OnFrame] [ActionReplay] [Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SD2J01.ini b/Data/User/GameConfig/SD2J01.ini index f29168a46c..3285e7c75a 100644 --- a/Data/User/GameConfig/SD2J01.ini +++ b/Data/User/GameConfig/SD2J01.ini @@ -16,5 +16,4 @@ EmulationIssues = [OnFrame] [ActionReplay] [Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SD2P41.ini b/Data/User/GameConfig/SD2P41.ini index 744a354aaf..2111a3c298 100644 --- a/Data/User/GameConfig/SD2P41.ini +++ b/Data/User/GameConfig/SD2P41.ini @@ -16,5 +16,4 @@ EmulationIssues = [OnFrame] [ActionReplay] [Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SD2Y41.ini b/Data/User/GameConfig/SD2Y41.ini index 9daa079aac..59c9fb666b 100644 --- a/Data/User/GameConfig/SD2Y41.ini +++ b/Data/User/GameConfig/SD2Y41.ini @@ -16,5 +16,4 @@ EmulationIssues = [OnFrame] [ActionReplay] [Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SEME4Q.ini b/Data/User/GameConfig/SEME4Q.ini index 7e340985b3..48056894b9 100644 --- a/Data/User/GameConfig/SEME4Q.ini +++ b/Data/User/GameConfig/SEME4Q.ini @@ -20,5 +20,4 @@ SafeTextureCacheColorSamples = 0 ForceFiltering = False [Video_Hacks] DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SEMJ01.ini b/Data/User/GameConfig/SEMJ01.ini index 7dc481ea34..f0740ca7a3 100644 --- a/Data/User/GameConfig/SEMJ01.ini +++ b/Data/User/GameConfig/SEMJ01.ini @@ -20,5 +20,4 @@ SafeTextureCacheColorSamples = 0 ForceFiltering = False [Video_Hacks] DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SEMP4Q.ini b/Data/User/GameConfig/SEMP4Q.ini index fa1afc01c2..f425547cf4 100644 --- a/Data/User/GameConfig/SEMP4Q.ini +++ b/Data/User/GameConfig/SEMP4Q.ini @@ -20,5 +20,4 @@ SafeTextureCacheColorSamples = 0 ForceFiltering = False [Video_Hacks] DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SEMX4Q.ini b/Data/User/GameConfig/SEMX4Q.ini index b4c56197ea..43232806a2 100644 --- a/Data/User/GameConfig/SEMX4Q.ini +++ b/Data/User/GameConfig/SEMX4Q.ini @@ -20,5 +20,4 @@ SafeTextureCacheColorSamples = 0 ForceFiltering = False [Video_Hacks] DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SEMY4Q.ini b/Data/User/GameConfig/SEMY4Q.ini index 5d8798227d..817f8387e0 100644 --- a/Data/User/GameConfig/SEMY4Q.ini +++ b/Data/User/GameConfig/SEMY4Q.ini @@ -20,5 +20,4 @@ SafeTextureCacheColorSamples = 0 ForceFiltering = False [Video_Hacks] DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SEMZ4Q.ini b/Data/User/GameConfig/SEMZ4Q.ini index eecaa23166..515a1bd029 100644 --- a/Data/User/GameConfig/SEMZ4Q.ini +++ b/Data/User/GameConfig/SEMZ4Q.ini @@ -20,5 +20,4 @@ SafeTextureCacheColorSamples = 0 ForceFiltering = False [Video_Hacks] DlistCachingEnable = False -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SERE4Q.ini b/Data/User/GameConfig/SERE4Q.ini index ef5f4edfb2..fbc9fa9d3c 100644 --- a/Data/User/GameConfig/SERE4Q.ini +++ b/Data/User/GameConfig/SERE4Q.ini @@ -16,5 +16,4 @@ PH_ZFar = [Video_Settings] EFBScale = 1 SafeTextureCacheColorSamples = 0 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SERF4Q.ini b/Data/User/GameConfig/SERF4Q.ini index b03abcf0e9..cd2fca395e 100644 --- a/Data/User/GameConfig/SERF4Q.ini +++ b/Data/User/GameConfig/SERF4Q.ini @@ -16,5 +16,4 @@ PH_ZFar = [Video_Settings] EFBScale = 1 SafeTextureCacheColorSamples = 0 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SERP4Q.ini b/Data/User/GameConfig/SERP4Q.ini index e57bb14704..7e332b8bcd 100644 --- a/Data/User/GameConfig/SERP4Q.ini +++ b/Data/User/GameConfig/SERP4Q.ini @@ -16,5 +16,4 @@ PH_ZFar = [Video_Settings] EFBScale = 1 SafeTextureCacheColorSamples = 0 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SF8E01.ini b/Data/User/GameConfig/SF8E01.ini index e8e185cda9..bb2bce7406 100644 --- a/Data/User/GameConfig/SF8E01.ini +++ b/Data/User/GameConfig/SF8E01.ini @@ -16,5 +16,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 512 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SF8J01.ini b/Data/User/GameConfig/SF8J01.ini index bc0b0c2ba5..1f3ef9bb85 100644 --- a/Data/User/GameConfig/SF8J01.ini +++ b/Data/User/GameConfig/SF8J01.ini @@ -16,5 +16,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 512 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SF8P01.ini b/Data/User/GameConfig/SF8P01.ini index 41a5957888..e17f5f4247 100644 --- a/Data/User/GameConfig/SF8P01.ini +++ b/Data/User/GameConfig/SF8P01.ini @@ -16,5 +16,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 512 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SFIE01.ini b/Data/User/GameConfig/SFIE01.ini index 867859d8c4..7475f94fca 100644 --- a/Data/User/GameConfig/SFIE01.ini +++ b/Data/User/GameConfig/SFIE01.ini @@ -6,7 +6,6 @@ EmulationIssues = Needs real xfb for videos to show up. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SFIP01.ini b/Data/User/GameConfig/SFIP01.ini index 8a198d4fe8..114906aac3 100644 --- a/Data/User/GameConfig/SFIP01.ini +++ b/Data/User/GameConfig/SFIP01.ini @@ -6,7 +6,6 @@ EmulationIssues = Needs real xfb for videos to show up. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SHLPA4.ini b/Data/User/GameConfig/SHLPA4.ini index ce64ff21e1..b9eebf93c5 100644 --- a/Data/User/GameConfig/SHLPA4.ini +++ b/Data/User/GameConfig/SHLPA4.ini @@ -15,5 +15,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 512 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SJDE41.ini b/Data/User/GameConfig/SJDE41.ini index 1e16ddd21f..64b712f81d 100644 --- a/Data/User/GameConfig/SJDE41.ini +++ b/Data/User/GameConfig/SJDE41.ini @@ -6,7 +6,6 @@ EmulationIssues = Suffers from random ingame lock ups. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SJDP41.ini b/Data/User/GameConfig/SJDP41.ini index 53f65d5704..450a81c4f8 100644 --- a/Data/User/GameConfig/SJDP41.ini +++ b/Data/User/GameConfig/SJDP41.ini @@ -6,7 +6,6 @@ EmulationIssues = Suffers from random ingame lock ups. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SJDY41.ini b/Data/User/GameConfig/SJDY41.ini index 107abedfd2..74584766c3 100644 --- a/Data/User/GameConfig/SJDY41.ini +++ b/Data/User/GameConfig/SJDY41.ini @@ -6,7 +6,6 @@ EmulationIssues = Suffers from random ingame lock ups. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SJDZ41.ini b/Data/User/GameConfig/SJDZ41.ini index 53f65d5704..450a81c4f8 100644 --- a/Data/User/GameConfig/SJDZ41.ini +++ b/Data/User/GameConfig/SJDZ41.ini @@ -6,7 +6,6 @@ EmulationIssues = Suffers from random ingame lock ups. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SMOE41.ini b/Data/User/GameConfig/SMOE41.ini index 15dc5a693e..3c61475544 100644 --- a/Data/User/GameConfig/SMOE41.ini +++ b/Data/User/GameConfig/SMOE41.ini @@ -1,21 +1,20 @@ -# SMOE41 - MICHAEL JACKSON THE EXPERIENCE SPECIAL EDITION -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Sound noise eliminated using LLE audio. With hle disable idleskip for normal dance school speed. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Hacks] -EFBEmulateFormatChanges = True -[Video_Enhancements] -MaxAnisotropy = 0 -[Wii] -DisableWiimoteSpeaker = 1 +# SMOE41 - MICHAEL JACKSON THE EXPERIENCE SPECIAL EDITION +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Sound noise eliminated using LLE audio. With hle disable idleskip for normal dance school speed. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Hacks] +EFBEmulateFormatChanges = True +[Video_Enhancements] +MaxAnisotropy = 0 +[Wii] diff --git a/Data/User/GameConfig/SMOP41.ini b/Data/User/GameConfig/SMOP41.ini index 6095cd9174..b9f913a639 100644 --- a/Data/User/GameConfig/SMOP41.ini +++ b/Data/User/GameConfig/SMOP41.ini @@ -1,21 +1,20 @@ -# SMOP41 - MICHAEL JACKSON THE EXPERIENCE SPECIAL EDITION -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Sound noise eliminated using LLE audio. With hle disable idleskip for normal dance school speed. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Hacks] -EFBEmulateFormatChanges = True -[Video_Enhancements] -MaxAnisotropy = 0 -[Wii] -DisableWiimoteSpeaker = 1 +# SMOP41 - MICHAEL JACKSON THE EXPERIENCE SPECIAL EDITION +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Sound noise eliminated using LLE audio. With hle disable idleskip for normal dance school speed. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Hacks] +EFBEmulateFormatChanges = True +[Video_Enhancements] +MaxAnisotropy = 0 +[Wii] diff --git a/Data/User/GameConfig/SMOX41.ini b/Data/User/GameConfig/SMOX41.ini index 88ba03da1c..929a58f076 100644 --- a/Data/User/GameConfig/SMOX41.ini +++ b/Data/User/GameConfig/SMOX41.ini @@ -1,21 +1,20 @@ -# SMOX41 - Michael Jackson The Experience: Walmart Edition -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = Sound noise eliminated using LLE audio. With hle disable idleskip for normal dance school speed. -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 0 -PH_SZNear = 0 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Video_Hacks] -EFBEmulateFormatChanges = True -[Video_Enhancements] -MaxAnisotropy = 0 -[Wii] -DisableWiimoteSpeaker = 1 +# SMOX41 - Michael Jackson The Experience: Walmart Edition +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Sound noise eliminated using LLE audio. With hle disable idleskip for normal dance school speed. +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 0 +PH_SZNear = 0 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Video_Hacks] +EFBEmulateFormatChanges = True +[Video_Enhancements] +MaxAnisotropy = 0 +[Wii] diff --git a/Data/User/GameConfig/SO3EE9.ini b/Data/User/GameConfig/SO3EE9.ini index f8da896a23..c359fede43 100644 --- a/Data/User/GameConfig/SO3EE9.ini +++ b/Data/User/GameConfig/SO3EE9.ini @@ -6,7 +6,6 @@ EmulationIssues = Direct 3d 11 fixes some texture glitches. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SO3J99.ini b/Data/User/GameConfig/SO3J99.ini index 2ad57e3af2..e29dca5b96 100644 --- a/Data/User/GameConfig/SO3J99.ini +++ b/Data/User/GameConfig/SO3J99.ini @@ -6,7 +6,6 @@ EmulationIssues = Direct 3d 11 fixes some texture glitches. [OnFrame] Add memory patches to be applied every frame here. [ActionReplay] Add action replay cheats here. [Wii] -DisableWiimoteSpeaker = 1 [Video] ProjectionHack = 0 PH_SZNear = 0 diff --git a/Data/User/GameConfig/SOJE41.ini b/Data/User/GameConfig/SOJE41.ini index 183a8823ca..af6d49b785 100644 --- a/Data/User/GameConfig/SOJE41.ini +++ b/Data/User/GameConfig/SOJE41.ini @@ -1,17 +1,16 @@ -# SOJE41 - Rayman Origins -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 1 -PH_SZNear = 1 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# SOJE41 - Rayman Origins +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 1 +PH_SZNear = 1 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/SOJP41.ini b/Data/User/GameConfig/SOJP41.ini index 2c835fe6e2..fca55f9117 100644 --- a/Data/User/GameConfig/SOJP41.ini +++ b/Data/User/GameConfig/SOJP41.ini @@ -1,17 +1,16 @@ -# SOJP41 - Rayman Origins -[Core] Values set here will override the main dolphin settings. -[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationStateId = 4 -EmulationIssues = -[OnFrame] Add memory patches to be applied every frame here. -[ActionReplay] Add action replay cheats here. -[Video] -ProjectionHack = 1 -PH_SZNear = 1 -PH_SZFar = 0 -PH_ExtraParam = 0 -PH_ZNear = -PH_ZFar = -[Gecko] -[Wii] -DisableWiimoteSpeaker = 1 +# SOJP41 - Rayman Origins +[Core] Values set here will override the main dolphin settings. +[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = +[OnFrame] Add memory patches to be applied every frame here. +[ActionReplay] Add action replay cheats here. +[Video] +ProjectionHack = 1 +PH_SZNear = 1 +PH_SZFar = 0 +PH_ExtraParam = 0 +PH_ZNear = +PH_ZFar = +[Gecko] +[Wii] diff --git a/Data/User/GameConfig/SOUE01.ini b/Data/User/GameConfig/SOUE01.ini index 8461821933..7e37e04936 100644 --- a/Data/User/GameConfig/SOUE01.ini +++ b/Data/User/GameConfig/SOUE01.ini @@ -17,5 +17,4 @@ PH_ZFar = EFBAccessEnable = True DlistCachingEnable = False [Wii] -DisableWiimoteSpeaker = 1 [Video_Settings] diff --git a/Data/User/GameConfig/SOUJ01.ini b/Data/User/GameConfig/SOUJ01.ini index ede7d81148..b02302e15c 100644 --- a/Data/User/GameConfig/SOUJ01.ini +++ b/Data/User/GameConfig/SOUJ01.ini @@ -17,5 +17,4 @@ PH_ZFar = EFBAccessEnable = True DlistCachingEnable = False [Wii] -DisableWiimoteSpeaker = 1 [Video_Settings] diff --git a/Data/User/GameConfig/SOUK01.ini b/Data/User/GameConfig/SOUK01.ini index 512bd21408..201ec99315 100644 --- a/Data/User/GameConfig/SOUK01.ini +++ b/Data/User/GameConfig/SOUK01.ini @@ -17,5 +17,4 @@ PH_ZFar = EFBAccessEnable = True DlistCachingEnable = False [Wii] -DisableWiimoteSpeaker = 1 [Video_Settings] diff --git a/Data/User/GameConfig/SOUP01.ini b/Data/User/GameConfig/SOUP01.ini index 1b6e47096f..eab4d6b442 100644 --- a/Data/User/GameConfig/SOUP01.ini +++ b/Data/User/GameConfig/SOUP01.ini @@ -17,5 +17,4 @@ PH_ZFar = EFBAccessEnable = True DlistCachingEnable = False [Wii] -DisableWiimoteSpeaker = 1 [Video_Settings] diff --git a/Data/User/GameConfig/SRQE41.ini b/Data/User/GameConfig/SRQE41.ini index 5060189327..e923433ee8 100644 --- a/Data/User/GameConfig/SRQE41.ini +++ b/Data/User/GameConfig/SRQE41.ini @@ -14,6 +14,5 @@ PH_ZNear = PH_ZFar = [Gecko] [Wii] -DisableWiimoteSpeaker = 1 [Video_Hacks] DlistCachingEnable = False diff --git a/Data/User/GameConfig/SRQP41.ini b/Data/User/GameConfig/SRQP41.ini index f360aef050..c1001990b1 100644 --- a/Data/User/GameConfig/SRQP41.ini +++ b/Data/User/GameConfig/SRQP41.ini @@ -14,6 +14,5 @@ PH_ZNear = PH_ZFar = [Gecko] [Wii] -DisableWiimoteSpeaker = 1 [Video_Hacks] DlistCachingEnable = False diff --git a/Data/User/GameConfig/SX3J01.ini b/Data/User/GameConfig/SX3J01.ini index 276118af1a..3aef192f00 100644 --- a/Data/User/GameConfig/SX3J01.ini +++ b/Data/User/GameConfig/SX3J01.ini @@ -15,5 +15,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 0 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] diff --git a/Data/User/GameConfig/SX3P01.ini b/Data/User/GameConfig/SX3P01.ini index 94b5c6ef16..a753975414 100644 --- a/Data/User/GameConfig/SX3P01.ini +++ b/Data/User/GameConfig/SX3P01.ini @@ -15,5 +15,4 @@ PH_ZFar = [Gecko] [Video_Settings] SafeTextureCacheColorSamples = 0 -[Wii] -DisableWiimoteSpeaker = 1 +[Wii] From 7987d6babbc584956228272e65badf0bb179a2ea Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 12:42:09 -0600 Subject: [PATCH 071/167] Use templates for 8+16 bit indexed versions of SSSE3/SSE4 TextCoord reading. --- .../Src/VertexLoader_TextCoord.cpp | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp index d7a615333c..4be24640b3 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_TextCoord.cpp @@ -93,11 +93,14 @@ void LOADERDECL TexCoord_ReadIndex() #if _M_SSE >= 0x401 static const __m128i kMaskSwap16_2 = _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x02030001L); -void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() +template +void LOADERDECL TexCoord_ReadIndex_Short2_SSE4() { + static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); + // Heavy in ZWW - u16 Index = DataReadU16(); - const s32 *pData = (const s32*)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); + auto const index = DataRead(); + const s32 *pData = (const s32*)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); const __m128i a = _mm_cvtsi32_si128(*pData); const __m128i b = _mm_shuffle_epi8(a, kMaskSwap16_2); const __m128i c = _mm_cvtepi16_epi32(b); @@ -105,7 +108,7 @@ void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() const __m128 e = _mm_load1_ps(&tcScale[tcIndex]); const __m128 f = _mm_mul_ps(d, e); _mm_storeu_ps((float*)VertexManager::s_pCurBufferPointer, f); - VertexManager::s_pCurBufferPointer += 8; + VertexManager::s_pCurBufferPointer += sizeof(float) * 2; LOG_TEX<2>(); tcIndex++; } @@ -114,14 +117,17 @@ void LOADERDECL TexCoord_ReadIndex16_Short2_SSE4() #if _M_SSE >= 0x301 static const __m128i kMaskSwap32 = _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L); -void LOADERDECL TexCoord_ReadIndex16_Float2_SSSE3() +template +void LOADERDECL TexCoord_ReadIndex_Float2_SSSE3() { - u16 Index = DataReadU16(); - const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (Index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); + static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); + + auto const index = DataRead(); + const u32 *pData = (const u32 *)(cached_arraybases[ARRAY_TEXCOORD0+tcIndex] + (index * arraystrides[ARRAY_TEXCOORD0+tcIndex])); GC_ALIGNED128(const __m128i a = _mm_loadl_epi64((__m128i*)pData)); GC_ALIGNED128(const __m128i b = _mm_shuffle_epi8(a, kMaskSwap32)); _mm_storel_epi64((__m128i*)VertexManager::s_pCurBufferPointer, b); - VertexManager::s_pCurBufferPointer += 8; + VertexManager::s_pCurBufferPointer += sizeof(float) * 2; LOG_TEX<2>(); tcIndex++; } @@ -177,16 +183,20 @@ void VertexLoader_TextCoord::Init(void) { #if _M_SSE >= 0x301 - if (cpu_info.bSSSE3) { - tableReadTexCoord[3][4][1] = TexCoord_ReadIndex16_Float2_SSSE3; + if (cpu_info.bSSSE3) + { + tableReadTexCoord[2][4][1] = TexCoord_ReadIndex_Float2_SSSE3; + tableReadTexCoord[3][4][1] = TexCoord_ReadIndex_Float2_SSSE3; } #endif #if _M_SSE >= 0x401 - if (cpu_info.bSSE4_1) { - tableReadTexCoord[3][3][1] = TexCoord_ReadIndex16_Short2_SSE4; + if (cpu_info.bSSE4_1) + { + tableReadTexCoord[2][3][1] = TexCoord_ReadIndex_Short2_SSE4; + tableReadTexCoord[3][3][1] = TexCoord_ReadIndex_Short2_SSE4; } #endif From a92c93f8702802cf152d41b680a164ede35d1016 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 13:25:35 -0600 Subject: [PATCH 072/167] Automate some calculations, with templates! --- .../VideoCommon/Src/VertexLoader_Normal.cpp | 182 ++++++++++-------- .../VideoCommon/Src/VertexLoader_Normal.h | 13 +- 2 files changed, 109 insertions(+), 86 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp index 0b7a37926e..7e016828be 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader_Normal.cpp @@ -40,7 +40,7 @@ namespace { template -float FracAdjust(T val) +__forceinline float FracAdjust(T val) { //auto const S8FRAC = 1.f / (1u << 6); //auto const U8FRAC = 1.f / (1u << 7); @@ -52,11 +52,11 @@ float FracAdjust(T val) } template <> -float FracAdjust(float val) +__forceinline float FracAdjust(float val) { return val; } template -inline void ReadIndirect(const T* data) +__forceinline void ReadIndirect(const T* data) { static_assert(3 == N || 9 == N, "N is only sane as 3 or 9!"); @@ -69,15 +69,20 @@ inline void ReadIndirect(const T* data) } template -void LOADERDECL Normal_Direct() +struct Normal_Direct { - auto const source = reinterpret_cast(DataGetPosition()); - ReadIndirect(source); - DataSkip(); -} + static void LOADERDECL function() + { + auto const source = reinterpret_cast(DataGetPosition()); + ReadIndirect(source); + DataSkip(); + } + + static const int size = sizeof(T) * N * 3; +}; template -inline void Normal_Index_Offset() +__forceinline void Normal_Index_Offset() { static_assert(!std::numeric_limits::is_signed, "Only unsigned I is sane!"); @@ -88,88 +93,101 @@ inline void Normal_Index_Offset() } template -void LOADERDECL Normal_Index() +struct Normal_Index { - Normal_Index_Offset(); -} + static void LOADERDECL function() + { + Normal_Index_Offset(); + } + + static const int size = sizeof(I); +}; template -void LOADERDECL Normal_Index_Indices3() +struct Normal_Index_Indices3 { - Normal_Index_Offset(); - Normal_Index_Offset(); - Normal_Index_Offset(); -} + static void LOADERDECL function() + { + Normal_Index_Offset(); + Normal_Index_Offset(); + Normal_Index_Offset(); + } + + static const int size = sizeof(I) * 3; +}; } void VertexLoader_Normal::Init(void) { - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_Direct); - - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(3, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(3, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(6, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(6, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(12, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(9, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(9, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(18, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(18, Normal_Direct); - m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(36, Normal_Direct); - - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(1, Normal_Index); - - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(1, Normal_Index); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(3, Normal_Index_Indices3); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(3, Normal_Index_Indices3); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(3, Normal_Index_Indices3); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(3, Normal_Index_Indices3); - m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(3, Normal_Index_Indices3); - - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Set(2, Normal_Index); - - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Set(2, Normal_Index); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Set(6, Normal_Index_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Set(6, Normal_Index_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Set(6, Normal_Index_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Set(6, Normal_Index_Indices3); - m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Set(6, Normal_Index_Indices3); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Normal_Direct(); + + // Same as above + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Normal_Direct(); + m_Table[NRM_DIRECT] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Normal_Direct(); + + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Normal_Index(); + + // Same as above for NRM_NBT + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Normal_Index(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Normal_Index_Indices3(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Normal_Index_Indices3(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Normal_Index_Indices3(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Normal_Index_Indices3(); + m_Table[NRM_INDEX8] [NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Normal_Index_Indices3(); + + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_UBYTE] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_BYTE] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_USHORT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_SHORT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT] [FORMAT_FLOAT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_UBYTE] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_BYTE] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_USHORT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_SHORT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES1][NRM_NBT3][FORMAT_FLOAT] = Normal_Index(); + + // Same as above for NRM_NBT + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_UBYTE] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_BYTE] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_USHORT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_SHORT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT] [FORMAT_FLOAT] = Normal_Index(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_UBYTE] = Normal_Index_Indices3(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_BYTE] = Normal_Index_Indices3(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_USHORT] = Normal_Index_Indices3(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_SHORT] = Normal_Index_Indices3(); + m_Table[NRM_INDEX16][NRM_INDICES3][NRM_NBT3][FORMAT_FLOAT] = Normal_Index_Indices3(); } unsigned int VertexLoader_Normal::GetSize(unsigned int _type, diff --git a/Source/Core/VideoCommon/Src/VertexLoader_Normal.h b/Source/Core/VideoCommon/Src/VertexLoader_Normal.h index 71d4387ff0..d538b2a72e 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader_Normal.h +++ b/Source/Core/VideoCommon/Src/VertexLoader_Normal.h @@ -70,12 +70,17 @@ private: NUM_NRM_INDICES }; - struct Set { - Set() {} - Set(int gc_size_, TPipelineFunction function_) : gc_size(gc_size_), function(function_) {} + struct Set + { + template + void operator=(const T&) + { + gc_size = T::size; + function = T::function; + } + int gc_size; TPipelineFunction function; -// int pc_size; }; static Set m_Table[NUM_NRM_TYPE][NUM_NRM_INDICES][NUM_NRM_ELEMENTS][NUM_NRM_FORMAT]; From 677c6229ad4f0313a2346eb5ed4ae777ce02882d Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 14:41:06 -0600 Subject: [PATCH 073/167] Experimental VertexLoader cleanup! --- Source/Core/VideoCommon/Src/VertexLoader.cpp | 87 ++----------------- .../VideoCommon/Src/VertexManagerBase.cpp | 27 +----- 2 files changed, 10 insertions(+), 104 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index 23064dec9a..408c864406 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -562,86 +562,17 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) for (int i = 0; i < 2; i++) colElements[i] = m_VtxAttr.color[i].Elements; - // if strips or fans, make sure all vertices can fit in buffer, otherwise flush - int granularity = 1; - switch (primitive) { - case 3: // strip .. hm, weird - case 4: // fan - if (VertexManager::GetRemainingSize() < 3 * native_stride) - VertexManager::Flush(); - break; - case 6: // line strip - if (VertexManager::GetRemainingSize() < 2 * native_stride) - VertexManager::Flush(); - break; - case 0: granularity = 4; break; // quads - case 2: granularity = 3; break; // tris - case 5: granularity = 2; break; // lines - } - - int startv = 0, extraverts = 0; - int v = 0; - - //int remainingVerts2 = VertexManager::GetRemainingVertices(primitive); - while (v < count) + if (VertexManager::GetRemainingSize() < count * native_stride) { - int remainingVerts = VertexManager::GetRemainingSize() / native_stride; - //if (remainingVerts2 - v + startv < remainingVerts) - //remainingVerts = remainingVerts2 - v + startv; - if (remainingVerts < granularity) { - INCSTAT(stats.thisFrame.numBufferSplits); - // This buffer full - break current primitive and flush, to switch to the next buffer. - if (v - startv > 0) - VertexManager::AddVertices(primitive, v - startv + extraverts); - VertexManager::Flush(); - //remainingVerts2 = VertexManager::GetRemainingVertices(primitive); - // Why does this need to be so complicated? - switch (primitive) { - case 3: // triangle strip, copy last two vertices - // a little trick since we have to keep track of signs - if (v & 1) { - g_pVideoData -= m_VertexSize*2; - ConvertVertices(1); - g_pVideoData -= m_VertexSize; - ConvertVertices(2); - extraverts = 3; - } - else { - g_pVideoData -= m_VertexSize*2; - ConvertVertices(2); - extraverts = 2; - } - break; - case 4: // tri fan, copy first and last vert - g_pVideoData -= m_VertexSize*(v-startv+extraverts); - ConvertVertices(1); - g_pVideoData += m_VertexSize*(v-startv+extraverts-2); - ConvertVertices(1); - extraverts = 2; - break; - case 6: // line strip - g_pVideoData -= m_VertexSize*1; - ConvertVertices(1); - extraverts = 1; - break; - default: - extraverts = 0; - break; - } - startv = v; - } - int remainingPrims = remainingVerts / granularity; - remainingVerts = remainingPrims * granularity; - if (count - v < remainingVerts) - remainingVerts = count - v; - - ConvertVertices(remainingVerts); - - v += remainingVerts; + VertexManager::Flush(); + + if (VertexManager::GetRemainingSize() < count * native_stride) + ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all vertices! " + "Increase MAXVBUFFERSIZE or we need primitive breaking afterall."); } - - if (startv < count) - VertexManager::AddVertices(primitive, count - startv + extraverts); + + VertexManager::AddVertices(primitive, count); + ConvertVertices(count); } diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 6fd1898db6..e36b03d1b1 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -92,6 +92,7 @@ int VertexManager::GetRemainingSize() return (int)(s_pEndBufferPointer - s_pCurBufferPointer); } +// Not used anywhere int VertexManager::GetRemainingVertices(int primitive) { switch (primitive) @@ -123,32 +124,6 @@ void VertexManager::AddVertices(int primitive, int numVertices) if (numVertices <= 0) return; - switch (primitive) - { - case GX_DRAW_QUADS: - case GX_DRAW_TRIANGLES: - case GX_DRAW_TRIANGLE_STRIP: - case GX_DRAW_TRIANGLE_FAN: - if (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen() < 3 * numVertices) - Flush(); - break; - - case GX_DRAW_LINES: - case GX_DRAW_LINE_STRIP: - if (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen() < 2 * numVertices) - Flush(); - break; - - case GX_DRAW_POINTS: - if (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen() < numVertices) - Flush(); - break; - - default: - return; - break; - } - if (Flushed) { IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer); From 368c78dd5c167208454c8c9ac8f458130f23740b Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 19:10:00 -0600 Subject: [PATCH 074/167] IndexGenerator cleanup. --- .../Core/VideoCommon/Src/IndexGenerator.cpp | 376 +++++++----------- Source/Core/VideoCommon/Src/IndexGenerator.h | 71 ++-- .../VideoCommon/Src/VertexManagerBase.cpp | 32 +- .../Core/VideoCommon/Src/VertexManagerBase.h | 3 +- 4 files changed, 193 insertions(+), 289 deletions(-) diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.cpp b/Source/Core/VideoCommon/Src/IndexGenerator.cpp index 8053114fae..edcf93d6bd 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/Src/IndexGenerator.cpp @@ -15,6 +15,8 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include + #include "IndexGenerator.h" /* @@ -33,18 +35,12 @@ u16 *IndexGenerator::Lptr = 0; u16 *IndexGenerator::BASELptr = 0; u16 *IndexGenerator::Pptr = 0; u16 *IndexGenerator::BASEPptr = 0; -int IndexGenerator::numT = 0; -int IndexGenerator::numL = 0; -int IndexGenerator::numP = 0; -int IndexGenerator::index = 0; -int IndexGenerator::Tadds = 0; -int IndexGenerator::Ladds = 0; -int IndexGenerator::Padds = 0; -IndexGenerator::IndexPrimitiveType IndexGenerator::LastTPrimitive = Prim_None; -IndexGenerator::IndexPrimitiveType IndexGenerator::LastLPrimitive = Prim_None; -bool IndexGenerator::used = false; +u32 IndexGenerator::numT = 0; +u32 IndexGenerator::numL = 0; +u32 IndexGenerator::numP = 0; +u32 IndexGenerator::index = 0; -void IndexGenerator::Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr) +void IndexGenerator::Start(u16* Triangleptr, u16* Lineptr, u16* Pointptr) { Tptr = Triangleptr; Lptr = Lineptr; @@ -56,288 +52,220 @@ void IndexGenerator::Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr) numT = 0; numL = 0; numP = 0; - Tadds = 0; - Ladds = 0; - Padds = 0; - LastTPrimitive = Prim_None; - LastLPrimitive = Prim_None; } -// Triangles -void IndexGenerator::AddList(int numVerts) + +void IndexGenerator::AddIndices(int primitive, u32 numVerts) { - //if we have no vertices return - if(numVerts <= 0) return; - int numTris = numVerts / 3; + //switch (primitive) + //{ + //case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break; + //case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break; + //case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break; + //case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break; + //case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break; + //case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break; + //case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break; + //} + + static void (*const primitive_table[])(u32) = + { + IndexGenerator::AddQuads, + NULL, + IndexGenerator::AddList, + IndexGenerator::AddStrip, + IndexGenerator::AddFan, + IndexGenerator::AddLineList, + IndexGenerator::AddLineStrip, + IndexGenerator::AddPoints, + }; + + primitive_table[primitive](numVerts); + index += numVerts; +} + +// Triangles +void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3) +{ + *Tptr++ = index1; + *Tptr++ = index2; + *Tptr++ = index3; + + ++numT; +} + +void IndexGenerator::AddList(u32 const numVerts) +{ + auto const numTris = numVerts / 3; if (!numTris) { - //if we have less than 3 verts - if(numVerts == 1) + if (2 == numVerts) { - // discard - index++; - return; - } - else - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index+1; - *Tptr++ = index; + // We have two verts. Render a degenerated triangle. + WriteTriangle(index, index + 1, index); } } else { - for (int i = 0; i < numTris; i++) + for (u32 i = 0; i != numTris; ++i) { - *Tptr++ = index+i*3; - *Tptr++ = index+i*3+1; - *Tptr++ = index+i*3+2; + WriteTriangle(index + i * 3, index + i * 3 + 1, index + i * 3 + 2); } - int baseRemainingverts = numVerts - numVerts % 3; + + auto const base_remaining_verts = numTris * 3; switch (numVerts % 3) { case 2: - //whe have 2 remaining verts use strip method - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - *Tptr++ = index + baseRemainingverts + 1; - numTris++; + // We have 2 remaining verts. Use strip method + WriteTriangle( + index + base_remaining_verts - 1, + index + base_remaining_verts, + index + base_remaining_verts + 1); + break; + case 1: - //whe have 1 remaining verts use strip method this is only a conjeture - *Tptr++ = index + baseRemainingverts - 2; - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - numTris++; + // We have 1 remaining vert. Use strip method this is only a conjeture + WriteTriangle( + index + base_remaining_verts - 2, + index + base_remaining_verts - 1, + index + base_remaining_verts); break; + default: break; }; } - index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_List; } -void IndexGenerator::AddStrip(int numVerts) +void IndexGenerator::AddStrip(u32 const numVerts) { - if(numVerts <= 0) return; - int numTris = numVerts - 2; - if (numTris < 1) + if (numVerts < 3) { - //if we have less than 3 verts - if(numVerts == 1) + if (2 == numVerts) { - // discard - index++; - return; - } - else - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index+1; - *Tptr++ = index; + // We have two verts. Render a degenerated triangle. + WriteTriangle(index, index + 1, index); } } else - { + { bool wind = false; - for (int i = 0; i < numTris; i++) + for (u32 i = 2; i < numVerts; ++i) { - *Tptr++ = index+i; - *Tptr++ = index+i+(wind?2:1); - *Tptr++ = index+i+(wind?1:2); - wind = !wind; + WriteTriangle( + index + i - 2, + index + i - !wind, + index + i - wind); + + wind ^= true; } } - index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_Strip; -} -void IndexGenerator::AddFan(int numVerts) -{ - if(numVerts <= 0) return; - int numTris = numVerts - 2; - if (numTris < 1) - { - //if we have less than 3 verts - if(numVerts == 1) - { - //Discard - index++; - return; - } - else - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index+1; - *Tptr++ = index; - } - } - else - { - for (int i = 0; i < numTris; i++) - { - *Tptr++ = index; - *Tptr++ = index+i+1; - *Tptr++ = index+i+2; - } - } - index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_Fan; } -void IndexGenerator::AddQuads(int numVerts) +void IndexGenerator::AddFan(u32 numVerts) { - if(numVerts <= 0) return; - int numTris = (numVerts/4)*2; - if (numTris == 0) + if (numVerts < 3) { - //if we have less than 3 verts - if(numVerts == 1) + if (2 == numVerts) { - //discard - index++; - return; - } - else - { - if(numVerts == 2) - { - //we have two verts render a degenerated triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index + 1; - *Tptr++ = index; - } - else - { - //we have 3 verts render a full triangle - numTris = 1; - *Tptr++ = index; - *Tptr++ = index + 1; - *Tptr++ = index + 2; - } + // We have two verts. Render a degenerated triangle. + WriteTriangle(index, index + 1, index); } } else { - for (int i = 0; i < numTris / 2; i++) + for (u32 i = 2; i < numVerts; ++i) { - *Tptr++ = index+i*4; - *Tptr++ = index+i*4+1; - *Tptr++ = index+i*4+2; - *Tptr++ = index+i*4; - *Tptr++ = index+i*4+2; - *Tptr++ = index+i*4+3; + WriteTriangle(index, index + i - 1, index + i); } - int baseRemainingverts = numVerts - numVerts % 4; + } +} + +void IndexGenerator::AddQuads(u32 numVerts) +{ + auto const numQuads = numVerts / 4; + if (!numQuads) + { + if (2 == numVerts) + { + // We have two verts. Render a degenerated triangle. + WriteTriangle(index, index + 1, index); + } + else if (3 == numVerts); + { + // We have 3 verts. Render a full triangle. + WriteTriangle(index, index + 1, index + 2); + } + } + else + { + for (u32 i = 0; i != numQuads; ++i) + { + WriteTriangle(index + i * 4, index + i * 4 + 1, index + i * 4 + 2); + WriteTriangle(index + i * 4, index + i * 4 + 2, index + i * 4 + 3); + } + + auto const base_remaining_verts = numQuads * 4; switch (numVerts % 4) { case 3: - //whe have 3 remaining verts use strip method - *Tptr++ = index + baseRemainingverts; - *Tptr++ = index + baseRemainingverts + 1; - *Tptr++ = index + baseRemainingverts + 2; - numTris++; + // We have 3 remaining verts. Use strip method. + WriteTriangle( + index + base_remaining_verts, + index + base_remaining_verts + 1, + index + base_remaining_verts + 2); break; + case 2: - //whe have 2 remaining verts use strip method - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - *Tptr++ = index + baseRemainingverts + 1; - numTris++; + // We have 3 remaining verts. Use strip method. + WriteTriangle( + index + base_remaining_verts - 1, + index + base_remaining_verts, + index + base_remaining_verts + 1); break; + case 1: - //whe have 1 remaining verts use strip method this is only a conjeture - *Tptr++ = index + baseRemainingverts - 2; - *Tptr++ = index + baseRemainingverts - 1; - *Tptr++ = index + baseRemainingverts; - numTris++; + // We have 1 remaining verts use strip method. This is only a conjeture. + WriteTriangle( + base_remaining_verts - 2, + index + base_remaining_verts - 1, + index + base_remaining_verts); break; + default: break; }; } - index += numVerts; - numT += numTris; - Tadds++; - LastTPrimitive = Prim_List; } - -//Lines -void IndexGenerator::AddLineList(int numVerts) +// Lines +void IndexGenerator::AddLineList(u32 numVerts) { - if(numVerts <= 0) return; - int numLines = numVerts / 2; - if (!numLines) + auto const numLines = numVerts / 2; + for (u32 i = 0; i != numLines; ++i) { - //Discard - index++; - return; + *Lptr++ = index + i * 2; + *Lptr++ = index + i * 2 + 1; + ++numL; } - else - { - for (int i = 0; i < numLines; i++) - { - *Lptr++ = index+i*2; - *Lptr++ = index+i*2+1; - } - if((numVerts & 1) != 0) - { - //use line strip for remaining vert - *Lptr++ = index + numLines * 2 - 1; - *Lptr++ = index + numLines * 2; - } - } - index += numVerts; - numL += numLines; - Ladds++; - LastLPrimitive = Prim_List; } -void IndexGenerator::AddLineStrip(int numVerts) +void IndexGenerator::AddLineStrip(u32 numVerts) { - int numLines = numVerts - 1; - if (numLines <= 0) + for (u32 i = 1; i < numVerts; ++i) { - if(numVerts == 1) - { - index++; - } - return; + *Lptr++ = index + i - 1; + *Lptr++ = index + i; + ++numL; } - for (int i = 0; i < numLines; i++) - { - *Lptr++ = index+i; - *Lptr++ = index+i+1; - } - index += numVerts; - numL += numLines; - Ladds++; - LastLPrimitive = Prim_Strip; } - - -//Points -void IndexGenerator::AddPoints(int numVerts) +// Points +void IndexGenerator::AddPoints(u32 numVerts) { - for (int i = 0; i < numVerts; i++) + for (u32 i = 0; i != numVerts; ++i) { - *Pptr++ = index+i; + *Pptr++ = index + i; + ++numP; } - index += numVerts; - numP += numVerts; - Padds++; } diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.h b/Source/Core/VideoCommon/Src/IndexGenerator.h index d1ed143d98..5c6b7a5273 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.h +++ b/Source/Core/VideoCommon/Src/IndexGenerator.h @@ -25,53 +25,58 @@ class IndexGenerator { public: - //Init + // Init static void Start(u16 *Triangleptr,u16 *Lineptr,u16 *Pointptr); - //Triangles - static void AddList(int numVerts); - static void AddStrip(int numVerts); - static void AddFan(int numVerts); - static void AddQuads(int numVerts); - //Lines - static void AddLineList(int numVerts); - static void AddLineStrip(int numVerts); - //Points - static void AddPoints(int numVerts); - //Interface - static int GetNumTriangles() {used = true; return numT;} - static int GetNumLines() {used = true;return numL;} - static int GetNumPoints() {used = true;return numP;} - static int GetNumVerts() {return index;} //returns numprimitives - static int GetNumAdds() {return Tadds + Ladds + Padds;} - static int GetTriangleindexLen() {return (int)(Tptr - BASETptr);} - static int GetLineindexLen() {return (int)(Lptr - BASELptr);} - static int GetPointindexLen() {return (int)(Pptr - BASEPptr);} - + + static void AddIndices(int primitive, u32 numVertices); + + // Interface + static u32 GetNumTriangles() {return numT;} + static u32 GetNumLines() {return numL;} + static u32 GetNumPoints() {return numP;} + + // returns numprimitives + static u32 GetNumVerts() {return index;} + + static u32 GetTriangleindexLen() {return (u32)(Tptr - BASETptr);} + static u32 GetLineindexLen() {return (u32)(Lptr - BASELptr);} + static u32 GetPointindexLen() {return (u32)(Pptr - BASEPptr);} +/* enum IndexPrimitiveType { Prim_None = 0, Prim_List, Prim_Strip, Prim_Fan - } ; + }; +*/ private: + // Triangles + static void AddList(u32 numVerts); + static void AddStrip(u32 numVerts); + static void AddFan(u32 numVerts); + static void AddQuads(u32 numVerts); + + static void WriteTriangle(u32 index1, u32 index2, u32 index3); + + // Lines + static void AddLineList(u32 numVerts); + static void AddLineStrip(u32 numVerts); + + // Points + static void AddPoints(u32 numVerts); + static u16 *Tptr; static u16 *BASETptr; static u16 *Lptr; static u16 *BASELptr; static u16 *Pptr; static u16 *BASEPptr; - static int numT; - static int numL; - static int numP; - static int index; - static int Tadds; - static int Ladds; - static int Padds; - static IndexPrimitiveType LastTPrimitive; - static IndexPrimitiveType LastLPrimitive; - static bool used; - + // TODO: redundant variables + static u32 numT; + static u32 numL; + static u32 numP; + static u32 index; }; #endif // _INDEXGENERATOR_H diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index e36b03d1b1..af4d646cc3 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -59,34 +59,6 @@ VertexManager::~VertexManager() ResetBuffer(); } -void VertexManager::AddIndices(int primitive, int numVertices) -{ - //switch (primitive) - //{ - //case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break; - //case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break; - //case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break; - //case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break; - //case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break; - //case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break; - //case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break; - //} - - static void (*const primitive_table[])(int) = - { - IndexGenerator::AddQuads, - NULL, - IndexGenerator::AddList, - IndexGenerator::AddStrip, - IndexGenerator::AddFan, - IndexGenerator::AddLineList, - IndexGenerator::AddLineStrip, - IndexGenerator::AddPoints, - }; - - primitive_table[primitive](numVertices); -} - int VertexManager::GetRemainingSize() { return (int)(s_pEndBufferPointer - s_pCurBufferPointer); @@ -119,7 +91,7 @@ int VertexManager::GetRemainingVertices(int primitive) } } -void VertexManager::AddVertices(int primitive, int numVertices) +void VertexManager::AddVertices(int primitive, u32 numVertices) { if (numVertices <= 0) return; @@ -132,7 +104,7 @@ void VertexManager::AddVertices(int primitive, int numVertices) ADDSTAT(stats.thisFrame.numPrims, numVertices); INCSTAT(stats.thisFrame.numPrimitiveJoins); - AddIndices(primitive, numVertices); + IndexGenerator::AddIndices(primitive, numVertices); } void VertexManager::Flush() diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h index d4608630ca..5169422b3c 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.h +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h @@ -27,7 +27,7 @@ public: VertexManager(); virtual ~VertexManager(); // needs to be virtual for DX11's dtor - static void AddVertices(int _primitive, int _numVertices); + static void AddVertices(int _primitive, u32 _numVertices); // TODO: protected? static u8 *s_pBaseBufferPointer; @@ -63,7 +63,6 @@ protected: void DoStateShared(PointerWrap& p); private: - static void AddIndices(int primitive, int numVertices); //virtual void Draw(u32 stride, bool alphapass) = 0; // temp virtual void vFlush() = 0; From f16dcfe6f69c0cb8ba89ea6611157c8c2eab3dad Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 21:01:53 -0600 Subject: [PATCH 075/167] Remove logic from IndexGenerator which does not seem to match that of Video Software. --- .../Core/VideoCommon/Src/IndexGenerator.cpp | 172 ++++-------------- Source/Core/VideoCommon/Src/IndexGenerator.h | 4 +- 2 files changed, 36 insertions(+), 140 deletions(-) diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.cpp b/Source/Core/VideoCommon/Src/IndexGenerator.cpp index edcf93d6bd..a7d073890f 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/Src/IndexGenerator.cpp @@ -29,16 +29,16 @@ QUAD simulator */ //Init -u16 *IndexGenerator::Tptr = 0; -u16 *IndexGenerator::BASETptr = 0; -u16 *IndexGenerator::Lptr = 0; -u16 *IndexGenerator::BASELptr = 0; -u16 *IndexGenerator::Pptr = 0; -u16 *IndexGenerator::BASEPptr = 0; -u32 IndexGenerator::numT = 0; -u32 IndexGenerator::numL = 0; -u32 IndexGenerator::numP = 0; -u32 IndexGenerator::index = 0; +u16 *IndexGenerator::Tptr; +u16 *IndexGenerator::BASETptr; +u16 *IndexGenerator::Lptr; +u16 *IndexGenerator::BASELptr; +u16 *IndexGenerator::Pptr; +u16 *IndexGenerator::BASEPptr; +u32 IndexGenerator::numT; +u32 IndexGenerator::numL; +u32 IndexGenerator::numP; +u32 IndexGenerator::index; void IndexGenerator::Start(u16* Triangleptr, u16* Lineptr, u16* Pointptr) { @@ -58,13 +58,13 @@ void IndexGenerator::AddIndices(int primitive, u32 numVerts) { //switch (primitive) //{ - //case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVertices); break; - //case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVertices); break; - //case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVertices); break; - //case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVertices); break; - //case GX_DRAW_LINES: IndexGenerator::AddLineList(numVertices); break; - //case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVertices); break; - //case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVertices); break; + //case GX_DRAW_QUADS: IndexGenerator::AddQuads(numVerts); break; + //case GX_DRAW_TRIANGLES: IndexGenerator::AddList(numVerts); break; + //case GX_DRAW_TRIANGLE_STRIP: IndexGenerator::AddStrip(numVerts); break; + //case GX_DRAW_TRIANGLE_FAN: IndexGenerator::AddFan(numVerts); break; + //case GX_DRAW_LINES: IndexGenerator::AddLineList(numVerts); break; + //case GX_DRAW_LINE_STRIP: IndexGenerator::AddLineStrip(numVerts); break; + //case GX_DRAW_POINTS: IndexGenerator::AddPoints(numVerts); break; //} static void (*const primitive_table[])(u32) = @@ -89,152 +89,48 @@ void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3) *Tptr++ = index1; *Tptr++ = index2; *Tptr++ = index3; - + ++numT; } void IndexGenerator::AddList(u32 const numVerts) -{ +{ auto const numTris = numVerts / 3; - if (!numTris) + for (u32 i = 0; i != numTris; ++i) { - if (2 == numVerts) - { - // We have two verts. Render a degenerated triangle. - WriteTriangle(index, index + 1, index); - } - } - else - { - for (u32 i = 0; i != numTris; ++i) - { - WriteTriangle(index + i * 3, index + i * 3 + 1, index + i * 3 + 2); - } - - auto const base_remaining_verts = numTris * 3; - switch (numVerts % 3) - { - case 2: - // We have 2 remaining verts. Use strip method - WriteTriangle( - index + base_remaining_verts - 1, - index + base_remaining_verts, - index + base_remaining_verts + 1); - - break; - - case 1: - // We have 1 remaining vert. Use strip method this is only a conjeture - WriteTriangle( - index + base_remaining_verts - 2, - index + base_remaining_verts - 1, - index + base_remaining_verts); - break; - - default: - break; - }; + WriteTriangle(index + i * 3, index + i * 3 + 1, index + i * 3 + 2); } } void IndexGenerator::AddStrip(u32 const numVerts) { - if (numVerts < 3) + bool wind = false; + for (u32 i = 2; i < numVerts; ++i) { - if (2 == numVerts) - { - // We have two verts. Render a degenerated triangle. - WriteTriangle(index, index + 1, index); - } - } - else - { - bool wind = false; - for (u32 i = 2; i < numVerts; ++i) - { - WriteTriangle( - index + i - 2, - index + i - !wind, - index + i - wind); - - wind ^= true; - } + WriteTriangle( + index + i - 2, + index + i - !wind, + index + i - wind); + + wind ^= true; } } void IndexGenerator::AddFan(u32 numVerts) { - if (numVerts < 3) + for (u32 i = 2; i < numVerts; ++i) { - if (2 == numVerts) - { - // We have two verts. Render a degenerated triangle. - WriteTriangle(index, index + 1, index); - } - } - else - { - for (u32 i = 2; i < numVerts; ++i) - { - WriteTriangle(index, index + i - 1, index + i); - } + WriteTriangle(index, index + i - 1, index + i); } } void IndexGenerator::AddQuads(u32 numVerts) { auto const numQuads = numVerts / 4; - if (!numQuads) + for (u32 i = 0; i != numQuads; ++i) { - if (2 == numVerts) - { - // We have two verts. Render a degenerated triangle. - WriteTriangle(index, index + 1, index); - } - else if (3 == numVerts); - { - // We have 3 verts. Render a full triangle. - WriteTriangle(index, index + 1, index + 2); - } - } - else - { - for (u32 i = 0; i != numQuads; ++i) - { - WriteTriangle(index + i * 4, index + i * 4 + 1, index + i * 4 + 2); - WriteTriangle(index + i * 4, index + i * 4 + 2, index + i * 4 + 3); - } - - auto const base_remaining_verts = numQuads * 4; - switch (numVerts % 4) - { - case 3: - // We have 3 remaining verts. Use strip method. - WriteTriangle( - index + base_remaining_verts, - index + base_remaining_verts + 1, - index + base_remaining_verts + 2); - break; - - case 2: - // We have 3 remaining verts. Use strip method. - WriteTriangle( - index + base_remaining_verts - 1, - index + base_remaining_verts, - index + base_remaining_verts + 1); - break; - - case 1: - // We have 1 remaining verts use strip method. This is only a conjeture. - WriteTriangle( - base_remaining_verts - 2, - index + base_remaining_verts - 1, - index + base_remaining_verts); - break; - - default: - break; - }; + WriteTriangle(index + i * 4, index + i * 4 + 1, index + i * 4 + 2); + WriteTriangle(index + i * 4, index + i * 4 + 2, index + i * 4 + 3); } } diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.h b/Source/Core/VideoCommon/Src/IndexGenerator.h index 5c6b7a5273..400d252bf8 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.h +++ b/Source/Core/VideoCommon/Src/IndexGenerator.h @@ -57,8 +57,6 @@ private: static void AddFan(u32 numVerts); static void AddQuads(u32 numVerts); - static void WriteTriangle(u32 index1, u32 index2, u32 index3); - // Lines static void AddLineList(u32 numVerts); static void AddLineStrip(u32 numVerts); @@ -66,6 +64,8 @@ private: // Points static void AddPoints(u32 numVerts); + static void WriteTriangle(u32 index1, u32 index2, u32 index3); + static u16 *Tptr; static u16 *BASETptr; static u16 *Lptr; From d76ca5783743d654f3fa6ad8b69c239f93c9493e Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 22 Feb 2013 15:13:49 +1100 Subject: [PATCH 076/167] Fixed a JIT timing bug that prevented Eternal Darkness from booting in Single Core mode. --- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 31caca0a43..900a8475f7 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -338,7 +338,7 @@ void Jit64::WriteRfiExitDestInEAX() Cleanup(); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); - JMP(asm_routines.dispatcher, true); + JMP(asm_routines.outerLoop, true); } void Jit64::WriteExceptionExit() From 21bd5be753efb016ab5e3a75bf5e6f8e71a3576a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 21 Feb 2013 23:12:53 -0600 Subject: [PATCH 077/167] Buffer size changes. --- .../Core/VideoCommon/Src/VertexManagerBase.h | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h index 5169422b3c..d846a65b90 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.h +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h @@ -7,25 +7,28 @@ class PointerWrap; class VertexManager { +private: + // What are the actual values? + static const u32 SMALLEST_POSSIBLE_VERTEX = 1; + static const u32 LARGEST_POSSIBLE_VERTEX = 188; + + static const u32 MAX_PRIMITIVES_PER_COMMAND = (u16)-1; + public: - - enum - { - // values from OGL backend - //MAXVBUFFERSIZE = 0x1FFFF, - //MAXIBUFFERSIZE = 0xFFFF, - - // values from DX9 backend - //MAXVBUFFERSIZE = 0x50000, - //MAXIBUFFERSIZE = 0xFFFF, - - // values from DX11 backend - MAXVBUFFERSIZE = 0x50000, - MAXIBUFFERSIZE = 0xFFFF, - }; + // values from OGL backend + //static const u32 MAXVBUFFERSIZE = 0x1FFFF; + + // values from DX9/11 backend + static const u32 MAXVBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * LARGEST_POSSIBLE_VERTEX; + + // We may convert triangle-fans to triangle-lists, almost 3x as many indices. + // Watching for a full index buffer would probably be smarter than this calculation. + static const u32 MAXIBUFFERSIZE = MAXVBUFFERSIZE * 3 / SMALLEST_POSSIBLE_VERTEX; + //static const u32 MAXIBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * 3; VertexManager(); - virtual ~VertexManager(); // needs to be virtual for DX11's dtor + // needs to be virtual for DX11's dtor + virtual ~VertexManager(); static void AddVertices(int _primitive, u32 _numVertices); From db1be085c2d0a359e5ee561bbbad8e8428a72552 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 22 Feb 2013 01:41:52 -0600 Subject: [PATCH 078/167] VertexManager cleanup --- Source/Core/VideoCommon/Src/VertexLoader.cpp | 3 +- .../VideoCommon/Src/VertexManagerBase.cpp | 74 ++++++++----------- .../Core/VideoCommon/Src/VertexManagerBase.h | 35 ++++----- .../Plugin_VideoDX11/Src/VertexManager.cpp | 12 +-- .../Plugin_VideoDX9/Src/VertexManager.cpp | 6 -- .../Plugin_VideoOGL/Src/VertexManager.cpp | 6 -- 6 files changed, 54 insertions(+), 82 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index 408c864406..5e1490e020 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -571,8 +571,9 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) "Increase MAXVBUFFERSIZE or we need primitive breaking afterall."); } - VertexManager::AddVertices(primitive, count); ConvertVertices(count); + VertexManager::AddVertices(primitive, count); + //VertexManager::Flush(); } diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index af4d646cc3..131d6de42a 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -12,25 +12,17 @@ #include "BPStructs.h" #include "VertexManagerBase.h" +#include "MainBase.h" #include "VideoConfig.h" VertexManager *g_vertex_manager; -u8 *VertexManager::s_pBaseBufferPointer; u8 *VertexManager::s_pCurBufferPointer; +u8 *VertexManager::s_pBaseBufferPointer; u8 *VertexManager::s_pEndBufferPointer; -u8 *VertexManager::LocalVBuffer; -u16 *VertexManager::TIBuffer; -u16 *VertexManager::LIBuffer; -u16 *VertexManager::PIBuffer; - -bool VertexManager::Flushed; - VertexManager::VertexManager() { - Flushed = false; - LocalVBuffer = new u8[MAXVBUFFERSIZE]; s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer; s_pEndBufferPointer = s_pBaseBufferPointer + MAXVBUFFERSIZE; @@ -39,12 +31,7 @@ VertexManager::VertexManager() LIBuffer = new u16[MAXIBUFFERSIZE]; PIBuffer = new u16[MAXIBUFFERSIZE]; - IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer); -} - -void VertexManager::ResetBuffer() -{ - s_pCurBufferPointer = s_pBaseBufferPointer; + ResetBuffer(); } VertexManager::~VertexManager() @@ -59,12 +46,25 @@ VertexManager::~VertexManager() ResetBuffer(); } +void VertexManager::ResetBuffer() +{ + s_pCurBufferPointer = s_pBaseBufferPointer; + IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer); +} + int VertexManager::GetRemainingSize() { return (int)(s_pEndBufferPointer - s_pCurBufferPointer); } +bool VertexManager::IsFlushed() const +{ + return s_pBaseBufferPointer == s_pCurBufferPointer; +} + // Not used anywhere +// TODO: use this +#if 0 int VertexManager::GetRemainingVertices(int primitive) { switch (primitive) @@ -90,42 +90,38 @@ int VertexManager::GetRemainingVertices(int primitive) break; } } +#endif void VertexManager::AddVertices(int primitive, u32 numVertices) { if (numVertices <= 0) return; - if (Flushed) - { - IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer); - Flushed = false; - } - ADDSTAT(stats.thisFrame.numPrims, numVertices); INCSTAT(stats.thisFrame.numPrimitiveJoins); + IndexGenerator::AddIndices(primitive, numVertices); } void VertexManager::Flush() { + if (g_vertex_manager->IsFlushed()) + return; + // loading a state will invalidate BP, so check for it g_video_backend->CheckInvalidState(); + VideoFifo_CheckEFBAccess(); + g_vertex_manager->vFlush(); + + g_vertex_manager->ResetBuffer(); } // TODO: need to merge more stuff into VideoCommon to use this #if (0) void VertexManager::Flush() { - if (s_pBaseBufferPointer == s_pCurBufferPointer || Flushed) - return; - - Flushed = true; - - VideoFifo_CheckEFBAccess(); - #if defined(_DEBUG) || defined(DEBUGFAST) PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGens, xfregs.nNumChans, (int)xfregs.bEnableDualTexTransform, bpmem.ztex2.op, @@ -198,9 +194,9 @@ void VertexManager::Flush() // finally bind if (false == PixelShaderCache::SetShader(false, g_nativeVertexFmt->m_components)) - goto shader_fail; + return; if (false == VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) - goto shader_fail; + return; const int stride = g_nativeVertexFmt->GetVertexStride(); //if (g_nativeVertexFmt) @@ -212,7 +208,7 @@ void VertexManager::Flush() if (false == g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate) { if (false == PixelShaderCache::SetShader(true, g_nativeVertexFmt->m_components)) - goto shader_fail; + return; g_vertex_manager->Draw(stride, true); } @@ -246,9 +242,6 @@ void VertexManager::Flush() } #endif ++g_Config.iSaveTargetId; - -shader_fail: - ResetBuffer(); } #endif @@ -259,12 +252,9 @@ void VertexManager::DoState(PointerWrap& p) void VertexManager::DoStateShared(PointerWrap& p) { - p.DoPointer(s_pCurBufferPointer, LocalVBuffer); + p.DoPointer(s_pCurBufferPointer, g_vertex_manager->LocalVBuffer); p.DoArray(LocalVBuffer, MAXVBUFFERSIZE); - p.DoArray(TIBuffer, MAXIBUFFERSIZE); - p.DoArray(LIBuffer, MAXIBUFFERSIZE); - p.DoArray(PIBuffer, MAXIBUFFERSIZE); - - if (p.GetMode() == PointerWrap::MODE_READ) - Flushed = false; + p.DoArray(g_vertex_manager->TIBuffer, MAXIBUFFERSIZE); + p.DoArray(g_vertex_manager->LIBuffer, MAXIBUFFERSIZE); + p.DoArray(g_vertex_manager->PIBuffer, MAXIBUFFERSIZE); } diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h index d846a65b90..4bf5541cbd 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.h +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h @@ -32,46 +32,47 @@ public: static void AddVertices(int _primitive, u32 _numVertices); - // TODO: protected? - static u8 *s_pBaseBufferPointer; static u8 *s_pCurBufferPointer; + static u8 *s_pBaseBufferPointer; static u8 *s_pEndBufferPointer; static int GetRemainingSize(); - static int GetRemainingVertices(int primitive); + + //int GetRemainingVertices(int primitive); static void Flush(); virtual ::NativeVertexFormat* CreateNativeVertexFormat() = 0; - static u16* GetTriangleIndexBuffer() { return TIBuffer; } - static u16* GetLineIndexBuffer() { return LIBuffer; } - static u16* GetPointIndexBuffer() { return PIBuffer; } - static u8* GetVertexBuffer() { return s_pBaseBufferPointer; } + // TODO: use these instead of TIBuffer, etc + +// u16* GetTriangleIndexBuffer() { return TIBuffer; } +// u16* GetLineIndexBuffer() { return LIBuffer; } +// u16* GetPointIndexBuffer() { return PIBuffer; } +// u8* GetVertexBuffer() { return s_pBaseBufferPointer; } static void DoState(PointerWrap& p); virtual void CreateDeviceObjects(){}; virtual void DestroyDeviceObjects(){}; + protected: - // TODO: make private after Flush() is merged - static void ResetBuffer(); - - static u16 *TIBuffer; - static u16 *LIBuffer; - static u16 *PIBuffer; - - static bool Flushed; + u16* TIBuffer; + u16* LIBuffer; + u16* PIBuffer; virtual void vDoState(PointerWrap& p) { DoStateShared(p); } void DoStateShared(PointerWrap& p); private: + bool IsFlushed() const; + + void ResetBuffer(); + //virtual void Draw(u32 stride, bool alphapass) = 0; // temp virtual void vFlush() = 0; - static u8 *LocalVBuffer; - + u8* LocalVBuffer; }; extern VertexManager *g_vertex_manager; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index b227a4d27b..573180e0b7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -211,11 +211,6 @@ void VertexManager::Draw(UINT stride) void VertexManager::vFlush() { - if (s_pBaseBufferPointer == s_pCurBufferPointer) return; - if (Flushed) return; - Flushed=true; - VideoFifo_CheckEFBAccess(); - u32 usedtextures = 0; for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) if (bpmem.tevorders[i / 2].getEnable(i & 1)) @@ -263,12 +258,12 @@ void VertexManager::vFlush() g_nativeVertexFmt->m_components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; + return; } if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); - goto shader_fail; + return; } LoadBuffers(); unsigned int stride = g_nativeVertexFmt->GetVertexStride(); @@ -280,9 +275,6 @@ void VertexManager::vFlush() GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); g_renderer->RestoreState(); - -shader_fail: - ResetBuffer(); } } // namespace diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 5ca6018fb1..7ef3052a96 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -307,11 +307,6 @@ void VertexManager::DrawVA(int stride) void VertexManager::vFlush() { - if (s_pBaseBufferPointer == s_pCurBufferPointer) return; - if (Flushed) return; - Flushed = true; - VideoFifo_CheckEFBAccess(); - u32 usedtextures = 0; for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages + 1; ++i) if (bpmem.tevorders[i / 2].getEnable(i & 1)) @@ -388,7 +383,6 @@ shader_fail: CurrentIBufferIndex += IndexGenerator::GetTriangleindexLen() + IndexGenerator::GetLineindexLen() + IndexGenerator::GetPointindexLen(); CurrentVBufferIndex += IndexGenerator::GetNumVerts() * stride; } - ResetBuffer(); } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 5a07f42662..5777f225cd 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -100,10 +100,6 @@ void VertexManager::Draw() void VertexManager::vFlush() { - if (s_pBaseBufferPointer == s_pCurBufferPointer) return; - if (Flushed) return; - Flushed=true; - VideoFifo_CheckEFBAccess(); #if defined(_DEBUG) || defined(DEBUGFAST) PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGen.numTexGens, xfregs.numChan.numColorChans, xfregs.dualTexTrans.enabled, bpmem.ztex2.op, @@ -240,8 +236,6 @@ void VertexManager::vFlush() GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); //s_nCurVBOIndex = (s_nCurVBOIndex + 1) % ARRAYSIZE(s_vboBuffers); - s_pCurBufferPointer = s_pBaseBufferPointer; - IndexGenerator::Start(TIBuffer,LIBuffer,PIBuffer); #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) From d3f1bb93f2454ab1e1daf4c2b75d18269719c9b3 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 22 Feb 2013 02:19:59 -0600 Subject: [PATCH 079/167] Use DataWrite in a few more places. --- Source/Core/VideoCommon/Src/VertexLoader.cpp | 26 +++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index 5e1490e020..7d1b9d99a5 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -97,10 +97,10 @@ void LOADERDECL PosMtx_ReadDirect_UByte() void LOADERDECL PosMtx_Write() { - *VertexManager::s_pCurBufferPointer++ = s_curposmtx; - *VertexManager::s_pCurBufferPointer++ = 0; - *VertexManager::s_pCurBufferPointer++ = 0; - *VertexManager::s_pCurBufferPointer++ = 0; + DataWrite(s_curposmtx); + DataWrite(0); + DataWrite(0); + DataWrite(0); } void LOADERDECL UpdateBoundingBoxPrepare() @@ -166,24 +166,22 @@ void LOADERDECL TexMtx_ReadDirect_UByte() void LOADERDECL TexMtx_Write_Float() { - *(float*)VertexManager::s_pCurBufferPointer = (float)s_curtexmtx[s_texmtxwrite++]; - VertexManager::s_pCurBufferPointer += 4; + DataWrite(float(s_curtexmtx[s_texmtxwrite++])); } void LOADERDECL TexMtx_Write_Float2() { - ((float*)VertexManager::s_pCurBufferPointer)[0] = 0; - ((float*)VertexManager::s_pCurBufferPointer)[1] = (float)s_curtexmtx[s_texmtxwrite++]; - VertexManager::s_pCurBufferPointer += 8; + DataWrite(0.f); + DataWrite(float(s_curtexmtx[s_texmtxwrite++])); } void LOADERDECL TexMtx_Write_Float4() { - ((float*)VertexManager::s_pCurBufferPointer)[0] = 0; - ((float*)VertexManager::s_pCurBufferPointer)[1] = 0; - ((float*)VertexManager::s_pCurBufferPointer)[2] = s_curtexmtx[s_texmtxwrite++]; - ((float*)VertexManager::s_pCurBufferPointer)[3] = 0; // Just to fill out with 0. - VertexManager::s_pCurBufferPointer += 16; + DataWrite(0.f); + DataWrite(0.f); + DataWrite(float(s_curtexmtx[s_texmtxwrite++])); + // Just to fill out with 0. + DataWrite(0.f); } VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr) From 86935ab4fd2d6fe2989a00d9b497fb0a3e08c3b4 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 22 Feb 2013 03:22:20 -0600 Subject: [PATCH 080/167] forceinline IndexGenerator::WriteTriangle --- Source/Core/VideoCommon/Src/IndexGenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/IndexGenerator.cpp b/Source/Core/VideoCommon/Src/IndexGenerator.cpp index a7d073890f..f2d23a7fce 100644 --- a/Source/Core/VideoCommon/Src/IndexGenerator.cpp +++ b/Source/Core/VideoCommon/Src/IndexGenerator.cpp @@ -17,6 +17,7 @@ #include +#include "Common.h" #include "IndexGenerator.h" /* @@ -84,7 +85,7 @@ void IndexGenerator::AddIndices(int primitive, u32 numVerts) } // Triangles -void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3) +__forceinline void IndexGenerator::WriteTriangle(u32 index1, u32 index2, u32 index3) { *Tptr++ = index1; *Tptr++ = index2; From ba979582e2d0b4961f1087b76eef659856eb23bb Mon Sep 17 00:00:00 2001 From: Jonathan Jones Date: Fri, 22 Feb 2013 15:27:28 -0500 Subject: [PATCH 081/167] Makes the "No banner" banner image theme-able. Current "sexy X" banner included as part of "Boomy" theme. Fixes issue 6023. --- Data/User/Themes/Boomy/nobanner.png | Bin 0 -> 2484 bytes Source/Core/DolphinWX/Src/ConfigMain.cpp | 1 + Source/Core/DolphinWX/Src/ISOFile.cpp | 14 ++++++--- Source/Core/DolphinWX/resources/no_banner.cpp | 28 ------------------ 4 files changed, 11 insertions(+), 32 deletions(-) create mode 100644 Data/User/Themes/Boomy/nobanner.png delete mode 100644 Source/Core/DolphinWX/resources/no_banner.cpp diff --git a/Data/User/Themes/Boomy/nobanner.png b/Data/User/Themes/Boomy/nobanner.png new file mode 100644 index 0000000000000000000000000000000000000000..4d34be77626c7f9d77659f8766109b9017baa619 GIT binary patch literal 2484 zcmV;l2}|~gP)WFU8GbZ8()Nlj2>E@cM*00|gLL_t(&-p!hAbKloBF>s^;&fX(Gmm_Z|S}9000{tr#Q2F!1#Bg!i6d7^td>VHoh*_Jsw#kde_Q2wMC9VVa}E(<7zR$K6VK1jytjmejt5-uBv~^m z_)zok@Ico#)OAf7C!FZ~r)hpR^+Y@=DKKLa$B9t6jHQoIF6_)(=_3|XPTz`fF`u6s_@?DhfgVGkVFLM93cc&s}<8U&4-LJgY3P> zdr#l@d9Q)C+wC|Wj~QHBc7MA^`I&)l0Q7y&uV25owW_+oxqy(UgX5uD@zAdERUpO@ zClRj`#A#L(h2#M52&;;^5`=-ON=(Cv@pOa~nWiZ#u$}XCI#I7y48wo}Sg+T4L#g>8 z1gfga!ZASWx@H&#LI^nLvY<-sv}ODM{`+s*w!Juz32hul+O{Ren1xfOYEK;;>pB!l5fJgH3U$3E#yI0QP174GnHH;RKD=3hs%9D~KR1&% z?KAo*ule)mPk#LP!8ne2k6F<$44H~dpeB&R;lSy1Vw$E4z^_?@Da+w-;N|6oVHmQt zeIx)SoN1?H+qBe`N2dreQHKhTBFq*ZH4#xD5m1~YDj)Ebojo$9$fPNs(-hU%Vi*RH zM5wAN1MZy54^#5Fh-C2XyK5A%|WbvtPe{vDs{J z&gF+N;TqjkRYi=EmzS4|>z5q7v>ZFzMB;JN@z^y4fi!>H;E)W40E5 z_6G?iB|%(30dbBgD&hkPK-27FjA^R**+Pu*f?vOCnT44UM1;QYGx#Es0|0wpg5{j! z_wV0`2;1#8Tc-J@x~@5$PV{}x;c&R#KuRPa zoh>He07sGurwNs_vYcN5L~r8~?g4&j1tLOS*IE0FqpvyI^1THJyWI{Ep=p||-Of3t zX`=6YUS3`A~1wVoj5tj)^09Ts&S1$v>9DLVxG)xMnk0~v~3GO z-}gC;y%zHuaONM3j@Iinec!X+@AEzr%F?3j{-px6Z99j?Q$k4~uhytcI2A-CLz@)* z95;a`km(hCEijbxbKDYuap=8hsN{AF#kSimBEo*Z&$)u-3+6YLp`_8#;c$3!ezS}+ zDk`nYdp{>xU6-v&oQHhAgq|q^=Wu7>-GW9SA!jG77uugnvv@;IZ!EwPuY37`^1Veh z79ExQmyt^u(HL;2(pHN0N z=4g$^-b>2L`=pfk@#9AhflGf9qt02XF^4!1(_3Y}l(O)+7u1tr&KcCbBdBW>lyFVc z%vsqtFA?E*JW^E^fBp3rP1C$_s<(t`b)}TjMa-|NY`5EUobTSDIamDs56UE$ueZT3 ze1KImzgqxhvbNoBFQTJcLa->Qq^&a4G>5zN57#2DdoFjcO!zYzY$a){HEp+Bnx^?w zh`cOCo8_!lD;^&ob19|t70YbUXa2o&0xA0AgKJ`y=f);LGy2 zm8UJ|Skl>d`#*P2fIsSHSz{)p#PjnryWKATrp#__zm+N8)7~YpPft&|Sa+?TT(&fC zUF(lpz-vWOzno&0pqJWutDavL(=0Q#1kE)6RzJZks_VLotl7GH*BVP-Z6QJRK4EC- zV6O?}Rz3e(NqgC7xz$fl)ofW^*X5+G>?dEdsIT-7?w$>qQY)8^@K!y))Ku#mTVtji zt9h@VVEjK#6T97xzVCCR-*SX&{pGI~Kv}1sE~Ah#G1~2R02hrG1E{Rmmm`snkB@X+ckz805m^Bb$QiWFqb`NI zoO`mlBb)ZSRx$k(VR%V#&N+fjYyI2KSUCZ9O>+#0ID8V?tbh0M22PF_ZxQsYvHq7HP4!&4n&GHiU37p=}3jnuhImd(m`XCQRjP88NkOi>h)w y9&c)})u7BVmzGdAd;ZsD5!q_B$^*zLCH@1LNII_TaD>hP0000GetStringSelection(); main_frame->InitBitmaps(); + main_frame->UpdateGameList(); })); auto const scInterface = new wxBoxSizer(wxHORIZONTAL); diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index 1e4164b7aa..833268ad63 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -34,7 +34,7 @@ #include "FileSearch.h" #include "CompressedBlob.h" #include "ChunkFile.h" -#include "../resources/no_banner.cpp" +#include "ConfigManager.h" #define CACHE_REVISION 0x10F @@ -174,10 +174,16 @@ GameListItem::GameListItem(const std::string& _rFileName) } else { + std::string theme = SConfig::GetInstance().m_LocalCoreStartupParameter.theme_name + "/"; + std::string dir = File::GetUserPath(D_THEMES_IDX) + theme; + +#if !defined(_WIN32) + // If theme does not exist in user's dir load from shared directory + if (!File::Exists(dir)) + dir = SHARED_USER_DIR THEMES_DIR "/" + theme; +#endif // default banner - wxMemoryInputStream istream(no_banner_png, sizeof no_banner_png); - wxImage iNoBanner(istream, wxBITMAP_TYPE_PNG); - m_Image = iNoBanner; + m_Image = wxImage(dir + "nobanner.png", wxBITMAP_TYPE_PNG); } } diff --git a/Source/Core/DolphinWX/resources/no_banner.cpp b/Source/Core/DolphinWX/resources/no_banner.cpp deleted file mode 100644 index df8d51d737..0000000000 --- a/Source/Core/DolphinWX/resources/no_banner.cpp +++ /dev/null @@ -1,28 +0,0 @@ -static const unsigned char no_banner_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, - 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x04, 0x03, - 0x00, 0x00, 0x00, 0x1f, 0xee, 0x60, 0x67, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, - 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, - 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdd, 0x02, - 0x09, 0x16, 0x39, 0x17, 0xf0, 0x40, 0x6e, 0x04, 0x00, 0x00, 0x00, 0x15, 0x50, - 0x4c, 0x54, 0x45, 0x66, 0x66, 0x66, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6d, - 0x6d, 0x6d, 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x80, 0x80, 0x80, 0xd1, 0x7d, - 0x40, 0x35, 0x00, 0x00, 0x00, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x8d, - 0xd4, 0x31, 0x0e, 0xc3, 0x20, 0x10, 0x44, 0xd1, 0x51, 0x64, 0xfa, 0x1c, 0x25, - 0x47, 0x48, 0x45, 0xed, 0xca, 0x07, 0xb0, 0x80, 0xfb, 0x1f, 0x21, 0x05, 0x60, - 0xd6, 0x30, 0xe3, 0xac, 0xbb, 0x95, 0xf8, 0x7a, 0xb2, 0x01, 0xa3, 0x98, 0x27, - 0x01, 0x00, 0x10, 0xfa, 0x9c, 0xeb, 0xbc, 0xd9, 0x35, 0xb0, 0x43, 0xf9, 0xd6, - 0x15, 0x47, 0x1b, 0xf7, 0x3a, 0x46, 0x1d, 0xdc, 0x09, 0x06, 0x4c, 0xc1, 0x9d, - 0x60, 0xc0, 0x1c, 0x58, 0x82, 0x02, 0x73, 0x60, 0x09, 0x0a, 0x2c, 0xc1, 0x20, - 0x38, 0xb0, 0x04, 0x83, 0xe0, 0xc0, 0x1a, 0x74, 0x42, 0x00, 0x6b, 0xd0, 0x89, - 0x0f, 0x07, 0x48, 0xd0, 0x08, 0x01, 0x90, 0xa0, 0x13, 0x1c, 0x60, 0x41, 0x7a, - 0x02, 0x58, 0x60, 0x88, 0xe8, 0x0b, 0xd2, 0x03, 0x40, 0x83, 0x8b, 0x88, 0xde, - 0xe0, 0xac, 0xeb, 0x5f, 0xc5, 0x1b, 0xb4, 0x4d, 0xbe, 0xee, 0xc5, 0xbf, 0x20, - 0xf7, 0x77, 0x08, 0xce, 0x60, 0xbf, 0xbe, 0xd2, 0xe1, 0x0a, 0xf2, 0xd8, 0x87, - 0xe0, 0x0a, 0x76, 0xb3, 0xd3, 0x87, 0x23, 0xc8, 0xf6, 0x2c, 0x05, 0x47, 0xd0, - 0x80, 0xb7, 0x20, 0x20, 0x80, 0x2d, 0x09, 0x02, 0x02, 0x88, 0xf3, 0x3f, 0x4a, - 0x05, 0xe3, 0xa2, 0x09, 0x02, 0x0a, 0x28, 0x82, 0x80, 0x02, 0x14, 0x01, 0x09, - 0x08, 0x02, 0x12, 0x10, 0x04, 0x34, 0xc0, 0x89, 0x1f, 0xe2, 0x9a, 0xca, 0x1c, - 0x5f, 0x12, 0x62, 0x57, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82 -}; From 4aeaf3477e7bf2e4b8a6dc692ca7d43f26c63855 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 22 Feb 2013 22:17:32 -0600 Subject: [PATCH 082/167] Eliminate artifacts in nobanner.png. --- Data/User/Themes/Boomy/nobanner.png | Bin 2484 -> 321 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Data/User/Themes/Boomy/nobanner.png b/Data/User/Themes/Boomy/nobanner.png index 4d34be77626c7f9d77659f8766109b9017baa619..08a30884310ecba0d240432e197700b8db560f68 100644 GIT binary patch delta 306 zcmV-20nPrj6Tt$I7=Hu<0000V?qFvC000?uMObuGZ)S9NVRB^vL1b@YWgtmyVP|Dh zWnpA_ami&o0000LP)t-sW@ct;YHDk1Yi(_9aBy&Qb8~=zfYE(GH2?qr!bwCyR5;6x z)H@EtAP|J%QDpiYB}Yg_?aBwRfcqaI1+O*C5ZtY_zdqRrBY&AE007|X9P@nG9oQj# z^Tt)iGml;ePl5qM@FW;829}_}7+8V=Q_u+xOhG3&Fb9(so{0m}z2e%oV?JHedLG0(?wt@~Y0xN(KP{3Od z5Wo=x0Ri~&A1kGTe$fO01tdX00g8YG1OW*M0vh1N58|529GnDB{Qv*}07*qoM6N<$ Ef@VQ+I{*Lx literal 2484 zcmV;l2}|~gP)WFU8GbZ8()Nlj2>E@cM*00|gLL_t(&-p!hAbKloBF>s^;&fX(Gmm_Z|S}9000{tr#Q2F!1#Bg!i6d7^td>VHoh*_Jsw#kde_Q2wMC9VVa}E(<7zR$K6VK1jytjmejt5-uBv~^m z_)zok@Ico#)OAf7C!FZ~r)hpR^+Y@=DKKLa$B9t6jHQoIF6_)(=_3|XPTz`fF`u6s_@?DhfgVGkVFLM93cc&s}<8U&4-LJgY3P> zdr#l@d9Q)C+wC|Wj~QHBc7MA^`I&)l0Q7y&uV25owW_+oxqy(UgX5uD@zAdERUpO@ zClRj`#A#L(h2#M52&;;^5`=-ON=(Cv@pOa~nWiZ#u$}XCI#I7y48wo}Sg+T4L#g>8 z1gfga!ZASWx@H&#LI^nLvY<-sv}ODM{`+s*w!Juz32hul+O{Ren1xfOYEK;;>pB!l5fJgH3U$3E#yI0QP174GnHH;RKD=3hs%9D~KR1&% z?KAo*ule)mPk#LP!8ne2k6F<$44H~dpeB&R;lSy1Vw$E4z^_?@Da+w-;N|6oVHmQt zeIx)SoN1?H+qBe`N2dreQHKhTBFq*ZH4#xD5m1~YDj)Ebojo$9$fPNs(-hU%Vi*RH zM5wAN1MZy54^#5Fh-C2XyK5A%|WbvtPe{vDs{J z&gF+N;TqjkRYi=EmzS4|>z5q7v>ZFzMB;JN@z^y4fi!>H;E)W40E5 z_6G?iB|%(30dbBgD&hkPK-27FjA^R**+Pu*f?vOCnT44UM1;QYGx#Es0|0wpg5{j! z_wV0`2;1#8Tc-J@x~@5$PV{}x;c&R#KuRPa zoh>He07sGurwNs_vYcN5L~r8~?g4&j1tLOS*IE0FqpvyI^1THJyWI{Ep=p||-Of3t zX`=6YUS3`A~1wVoj5tj)^09Ts&S1$v>9DLVxG)xMnk0~v~3GO z-}gC;y%zHuaONM3j@Iinec!X+@AEzr%F?3j{-px6Z99j?Q$k4~uhytcI2A-CLz@)* z95;a`km(hCEijbxbKDYuap=8hsN{AF#kSimBEo*Z&$)u-3+6YLp`_8#;c$3!ezS}+ zDk`nYdp{>xU6-v&oQHhAgq|q^=Wu7>-GW9SA!jG77uugnvv@;IZ!EwPuY37`^1Veh z79ExQmyt^u(HL;2(pHN0N z=4g$^-b>2L`=pfk@#9AhflGf9qt02XF^4!1(_3Y}l(O)+7u1tr&KcCbBdBW>lyFVc z%vsqtFA?E*JW^E^fBp3rP1C$_s<(t`b)}TjMa-|NY`5EUobTSDIamDs56UE$ueZT3 ze1KImzgqxhvbNoBFQTJcLa->Qq^&a4G>5zN57#2DdoFjcO!zYzY$a){HEp+Bnx^?w zh`cOCo8_!lD;^&ob19|t70YbUXa2o&0xA0AgKJ`y=f);LGy2 zm8UJ|Skl>d`#*P2fIsSHSz{)p#PjnryWKATrp#__zm+N8)7~YpPft&|Sa+?TT(&fC zUF(lpz-vWOzno&0pqJWutDavL(=0Q#1kE)6RzJZks_VLotl7GH*BVP-Z6QJRK4EC- zV6O?}Rz3e(NqgC7xz$fl)ofW^*X5+G>?dEdsIT-7?w$>qQY)8^@K!y))Ku#mTVtji zt9h@VVEjK#6T97xzVCCR-*SX&{pGI~Kv}1sE~Ah#G1~2R02hrG1E{Rmmm`snkB@X+ckz805m^Bb$QiWFqb`NI zoO`mlBb)ZSRx$k(VR%V#&N+fjYyI2KSUCZ9O>+#0ID8V?tbh0M22PF_ZxQsYvHq7HP4!&4n&GHiU37p=}3jnuhImd(m`XCQRjP88NkOi>h)w y9&c)})u7BVmzGdAd;ZsD5!q_B$^*zLCH@1LNII_TaD>hP0000 Date: Sat, 23 Feb 2013 01:47:37 -0500 Subject: [PATCH 083/167] Update CLRun to have OCL 1.2 --- Externals/CLRun/CMakeLists.txt | 5 +- Externals/CLRun/clrun/Makefile | 5 + Externals/CLRun/clrun/gencl.c | 343 +++++++++---- Externals/CLRun/clrun/genclext.c | 28 ++ Externals/CLRun/clrun/genclgl.c | 42 +- Externals/CLRun/clrun/genclglext.c | 11 + Externals/CLRun/clrun/generateClRun.pl | 0 Externals/CLRun/include/CL/cl.h | 454 +++++++++++++++--- Externals/CLRun/include/CL/cl_d3d10.h | 126 +++++ Externals/CLRun/include/CL/cl_d3d11.h | 126 +++++ .../CLRun/include/CL/cl_dx9_media_sharing.h | 127 +++++ Externals/CLRun/include/CL/cl_ext.h | 251 ++++++++++ Externals/CLRun/include/CL/cl_gl.h | 95 ++-- Externals/CLRun/include/CL/cl_gl_ext.h | 69 +++ Externals/CLRun/include/CL/cl_platform.h | 203 +++++++- 15 files changed, 1649 insertions(+), 236 deletions(-) create mode 100644 Externals/CLRun/clrun/genclext.c create mode 100644 Externals/CLRun/clrun/genclglext.c mode change 100644 => 100755 Externals/CLRun/clrun/generateClRun.pl create mode 100644 Externals/CLRun/include/CL/cl_d3d10.h create mode 100644 Externals/CLRun/include/CL/cl_d3d11.h create mode 100644 Externals/CLRun/include/CL/cl_dx9_media_sharing.h create mode 100644 Externals/CLRun/include/CL/cl_ext.h create mode 100644 Externals/CLRun/include/CL/cl_gl_ext.h diff --git a/Externals/CLRun/CMakeLists.txt b/Externals/CLRun/CMakeLists.txt index 7810173a81..3a57ae4563 100644 --- a/Externals/CLRun/CMakeLists.txt +++ b/Externals/CLRun/CMakeLists.txt @@ -1,7 +1,10 @@ set(SRCS clrun/clrun.c clrun/dynamiclib.c clrun/gencl.c - clrun/genclgl.c) + clrun/genclgl.c + clrun/genclext.c + clrun/genclglext.c + ) add_library(clrun STATIC ${SRCS}) target_link_libraries(clrun ${CMAKE_DL_LIBS}) diff --git a/Externals/CLRun/clrun/Makefile b/Externals/CLRun/clrun/Makefile index 9f637269e0..f4186ff741 100644 --- a/Externals/CLRun/clrun/Makefile +++ b/Externals/CLRun/clrun/Makefile @@ -10,6 +10,11 @@ compile: genclrun gencl.c genclgl.c genclrun: ../include/CL/cl.h ../include/CL/cl_gl.h ./generateClRun.pl ../include/CL/cl.h > gencl.c ./generateClRun.pl ../include/CL/cl_gl.h > genclgl.c + ./generateClRun.pl ../include/CL/cl_ext.h > genclext.c + ./generateClRun.pl ../include/CL/cl_gl_ext.h > genclglext.c + ./generateClRun.pl ../include/CL/cl_d3d10.h > gencld3d10.c + ./generateClRun.pl ../include/CL/cl_d3d11.h > gencld3d11.c + ./generateClRun.pl ../include/CL/cl_dx9_media_sharing.h > gencldx9.c clean: diff --git a/Externals/CLRun/clrun/gencl.c b/Externals/CLRun/clrun/gencl.c index 9d55b70232..649e3c67b7 100644 --- a/Externals/CLRun/clrun/gencl.c +++ b/Externals/CLRun/clrun/gencl.c @@ -3,398 +3,543 @@ #include "../include/CL/cl.h" -static cl_int (CL_API_CALL *clGetPlatformIDs_ptr)(cl_uint, cl_platform_id *, cl_uint *) = NULL; +static cl_int (*clGetPlatformIDs_ptr)(cl_uint, cl_platform_id *, cl_uint *) = NULL; cl_int CL_API_CALL clGetPlatformIDs (cl_uint num_entries,cl_platform_id * platforms,cl_uint * num_platforms) { if(!clGetPlatformIDs_ptr) clGetPlatformIDs_ptr = getFunction("clGetPlatformIDs"); return (*clGetPlatformIDs_ptr)(num_entries, platforms, num_platforms); } -static cl_int (CL_API_CALL *clGetPlatformInfo_ptr)(cl_platform_id, cl_platform_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetPlatformInfo_ptr)(cl_platform_id, cl_platform_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetPlatformInfo (cl_platform_id platform,cl_platform_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetPlatformInfo_ptr) clGetPlatformInfo_ptr = getFunction("clGetPlatformInfo"); return (*clGetPlatformInfo_ptr)(platform, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clGetDeviceIDs_ptr)(cl_platform_id, cl_device_type, cl_uint, cl_device_id *, cl_uint *) = NULL; +static cl_int (*clGetDeviceIDs_ptr)(cl_platform_id, cl_device_type, cl_uint, cl_device_id *, cl_uint *) = NULL; cl_int CL_API_CALL clGetDeviceIDs (cl_platform_id platform,cl_device_type device_type,cl_uint num_entries,cl_device_id * devices,cl_uint * num_devices) { if(!clGetDeviceIDs_ptr) clGetDeviceIDs_ptr = getFunction("clGetDeviceIDs"); return (*clGetDeviceIDs_ptr)(platform, device_type, num_entries, devices, num_devices); } -static cl_int (CL_API_CALL *clGetDeviceInfo_ptr)(cl_device_id, cl_device_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetDeviceInfo_ptr)(cl_device_id, cl_device_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetDeviceInfo (cl_device_id device,cl_device_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetDeviceInfo_ptr) clGetDeviceInfo_ptr = getFunction("clGetDeviceInfo"); return (*clGetDeviceInfo_ptr)(device, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_context (CL_API_CALL *clCreateContext_ptr)(const cl_context_properties *, cl_uint, const cl_device_id *, void (CL_CALLBACK *)(const char *, const void *, size_t, void *), void *, cl_int *) = NULL; -cl_context CL_API_CALL clCreateContext (const cl_context_properties * properties,cl_uint num_devices,const cl_device_id * devices,void (CL_CALLBACK * pfn_notify)(const char *, const void *, size_t, void *),void * user_data,cl_int * errcode_ret) { +static cl_int (*clCreateSubDevices_ptr)(cl_device_id, const cl_device_partition_property *, cl_uint, cl_device_id *, cl_uint *) = NULL; +cl_int CL_API_CALL clCreateSubDevices (cl_device_id in_device,const cl_device_partition_property * properties,cl_uint num_devices,cl_device_id * out_devices,cl_uint * num_devices_ret) { + if(!clCreateSubDevices_ptr) clCreateSubDevices_ptr = getFunction("clCreateSubDevices"); + return (*clCreateSubDevices_ptr)(in_device, properties, num_devices, out_devices, num_devices_ret); +} + +static cl_int (*clRetainDevice_ptr)(cl_device_id) = NULL; +cl_int CL_API_CALL clRetainDevice (cl_device_id device) { + if(!clRetainDevice_ptr) clRetainDevice_ptr = getFunction("clRetainDevice"); + return (*clRetainDevice_ptr)(device); +} + +static cl_int (*clReleaseDevice_ptr)(cl_device_id) = NULL; +cl_int CL_API_CALL clReleaseDevice (cl_device_id device) { + if(!clReleaseDevice_ptr) clReleaseDevice_ptr = getFunction("clReleaseDevice"); + return (*clReleaseDevice_ptr)(device); +} + +static cl_context (*clCreateContext_ptr)(const cl_context_properties *, cl_uint, const cl_device_id *, void (CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *), void*, cl_int*) = NULL; +cl_context CL_API_CALL clCreateContext(const cl_context_properties * properties, + cl_uint num_devices, + const cl_device_id * devices, + void (CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *), + void * user_data, + cl_int * errcode_ret) { if(!clCreateContext_ptr) clCreateContext_ptr = getFunction("clCreateContext"); return (*clCreateContext_ptr)(properties, num_devices, devices, pfn_notify, user_data, errcode_ret); } -static cl_context (CL_API_CALL *clCreateContextFromType_ptr)(const cl_context_properties *, cl_device_type, void (CL_CALLBACK *)(const char *, const void *, size_t, void *), void *, cl_int *) = NULL; -cl_context CL_API_CALL clCreateContextFromType (const cl_context_properties * properties,cl_device_type device_type,void (CL_CALLBACK * pfn_notify)(const char *, const void *, size_t, void *),void * user_data,cl_int * errcode_ret) { +static cl_context (*clCreateContextFromType_ptr)(const cl_context_properties *, cl_device_type, void (CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *), void*, cl_int*) = NULL; +cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * properties, + cl_device_type device_type, + void (CL_CALLBACK * pfn_notify)(const char *, const void *, size_t, void *), + void * user_data, + cl_int * errcode_ret) { if(!clCreateContextFromType_ptr) clCreateContextFromType_ptr = getFunction("clCreateContextFromType"); return (*clCreateContextFromType_ptr)(properties, device_type, pfn_notify, user_data, errcode_ret); } -static cl_int (CL_API_CALL *clRetainContext_ptr)(cl_context) = NULL; +static cl_int (*clRetainContext_ptr)(cl_context) = NULL; cl_int CL_API_CALL clRetainContext (cl_context context) { if(!clRetainContext_ptr) clRetainContext_ptr = getFunction("clRetainContext"); return (*clRetainContext_ptr)(context); } -static cl_int (CL_API_CALL *clReleaseContext_ptr)(cl_context) = NULL; +static cl_int (*clReleaseContext_ptr)(cl_context) = NULL; cl_int CL_API_CALL clReleaseContext (cl_context context) { if(!clReleaseContext_ptr) clReleaseContext_ptr = getFunction("clReleaseContext"); return (*clReleaseContext_ptr)(context); } -static cl_int (CL_API_CALL *clGetContextInfo_ptr)(cl_context, cl_context_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetContextInfo_ptr)(cl_context, cl_context_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetContextInfo (cl_context context,cl_context_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetContextInfo_ptr) clGetContextInfo_ptr = getFunction("clGetContextInfo"); return (*clGetContextInfo_ptr)(context, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_command_queue (CL_API_CALL *clCreateCommandQueue_ptr)(cl_context, cl_device_id, cl_command_queue_properties, cl_int *) = NULL; +static cl_command_queue (*clCreateCommandQueue_ptr)(cl_context, cl_device_id, cl_command_queue_properties, cl_int *) = NULL; cl_command_queue CL_API_CALL clCreateCommandQueue (cl_context context,cl_device_id device,cl_command_queue_properties properties,cl_int * errcode_ret) { if(!clCreateCommandQueue_ptr) clCreateCommandQueue_ptr = getFunction("clCreateCommandQueue"); return (*clCreateCommandQueue_ptr)(context, device, properties, errcode_ret); } -static cl_int (CL_API_CALL *clRetainCommandQueue_ptr)(cl_command_queue) = NULL; +static cl_int (*clRetainCommandQueue_ptr)(cl_command_queue) = NULL; cl_int CL_API_CALL clRetainCommandQueue (cl_command_queue command_queue) { if(!clRetainCommandQueue_ptr) clRetainCommandQueue_ptr = getFunction("clRetainCommandQueue"); return (*clRetainCommandQueue_ptr)(command_queue); } -static cl_int (CL_API_CALL *clReleaseCommandQueue_ptr)(cl_command_queue) = NULL; +static cl_int (*clReleaseCommandQueue_ptr)(cl_command_queue) = NULL; cl_int CL_API_CALL clReleaseCommandQueue (cl_command_queue command_queue) { if(!clReleaseCommandQueue_ptr) clReleaseCommandQueue_ptr = getFunction("clReleaseCommandQueue"); return (*clReleaseCommandQueue_ptr)(command_queue); } -static cl_int (CL_API_CALL *clGetCommandQueueInfo_ptr)(cl_command_queue, cl_command_queue_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetCommandQueueInfo_ptr)(cl_command_queue, cl_command_queue_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetCommandQueueInfo (cl_command_queue command_queue,cl_command_queue_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetCommandQueueInfo_ptr) clGetCommandQueueInfo_ptr = getFunction("clGetCommandQueueInfo"); return (*clGetCommandQueueInfo_ptr)(command_queue, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clSetCommandQueueProperty_ptr)(cl_command_queue, cl_command_queue_properties, cl_bool, cl_command_queue_properties *) = NULL; -cl_int CL_API_CALL clSetCommandQueueProperty (cl_command_queue command_queue,cl_command_queue_properties properties,cl_bool enable,cl_command_queue_properties * old_properties) { - if(!clSetCommandQueueProperty_ptr) clSetCommandQueueProperty_ptr = getFunction("clSetCommandQueueProperty"); - return (*clSetCommandQueueProperty_ptr)(command_queue, properties, enable, old_properties); -} - -static cl_mem (CL_API_CALL *clCreateBuffer_ptr)(cl_context, cl_mem_flags, size_t, void *, cl_int *) = NULL; +static cl_mem (*clCreateBuffer_ptr)(cl_context, cl_mem_flags, size_t, void *, cl_int *) = NULL; cl_mem CL_API_CALL clCreateBuffer (cl_context context,cl_mem_flags flags,size_t size,void * host_ptr,cl_int * errcode_ret) { if(!clCreateBuffer_ptr) clCreateBuffer_ptr = getFunction("clCreateBuffer"); return (*clCreateBuffer_ptr)(context, flags, size, host_ptr, errcode_ret); } -static cl_mem (CL_API_CALL *clCreateImage2D_ptr)(cl_context, cl_mem_flags, const cl_image_format *, size_t, size_t, size_t, void *, cl_int *) = NULL; -cl_mem CL_API_CALL clCreateImage2D (cl_context context,cl_mem_flags flags,const cl_image_format * image_format,size_t image_width,size_t image_height,size_t image_row_pitch,void * host_ptr,cl_int * errcode_ret) { - if(!clCreateImage2D_ptr) clCreateImage2D_ptr = getFunction("clCreateImage2D"); - return (*clCreateImage2D_ptr)(context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret); +static cl_mem (*clCreateSubBuffer_ptr)(cl_mem, cl_mem_flags, cl_buffer_create_type, const void *, cl_int *) = NULL; +cl_mem CL_API_CALL clCreateSubBuffer (cl_mem buffer,cl_mem_flags flags,cl_buffer_create_type buffer_create_type,const void * buffer_create_info,cl_int * errcode_ret) { + if(!clCreateSubBuffer_ptr) clCreateSubBuffer_ptr = getFunction("clCreateSubBuffer"); + return (*clCreateSubBuffer_ptr)(buffer, flags, buffer_create_type, buffer_create_info, errcode_ret); } -static cl_mem (CL_API_CALL *clCreateImage3D_ptr)(cl_context, cl_mem_flags, const cl_image_format *, size_t, size_t, size_t, size_t, size_t, void *, cl_int *) = NULL; -cl_mem CL_API_CALL clCreateImage3D (cl_context context,cl_mem_flags flags,const cl_image_format * image_format,size_t image_width,size_t image_height,size_t image_depth,size_t image_row_pitch,size_t image_slice_pitch,void * host_ptr,cl_int * errcode_ret) { - if(!clCreateImage3D_ptr) clCreateImage3D_ptr = getFunction("clCreateImage3D"); - return (*clCreateImage3D_ptr)(context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret); +static cl_mem (*clCreateImage_ptr)(cl_context, cl_mem_flags, const cl_image_format *, const cl_image_desc *, void *, cl_int *) = NULL; +cl_mem CL_API_CALL clCreateImage (cl_context context,cl_mem_flags flags,const cl_image_format * image_format,const cl_image_desc * image_desc,void * host_ptr,cl_int * errcode_ret) { + if(!clCreateImage_ptr) clCreateImage_ptr = getFunction("clCreateImage"); + return (*clCreateImage_ptr)(context, flags, image_format, image_desc, host_ptr, errcode_ret); } -static cl_int (CL_API_CALL *clRetainMemObject_ptr)(cl_mem) = NULL; +static cl_int (*clRetainMemObject_ptr)(cl_mem) = NULL; cl_int CL_API_CALL clRetainMemObject (cl_mem memobj) { if(!clRetainMemObject_ptr) clRetainMemObject_ptr = getFunction("clRetainMemObject"); return (*clRetainMemObject_ptr)(memobj); } -static cl_int (CL_API_CALL *clReleaseMemObject_ptr)(cl_mem) = NULL; +static cl_int (*clReleaseMemObject_ptr)(cl_mem) = NULL; cl_int CL_API_CALL clReleaseMemObject (cl_mem memobj) { if(!clReleaseMemObject_ptr) clReleaseMemObject_ptr = getFunction("clReleaseMemObject"); return (*clReleaseMemObject_ptr)(memobj); } -static cl_int (CL_API_CALL *clGetSupportedImageFormats_ptr)(cl_context, cl_mem_flags, cl_mem_object_type, cl_uint, cl_image_format *, cl_uint *) = NULL; +static cl_int (*clGetSupportedImageFormats_ptr)(cl_context, cl_mem_flags, cl_mem_object_type, cl_uint, cl_image_format *, cl_uint *) = NULL; cl_int CL_API_CALL clGetSupportedImageFormats (cl_context context,cl_mem_flags flags,cl_mem_object_type image_type,cl_uint num_entries,cl_image_format * image_formats,cl_uint * num_image_formats) { if(!clGetSupportedImageFormats_ptr) clGetSupportedImageFormats_ptr = getFunction("clGetSupportedImageFormats"); return (*clGetSupportedImageFormats_ptr)(context, flags, image_type, num_entries, image_formats, num_image_formats); } -static cl_int (CL_API_CALL *clGetMemObjectInfo_ptr)(cl_mem, cl_mem_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetMemObjectInfo_ptr)(cl_mem, cl_mem_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetMemObjectInfo (cl_mem memobj,cl_mem_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetMemObjectInfo_ptr) clGetMemObjectInfo_ptr = getFunction("clGetMemObjectInfo"); return (*clGetMemObjectInfo_ptr)(memobj, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clGetImageInfo_ptr)(cl_mem, cl_image_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetImageInfo_ptr)(cl_mem, cl_image_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetImageInfo (cl_mem image,cl_image_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetImageInfo_ptr) clGetImageInfo_ptr = getFunction("clGetImageInfo"); return (*clGetImageInfo_ptr)(image, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_sampler (CL_API_CALL *clCreateSampler_ptr)(cl_context, cl_bool, cl_addressing_mode, cl_filter_mode, cl_int *) = NULL; -cl_sampler CL_API_CALL clCreateSampler (cl_context context,cl_bool normalized_coords,cl_addressing_mode addressing_mode,cl_filter_mode filter_mode,cl_int * errcode_ret) { +/* Sampler APIs */ +static cl_int (*clSetMemObjectDestructorCallback_ptr)(cl_mem memobj,void (CL_CALLBACK *pfn_notify)( cl_mem memobj, void*) ,void *user_data ) = NULL; +cl_int CL_API_CALL clSetMemObjectDestructorCallback (cl_mem memobj,void (CL_CALLBACK *pfn_notify)( cl_mem memobj, void*) ,void *user_data ) +{ + if(!clSetMemObjectDestructorCallback_ptr) clSetMemObjectDestructorCallback_ptr = getFunction("clSetMemObjectDestructorCallback"); + return (*clSetMemObjectDestructorCallback_ptr)(memobj, pfn_notify, user_data); +} + +/* Sampler APIs */ +static cl_sampler (*clCreateSampler_ptr)(cl_context, cl_bool, cl_addressing_mode, cl_filter_mode, cl_int *) = NULL; +cl_sampler CL_API_CALL clCreateSampler(cl_context context,cl_bool normalized_coords,cl_addressing_mode addressing_mode,cl_filter_mode filter_mode,cl_int * errcode_ret) { if(!clCreateSampler_ptr) clCreateSampler_ptr = getFunction("clCreateSampler"); return (*clCreateSampler_ptr)(context, normalized_coords, addressing_mode, filter_mode, errcode_ret); } -static cl_int (CL_API_CALL *clRetainSampler_ptr)(cl_sampler) = NULL; +static cl_int (*clRetainSampler_ptr)(cl_sampler) = NULL; cl_int CL_API_CALL clRetainSampler (cl_sampler sampler) { if(!clRetainSampler_ptr) clRetainSampler_ptr = getFunction("clRetainSampler"); return (*clRetainSampler_ptr)(sampler); } -static cl_int (CL_API_CALL *clReleaseSampler_ptr)(cl_sampler) = NULL; +static cl_int (*clReleaseSampler_ptr)(cl_sampler) = NULL; cl_int CL_API_CALL clReleaseSampler (cl_sampler sampler) { if(!clReleaseSampler_ptr) clReleaseSampler_ptr = getFunction("clReleaseSampler"); return (*clReleaseSampler_ptr)(sampler); } -static cl_int (CL_API_CALL *clGetSamplerInfo_ptr)(cl_sampler, cl_sampler_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetSamplerInfo_ptr)(cl_sampler, cl_sampler_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetSamplerInfo (cl_sampler sampler,cl_sampler_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetSamplerInfo_ptr) clGetSamplerInfo_ptr = getFunction("clGetSamplerInfo"); return (*clGetSamplerInfo_ptr)(sampler, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_program (CL_API_CALL *clCreateProgramWithSource_ptr)(cl_context, cl_uint, const char **, const size_t *, cl_int *) = NULL; +static cl_program (*clCreateProgramWithSource_ptr)(cl_context, cl_uint, const char **, const size_t *, cl_int *) = NULL; cl_program CL_API_CALL clCreateProgramWithSource (cl_context context,cl_uint count,const char ** strings,const size_t * lengths,cl_int * errcode_ret) { if(!clCreateProgramWithSource_ptr) clCreateProgramWithSource_ptr = getFunction("clCreateProgramWithSource"); return (*clCreateProgramWithSource_ptr)(context, count, strings, lengths, errcode_ret); } -static cl_program (CL_API_CALL *clCreateProgramWithBinary_ptr)(cl_context, cl_uint, const cl_device_id *, const size_t *, const unsigned char **, cl_int *, cl_int *) = NULL; +static cl_program (*clCreateProgramWithBinary_ptr)(cl_context, cl_uint, const cl_device_id *, const size_t *, const unsigned char **, cl_int *, cl_int *) = NULL; cl_program CL_API_CALL clCreateProgramWithBinary (cl_context context,cl_uint num_devices,const cl_device_id * device_list,const size_t * lengths,const unsigned char ** binaries,cl_int * binary_status,cl_int * errcode_ret) { if(!clCreateProgramWithBinary_ptr) clCreateProgramWithBinary_ptr = getFunction("clCreateProgramWithBinary"); return (*clCreateProgramWithBinary_ptr)(context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret); } -static cl_int (CL_API_CALL *clRetainProgram_ptr)(cl_program) = NULL; +static cl_program (*clCreateProgramWithBuiltInKernels_ptr)(cl_context, cl_uint, const cl_device_id *, const char *, cl_int *) = NULL; +cl_program CL_API_CALL clCreateProgramWithBuiltInKernels (cl_context context,cl_uint num_devices,const cl_device_id * device_list,const char * kernel_names,cl_int * errcode_ret) { + if(!clCreateProgramWithBuiltInKernels_ptr) clCreateProgramWithBuiltInKernels_ptr = getFunction("clCreateProgramWithBuiltInKernels"); + return (*clCreateProgramWithBuiltInKernels_ptr)(context, num_devices, device_list, kernel_names, errcode_ret); +} + +static cl_int (*clRetainProgram_ptr)(cl_program) = NULL; cl_int CL_API_CALL clRetainProgram (cl_program program) { if(!clRetainProgram_ptr) clRetainProgram_ptr = getFunction("clRetainProgram"); return (*clRetainProgram_ptr)(program); } -static cl_int (CL_API_CALL *clReleaseProgram_ptr)(cl_program) = NULL; +static cl_int (*clReleaseProgram_ptr)(cl_program) = NULL; cl_int CL_API_CALL clReleaseProgram (cl_program program) { if(!clReleaseProgram_ptr) clReleaseProgram_ptr = getFunction("clReleaseProgram"); return (*clReleaseProgram_ptr)(program); } -static cl_int (CL_API_CALL *clBuildProgram_ptr)(cl_program, cl_uint, const cl_device_id *, const char *, void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void *), void *) = NULL; -cl_int CL_API_CALL clBuildProgram (cl_program program,cl_uint num_devices,const cl_device_id * device_list,const char * options,void (CL_CALLBACK * pfn_notify)(cl_program /* program */, void *),void * user_data) { +static cl_int (*clBuildProgram_ptr)(cl_program, cl_uint, const cl_device_id *, const char *, void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), void *) = NULL; +cl_int CL_API_CALL clBuildProgram (cl_program program,cl_uint num_devices,const cl_device_id * device_list,const char * options, void (CL_CALLBACK * pfn_notify)(cl_program /* program */, void * /* user_data */),void * user_data) { if(!clBuildProgram_ptr) clBuildProgram_ptr = getFunction("clBuildProgram"); - return (*clBuildProgram_ptr)(program, num_devices, device_list, options, pfn_notify, user_data); + return (*clBuildProgram_ptr)(program, num_devices, device_list, options, user_data, user_data); } -static cl_int (CL_API_CALL *clUnloadCompiler_ptr)(void) = NULL; -cl_int CL_API_CALL clUnloadCompiler (void) { - if(!clUnloadCompiler_ptr) clUnloadCompiler_ptr = getFunction("clUnloadCompiler"); - return (*clUnloadCompiler_ptr)(); +static cl_int (*clCompileProgram_ptr)(cl_program, cl_uint, const cl_device_id *, const char *, cl_uint, const cl_program *, const char **, void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), void *) = NULL; +cl_int CL_API_CALL clCompileProgram (cl_program program,cl_uint num_devices,const cl_device_id * device_list,const char * options,cl_uint num_input_headers,const cl_program * input_headers,const char ** header_include_names,void (CL_CALLBACK * pfn_notify)(cl_program /* program */, void * /* user_data */),void * user_data) { + if(!clCompileProgram_ptr) clCompileProgram_ptr = getFunction("clCompileProgram"); + return (*clCompileProgram_ptr)(program, num_devices, device_list, options, num_input_headers, input_headers, header_include_names, user_data, user_data); } -static cl_int (CL_API_CALL *clGetProgramInfo_ptr)(cl_program, cl_program_info, size_t, void *, size_t *) = NULL; +static cl_program (*clLinkProgram_ptr)(cl_context, cl_uint, const cl_device_id *, const char *, cl_uint, const cl_program *, void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), void *, cl_int *) = NULL; +cl_program CL_API_CALL clLinkProgram (cl_context context,cl_uint num_devices,const cl_device_id * device_list,const char * options,cl_uint num_input_programs,const cl_program * input_programs,void (CL_CALLBACK * pfn_notify)(cl_program /* program */, void * /* user_data */),void * user_data,cl_int * errcode_ret) { + if(!clLinkProgram_ptr) clLinkProgram_ptr = getFunction("clLinkProgram"); + return (*clLinkProgram_ptr)(context, num_devices, device_list, options, num_input_programs, input_programs, user_data, user_data, errcode_ret); +} + +static cl_int (*clUnloadPlatformCompiler_ptr)(cl_platform_id) = NULL; +cl_int CL_API_CALL clUnloadPlatformCompiler (cl_platform_id platform) { + if(!clUnloadPlatformCompiler_ptr) clUnloadPlatformCompiler_ptr = getFunction("clUnloadPlatformCompiler"); + return (*clUnloadPlatformCompiler_ptr)(platform); +} + +static cl_int (*clGetProgramInfo_ptr)(cl_program, cl_program_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetProgramInfo (cl_program program,cl_program_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetProgramInfo_ptr) clGetProgramInfo_ptr = getFunction("clGetProgramInfo"); return (*clGetProgramInfo_ptr)(program, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clGetProgramBuildInfo_ptr)(cl_program, cl_device_id, cl_program_build_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetProgramBuildInfo_ptr)(cl_program, cl_device_id, cl_program_build_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetProgramBuildInfo (cl_program program,cl_device_id device,cl_program_build_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetProgramBuildInfo_ptr) clGetProgramBuildInfo_ptr = getFunction("clGetProgramBuildInfo"); return (*clGetProgramBuildInfo_ptr)(program, device, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_kernel (CL_API_CALL *clCreateKernel_ptr)(cl_program, const char *, cl_int *) = NULL; +static cl_kernel (*clCreateKernel_ptr)(cl_program, const char *, cl_int *) = NULL; cl_kernel CL_API_CALL clCreateKernel (cl_program program,const char * kernel_name,cl_int * errcode_ret) { if(!clCreateKernel_ptr) clCreateKernel_ptr = getFunction("clCreateKernel"); return (*clCreateKernel_ptr)(program, kernel_name, errcode_ret); } -static cl_int (CL_API_CALL *clCreateKernelsInProgram_ptr)(cl_program, cl_uint, cl_kernel *, cl_uint *) = NULL; +static cl_int (*clCreateKernelsInProgram_ptr)(cl_program, cl_uint, cl_kernel *, cl_uint *) = NULL; cl_int CL_API_CALL clCreateKernelsInProgram (cl_program program,cl_uint num_kernels,cl_kernel * kernels,cl_uint * num_kernels_ret) { if(!clCreateKernelsInProgram_ptr) clCreateKernelsInProgram_ptr = getFunction("clCreateKernelsInProgram"); return (*clCreateKernelsInProgram_ptr)(program, num_kernels, kernels, num_kernels_ret); } -static cl_int (CL_API_CALL *clRetainKernel_ptr)(cl_kernel) = NULL; +static cl_int (*clRetainKernel_ptr)(cl_kernel) = NULL; cl_int CL_API_CALL clRetainKernel (cl_kernel kernel) { if(!clRetainKernel_ptr) clRetainKernel_ptr = getFunction("clRetainKernel"); return (*clRetainKernel_ptr)(kernel); } -static cl_int (CL_API_CALL *clReleaseKernel_ptr)(cl_kernel) = NULL; +static cl_int (*clReleaseKernel_ptr)(cl_kernel) = NULL; cl_int CL_API_CALL clReleaseKernel (cl_kernel kernel) { if(!clReleaseKernel_ptr) clReleaseKernel_ptr = getFunction("clReleaseKernel"); return (*clReleaseKernel_ptr)(kernel); } -static cl_int (CL_API_CALL *clSetKernelArg_ptr)(cl_kernel, cl_uint, size_t, const void *) = NULL; +static cl_int (*clSetKernelArg_ptr)(cl_kernel, cl_uint, size_t, const void *) = NULL; cl_int CL_API_CALL clSetKernelArg (cl_kernel kernel,cl_uint arg_index,size_t arg_size,const void * arg_value) { if(!clSetKernelArg_ptr) clSetKernelArg_ptr = getFunction("clSetKernelArg"); return (*clSetKernelArg_ptr)(kernel, arg_index, arg_size, arg_value); } -static cl_int (CL_API_CALL *clGetKernelInfo_ptr)(cl_kernel, cl_kernel_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetKernelInfo_ptr)(cl_kernel, cl_kernel_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetKernelInfo (cl_kernel kernel,cl_kernel_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetKernelInfo_ptr) clGetKernelInfo_ptr = getFunction("clGetKernelInfo"); return (*clGetKernelInfo_ptr)(kernel, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clGetKernelWorkGroupInfo_ptr)(cl_kernel, cl_device_id, cl_kernel_work_group_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetKernelArgInfo_ptr)(cl_kernel, cl_uint, cl_kernel_arg_info, size_t, void *, size_t *) = NULL; +cl_int CL_API_CALL clGetKernelArgInfo (cl_kernel kernel,cl_uint arg_indx,cl_kernel_arg_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { + if(!clGetKernelArgInfo_ptr) clGetKernelArgInfo_ptr = getFunction("clGetKernelArgInfo"); + return (*clGetKernelArgInfo_ptr)(kernel, arg_indx, param_name, param_value_size, param_value, param_value_size_ret); +} + +static cl_int (*clGetKernelWorkGroupInfo_ptr)(cl_kernel, cl_device_id, cl_kernel_work_group_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetKernelWorkGroupInfo (cl_kernel kernel,cl_device_id device,cl_kernel_work_group_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetKernelWorkGroupInfo_ptr) clGetKernelWorkGroupInfo_ptr = getFunction("clGetKernelWorkGroupInfo"); return (*clGetKernelWorkGroupInfo_ptr)(kernel, device, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clWaitForEvents_ptr)(cl_uint, const cl_event *) = NULL; +static cl_int (*clWaitForEvents_ptr)(cl_uint, const cl_event *) = NULL; cl_int CL_API_CALL clWaitForEvents (cl_uint num_events,const cl_event * event_list) { if(!clWaitForEvents_ptr) clWaitForEvents_ptr = getFunction("clWaitForEvents"); return (*clWaitForEvents_ptr)(num_events, event_list); } -static cl_int (CL_API_CALL *clGetEventInfo_ptr)(cl_event, cl_event_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetEventInfo_ptr)(cl_event, cl_event_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetEventInfo (cl_event event,cl_event_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetEventInfo_ptr) clGetEventInfo_ptr = getFunction("clGetEventInfo"); return (*clGetEventInfo_ptr)(event, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clRetainEvent_ptr)(cl_event) = NULL; -cl_int CL_API_CALL clRetainEvent (cl_event event) { +static cl_event (*clCreateUserEvent_ptr)(cl_context, cl_int * /* errcode_ret */) = NULL; +cl_event CL_API_CALL clCreateUserEvent (cl_context context,cl_int * errcode_ret) +{ + if(!clCreateUserEvent_ptr) clCreateUserEvent_ptr = getFunction("clCreateUserEvent"); + return (*clCreateUserEvent_ptr)(context,errcode_ret); +} + +static cl_int (*clRetainEvent_ptr)(cl_event) = NULL; +cl_int CL_API_CALL clRetainEvent(cl_event event) { if(!clRetainEvent_ptr) clRetainEvent_ptr = getFunction("clRetainEvent"); return (*clRetainEvent_ptr)(event); } -static cl_int (CL_API_CALL *clReleaseEvent_ptr)(cl_event) = NULL; +static cl_int (*clReleaseEvent_ptr)(cl_event) = NULL; cl_int CL_API_CALL clReleaseEvent (cl_event event) { if(!clReleaseEvent_ptr) clReleaseEvent_ptr = getFunction("clReleaseEvent"); return (*clReleaseEvent_ptr)(event); } -static cl_int (CL_API_CALL *clGetEventProfilingInfo_ptr)(cl_event, cl_profiling_info, size_t, void *, size_t *) = NULL; +static cl_int (*clSetUserEventStatus_ptr)(cl_event, cl_int) = NULL; +cl_int CL_API_CALL clSetUserEventStatus (cl_event event,cl_int execution_status) { + if(!clSetUserEventStatus_ptr) clSetUserEventStatus_ptr = getFunction("clSetUserEventStatus"); + return (*clSetUserEventStatus_ptr)(event, execution_status); +} + +static cl_int (*clSetEventCallback_ptr)(cl_event, cl_int, void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *), void*) = NULL; +cl_int CL_API_CALL clSetEventCallback (cl_event event,cl_int command_exec_callback_type, void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *), void* user_data) { + if(!clSetEventCallback_ptr) clSetEventCallback_ptr = getFunction("clSetEventCallback"); + return (*clSetEventCallback_ptr)(event, command_exec_callback_type, pfn_notify, user_data); +} + +static cl_int (*clGetEventProfilingInfo_ptr)(cl_event, cl_profiling_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetEventProfilingInfo (cl_event event,cl_profiling_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetEventProfilingInfo_ptr) clGetEventProfilingInfo_ptr = getFunction("clGetEventProfilingInfo"); return (*clGetEventProfilingInfo_ptr)(event, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clFlush_ptr)(cl_command_queue) = NULL; +static cl_int (*clFlush_ptr)(cl_command_queue) = NULL; cl_int CL_API_CALL clFlush (cl_command_queue command_queue) { if(!clFlush_ptr) clFlush_ptr = getFunction("clFlush"); return (*clFlush_ptr)(command_queue); } -static cl_int (CL_API_CALL *clFinish_ptr)(cl_command_queue) = NULL; +static cl_int (*clFinish_ptr)(cl_command_queue) = NULL; cl_int CL_API_CALL clFinish (cl_command_queue command_queue) { if(!clFinish_ptr) clFinish_ptr = getFunction("clFinish"); return (*clFinish_ptr)(command_queue); } -static cl_int (CL_API_CALL *clEnqueueReadBuffer_ptr)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *) = NULL; -cl_int CL_API_CALL clEnqueueReadBuffer (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_read,size_t offset,size_t cb,void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { +static cl_int (*clEnqueueReadBuffer_ptr)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueReadBuffer (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_read,size_t offset,size_t size,void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueReadBuffer_ptr) clEnqueueReadBuffer_ptr = getFunction("clEnqueueReadBuffer"); - return (*clEnqueueReadBuffer_ptr)(command_queue, buffer, blocking_read, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event); + return (*clEnqueueReadBuffer_ptr)(command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueWriteBuffer_ptr)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *) = NULL; -cl_int CL_API_CALL clEnqueueWriteBuffer (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_write,size_t offset,size_t cb,const void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { +static cl_int (*clEnqueueReadBufferRect_ptr)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueReadBufferRect (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_read,const size_t * buffer_offset,const size_t * host_offset,const size_t * region,size_t buffer_row_pitch,size_t buffer_slice_pitch,size_t host_row_pitch,size_t host_slice_pitch,void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueReadBufferRect_ptr) clEnqueueReadBufferRect_ptr = getFunction("clEnqueueReadBufferRect"); + return (*clEnqueueReadBufferRect_ptr)(command_queue, buffer, blocking_read, buffer_offset, host_offset, region, buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); +} + +static cl_int (*clEnqueueWriteBuffer_ptr)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueWriteBuffer (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_write,size_t offset,size_t size,const void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueWriteBuffer_ptr) clEnqueueWriteBuffer_ptr = getFunction("clEnqueueWriteBuffer"); - return (*clEnqueueWriteBuffer_ptr)(command_queue, buffer, blocking_write, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event); + return (*clEnqueueWriteBuffer_ptr)(command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueCopyBuffer_ptr)(cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *) = NULL; -cl_int CL_API_CALL clEnqueueCopyBuffer (cl_command_queue command_queue,cl_mem src_buffer,cl_mem dst_buffer,size_t src_offset,size_t dst_offset,size_t cb,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { +static cl_int (*clEnqueueWriteBufferRect_ptr)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueWriteBufferRect (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_write,const size_t * buffer_offset,const size_t * host_offset,const size_t * region,size_t buffer_row_pitch,size_t buffer_slice_pitch,size_t host_row_pitch,size_t host_slice_pitch,const void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueWriteBufferRect_ptr) clEnqueueWriteBufferRect_ptr = getFunction("clEnqueueWriteBufferRect"); + return (*clEnqueueWriteBufferRect_ptr)(command_queue, buffer, blocking_write, buffer_offset, host_offset, region, buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); +} + +static cl_int (*clEnqueueFillBuffer_ptr)(cl_command_queue, cl_mem, const void *, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueFillBuffer (cl_command_queue command_queue,cl_mem buffer,const void * pattern,size_t pattern_size,size_t offset,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueFillBuffer_ptr) clEnqueueFillBuffer_ptr = getFunction("clEnqueueFillBuffer"); + return (*clEnqueueFillBuffer_ptr)(command_queue, buffer, pattern, pattern_size, offset, size, num_events_in_wait_list, event_wait_list, event); +} + +static cl_int (*clEnqueueCopyBuffer_ptr)(cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueCopyBuffer (cl_command_queue command_queue,cl_mem src_buffer,cl_mem dst_buffer,size_t src_offset,size_t dst_offset,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueCopyBuffer_ptr) clEnqueueCopyBuffer_ptr = getFunction("clEnqueueCopyBuffer"); - return (*clEnqueueCopyBuffer_ptr)(command_queue, src_buffer, dst_buffer, src_offset, dst_offset, cb, num_events_in_wait_list, event_wait_list, event); + return (*clEnqueueCopyBuffer_ptr)(command_queue, src_buffer, dst_buffer, src_offset, dst_offset, size, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueReadImage_ptr)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueCopyBufferRect_ptr)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueCopyBufferRect (cl_command_queue command_queue,cl_mem src_buffer,cl_mem dst_buffer,const size_t * src_origin,const size_t * dst_origin,const size_t * region,size_t src_row_pitch,size_t src_slice_pitch,size_t dst_row_pitch,size_t dst_slice_pitch,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueCopyBufferRect_ptr) clEnqueueCopyBufferRect_ptr = getFunction("clEnqueueCopyBufferRect"); + return (*clEnqueueCopyBufferRect_ptr)(command_queue, src_buffer, dst_buffer, src_origin, dst_origin, region, src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, num_events_in_wait_list, event_wait_list, event); +} + +static cl_int (*clEnqueueReadImage_ptr)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueReadImage (cl_command_queue command_queue,cl_mem image,cl_bool blocking_read,const size_t * origin,const size_t * region,size_t row_pitch,size_t slice_pitch,void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueReadImage_ptr) clEnqueueReadImage_ptr = getFunction("clEnqueueReadImage"); return (*clEnqueueReadImage_ptr)(command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueWriteImage_ptr)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueWriteImage_ptr)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueWriteImage (cl_command_queue command_queue,cl_mem image,cl_bool blocking_write,const size_t * origin,const size_t * region,size_t input_row_pitch,size_t input_slice_pitch,const void * ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueWriteImage_ptr) clEnqueueWriteImage_ptr = getFunction("clEnqueueWriteImage"); return (*clEnqueueWriteImage_ptr)(command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueCopyImage_ptr)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueFillImage_ptr)(cl_command_queue, cl_mem, const void *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueFillImage (cl_command_queue command_queue,cl_mem image,const void * fill_color,const size_t * origin,const size_t * region,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueFillImage_ptr) clEnqueueFillImage_ptr = getFunction("clEnqueueFillImage"); + return (*clEnqueueFillImage_ptr)(command_queue, image, fill_color, origin, region, num_events_in_wait_list, event_wait_list, event); +} + +static cl_int (*clEnqueueCopyImage_ptr)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueCopyImage (cl_command_queue command_queue,cl_mem src_image,cl_mem dst_image,const size_t * src_origin,const size_t * dst_origin,const size_t * region,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueCopyImage_ptr) clEnqueueCopyImage_ptr = getFunction("clEnqueueCopyImage"); return (*clEnqueueCopyImage_ptr)(command_queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueCopyImageToBuffer_ptr)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, size_t, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueCopyImageToBuffer_ptr)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, size_t, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueCopyImageToBuffer (cl_command_queue command_queue,cl_mem src_image,cl_mem dst_buffer,const size_t * src_origin,const size_t * region,size_t dst_offset,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueCopyImageToBuffer_ptr) clEnqueueCopyImageToBuffer_ptr = getFunction("clEnqueueCopyImageToBuffer"); return (*clEnqueueCopyImageToBuffer_ptr)(command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueCopyBufferToImage_ptr)(cl_command_queue, cl_mem, cl_mem, size_t, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueCopyBufferToImage_ptr)(cl_command_queue, cl_mem, cl_mem, size_t, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueCopyBufferToImage (cl_command_queue command_queue,cl_mem src_buffer,cl_mem dst_image,size_t src_offset,const size_t * dst_origin,const size_t * region,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueCopyBufferToImage_ptr) clEnqueueCopyBufferToImage_ptr = getFunction("clEnqueueCopyBufferToImage"); return (*clEnqueueCopyBufferToImage_ptr)(command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list, event); } -static void * (CL_API_CALL *clEnqueueMapBuffer_ptr)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, const cl_event *, cl_event *, cl_int *) = NULL; -void * CL_API_CALL clEnqueueMapBuffer (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_map,cl_map_flags map_flags,size_t offset,size_t cb,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event,cl_int * errcode_ret) { +static void * (*clEnqueueMapBuffer_ptr)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, const cl_event *, cl_event *, cl_int *) = NULL; +void * CL_API_CALL clEnqueueMapBuffer (cl_command_queue command_queue,cl_mem buffer,cl_bool blocking_map,cl_map_flags map_flags,size_t offset,size_t size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event,cl_int * errcode_ret) { if(!clEnqueueMapBuffer_ptr) clEnqueueMapBuffer_ptr = getFunction("clEnqueueMapBuffer"); - return (*clEnqueueMapBuffer_ptr)(command_queue, buffer, blocking_map, map_flags, offset, cb, num_events_in_wait_list, event_wait_list, event, errcode_ret); + return (*clEnqueueMapBuffer_ptr)(command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret); } -static void * (CL_API_CALL *clEnqueueMapImage_ptr)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, const size_t *, const size_t *, size_t *, size_t *, cl_uint, const cl_event *, cl_event *, cl_int *) = NULL; +static void * (*clEnqueueMapImage_ptr)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, const size_t *, const size_t *, size_t *, size_t *, cl_uint, const cl_event *, cl_event *, cl_int *) = NULL; void * CL_API_CALL clEnqueueMapImage (cl_command_queue command_queue,cl_mem image,cl_bool blocking_map,cl_map_flags map_flags,const size_t * origin,const size_t * region,size_t * image_row_pitch,size_t * image_slice_pitch,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event,cl_int * errcode_ret) { if(!clEnqueueMapImage_ptr) clEnqueueMapImage_ptr = getFunction("clEnqueueMapImage"); return (*clEnqueueMapImage_ptr)(command_queue, image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event, errcode_ret); } -static cl_int (CL_API_CALL *clEnqueueUnmapMemObject_ptr)(cl_command_queue, cl_mem, void *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueUnmapMemObject_ptr)(cl_command_queue, cl_mem, void *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueUnmapMemObject (cl_command_queue command_queue,cl_mem memobj,void * mapped_ptr,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueUnmapMemObject_ptr) clEnqueueUnmapMemObject_ptr = getFunction("clEnqueueUnmapMemObject"); return (*clEnqueueUnmapMemObject_ptr)(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueNDRangeKernel_ptr)(cl_command_queue, cl_kernel, cl_uint, const size_t *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueMigrateMemObjects_ptr)(cl_command_queue, cl_uint, const cl_mem *, cl_mem_migration_flags, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueMigrateMemObjects (cl_command_queue command_queue,cl_uint num_mem_objects,const cl_mem * mem_objects,cl_mem_migration_flags flags,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueMigrateMemObjects_ptr) clEnqueueMigrateMemObjects_ptr = getFunction("clEnqueueMigrateMemObjects"); + return (*clEnqueueMigrateMemObjects_ptr)(command_queue, num_mem_objects, mem_objects, flags, num_events_in_wait_list, event_wait_list, event); +} + +static cl_int (*clEnqueueNDRangeKernel_ptr)(cl_command_queue, cl_kernel, cl_uint, const size_t *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueNDRangeKernel (cl_command_queue command_queue,cl_kernel kernel,cl_uint work_dim,const size_t * global_work_offset,const size_t * global_work_size,const size_t * local_work_size,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueNDRangeKernel_ptr) clEnqueueNDRangeKernel_ptr = getFunction("clEnqueueNDRangeKernel"); return (*clEnqueueNDRangeKernel_ptr)(command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueTask_ptr)(cl_command_queue, cl_kernel, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueTask_ptr)(cl_command_queue, cl_kernel, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueTask (cl_command_queue command_queue,cl_kernel kernel,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueTask_ptr) clEnqueueTask_ptr = getFunction("clEnqueueTask"); return (*clEnqueueTask_ptr)(command_queue, kernel, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueNativeKernel_ptr)(cl_command_queue, void (*)(void *), void *, size_t, cl_uint, const cl_mem *, const void **, cl_uint, const cl_event *, cl_event *) = NULL; -cl_int CL_API_CALL clEnqueueNativeKernel (cl_command_queue command_queue,void (*user_func)(void *),void * args,size_t cb_args,cl_uint num_mem_objects,const cl_mem * mem_list,const void ** args_mem_loc,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { +static cl_int (*clEnqueueNativeKernel_ptr)(cl_command_queue, void (CL_CALLBACK * /*user_func*/)(void *), void *, size_t, cl_uint, const cl_mem *, const void **, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueNativeKernel (cl_command_queue command_queue,void (CL_CALLBACK *user_func)(void *) ,void * args,size_t cb_args,cl_uint num_mem_objects,const cl_mem * mem_list,const void ** args_mem_loc,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueNativeKernel_ptr) clEnqueueNativeKernel_ptr = getFunction("clEnqueueNativeKernel"); return (*clEnqueueNativeKernel_ptr)(command_queue, user_func, args, cb_args, num_mem_objects, mem_list, args_mem_loc, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueMarker_ptr)(cl_command_queue, cl_event *) = NULL; -cl_int CL_API_CALL clEnqueueMarker (cl_command_queue command_queue,cl_event * event) { +static cl_int (*clEnqueueMarkerWithWaitList_ptr)(cl_command_queue, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueMarkerWithWaitList (cl_command_queue command_queue,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueMarkerWithWaitList_ptr) clEnqueueMarkerWithWaitList_ptr = getFunction("clEnqueueMarkerWithWaitList"); + return (*clEnqueueMarkerWithWaitList_ptr)(command_queue, num_events_in_wait_list, event_wait_list, event); +} + +static cl_int (*clEnqueueBarrierWithWaitList_ptr)(cl_command_queue, cl_uint, const cl_event *, cl_event *) = NULL; +cl_int CL_API_CALL clEnqueueBarrierWithWaitList (cl_command_queue command_queue,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { + if(!clEnqueueBarrierWithWaitList_ptr) clEnqueueBarrierWithWaitList_ptr = getFunction("clEnqueueBarrierWithWaitList"); + return (*clEnqueueBarrierWithWaitList_ptr)(command_queue, num_events_in_wait_list, event_wait_list, event); +} + +static void * (*clGetExtensionFunctionAddressForPlatform_ptr)(cl_platform_id, const char *) = NULL; +void * CL_API_CALL clGetExtensionFunctionAddressForPlatform (cl_platform_id platform,const char * func_name) { + if(!clGetExtensionFunctionAddressForPlatform_ptr) clGetExtensionFunctionAddressForPlatform_ptr = getFunction("clGetExtensionFunctionAddressForPlatform"); + return (*clGetExtensionFunctionAddressForPlatform_ptr)(platform, func_name); +} + +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem (*clCreateImage2D_ptr)(cl_context, cl_mem_flags, const cl_image_format *, size_t, size_t, size_t, void *, cl_int *) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL clCreateImage2D (cl_context context,cl_mem_flags flags,const cl_image_format * image_format,size_t image_width,size_t image_height,size_t image_row_pitch,void * host_ptr,cl_int * errcode_ret) { + if(!clCreateImage2D_ptr) clCreateImage2D_ptr = getFunction("clCreateImage2D"); + return (*clCreateImage2D_ptr)(context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret); +} + +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem (*clCreateImage3D_ptr)(cl_context, cl_mem_flags, const cl_image_format *, size_t, size_t, size_t, size_t, size_t, void *, cl_int *) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL clCreateImage3D (cl_context context,cl_mem_flags flags,const cl_image_format * image_format,size_t image_width,size_t image_height,size_t image_depth,size_t image_row_pitch,size_t image_slice_pitch,void * host_ptr,cl_int * errcode_ret) { + if(!clCreateImage3D_ptr) clCreateImage3D_ptr = getFunction("clCreateImage3D"); + return (*clCreateImage3D_ptr)(context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret); +} + +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int (*clEnqueueMarker_ptr)(cl_command_queue, cl_event *) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL clEnqueueMarker (cl_command_queue command_queue,cl_event * event) { if(!clEnqueueMarker_ptr) clEnqueueMarker_ptr = getFunction("clEnqueueMarker"); return (*clEnqueueMarker_ptr)(command_queue, event); } -static cl_int (CL_API_CALL *clEnqueueWaitForEvents_ptr)(cl_command_queue, cl_uint, const cl_event *) = NULL; -cl_int CL_API_CALL clEnqueueWaitForEvents (cl_command_queue command_queue,cl_uint num_events,const cl_event * event_list) { +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int (*clEnqueueWaitForEvents_ptr)(cl_command_queue, cl_uint, const cl_event *) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL clEnqueueWaitForEvents (cl_command_queue command_queue,cl_uint num_events,const cl_event * event_list) { if(!clEnqueueWaitForEvents_ptr) clEnqueueWaitForEvents_ptr = getFunction("clEnqueueWaitForEvents"); return (*clEnqueueWaitForEvents_ptr)(command_queue, num_events, event_list); } -static cl_int (CL_API_CALL *clEnqueueBarrier_ptr)(cl_command_queue) = NULL; -cl_int CL_API_CALL clEnqueueBarrier (cl_command_queue command_queue) { +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int (*clEnqueueBarrier_ptr)(cl_command_queue) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL clEnqueueBarrier (cl_command_queue command_queue) { if(!clEnqueueBarrier_ptr) clEnqueueBarrier_ptr = getFunction("clEnqueueBarrier"); return (*clEnqueueBarrier_ptr)(command_queue); } -static void * (CL_API_CALL *clGetExtensionFunctionAddress_ptr)(const char *) = NULL; -void * CL_API_CALL clGetExtensionFunctionAddress (const char * func_name) { +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int (*clUnloadCompiler_ptr)(void) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL clUnloadCompiler (void) { + if(!clUnloadCompiler_ptr) clUnloadCompiler_ptr = getFunction("clUnloadCompiler"); + return (*clUnloadCompiler_ptr)(); +} + +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED void * (*clGetExtensionFunctionAddress_ptr)(const char *) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED void * CL_API_CALL clGetExtensionFunctionAddress (const char * func_name) { if(!clGetExtensionFunctionAddress_ptr) clGetExtensionFunctionAddress_ptr = getFunction("clGetExtensionFunctionAddress"); return (*clGetExtensionFunctionAddress_ptr)(func_name); } diff --git a/Externals/CLRun/clrun/genclext.c b/Externals/CLRun/clrun/genclext.c new file mode 100644 index 0000000000..e6a73afabf --- /dev/null +++ b/Externals/CLRun/clrun/genclext.c @@ -0,0 +1,28 @@ +// Automatically generated by generateClRun.pl +#include "dynamiclib.h" +#include "../include/CL/cl_ext.h" + + +static cl_int (*clIcdGetPlatformIDsKHR_ptr)(cl_uint, cl_platform_id *, cl_uint *) = NULL; +cl_int CL_API_CALL clIcdGetPlatformIDsKHR (cl_uint num_entries,cl_platform_id * platforms,cl_uint * num_platforms) { + if(!clIcdGetPlatformIDsKHR_ptr) clIcdGetPlatformIDsKHR_ptr = getFunction("clIcdGetPlatformIDsKHR"); + return (*clIcdGetPlatformIDsKHR_ptr)(num_entries, platforms, num_platforms); +} +static cl_int (* clReleaseDeviceEXT_ptr)(cl_device_id) = NULL; +cl_int CL_API_CALL clReleaseDeviceEXT (cl_device_id device) { + if(! clReleaseDeviceEXT_ptr) clReleaseDeviceEXT_ptr = getFunction(" clReleaseDeviceEXT"); + return (* clReleaseDeviceEXT_ptr)(device); +} + +static cl_int (* clRetainDeviceEXT_ptr)(cl_device_id) = NULL; +cl_int CL_API_CALL clRetainDeviceEXT (cl_device_id device) { + if(! clRetainDeviceEXT_ptr) clRetainDeviceEXT_ptr = getFunction(" clRetainDeviceEXT"); + return (* clRetainDeviceEXT_ptr)(device); +} + +static cl_int (* clCreateSubDevicesEXT_ptr)(cl_device_id, const cl_device_partition_property_ext *, cl_uint, cl_device_id *, cl_uint *) = NULL; +cl_int CL_API_CALL clCreateSubDevicesEXT (cl_device_id in_device,const cl_device_partition_property_ext * properties,cl_uint num_entries,cl_device_id * out_devices,cl_uint * num_devices) { + if(! clCreateSubDevicesEXT_ptr) clCreateSubDevicesEXT_ptr = getFunction(" clCreateSubDevicesEXT"); + return (* clCreateSubDevicesEXT_ptr)(in_device, properties, num_entries, out_devices, num_devices); +} + diff --git a/Externals/CLRun/clrun/genclgl.c b/Externals/CLRun/clrun/genclgl.c index cc83a8a7ff..acb06a1ff7 100644 --- a/Externals/CLRun/clrun/genclgl.c +++ b/Externals/CLRun/clrun/genclgl.c @@ -3,55 +3,61 @@ #include "../include/CL/cl_gl.h" -static cl_mem (CL_API_CALL *clCreateFromGLBuffer_ptr)(cl_context, cl_mem_flags, cl_GLuint, int *) = NULL; +static cl_mem (*clCreateFromGLBuffer_ptr)(cl_context, cl_mem_flags, cl_GLuint, int *) = NULL; cl_mem CL_API_CALL clCreateFromGLBuffer (cl_context context,cl_mem_flags flags,cl_GLuint bufobj,int * errcode_ret) { if(!clCreateFromGLBuffer_ptr) clCreateFromGLBuffer_ptr = getFunction("clCreateFromGLBuffer"); - return (*clCreateFromGLBuffer_ptr)(context, flags, bufobj, errcode_ret ); + return (*clCreateFromGLBuffer_ptr)(context, flags, bufobj, errcode_ret); } -static cl_mem (CL_API_CALL *clCreateFromGLTexture2D_ptr)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int *) = NULL; -cl_mem CL_API_CALL clCreateFromGLTexture2D (cl_context context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texture,cl_int * errcode_ret) { - if(!clCreateFromGLTexture2D_ptr) clCreateFromGLTexture2D_ptr = getFunction("clCreateFromGLTexture2D"); - return (*clCreateFromGLTexture2D_ptr)(context, flags, target, miplevel, texture, errcode_ret); +static cl_mem (*clCreateFromGLTexture_ptr)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int *) = NULL; +cl_mem CL_API_CALL clCreateFromGLTexture (cl_context context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texture,cl_int * errcode_ret) { + if(!clCreateFromGLTexture_ptr) clCreateFromGLTexture_ptr = getFunction("clCreateFromGLTexture"); + return (*clCreateFromGLTexture_ptr)(context, flags, target, miplevel, texture, errcode_ret); } -static cl_mem (CL_API_CALL *clCreateFromGLTexture3D_ptr)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int *) = NULL; -cl_mem CL_API_CALL clCreateFromGLTexture3D (cl_context context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texture,cl_int * errcode_ret) { - if(!clCreateFromGLTexture3D_ptr) clCreateFromGLTexture3D_ptr = getFunction("clCreateFromGLTexture3D"); - return (*clCreateFromGLTexture3D_ptr)(context, flags, target, miplevel, texture, errcode_ret); -} - -static cl_mem (CL_API_CALL *clCreateFromGLRenderbuffer_ptr)(cl_context, cl_mem_flags, cl_GLuint, cl_int *) = NULL; +static cl_mem (*clCreateFromGLRenderbuffer_ptr)(cl_context, cl_mem_flags, cl_GLuint, cl_int *) = NULL; cl_mem CL_API_CALL clCreateFromGLRenderbuffer (cl_context context,cl_mem_flags flags,cl_GLuint renderbuffer,cl_int * errcode_ret) { if(!clCreateFromGLRenderbuffer_ptr) clCreateFromGLRenderbuffer_ptr = getFunction("clCreateFromGLRenderbuffer"); return (*clCreateFromGLRenderbuffer_ptr)(context, flags, renderbuffer, errcode_ret); } -static cl_int (CL_API_CALL *clGetGLObjectInfo_ptr)(cl_mem, cl_gl_object_type *, cl_GLuint *) = NULL; +static cl_int (*clGetGLObjectInfo_ptr)(cl_mem, cl_gl_object_type *, cl_GLuint *) = NULL; cl_int CL_API_CALL clGetGLObjectInfo (cl_mem memobj,cl_gl_object_type * gl_object_type,cl_GLuint * gl_object_name) { if(!clGetGLObjectInfo_ptr) clGetGLObjectInfo_ptr = getFunction("clGetGLObjectInfo"); return (*clGetGLObjectInfo_ptr)(memobj, gl_object_type, gl_object_name); } -static cl_int (CL_API_CALL *clGetGLTextureInfo_ptr)(cl_mem, cl_gl_texture_info, size_t, void *, size_t *) = NULL; +static cl_int (*clGetGLTextureInfo_ptr)(cl_mem, cl_gl_texture_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetGLTextureInfo (cl_mem memobj,cl_gl_texture_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetGLTextureInfo_ptr) clGetGLTextureInfo_ptr = getFunction("clGetGLTextureInfo"); return (*clGetGLTextureInfo_ptr)(memobj, param_name, param_value_size, param_value, param_value_size_ret); } -static cl_int (CL_API_CALL *clEnqueueAcquireGLObjects_ptr)(cl_command_queue, cl_uint, const cl_mem *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueAcquireGLObjects_ptr)(cl_command_queue, cl_uint, const cl_mem *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueAcquireGLObjects (cl_command_queue command_queue,cl_uint num_objects,const cl_mem * mem_objects,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueAcquireGLObjects_ptr) clEnqueueAcquireGLObjects_ptr = getFunction("clEnqueueAcquireGLObjects"); return (*clEnqueueAcquireGLObjects_ptr)(command_queue, num_objects, mem_objects, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clEnqueueReleaseGLObjects_ptr)(cl_command_queue, cl_uint, const cl_mem *, cl_uint, const cl_event *, cl_event *) = NULL; +static cl_int (*clEnqueueReleaseGLObjects_ptr)(cl_command_queue, cl_uint, const cl_mem *, cl_uint, const cl_event *, cl_event *) = NULL; cl_int CL_API_CALL clEnqueueReleaseGLObjects (cl_command_queue command_queue,cl_uint num_objects,const cl_mem * mem_objects,cl_uint num_events_in_wait_list,const cl_event * event_wait_list,cl_event * event) { if(!clEnqueueReleaseGLObjects_ptr) clEnqueueReleaseGLObjects_ptr = getFunction("clEnqueueReleaseGLObjects"); return (*clEnqueueReleaseGLObjects_ptr)(command_queue, num_objects, mem_objects, num_events_in_wait_list, event_wait_list, event); } -static cl_int (CL_API_CALL *clGetGLContextInfoKHR_ptr)(const cl_context_properties *, cl_gl_context_info, size_t, void *, size_t *) = NULL; +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem (*clCreateFromGLTexture2D_ptr)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int *) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL clCreateFromGLTexture2D (cl_context context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texture,cl_int * errcode_ret) { + if(!clCreateFromGLTexture2D_ptr) clCreateFromGLTexture2D_ptr = getFunction("clCreateFromGLTexture2D"); + return (*clCreateFromGLTexture2D_ptr)(context, flags, target, miplevel, texture, errcode_ret); +} + +static CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem (*clCreateFromGLTexture3D_ptr)(cl_context, cl_mem_flags, cl_GLenum, cl_GLint, cl_GLuint, cl_int *) = NULL; +CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL clCreateFromGLTexture3D (cl_context context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texture,cl_int * errcode_ret) { + if(!clCreateFromGLTexture3D_ptr) clCreateFromGLTexture3D_ptr = getFunction("clCreateFromGLTexture3D"); + return (*clCreateFromGLTexture3D_ptr)(context, flags, target, miplevel, texture, errcode_ret); +} + +static cl_int (*clGetGLContextInfoKHR_ptr)(const cl_context_properties *, cl_gl_context_info, size_t, void *, size_t *) = NULL; cl_int CL_API_CALL clGetGLContextInfoKHR (const cl_context_properties * properties,cl_gl_context_info param_name,size_t param_value_size,void * param_value,size_t * param_value_size_ret) { if(!clGetGLContextInfoKHR_ptr) clGetGLContextInfoKHR_ptr = getFunction("clGetGLContextInfoKHR"); return (*clGetGLContextInfoKHR_ptr)(properties, param_name, param_value_size, param_value, param_value_size_ret); diff --git a/Externals/CLRun/clrun/genclglext.c b/Externals/CLRun/clrun/genclglext.c new file mode 100644 index 0000000000..333103ea85 --- /dev/null +++ b/Externals/CLRun/clrun/genclglext.c @@ -0,0 +1,11 @@ +// Automatically generated by generateClRun.pl +#include "dynamiclib.h" +#include "../include/CL/cl_gl_ext.h" + + +static cl_event (*clCreateEventFromGLsyncKHR_ptr)(cl_context, cl_GLsync, cl_int *) = NULL; +cl_event CL_API_CALL clCreateEventFromGLsyncKHR (cl_context context,cl_GLsync cl_GLsync,cl_int * errcode_ret) { + if(!clCreateEventFromGLsyncKHR_ptr) clCreateEventFromGLsyncKHR_ptr = getFunction("clCreateEventFromGLsyncKHR"); + return (*clCreateEventFromGLsyncKHR_ptr)(context, cl_GLsync, errcode_ret); +} + diff --git a/Externals/CLRun/clrun/generateClRun.pl b/Externals/CLRun/clrun/generateClRun.pl old mode 100644 new mode 100755 diff --git a/Externals/CLRun/include/CL/cl.h b/Externals/CLRun/include/CL/cl.h index 6e9a72c776..203c65974f 100644 --- a/Externals/CLRun/include/CL/cl.h +++ b/Externals/CLRun/include/CL/cl.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008-2010 The Khronos Group Inc. + * Copyright (c) 2008 - 2012 The Khronos Group Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the @@ -21,8 +21,6 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. ******************************************************************************/ -/* $Revision: 11707 $ on $Date: 2010-06-13 23:30:16 -0700 (Sun, 13 Jun 2010) $ */ - #ifndef __OPENCL_CL_H #define __OPENCL_CL_H @@ -53,14 +51,15 @@ typedef cl_ulong cl_bitfield; typedef cl_bitfield cl_device_type; typedef cl_uint cl_platform_info; typedef cl_uint cl_device_info; -typedef cl_bitfield cl_device_address_info; typedef cl_bitfield cl_device_fp_config; typedef cl_uint cl_device_mem_cache_type; typedef cl_uint cl_device_local_mem_type; typedef cl_bitfield cl_device_exec_capabilities; typedef cl_bitfield cl_command_queue_properties; +typedef intptr_t cl_device_partition_property; +typedef cl_bitfield cl_device_affinity_domain; -typedef intptr_t cl_context_properties; +typedef intptr_t cl_context_properties; typedef cl_uint cl_context_info; typedef cl_uint cl_command_queue_info; typedef cl_uint cl_channel_order; @@ -68,25 +67,50 @@ typedef cl_uint cl_channel_type; typedef cl_bitfield cl_mem_flags; typedef cl_uint cl_mem_object_type; typedef cl_uint cl_mem_info; +typedef cl_bitfield cl_mem_migration_flags; typedef cl_uint cl_image_info; +typedef cl_uint cl_buffer_create_type; typedef cl_uint cl_addressing_mode; typedef cl_uint cl_filter_mode; typedef cl_uint cl_sampler_info; typedef cl_bitfield cl_map_flags; typedef cl_uint cl_program_info; typedef cl_uint cl_program_build_info; +typedef cl_uint cl_program_binary_type; typedef cl_int cl_build_status; typedef cl_uint cl_kernel_info; +typedef cl_uint cl_kernel_arg_info; +typedef cl_uint cl_kernel_arg_address_qualifier; +typedef cl_uint cl_kernel_arg_access_qualifier; +typedef cl_bitfield cl_kernel_arg_type_qualifier; typedef cl_uint cl_kernel_work_group_info; typedef cl_uint cl_event_info; typedef cl_uint cl_command_type; typedef cl_uint cl_profiling_info; + typedef struct _cl_image_format { cl_channel_order image_channel_order; cl_channel_type image_channel_data_type; } cl_image_format; +typedef struct _cl_image_desc { + cl_mem_object_type image_type; + size_t image_width; + size_t image_height; + size_t image_depth; + size_t image_array_size; + size_t image_row_pitch; + size_t image_slice_pitch; + cl_uint num_mip_levels; + cl_uint num_samples; + cl_mem buffer; +} cl_image_desc; + +typedef struct _cl_buffer_region { + size_t origin; + size_t size; +} cl_buffer_region; /******************************************************************************/ @@ -105,6 +129,13 @@ typedef struct _cl_image_format { #define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 #define CL_BUILD_PROGRAM_FAILURE -11 #define CL_MAP_FAILURE -12 +#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13 +#define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14 +#define CL_COMPILE_PROGRAM_FAILURE -15 +#define CL_LINKER_NOT_AVAILABLE -16 +#define CL_LINK_PROGRAM_FAILURE -17 +#define CL_DEVICE_PARTITION_FAILED -18 +#define CL_KERNEL_ARG_INFO_NOT_AVAILABLE -19 #define CL_INVALID_VALUE -30 #define CL_INVALID_DEVICE_TYPE -31 @@ -140,13 +171,22 @@ typedef struct _cl_image_format { #define CL_INVALID_BUFFER_SIZE -61 #define CL_INVALID_MIP_LEVEL -62 #define CL_INVALID_GLOBAL_WORK_SIZE -63 +#define CL_INVALID_PROPERTY -64 +#define CL_INVALID_IMAGE_DESCRIPTOR -65 +#define CL_INVALID_COMPILER_OPTIONS -66 +#define CL_INVALID_LINKER_OPTIONS -67 +#define CL_INVALID_DEVICE_PARTITION_COUNT -68 /* OpenCL Version */ #define CL_VERSION_1_0 1 +#define CL_VERSION_1_1 1 +#define CL_VERSION_1_2 1 /* cl_bool */ #define CL_FALSE 0 #define CL_TRUE 1 +#define CL_BLOCKING CL_TRUE +#define CL_NON_BLOCKING CL_FALSE /* cl_platform_info */ #define CL_PLATFORM_PROFILE 0x0900 @@ -160,6 +200,7 @@ typedef struct _cl_image_format { #define CL_DEVICE_TYPE_CPU (1 << 1) #define CL_DEVICE_TYPE_GPU (1 << 2) #define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) +#define CL_DEVICE_TYPE_CUSTOM (1 << 4) #define CL_DEVICE_TYPE_ALL 0xFFFFFFFF /* cl_device_info */ @@ -213,8 +254,32 @@ typedef struct _cl_image_format { #define CL_DEVICE_VERSION 0x102F #define CL_DEVICE_EXTENSIONS 0x1030 #define CL_DEVICE_PLATFORM 0x1031 -/* 0x1032 reserved for CL_DEVICE_DOUBLE_FP_CONFIG */ +#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 /* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */ +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 +#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C +#define CL_DEVICE_OPENCL_C_VERSION 0x103D +#define CL_DEVICE_LINKER_AVAILABLE 0x103E +#define CL_DEVICE_BUILT_IN_KERNELS 0x103F +#define CL_DEVICE_IMAGE_MAX_BUFFER_SIZE 0x1040 +#define CL_DEVICE_IMAGE_MAX_ARRAY_SIZE 0x1041 +#define CL_DEVICE_PARENT_DEVICE 0x1042 +#define CL_DEVICE_PARTITION_MAX_SUB_DEVICES 0x1043 +#define CL_DEVICE_PARTITION_PROPERTIES 0x1044 +#define CL_DEVICE_PARTITION_AFFINITY_DOMAIN 0x1045 +#define CL_DEVICE_PARTITION_TYPE 0x1046 +#define CL_DEVICE_REFERENCE_COUNT 0x1047 +#define CL_DEVICE_PREFERRED_INTEROP_USER_SYNC 0x1048 +#define CL_DEVICE_PRINTF_BUFFER_SIZE 0x1049 +#define CL_DEVICE_IMAGE_PITCH_ALIGNMENT 0x104A +#define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 0x104B /* cl_device_fp_config - bitfield */ #define CL_FP_DENORM (1 << 0) @@ -223,6 +288,8 @@ typedef struct _cl_image_format { #define CL_FP_ROUND_TO_ZERO (1 << 3) #define CL_FP_ROUND_TO_INF (1 << 4) #define CL_FP_FMA (1 << 5) +#define CL_FP_SOFT_FLOAT (1 << 6) +#define CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT (1 << 7) /* cl_device_mem_cache_type */ #define CL_NONE 0x0 @@ -245,9 +312,25 @@ typedef struct _cl_image_format { #define CL_CONTEXT_REFERENCE_COUNT 0x1080 #define CL_CONTEXT_DEVICES 0x1081 #define CL_CONTEXT_PROPERTIES 0x1082 +#define CL_CONTEXT_NUM_DEVICES 0x1083 -/* cl_context_info + cl_context_properties */ +/* cl_context_properties */ #define CL_CONTEXT_PLATFORM 0x1084 +#define CL_CONTEXT_INTEROP_USER_SYNC 0x1085 + +/* cl_device_partition_property */ +#define CL_DEVICE_PARTITION_EQUALLY 0x1086 +#define CL_DEVICE_PARTITION_BY_COUNTS 0x1087 +#define CL_DEVICE_PARTITION_BY_COUNTS_LIST_END 0x0 +#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN 0x1088 + +/* cl_device_affinity_domain */ +#define CL_DEVICE_AFFINITY_DOMAIN_NUMA (1 << 0) +#define CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE (1 << 1) +#define CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE (1 << 2) +#define CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE (1 << 3) +#define CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE (1 << 4) +#define CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE (1 << 5) /* cl_command_queue_info */ #define CL_QUEUE_CONTEXT 0x1090 @@ -262,6 +345,14 @@ typedef struct _cl_image_format { #define CL_MEM_USE_HOST_PTR (1 << 3) #define CL_MEM_ALLOC_HOST_PTR (1 << 4) #define CL_MEM_COPY_HOST_PTR (1 << 5) +// reserved (1 << 6) +#define CL_MEM_HOST_WRITE_ONLY (1 << 7) +#define CL_MEM_HOST_READ_ONLY (1 << 8) +#define CL_MEM_HOST_NO_ACCESS (1 << 9) + +/* cl_mem_migration_flags - bitfield */ +#define CL_MIGRATE_MEM_OBJECT_HOST (1 << 0) +#define CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED (1 << 1) /* cl_channel_order */ #define CL_R 0x10B0 @@ -274,6 +365,11 @@ typedef struct _cl_image_format { #define CL_ARGB 0x10B7 #define CL_INTENSITY 0x10B8 #define CL_LUMINANCE 0x10B9 +#define CL_Rx 0x10BA +#define CL_RGx 0x10BB +#define CL_RGBx 0x10BC +#define CL_DEPTH 0x10BD +#define CL_DEPTH_STENCIL 0x10BE /* cl_channel_type */ #define CL_SNORM_INT8 0x10D0 @@ -291,11 +387,16 @@ typedef struct _cl_image_format { #define CL_UNSIGNED_INT32 0x10DC #define CL_HALF_FLOAT 0x10DD #define CL_FLOAT 0x10DE +#define CL_UNORM_INT24 0x10DF /* cl_mem_object_type */ #define CL_MEM_OBJECT_BUFFER 0x10F0 #define CL_MEM_OBJECT_IMAGE2D 0x10F1 #define CL_MEM_OBJECT_IMAGE3D 0x10F2 +#define CL_MEM_OBJECT_IMAGE2D_ARRAY 0x10F3 +#define CL_MEM_OBJECT_IMAGE1D 0x10F4 +#define CL_MEM_OBJECT_IMAGE1D_ARRAY 0x10F5 +#define CL_MEM_OBJECT_IMAGE1D_BUFFER 0x10F6 /* cl_mem_info */ #define CL_MEM_TYPE 0x1100 @@ -305,6 +406,8 @@ typedef struct _cl_image_format { #define CL_MEM_MAP_COUNT 0x1104 #define CL_MEM_REFERENCE_COUNT 0x1105 #define CL_MEM_CONTEXT 0x1106 +#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107 +#define CL_MEM_OFFSET 0x1108 /* cl_image_info */ #define CL_IMAGE_FORMAT 0x1110 @@ -314,12 +417,17 @@ typedef struct _cl_image_format { #define CL_IMAGE_WIDTH 0x1114 #define CL_IMAGE_HEIGHT 0x1115 #define CL_IMAGE_DEPTH 0x1116 +#define CL_IMAGE_ARRAY_SIZE 0x1117 +#define CL_IMAGE_BUFFER 0x1118 +#define CL_IMAGE_NUM_MIP_LEVELS 0x1119 +#define CL_IMAGE_NUM_SAMPLES 0x111A /* cl_addressing_mode */ #define CL_ADDRESS_NONE 0x1130 #define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 #define CL_ADDRESS_CLAMP 0x1132 #define CL_ADDRESS_REPEAT 0x1133 +#define CL_ADDRESS_MIRRORED_REPEAT 0x1134 /* cl_filter_mode */ #define CL_FILTER_NEAREST 0x1140 @@ -335,6 +443,7 @@ typedef struct _cl_image_format { /* cl_map_flags - bitfield */ #define CL_MAP_READ (1 << 0) #define CL_MAP_WRITE (1 << 1) +#define CL_MAP_WRITE_INVALIDATE_REGION (1 << 2) /* cl_program_info */ #define CL_PROGRAM_REFERENCE_COUNT 0x1160 @@ -344,11 +453,20 @@ typedef struct _cl_image_format { #define CL_PROGRAM_SOURCE 0x1164 #define CL_PROGRAM_BINARY_SIZES 0x1165 #define CL_PROGRAM_BINARIES 0x1166 +#define CL_PROGRAM_NUM_KERNELS 0x1167 +#define CL_PROGRAM_KERNEL_NAMES 0x1168 /* cl_program_build_info */ #define CL_PROGRAM_BUILD_STATUS 0x1181 #define CL_PROGRAM_BUILD_OPTIONS 0x1182 #define CL_PROGRAM_BUILD_LOG 0x1183 +#define CL_PROGRAM_BINARY_TYPE 0x1184 + +/* cl_program_binary_type */ +#define CL_PROGRAM_BINARY_TYPE_NONE 0x0 +#define CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT 0x1 +#define CL_PROGRAM_BINARY_TYPE_LIBRARY 0x2 +#define CL_PROGRAM_BINARY_TYPE_EXECUTABLE 0x4 /* cl_build_status */ #define CL_BUILD_SUCCESS 0 @@ -362,17 +480,47 @@ typedef struct _cl_image_format { #define CL_KERNEL_REFERENCE_COUNT 0x1192 #define CL_KERNEL_CONTEXT 0x1193 #define CL_KERNEL_PROGRAM 0x1194 +#define CL_KERNEL_ATTRIBUTES 0x1195 + +/* cl_kernel_arg_info */ +#define CL_KERNEL_ARG_ADDRESS_QUALIFIER 0x1196 +#define CL_KERNEL_ARG_ACCESS_QUALIFIER 0x1197 +#define CL_KERNEL_ARG_TYPE_NAME 0x1198 +#define CL_KERNEL_ARG_TYPE_QUALIFIER 0x1199 +#define CL_KERNEL_ARG_NAME 0x119A + +/* cl_kernel_arg_address_qualifier */ +#define CL_KERNEL_ARG_ADDRESS_GLOBAL 0x119B +#define CL_KERNEL_ARG_ADDRESS_LOCAL 0x119C +#define CL_KERNEL_ARG_ADDRESS_CONSTANT 0x119D +#define CL_KERNEL_ARG_ADDRESS_PRIVATE 0x119E + +/* cl_kernel_arg_access_qualifier */ +#define CL_KERNEL_ARG_ACCESS_READ_ONLY 0x11A0 +#define CL_KERNEL_ARG_ACCESS_WRITE_ONLY 0x11A1 +#define CL_KERNEL_ARG_ACCESS_READ_WRITE 0x11A2 +#define CL_KERNEL_ARG_ACCESS_NONE 0x11A3 + +/* cl_kernel_arg_type_qualifer */ +#define CL_KERNEL_ARG_TYPE_NONE 0 +#define CL_KERNEL_ARG_TYPE_CONST (1 << 0) +#define CL_KERNEL_ARG_TYPE_RESTRICT (1 << 1) +#define CL_KERNEL_ARG_TYPE_VOLATILE (1 << 2) /* cl_kernel_work_group_info */ #define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 #define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 #define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 +#define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3 +#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4 +#define CL_KERNEL_GLOBAL_WORK_SIZE 0x11B5 /* cl_event_info */ #define CL_EVENT_COMMAND_QUEUE 0x11D0 #define CL_EVENT_COMMAND_TYPE 0x11D1 #define CL_EVENT_REFERENCE_COUNT 0x11D2 #define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 +#define CL_EVENT_CONTEXT 0x11D4 /* cl_command_type */ #define CL_COMMAND_NDRANGE_KERNEL 0x11F0 @@ -392,13 +540,24 @@ typedef struct _cl_image_format { #define CL_COMMAND_MARKER 0x11FE #define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF #define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 +#define CL_COMMAND_READ_BUFFER_RECT 0x1201 +#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202 +#define CL_COMMAND_COPY_BUFFER_RECT 0x1203 +#define CL_COMMAND_USER 0x1204 +#define CL_COMMAND_BARRIER 0x1205 +#define CL_COMMAND_MIGRATE_MEM_OBJECTS 0x1206 +#define CL_COMMAND_FILL_BUFFER 0x1207 +#define CL_COMMAND_FILL_IMAGE 0x1208 /* command execution status */ #define CL_COMPLETE 0x0 #define CL_RUNNING 0x1 #define CL_SUBMITTED 0x2 #define CL_QUEUED 0x3 - + +/* cl_buffer_create_type */ +#define CL_BUFFER_CREATE_TYPE_REGION 0x1220 + /* cl_profiling_info */ #define CL_PROFILING_COMMAND_QUEUED 0x1280 #define CL_PROFILING_COMMAND_SUBMIT 0x1281 @@ -434,22 +593,35 @@ clGetDeviceInfo(cl_device_id /* device */, size_t /* param_value_size */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCreateSubDevices(cl_device_id /* in_device */, + const cl_device_partition_property * /* properties */, + cl_uint /* num_devices */, + cl_device_id * /* out_devices */, + cl_uint * /* num_devices_ret */) CL_API_SUFFIX__VERSION_1_2; +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainDevice(cl_device_id /* device */) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseDevice(cl_device_id /* device */) CL_API_SUFFIX__VERSION_1_2; + /* Context APIs */ extern CL_API_ENTRY cl_context CL_API_CALL clCreateContext(const cl_context_properties * /* properties */, - cl_uint /* num_devices */, - const cl_device_id * /* devices */, + cl_uint /* num_devices */, + const cl_device_id * /* devices */, void (CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * /* properties */, - cl_device_type /* device_type */, + cl_device_type /* device_type */, void (CL_CALLBACK * /* pfn_notify*/ )(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL clRetainContext(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; @@ -484,13 +656,7 @@ clGetCommandQueueInfo(cl_command_queue /* command_queue */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -extern CL_API_ENTRY cl_int CL_API_CALL -clSetCommandQueueProperty(cl_command_queue /* command_queue */, - cl_command_queue_properties /* properties */, - cl_bool /* enable */, - cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0; - -/* Memory Object APIs */ +/* Memory Object APIs */ extern CL_API_ENTRY cl_mem CL_API_CALL clCreateBuffer(cl_context /* context */, cl_mem_flags /* flags */, @@ -499,26 +665,19 @@ clCreateBuffer(cl_context /* context */, cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateImage2D(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_row_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - +clCreateSubBuffer(cl_mem /* buffer */, + cl_mem_flags /* flags */, + cl_buffer_create_type /* buffer_create_type */, + const void * /* buffer_create_info */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; + extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateImage3D(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_depth */, - size_t /* image_row_pitch */, - size_t /* image_slice_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; +clCreateImage(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + const cl_image_desc * /* image_desc */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2; extern CL_API_ENTRY cl_int CL_API_CALL clRetainMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; @@ -548,7 +707,12 @@ clGetImageInfo(cl_mem /* image */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -/* Sampler APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clSetMemObjectDestructorCallback( cl_mem /* memobj */, + void (CL_CALLBACK * /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/), + void * /*user_data */ ) CL_API_SUFFIX__VERSION_1_1; + +/* Sampler APIs */ extern CL_API_ENTRY cl_sampler CL_API_CALL clCreateSampler(cl_context /* context */, cl_bool /* normalized_coords */, @@ -586,6 +750,13 @@ clCreateProgramWithBinary(cl_context /* context */, cl_int * /* binary_status */, cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithBuiltInKernels(cl_context /* context */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const char * /* kernel_names */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2; + extern CL_API_ENTRY cl_int CL_API_CALL clRetainProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; @@ -601,7 +772,30 @@ clBuildProgram(cl_program /* program */, void * /* user_data */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL -clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_0; +clCompileProgram(cl_program /* program */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const char * /* options */, + cl_uint /* num_input_headers */, + const cl_program * /* input_headers */, + const char ** /* header_include_names */, + void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), + void * /* user_data */) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_program CL_API_CALL +clLinkProgram(cl_context /* context */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const char * /* options */, + cl_uint /* num_input_programs */, + const cl_program * /* input_programs */, + void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), + void * /* user_data */, + cl_int * /* errcode_ret */ ) CL_API_SUFFIX__VERSION_1_2; + + +extern CL_API_ENTRY cl_int CL_API_CALL +clUnloadPlatformCompiler(cl_platform_id /* platform */) CL_API_SUFFIX__VERSION_1_2; extern CL_API_ENTRY cl_int CL_API_CALL clGetProgramInfo(cl_program /* program */, @@ -649,6 +843,14 @@ clGetKernelInfo(cl_kernel /* kernel */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelArgInfo(cl_kernel /* kernel */, + cl_uint /* arg_indx */, + cl_kernel_arg_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_2; + extern CL_API_ENTRY cl_int CL_API_CALL clGetKernelWorkGroupInfo(cl_kernel /* kernel */, cl_device_id /* device */, @@ -657,7 +859,7 @@ clGetKernelWorkGroupInfo(cl_kernel /* kernel */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; -/* Event Object APIs */ +/* Event Object APIs */ extern CL_API_ENTRY cl_int CL_API_CALL clWaitForEvents(cl_uint /* num_events */, const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; @@ -669,13 +871,27 @@ clGetEventInfo(cl_event /* event */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_event CL_API_CALL +clCreateUserEvent(cl_context /* context */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; + extern CL_API_ENTRY cl_int CL_API_CALL clRetainEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL clReleaseEvent(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; -/* Profiling APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clSetUserEventStatus(cl_event /* event */, + cl_int /* execution_status */) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetEventCallback( cl_event /* event */, + cl_int /* command_exec_callback_type */, + void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *), + void * /* user_data */) CL_API_SUFFIX__VERSION_1_1; + +/* Profiling APIs */ extern CL_API_ENTRY cl_int CL_API_CALL clGetEventProfilingInfo(cl_event /* event */, cl_profiling_info /* param_name */, @@ -696,34 +912,92 @@ clEnqueueReadBuffer(cl_command_queue /* command_queue */, cl_mem /* buffer */, cl_bool /* blocking_read */, size_t /* offset */, - size_t /* cb */, + size_t /* size */, void * /* ptr */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReadBufferRect(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_read */, + const size_t * /* buffer_offset */, + const size_t * /* host_offset */, + const size_t * /* region */, + size_t /* buffer_row_pitch */, + size_t /* buffer_slice_pitch */, + size_t /* host_row_pitch */, + size_t /* host_slice_pitch */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; + extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue /* command_queue */, cl_mem /* buffer */, cl_bool /* blocking_write */, size_t /* offset */, - size_t /* cb */, + size_t /* size */, const void * /* ptr */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWriteBufferRect(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_write */, + const size_t * /* buffer_offset */, + const size_t * /* host_offset */, + const size_t * /* region */, + size_t /* buffer_row_pitch */, + size_t /* buffer_slice_pitch */, + size_t /* host_row_pitch */, + size_t /* host_slice_pitch */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueFillBuffer(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + const void * /* pattern */, + size_t /* pattern_size */, + size_t /* offset */, + size_t /* size */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; + extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueCopyBuffer(cl_command_queue /* command_queue */, cl_mem /* src_buffer */, cl_mem /* dst_buffer */, size_t /* src_offset */, size_t /* dst_offset */, - size_t /* cb */, + size_t /* size */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyBufferRect(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_buffer */, + const size_t * /* src_origin */, + const size_t * /* dst_origin */, + const size_t * /* region */, + size_t /* src_row_pitch */, + size_t /* src_slice_pitch */, + size_t /* dst_row_pitch */, + size_t /* dst_slice_pitch */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; + extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadImage(cl_command_queue /* command_queue */, cl_mem /* image */, @@ -750,6 +1024,16 @@ clEnqueueWriteImage(cl_command_queue /* command_queue */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueFillImage(cl_command_queue /* command_queue */, + cl_mem /* image */, + const void * /* fill_color */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; + extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueCopyImage(cl_command_queue /* command_queue */, cl_mem /* src_image */, @@ -789,7 +1073,7 @@ clEnqueueMapBuffer(cl_command_queue /* command_queue */, cl_bool /* blocking_map */, cl_map_flags /* map_flags */, size_t /* offset */, - size_t /* cb */, + size_t /* size */, cl_uint /* num_events_in_wait_list */, const cl_event * /* event_wait_list */, cl_event * /* event */, @@ -817,6 +1101,15 @@ clEnqueueUnmapMemObject(cl_command_queue /* command_queue */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMigrateMemObjects(cl_command_queue /* command_queue */, + cl_uint /* num_mem_objects */, + const cl_mem * /* mem_objects */, + cl_mem_migration_flags /* flags */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; + extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue /* command_queue */, cl_kernel /* kernel */, @@ -837,7 +1130,7 @@ clEnqueueTask(cl_command_queue /* command_queue */, extern CL_API_ENTRY cl_int CL_API_CALL clEnqueueNativeKernel(cl_command_queue /* command_queue */, - void (*user_func)(void *), + void (CL_CALLBACK * /*user_func*/)(void *), void * /* args */, size_t /* cb_args */, cl_uint /* num_mem_objects */, @@ -848,16 +1141,17 @@ clEnqueueNativeKernel(cl_command_queue /* command_queue */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueMarker(cl_command_queue /* command_queue */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; +clEnqueueMarkerWithWaitList(cl_command_queue /* command_queue */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueWaitForEvents(cl_command_queue /* command_queue */, - cl_uint /* num_events */, - const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; +clEnqueueBarrierWithWaitList(cl_command_queue /* command_queue */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_2; -extern CL_API_ENTRY cl_int CL_API_CALL -clEnqueueBarrier(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; /* Extension function access * @@ -866,7 +1160,51 @@ clEnqueueBarrier(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_ * check to make sure the address is not NULL, before using or * calling the returned function address. */ -extern CL_API_ENTRY void * CL_API_CALL clGetExtensionFunctionAddress(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0; +extern CL_API_ENTRY void * CL_API_CALL +clGetExtensionFunctionAddressForPlatform(cl_platform_id /* platform */, + const char * /* func_name */) CL_API_SUFFIX__VERSION_1_2; + + +// Deprecated OpenCL 1.1 APIs +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL +clCreateImage2D(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_row_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL +clCreateImage3D(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_depth */, + size_t /* image_row_pitch */, + size_t /* image_slice_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clEnqueueMarker(cl_command_queue /* command_queue */, + cl_event * /* event */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clEnqueueWaitForEvents(cl_command_queue /* command_queue */, + cl_uint /* num_events */, + const cl_event * /* event_list */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clEnqueueBarrier(cl_command_queue /* command_queue */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clUnloadCompiler(void) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED void * CL_API_CALL +clGetExtensionFunctionAddress(const char * /* func_name */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; #ifdef __cplusplus } diff --git a/Externals/CLRun/include/CL/cl_d3d10.h b/Externals/CLRun/include/CL/cl_d3d10.h new file mode 100644 index 0000000000..81b0d37214 --- /dev/null +++ b/Externals/CLRun/include/CL/cl_d3d10.h @@ -0,0 +1,126 @@ +/********************************************************************************** + * Copyright (c) 2008-2012 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + **********************************************************************************/ + +/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */ + +#ifndef __OPENCL_CL_D3D10_H +#define __OPENCL_CL_D3D10_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * cl_khr_d3d10_sharing */ +#define cl_khr_d3d10_sharing 1 + +typedef cl_uint cl_d3d10_device_source_khr; +typedef cl_uint cl_d3d10_device_set_khr; + +/******************************************************************************/ + +// Error Codes +#define CL_INVALID_D3D10_DEVICE_KHR -1002 +#define CL_INVALID_D3D10_RESOURCE_KHR -1003 +#define CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR -1004 +#define CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR -1005 + +// cl_d3d10_device_source_nv +#define CL_D3D10_DEVICE_KHR 0x4010 +#define CL_D3D10_DXGI_ADAPTER_KHR 0x4011 + +// cl_d3d10_device_set_nv +#define CL_PREFERRED_DEVICES_FOR_D3D10_KHR 0x4012 +#define CL_ALL_DEVICES_FOR_D3D10_KHR 0x4013 + +// cl_context_info +#define CL_CONTEXT_D3D10_DEVICE_KHR 0x4014 +#define CL_CONTEXT_D3D10_PREFER_SHARED_RESOURCES_KHR 0x402C + +// cl_mem_info +#define CL_MEM_D3D10_RESOURCE_KHR 0x4015 + +// cl_image_info +#define CL_IMAGE_D3D10_SUBRESOURCE_KHR 0x4016 + +// cl_command_type +#define CL_COMMAND_ACQUIRE_D3D10_OBJECTS_KHR 0x4017 +#define CL_COMMAND_RELEASE_D3D10_OBJECTS_KHR 0x4018 + +/******************************************************************************/ + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromD3D10KHR_fn)( + cl_platform_id platform, + cl_d3d10_device_source_khr d3d_device_source, + void * d3d_object, + cl_d3d10_device_set_khr d3d_device_set, + cl_uint num_entries, + cl_device_id * devices, + cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D10BufferKHR_fn)( + cl_context context, + cl_mem_flags flags, + ID3D10Buffer * resource, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D10Texture2DKHR_fn)( + cl_context context, + cl_mem_flags flags, + ID3D10Texture2D * resource, + UINT subresource, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D10Texture3DKHR_fn)( + cl_context context, + cl_mem_flags flags, + ID3D10Texture3D * resource, + UINT subresource, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireD3D10ObjectsKHR_fn)( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem * mem_objects, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseD3D10ObjectsKHR_fn)( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem * mem_objects, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef __cplusplus +} +#endif + +#endif // __OPENCL_CL_D3D10_H + diff --git a/Externals/CLRun/include/CL/cl_d3d11.h b/Externals/CLRun/include/CL/cl_d3d11.h new file mode 100644 index 0000000000..d3c8bdc2b1 --- /dev/null +++ b/Externals/CLRun/include/CL/cl_d3d11.h @@ -0,0 +1,126 @@ +/********************************************************************************** + * Copyright (c) 2008-2012 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + **********************************************************************************/ + +/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */ + +#ifndef __OPENCL_CL_D3D11_H +#define __OPENCL_CL_D3D11_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * cl_khr_d3d11_sharing */ +#define cl_khr_d3d11_sharing 1 + +typedef cl_uint cl_d3d11_device_source_khr; +typedef cl_uint cl_d3d11_device_set_khr; + +/******************************************************************************/ + +// Error Codes +#define CL_INVALID_D3D11_DEVICE_KHR -1006 +#define CL_INVALID_D3D11_RESOURCE_KHR -1007 +#define CL_D3D11_RESOURCE_ALREADY_ACQUIRED_KHR -1008 +#define CL_D3D11_RESOURCE_NOT_ACQUIRED_KHR -1009 + +// cl_d3d11_device_source +#define CL_D3D11_DEVICE_KHR 0x4019 +#define CL_D3D11_DXGI_ADAPTER_KHR 0x401A + +// cl_d3d11_device_set +#define CL_PREFERRED_DEVICES_FOR_D3D11_KHR 0x401B +#define CL_ALL_DEVICES_FOR_D3D11_KHR 0x401C + +// cl_context_info +#define CL_CONTEXT_D3D11_DEVICE_KHR 0x401D +#define CL_CONTEXT_D3D11_PREFER_SHARED_RESOURCES_KHR 0x402D + +// cl_mem_info +#define CL_MEM_D3D11_RESOURCE_KHR 0x401E + +// cl_image_info +#define CL_IMAGE_D3D11_SUBRESOURCE_KHR 0x401F + +// cl_command_type +#define CL_COMMAND_ACQUIRE_D3D11_OBJECTS_KHR 0x4020 +#define CL_COMMAND_RELEASE_D3D11_OBJECTS_KHR 0x4021 + +/******************************************************************************/ + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromD3D11KHR_fn)( + cl_platform_id platform, + cl_d3d11_device_source_khr d3d_device_source, + void * d3d_object, + cl_d3d11_device_set_khr d3d_device_set, + cl_uint num_entries, + cl_device_id * devices, + cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11BufferKHR_fn)( + cl_context context, + cl_mem_flags flags, + ID3D11Buffer * resource, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture2DKHR_fn)( + cl_context context, + cl_mem_flags flags, + ID3D11Texture2D * resource, + UINT subresource, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromD3D11Texture3DKHR_fn)( + cl_context context, + cl_mem_flags flags, + ID3D11Texture3D * resource, + UINT subresource, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireD3D11ObjectsKHR_fn)( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem * mem_objects, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseD3D11ObjectsKHR_fn)( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem * mem_objects, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +#ifdef __cplusplus +} +#endif + +#endif // __OPENCL_CL_D3D11_H + diff --git a/Externals/CLRun/include/CL/cl_dx9_media_sharing.h b/Externals/CLRun/include/CL/cl_dx9_media_sharing.h new file mode 100644 index 0000000000..1ef543a5af --- /dev/null +++ b/Externals/CLRun/include/CL/cl_dx9_media_sharing.h @@ -0,0 +1,127 @@ +/********************************************************************************** + * Copyright (c) 2008-2012 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + **********************************************************************************/ + +/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */ + +#ifndef __OPENCL_CL_DX9_MEDIA_SHARING_H +#define __OPENCL_CL_DX9_MEDIA_SHARING_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** +/* cl_khr_dx9_media_sharing */ +#define cl_khr_dx9_media_sharing 1 + +typedef cl_uint cl_dx9_media_adapter_type_khr; +typedef cl_uint cl_dx9_media_adapter_set_khr; + +#if defined(_WIN32) +#include +typedef struct _cl_dx9_surface_info_khr +{ + IDirect3DSurface9 *resource; + HANDLE shared_handle; +} cl_dx9_surface_info_khr; +#endif + + +/******************************************************************************/ + +// Error Codes +#define CL_INVALID_DX9_MEDIA_ADAPTER_KHR -1010 +#define CL_INVALID_DX9_MEDIA_SURFACE_KHR -1011 +#define CL_DX9_MEDIA_SURFACE_ALREADY_ACQUIRED_KHR -1012 +#define CL_DX9_MEDIA_SURFACE_NOT_ACQUIRED_KHR -1013 + +// cl_media_adapter_type_khr +#define CL_ADAPTER_D3D9_KHR 0x2020 +#define CL_ADAPTER_D3D9EX_KHR 0x2021 +#define CL_ADAPTER_DXVA_KHR 0x2022 + +// cl_media_adapter_set_khr +#define CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 0x2023 +#define CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 0x2024 + +// cl_context_info +#define CL_CONTEXT_ADAPTER_D3D9_KHR 0x2025 +#define CL_CONTEXT_ADAPTER_D3D9EX_KHR 0x2026 +#define CL_CONTEXT_ADAPTER_DXVA_KHR 0x2027 + +// cl_mem_info +#define CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR 0x2028 +#define CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR 0x2029 + +// cl_image_info +#define CL_IMAGE_DX9_MEDIA_PLANE_KHR 0x202A + +// cl_command_type +#define CL_COMMAND_ACQUIRE_DX9_MEDIA_SURFACES_KHR 0x202B +#define CL_COMMAND_RELEASE_DX9_MEDIA_SURFACES_KHR 0x202C + +/******************************************************************************/ + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetDeviceIDsFromDX9MediaAdapterKHR_fn)( + cl_platform_id platform, + cl_uint num_media_adapters, + cl_dx9_media_adapter_type_khr * media_adapter_type, + void * media_adapters, + cl_dx9_media_adapter_set_khr media_adapter_set, + cl_uint num_entries, + cl_device_id * devices, + cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_mem (CL_API_CALL *clCreateFromDX9MediaSurfaceKHR_fn)( + cl_context context, + cl_mem_flags flags, + cl_dx9_media_adapter_type_khr adapter_type, + void * surface_info, + cl_uint plane, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueAcquireDX9MediaSurfacesKHR_fn)( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem * mem_objects, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clEnqueueReleaseDX9MediaSurfacesKHR_fn)( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem * mem_objects, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +#ifdef __cplusplus +} +#endif + +#endif // __OPENCL_CL_DX9_MEDIA_SHARING_H + diff --git a/Externals/CLRun/include/CL/cl_ext.h b/Externals/CLRun/include/CL/cl_ext.h new file mode 100644 index 0000000000..632cb216b3 --- /dev/null +++ b/Externals/CLRun/include/CL/cl_ext.h @@ -0,0 +1,251 @@ +/******************************************************************************* + * Copyright (c) 2008 - 2012 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + ******************************************************************************/ + +/* $Revision: 11928 $ on $Date: 2010-07-13 09:04:56 -0700 (Tue, 13 Jul 2010) $ */ + +/* cl_ext.h contains OpenCL extensions which don't have external */ +/* (OpenGL, D3D) dependencies. */ + +#ifndef __CL_EXT_H +#define __CL_EXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __APPLE__ + #include + #include +#else + #include +#endif + +/* cl_khr_fp16 extension - no extension #define since it has no functions */ +#define CL_DEVICE_HALF_FP_CONFIG 0x1033 + +/* Memory object destruction + * + * Apple extension for use to manage externally allocated buffers used with cl_mem objects with CL_MEM_USE_HOST_PTR + * + * Registers a user callback function that will be called when the memory object is deleted and its resources + * freed. Each call to clSetMemObjectCallbackFn registers the specified user callback function on a callback + * stack associated with memobj. The registered user callback functions are called in the reverse order in + * which they were registered. The user callback functions are called and then the memory object is deleted + * and its resources freed. This provides a mechanism for the application (and libraries) using memobj to be + * notified when the memory referenced by host_ptr, specified when the memory object is created and used as + * the storage bits for the memory object, can be reused or freed. + * + * The application may not call CL api's with the cl_mem object passed to the pfn_notify. + * + * Please check for the "cl_APPLE_SetMemObjectDestructor" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS) + * before using. + */ +#define cl_APPLE_SetMemObjectDestructor 1 +cl_int CL_API_ENTRY clSetMemObjectDestructorAPPLE( cl_mem /* memobj */, + void (* /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/), + void * /*user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; + + +/* Context Logging Functions + * + * The next three convenience functions are intended to be used as the pfn_notify parameter to clCreateContext(). + * Please check for the "cl_APPLE_ContextLoggingFunctions" extension using clGetDeviceInfo(CL_DEVICE_EXTENSIONS) + * before using. + * + * clLogMessagesToSystemLog fowards on all log messages to the Apple System Logger + */ +#define cl_APPLE_ContextLoggingFunctions 1 +extern void CL_API_ENTRY clLogMessagesToSystemLogAPPLE( const char * /* errstr */, + const void * /* private_info */, + size_t /* cb */, + void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; + +/* clLogMessagesToStdout sends all log messages to the file descriptor stdout */ +extern void CL_API_ENTRY clLogMessagesToStdoutAPPLE( const char * /* errstr */, + const void * /* private_info */, + size_t /* cb */, + void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; + +/* clLogMessagesToStderr sends all log messages to the file descriptor stderr */ +extern void CL_API_ENTRY clLogMessagesToStderrAPPLE( const char * /* errstr */, + const void * /* private_info */, + size_t /* cb */, + void * /* user_data */ ) CL_EXT_SUFFIX__VERSION_1_0; + + +/************************ +* cl_khr_icd extension * +************************/ +#define cl_khr_icd 1 + +/* cl_platform_info */ +#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920 + +/* Additional Error Codes */ +#define CL_PLATFORM_NOT_FOUND_KHR -1001 + +extern CL_API_ENTRY cl_int CL_API_CALL +clIcdGetPlatformIDsKHR(cl_uint /* num_entries */, + cl_platform_id * /* platforms */, + cl_uint * /* num_platforms */); + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clIcdGetPlatformIDsKHR_fn)( + cl_uint /* num_entries */, + cl_platform_id * /* platforms */, + cl_uint * /* num_platforms */); + + +/* Extension: cl_khr_image2D_buffer + * + * This extension allows a 2D image to be created from a cl_mem buffer without a copy. + * The type associated with a 2D image created from a buffer in an OpenCL program is image2d_t. + * Both the sampler and sampler-less read_image built-in functions are supported for 2D images + * and 2D images created from a buffer. Similarly, the write_image built-ins are also supported + * for 2D images created from a buffer. + * + * When the 2D image from buffer is created, the client must specify the width, + * height, image format (i.e. channel order and channel data type) and optionally the row pitch + * + * The pitch specified must be a multiple of CL_DEVICE_IMAGE_PITCH_ALIGNMENT pixels. + * The base address of the buffer must be aligned to CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT pixels. + */ + +/************************************* + * cl_khr_initalize_memory extension * + *************************************/ + +#define CL_CONTEXT_MEMORY_INITIALIZE_KHR 0x200E + + +/************************************** + * cl_khr_terminate_context extension * + **************************************/ + +#define CL_DEVICE_TERMINATE_CAPABILITY_KHR 0x200F +#define CL_CONTEXT_TERMINATE_KHR 0x2010 + +#define cl_khr_terminate_context 1 +extern CL_API_ENTRY cl_int CL_API_CALL clTerminateContextKHR(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2; + +typedef CL_API_ENTRY cl_int (CL_API_CALL *clTerminateContextKHR_fn)(cl_context /* context */) CL_EXT_SUFFIX__VERSION_1_2; + + +/* + * Extension: cl_khr_spir + * + * This extension adds support to create an OpenCL program object from a + * Standard Portable Intermediate Representation (SPIR) instance + */ + +/****************************************** +* cl_nv_device_attribute_query extension * +******************************************/ +/* cl_nv_device_attribute_query extension - no extension #define since it has no functions */ +#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000 +#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001 +#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002 +#define CL_DEVICE_WARP_SIZE_NV 0x4003 +#define CL_DEVICE_GPU_OVERLAP_NV 0x4004 +#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005 +#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006 + + +/********************************* +* cl_amd_device_attribute_query * +*********************************/ +#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036 + +#ifdef CL_VERSION_1_1 + /*********************************** + * cl_ext_device_fission extension * + ***********************************/ + #define cl_ext_device_fission 1 + + extern CL_API_ENTRY cl_int CL_API_CALL + clReleaseDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int + (CL_API_CALL *clReleaseDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; + + extern CL_API_ENTRY cl_int CL_API_CALL + clRetainDeviceEXT( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int + (CL_API_CALL *clRetainDeviceEXT_fn)( cl_device_id /*device*/ ) CL_EXT_SUFFIX__VERSION_1_1; + + typedef cl_ulong cl_device_partition_property_ext; + extern CL_API_ENTRY cl_int CL_API_CALL + clCreateSubDevicesEXT( cl_device_id /*in_device*/, + const cl_device_partition_property_ext * /* properties */, + cl_uint /*num_entries*/, + cl_device_id * /*out_devices*/, + cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int + ( CL_API_CALL * clCreateSubDevicesEXT_fn)( cl_device_id /*in_device*/, + const cl_device_partition_property_ext * /* properties */, + cl_uint /*num_entries*/, + cl_device_id * /*out_devices*/, + cl_uint * /*num_devices*/ ) CL_EXT_SUFFIX__VERSION_1_1; + + /* cl_device_partition_property_ext */ + #define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050 + #define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051 + #define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052 + #define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053 + + /* clDeviceGetInfo selectors */ + #define CL_DEVICE_PARENT_DEVICE_EXT 0x4054 + #define CL_DEVICE_PARTITION_TYPES_EXT 0x4055 + #define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056 + #define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057 + #define CL_DEVICE_PARTITION_STYLE_EXT 0x4058 + + /* error codes */ + #define CL_DEVICE_PARTITION_FAILED_EXT -1057 + #define CL_INVALID_PARTITION_COUNT_EXT -1058 + #define CL_INVALID_PARTITION_NAME_EXT -1059 + + /* CL_AFFINITY_DOMAINs */ + #define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1 + #define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2 + #define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3 + #define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4 + #define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10 + #define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100 + + /* cl_device_partition_property_ext list terminators */ + #define CL_PROPERTIES_LIST_END_EXT ((cl_device_partition_property_ext) 0) + #define CL_PARTITION_BY_COUNTS_LIST_END_EXT ((cl_device_partition_property_ext) 0) + #define CL_PARTITION_BY_NAMES_LIST_END_EXT ((cl_device_partition_property_ext) 0 - 1) + + + +#endif /* CL_VERSION_1_1 */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __CL_EXT_H */ diff --git a/Externals/CLRun/include/CL/cl_gl.h b/Externals/CLRun/include/CL/cl_gl.h index fcaa5bd392..af2036cc99 100644 --- a/Externals/CLRun/include/CL/cl_gl.h +++ b/Externals/CLRun/include/CL/cl_gl.h @@ -1,5 +1,5 @@ /********************************************************************************** - * Copyright (c) 2008-2010 The Khronos Group Inc. + * Copyright (c) 2008 - 2012 The Khronos Group Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the @@ -21,14 +21,6 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. **********************************************************************************/ -/* $Revision: 11707 $ on $Date: 2010-06-13 23:30:16 -0700 (Sun, 13 Jun 2010) $ */ - -/* - * cl_gl.h contains Khronos-approved (KHR) OpenCL extensions which have - * OpenGL dependencies. The application is responsible for #including - * OpenGL or OpenGL ES headers before #including cl_gl.h. - */ - #ifndef __OPENCL_CL_GL_H #define __OPENCL_CL_GL_H @@ -36,7 +28,7 @@ #include #else #include -#endif +#endif #ifdef __cplusplus extern "C" { @@ -45,16 +37,23 @@ extern "C" { typedef cl_uint cl_gl_object_type; typedef cl_uint cl_gl_texture_info; typedef cl_uint cl_gl_platform_info; +typedef struct __GLsync *cl_GLsync; -/* cl_gl_object_type */ -#define CL_GL_OBJECT_BUFFER 0x2000 -#define CL_GL_OBJECT_TEXTURE2D 0x2001 -#define CL_GL_OBJECT_TEXTURE3D 0x2002 -#define CL_GL_OBJECT_RENDERBUFFER 0x2003 +/* cl_gl_object_type = 0x2000 - 0x200F enum values are currently taken */ +#define CL_GL_OBJECT_BUFFER 0x2000 +#define CL_GL_OBJECT_TEXTURE2D 0x2001 +#define CL_GL_OBJECT_TEXTURE3D 0x2002 +#define CL_GL_OBJECT_RENDERBUFFER 0x2003 +#define CL_GL_OBJECT_TEXTURE2D_ARRAY 0x200E +#define CL_GL_OBJECT_TEXTURE1D 0x200F +#define CL_GL_OBJECT_TEXTURE1D_ARRAY 0x2010 +#define CL_GL_OBJECT_TEXTURE_BUFFER 0x2011 + +/* cl_gl_texture_info */ +#define CL_GL_TEXTURE_TARGET 0x2004 +#define CL_GL_MIPMAP_LEVEL 0x2005 +#define CL_GL_NUM_SAMPLES 0x2012 -/* cl_gl_texture_info */ -#define CL_GL_TEXTURE_TARGET 0x2004 -#define CL_GL_MIPMAP_LEVEL 0x2005 extern CL_API_ENTRY cl_mem CL_API_CALL clCreateFromGLBuffer(cl_context /* context */, @@ -63,21 +62,13 @@ clCreateFromGLBuffer(cl_context /* context */, int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateFromGLTexture2D(cl_context /* context */, - cl_mem_flags /* flags */, - cl_GLenum /* target */, - cl_GLint /* miplevel */, - cl_GLuint /* texture */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -extern CL_API_ENTRY cl_mem CL_API_CALL -clCreateFromGLTexture3D(cl_context /* context */, - cl_mem_flags /* flags */, - cl_GLenum /* target */, - cl_GLint /* miplevel */, - cl_GLuint /* texture */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - +clCreateFromGLTexture(cl_context /* context */, + cl_mem_flags /* flags */, + cl_GLenum /* target */, + cl_GLint /* miplevel */, + cl_GLuint /* texture */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_2; + extern CL_API_ENTRY cl_mem CL_API_CALL clCreateFromGLRenderbuffer(cl_context /* context */, cl_mem_flags /* flags */, @@ -87,8 +78,8 @@ clCreateFromGLRenderbuffer(cl_context /* context */, extern CL_API_ENTRY cl_int CL_API_CALL clGetGLObjectInfo(cl_mem /* memobj */, cl_gl_object_type * /* gl_object_type */, - cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0; - + cl_GLuint * /* gl_object_name */) CL_API_SUFFIX__VERSION_1_0; + extern CL_API_ENTRY cl_int CL_API_CALL clGetGLTextureInfo(cl_mem /* memobj */, cl_gl_texture_info /* param_name */, @@ -112,33 +103,51 @@ clEnqueueReleaseGLObjects(cl_command_queue /* command_queue */, const cl_event * /* event_wait_list */, cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + +// Deprecated OpenCL 1.1 APIs +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL +clCreateFromGLTexture2D(cl_context /* context */, + cl_mem_flags /* flags */, + cl_GLenum /* target */, + cl_GLint /* miplevel */, + cl_GLuint /* texture */, + cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_EXT_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL +clCreateFromGLTexture3D(cl_context /* context */, + cl_mem_flags /* flags */, + cl_GLenum /* target */, + cl_GLint /* miplevel */, + cl_GLuint /* texture */, + cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED; + /* cl_khr_gl_sharing extension */ - + #define cl_khr_gl_sharing 1 - + typedef cl_uint cl_gl_context_info; - + /* Additional Error Codes */ #define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000 - + /* cl_gl_context_info */ #define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006 #define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007 - + /* Additional cl_context_properties */ #define CL_GL_CONTEXT_KHR 0x2008 #define CL_EGL_DISPLAY_KHR 0x2009 #define CL_GLX_DISPLAY_KHR 0x200A #define CL_WGL_HDC_KHR 0x200B #define CL_CGL_SHAREGROUP_KHR 0x200C - + extern CL_API_ENTRY cl_int CL_API_CALL clGetGLContextInfoKHR(const cl_context_properties * /* properties */, cl_gl_context_info /* param_name */, size_t /* param_value_size */, void * /* param_value */, size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - + typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)( const cl_context_properties * properties, cl_gl_context_info param_name, @@ -150,4 +159,4 @@ typedef CL_API_ENTRY cl_int (CL_API_CALL *clGetGLContextInfoKHR_fn)( } #endif -#endif /* __OPENCL_CL_GL_H */ +#endif /* __OPENCL_CL_GL_H */ diff --git a/Externals/CLRun/include/CL/cl_gl_ext.h b/Externals/CLRun/include/CL/cl_gl_ext.h new file mode 100644 index 0000000000..77d53536f6 --- /dev/null +++ b/Externals/CLRun/include/CL/cl_gl_ext.h @@ -0,0 +1,69 @@ +/********************************************************************************** + * Copyright (c) 2008-2012 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and/or associated documentation files (the + * "Materials"), to deal in the Materials without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Materials, and to + * permit persons to whom the Materials are furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Materials. + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. + **********************************************************************************/ + +/* $Revision: 11708 $ on $Date: 2010-06-13 23:36:24 -0700 (Sun, 13 Jun 2010) $ */ + +/* cl_gl_ext.h contains vendor (non-KHR) OpenCL extensions which have */ +/* OpenGL dependencies. */ + +#ifndef __OPENCL_CL_GL_EXT_H +#define __OPENCL_CL_GL_EXT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __APPLE__ + #include +#else + #include +#endif + +/* + * For each extension, follow this template + * cl_VEN_extname extension */ +/* #define cl_VEN_extname 1 + * ... define new types, if any + * ... define new tokens, if any + * ... define new APIs, if any + * + * If you need GLtypes here, mirror them with a cl_GLtype, rather than including a GL header + * This allows us to avoid having to decide whether to include GL headers or GLES here. + */ + +/* + * cl_khr_gl_event extension + * See section 9.9 in the OpenCL 1.1 spec for more information + */ +#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D + +extern CL_API_ENTRY cl_event CL_API_CALL +clCreateEventFromGLsyncKHR(cl_context /* context */, + cl_GLsync /* cl_GLsync */, + cl_int * /* errcode_ret */) CL_EXT_SUFFIX__VERSION_1_1; + +#ifdef __cplusplus +} +#endif + +#endif /* __OPENCL_CL_GL_EXT_H */ diff --git a/Externals/CLRun/include/CL/cl_platform.h b/Externals/CLRun/include/CL/cl_platform.h index 8fdcb17341..cf2b7210ac 100644 --- a/Externals/CLRun/include/CL/cl_platform.h +++ b/Externals/CLRun/include/CL/cl_platform.h @@ -1,5 +1,5 @@ /********************************************************************************** - * Copyright (c) 2008-2010 The Khronos Group Inc. + * Copyright (c) 2008-2012 The Khronos Group Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and/or associated documentation files (the @@ -21,7 +21,7 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. **********************************************************************************/ -/* $Revision: 11707 $ on $Date: 2010-06-13 23:30:16 -0700 (Sun, 13 Jun 2010) $ */ +/* $Revision: 11803 $ on $Date: 2010-06-25 10:02:12 -0700 (Fri, 25 Jun 2010) $ */ #ifndef __CL_PLATFORM_H #define __CL_PLATFORM_H @@ -36,21 +36,85 @@ extern "C" { #endif #if defined(_WIN32) -#define CL_API_ENTRY -#define CL_API_CALL __stdcall + #define CL_API_ENTRY + #define CL_API_CALL __stdcall + #define CL_CALLBACK __stdcall #else -#define CL_API_ENTRY -#define CL_API_CALL + #define CL_API_ENTRY + #define CL_API_CALL + #define CL_CALLBACK #endif #ifdef __APPLE__ -#define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER -#define CL_API_SUFFIX__VERSION_1_1 -#define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) + #define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) + #define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + #define CL_EXT_SUFFIX__VERSION_1_0 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER + #define CL_API_SUFFIX__VERSION_1_1 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + #define GCL_API_SUFFIX__VERSION_1_1 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + #define CL_EXT_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_7 + + #ifdef AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER + #define CL_API_SUFFIX__VERSION_1_2 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER + #define GCL_API_SUFFIX__VERSION_1_2 AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER + #define CL_EXT_SUFFIX__VERSION_1_2 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_8_AND_LATER + #define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_8 + #else + #warning This path should never happen outside of internal operating system development. AvailabilityMacros do not function correctly here! + #define CL_API_SUFFIX__VERSION_1_2 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + #define GCL_API_SUFFIX__VERSION_1_2 AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + #define CL_EXT_SUFFIX__VERSION_1_2 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_7_AND_LATER + #endif #else -#define CL_API_SUFFIX__VERSION_1_0 -#define CL_API_SUFFIX__VERSION_1_1 -#define CL_EXTENSION_WEAK_LINK + #define CL_EXTENSION_WEAK_LINK + #define CL_API_SUFFIX__VERSION_1_0 + #define CL_EXT_SUFFIX__VERSION_1_0 + #define CL_API_SUFFIX__VERSION_1_1 + #define CL_EXT_SUFFIX__VERSION_1_1 + #define CL_API_SUFFIX__VERSION_1_2 + #define CL_EXT_SUFFIX__VERSION_1_2 + + #ifdef __GNUC__ + #ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS + #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_0_DEPRECATED + #else + #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED __attribute__((deprecated)) + #define CL_EXT_PREFIX__VERSION_1_0_DEPRECATED + #endif + + #ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS + #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + #else + #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED __attribute__((deprecated)) + #define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + #endif + #elif _WIN32 + #ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS + #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_0_DEPRECATED + #else + #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_0_DEPRECATED __declspec(deprecated) + #endif + + #ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS + #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + #else + #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED __declspec(deprecated) + #endif + #else + #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_0_DEPRECATED + + #define CL_EXT_SUFFIX__VERSION_1_1_DEPRECATED + #define CL_EXT_PREFIX__VERSION_1_1_DEPRECATED + #endif #endif #if (defined (_WIN32) && defined(_MSC_VER)) @@ -108,14 +172,40 @@ typedef double cl_double; #define CL_DBL_MIN 2.225073858507201383090e-308 #define CL_DBL_EPSILON 2.220446049250313080847e-16 +#define CL_M_E 2.718281828459045090796 +#define CL_M_LOG2E 1.442695040888963387005 +#define CL_M_LOG10E 0.434294481903251816668 +#define CL_M_LN2 0.693147180559945286227 +#define CL_M_LN10 2.302585092994045901094 +#define CL_M_PI 3.141592653589793115998 +#define CL_M_PI_2 1.570796326794896557999 +#define CL_M_PI_4 0.785398163397448278999 +#define CL_M_1_PI 0.318309886183790691216 +#define CL_M_2_PI 0.636619772367581382433 +#define CL_M_2_SQRTPI 1.128379167095512558561 +#define CL_M_SQRT2 1.414213562373095145475 +#define CL_M_SQRT1_2 0.707106781186547572737 + +#define CL_M_E_F 2.71828174591064f +#define CL_M_LOG2E_F 1.44269502162933f +#define CL_M_LOG10E_F 0.43429449200630f +#define CL_M_LN2_F 0.69314718246460f +#define CL_M_LN10_F 2.30258512496948f +#define CL_M_PI_F 3.14159274101257f +#define CL_M_PI_2_F 1.57079637050629f +#define CL_M_PI_4_F 0.78539818525314f +#define CL_M_1_PI_F 0.31830987334251f +#define CL_M_2_PI_F 0.63661974668503f +#define CL_M_2_SQRTPI_F 1.12837922573090f +#define CL_M_SQRT2_F 1.41421353816986f +#define CL_M_SQRT1_2_F 0.70710676908493f + #define CL_NAN (CL_INFINITY - CL_INFINITY) #define CL_HUGE_VALF ((cl_float) 1e50) #define CL_HUGE_VAL ((cl_double) 1e500) #define CL_MAXFLOAT CL_FLT_MAX #define CL_INFINITY CL_HUGE_VALF -#define CL_CALLBACK __stdcall - #else #include @@ -173,6 +263,34 @@ typedef double cl_double __attribute__((aligned(8))); #define CL_DBL_MIN 0x1.0p-1022 #define CL_DBL_EPSILON 0x1.0p-52 +#define CL_M_E 2.718281828459045090796 +#define CL_M_LOG2E 1.442695040888963387005 +#define CL_M_LOG10E 0.434294481903251816668 +#define CL_M_LN2 0.693147180559945286227 +#define CL_M_LN10 2.302585092994045901094 +#define CL_M_PI 3.141592653589793115998 +#define CL_M_PI_2 1.570796326794896557999 +#define CL_M_PI_4 0.785398163397448278999 +#define CL_M_1_PI 0.318309886183790691216 +#define CL_M_2_PI 0.636619772367581382433 +#define CL_M_2_SQRTPI 1.128379167095512558561 +#define CL_M_SQRT2 1.414213562373095145475 +#define CL_M_SQRT1_2 0.707106781186547572737 + +#define CL_M_E_F 2.71828174591064f +#define CL_M_LOG2E_F 1.44269502162933f +#define CL_M_LOG10E_F 0.43429449200630f +#define CL_M_LN2_F 0.69314718246460f +#define CL_M_LN10_F 2.30258512496948f +#define CL_M_PI_F 3.14159274101257f +#define CL_M_PI_2_F 1.57079637050629f +#define CL_M_PI_4_F 0.78539818525314f +#define CL_M_1_PI_F 0.31830987334251f +#define CL_M_2_PI_F 0.63661974668503f +#define CL_M_2_SQRTPI_F 1.12837922573090f +#define CL_M_SQRT2_F 1.41421353816986f +#define CL_M_SQRT1_2_F 0.70710676908493f + #if defined( __GNUC__ ) #define CL_HUGE_VALF __builtin_huge_valf() #define CL_HUGE_VAL __builtin_huge_val() @@ -186,13 +304,11 @@ typedef double cl_double __attribute__((aligned(8))); #define CL_MAXFLOAT CL_FLT_MAX #define CL_INFINITY CL_HUGE_VALF -#define CL_CALLBACK - #endif #include -/* Mirror types to GL types. Mirror types allow us to avoid deciding which headers to load based on whether we are using GL or GLES here. */ +/* Mirror types to GL types. Mirror types allow us to avoid deciding which 87s to load based on whether we are using GL or GLES here. */ typedef unsigned int cl_GLuint; typedef int cl_GLint; typedef unsigned int cl_GLenum; @@ -389,6 +505,9 @@ typedef union #endif }cl_char4; +/* cl_char3 is identical in size, alignment and behavior to cl_char4. See section 6.1.5. */ +typedef cl_char4 cl_char3; + typedef union { cl_char CL_ALIGNED(8) s[8]; @@ -461,6 +580,9 @@ typedef union #endif }cl_uchar4; +/* cl_uchar3 is identical in size, alignment and behavior to cl_uchar4. See section 6.1.5. */ +typedef cl_uchar4 cl_uchar3; + typedef union { cl_uchar CL_ALIGNED(8) s[8]; @@ -533,6 +655,9 @@ typedef union #endif }cl_short4; +/* cl_short3 is identical in size, alignment and behavior to cl_short4. See section 6.1.5. */ +typedef cl_short4 cl_short3; + typedef union { cl_short CL_ALIGNED(16) s[8]; @@ -605,6 +730,9 @@ typedef union #endif }cl_ushort4; +/* cl_ushort3 is identical in size, alignment and behavior to cl_ushort4. See section 6.1.5. */ +typedef cl_ushort4 cl_ushort3; + typedef union { cl_ushort CL_ALIGNED(16) s[8]; @@ -676,6 +804,9 @@ typedef union #endif }cl_int4; +/* cl_int3 is identical in size, alignment and behavior to cl_int4. See section 6.1.5. */ +typedef cl_int4 cl_int3; + typedef union { cl_int CL_ALIGNED(32) s[8]; @@ -748,6 +879,9 @@ typedef union #endif }cl_uint4; +/* cl_uint3 is identical in size, alignment and behavior to cl_uint4. See section 6.1.5. */ +typedef cl_uint4 cl_uint3; + typedef union { cl_uint CL_ALIGNED(32) s[8]; @@ -819,6 +953,9 @@ typedef union #endif }cl_long4; +/* cl_long3 is identical in size, alignment and behavior to cl_long4. See section 6.1.5. */ +typedef cl_long4 cl_long3; + typedef union { cl_long CL_ALIGNED(64) s[8]; @@ -891,6 +1028,9 @@ typedef union #endif }cl_ulong4; +/* cl_ulong3 is identical in size, alignment and behavior to cl_ulong4. See section 6.1.5. */ +typedef cl_ulong4 cl_ulong3; + typedef union { cl_ulong CL_ALIGNED(64) s[8]; @@ -964,6 +1104,9 @@ typedef union #endif }cl_float4; +/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */ +typedef cl_float4 cl_float3; + typedef union { cl_float CL_ALIGNED(32) s[8]; @@ -1036,6 +1179,9 @@ typedef union #endif }cl_double4; +/* cl_double3 is identical in size, alignment and behavior to cl_double4. See section 6.1.5. */ +typedef cl_double4 cl_double3; + typedef union { cl_double CL_ALIGNED(64) s[8]; @@ -1077,6 +1223,29 @@ typedef union #endif }cl_double16; +/* Macro to facilitate debugging + * Usage: + * Place CL_PROGRAM_STRING_DEBUG_INFO on the line before the first line of your source. + * The first line ends with: CL_PROGRAM_STRING_DEBUG_INFO \" + * Each line thereafter of OpenCL C source must end with: \n\ + * The last line ends in "; + * + * Example: + * + * const char *my_program = CL_PROGRAM_STRING_DEBUG_INFO "\ + * kernel void foo( int a, float * b ) \n\ + * { \n\ + * // my comment \n\ + * *b[ get_global_id(0)] = a; \n\ + * } \n\ + * "; + * + * This should correctly set up the line, (column) and file information for your source + * string so you can do source level debugging. + */ +#define __CL_STRINGIFY( _x ) # _x +#define _CL_STRINGIFY( _x ) __CL_STRINGIFY( _x ) +#define CL_PROGRAM_STRING_DEBUG_INFO "#line " _CL_STRINGIFY(__LINE__) " \"" __FILE__ "\" \n\n" #ifdef __cplusplus } From dc98ce59224b7f0c175af1886d4d74d1d8fcb8d6 Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 24 Feb 2013 23:05:12 +1100 Subject: [PATCH 084/167] Added the addeo instruction to the JIT tables. Fixes Inkub (WiiWare). --- Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp | 1 + Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp | 1 + Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp index 8ea35503bf..07219218a2 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp @@ -297,6 +297,7 @@ static GekkoOPTemplate table31_2[] = {10, Interpreter::addcx, {"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT, 0, 0, 0, 0}}, {522, Interpreter::addcx, {"addcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT, 0, 0, 0, 0}}, {138, Interpreter::addex, {"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 0, 0, 0, 0}}, + {650, Interpreter::addex, {"addeox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 0, 0, 0, 0}}, {234, Interpreter::addmex, {"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 0, 0, 0, 0}}, {202, Interpreter::addzex, {"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT, 0, 0, 0, 0}}, {491, Interpreter::divwx, {"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39, 0, 0, 0}}, diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp index ddb59903d2..cee1f4d048 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp @@ -310,6 +310,7 @@ static GekkoOPTemplate table31_2[] = {10, &Jit64::addcx}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, {522, &Jit64::addcx}, //"addcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, {138, &Jit64::addex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {650, &Jit64::addex}, //"addeox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {234, &Jit64::addmex}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {202, &Jit64::addzex}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {491, &Jit64::divwx}, //"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp index 9418030b9c..fd920c4a48 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp @@ -311,6 +311,7 @@ static GekkoOPTemplate table31_2[] = {10, &JitIL::Default}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, {522, &JitIL::Default}, //"addcox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, {138, &JitIL::addex}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {650, &JitIL::addex}, //"addeox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {234, &JitIL::Default}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {202, &JitIL::addzex}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {491, &JitIL::Default}, //"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, From 6b2804e2960b4c8d9ba9ef95ad4c843eab9ae00b Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 24 Feb 2013 22:29:33 -0600 Subject: [PATCH 085/167] Possible crashfix for OSX. --- Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 3 ++- Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index fda1d99462..cec18ed63a 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -195,6 +195,8 @@ bool Wiimote::Connect() ERROR_LOG(WIIMOTE, "Unable to open L2CAP channels " "for wiimote %i", index + 1); Disconnect(); + + [cbt release]; return false; } @@ -209,7 +211,6 @@ bool Wiimote::Connect() m_connected = true; [cbt release]; - return true; } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index b5a1703527..3608c060fc 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -51,7 +51,7 @@ WiimoteScanner g_wiimote_scanner; Wiimote::Wiimote() : index() #ifdef __APPLE__ - , inputlen(0) + , btd(), ichan(), cchan(), inputlen(), m_connected() #elif defined(__linux__) && HAVE_BLUEZ , cmd_sock(-1), int_sock(-1) #elif defined(_WIN32) From 1141af64f64b801fc1509bb9c1eff92436f340e6 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 25 Feb 2013 12:36:50 +0000 Subject: [PATCH 086/167] TextureCacheBase: Do not assume EFB copies can safely be deleted when we think they're "unused". Fixes issue 6040. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index fda4f21a7e..46aaf79bd4 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -129,8 +129,13 @@ void TextureCache::Cleanup() TexCache::iterator tcend = textures.end(); while (iter != tcend) { - if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount) // TODO: Deleting EFB copies might not be a good idea here... + if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount) { + // EFB copies living on the host GPU are unrecoverable and thus shouldn't be deleted + // TODO: encoding the texture back to RAM here might be a good idea + if (g_ActiveConfig.bCopyEFBToTexture && entry->IsEfbCopy()) + continue; + delete iter->second; textures.erase(iter++); } From 73a0bdd379672c4f218b92788002dbc39815fb85 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Mon, 25 Feb 2013 12:42:52 +0000 Subject: [PATCH 087/167] Build fixing. --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 46aaf79bd4..d261d9d6d2 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -133,7 +133,7 @@ void TextureCache::Cleanup() { // EFB copies living on the host GPU are unrecoverable and thus shouldn't be deleted // TODO: encoding the texture back to RAM here might be a good idea - if (g_ActiveConfig.bCopyEFBToTexture && entry->IsEfbCopy()) + if (g_ActiveConfig.bCopyEFBToTexture && iter->second->IsEfbCopy()) continue; delete iter->second; From d173d646de18bc9e158651989045fef8ddd1523f Mon Sep 17 00:00:00 2001 From: degasus Date: Mon, 25 Feb 2013 16:11:24 +0100 Subject: [PATCH 088/167] fix last commit by neobrain --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index d261d9d6d2..6871c411fa 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -129,13 +129,12 @@ void TextureCache::Cleanup() TexCache::iterator tcend = textures.end(); while (iter != tcend) { - if (frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount) - { + if ( frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount + // EFB copies living on the host GPU are unrecoverable and thus shouldn't be deleted // TODO: encoding the texture back to RAM here might be a good idea - if (g_ActiveConfig.bCopyEFBToTexture && iter->second->IsEfbCopy()) - continue; - + && ! (g_ActiveConfig.bCopyEFBToTexture && iter->second->IsEfbCopy()) ) + { delete iter->second; textures.erase(iter++); } From 0e4b07ddf97b9769b341dbbc54b26b6784396da7 Mon Sep 17 00:00:00 2001 From: "kostamarino@hotmail.com" Date: Mon, 25 Feb 2013 19:14:36 +0200 Subject: [PATCH 089/167] Update the gameini of F-zero. Efb to Ram is no longer the default choice. --- Data/User/GameConfig/GFZE01.ini | 3 --- Data/User/GameConfig/GFZP01.ini | 3 --- 2 files changed, 6 deletions(-) diff --git a/Data/User/GameConfig/GFZE01.ini b/Data/User/GameConfig/GFZE01.ini index 450553aa06..32b1e195c0 100644 --- a/Data/User/GameConfig/GFZE01.ini +++ b/Data/User/GameConfig/GFZE01.ini @@ -43,7 +43,4 @@ $All Vehicles Unlocked 840030C8 FFDC6F00 [Gecko] [Video_Hacks] -EFBCopyEnable = True -EFBToTextureEnable = False -EFBCopyCacheEnable = True [Video_Settings] diff --git a/Data/User/GameConfig/GFZP01.ini b/Data/User/GameConfig/GFZP01.ini index 70c517ef4a..0586d53d3f 100644 --- a/Data/User/GameConfig/GFZP01.ini +++ b/Data/User/GameConfig/GFZP01.ini @@ -24,7 +24,4 @@ $Make Save Copyable 04C3110C 4B400410 [Gecko] [Video_Hacks] -EFBCopyEnable = True -EFBToTextureEnable = False -EFBCopyCacheEnable = True [Video_Settings] From a450ba442025d897a63f3b8e3655a8a49885df2b Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Mon, 25 Feb 2013 15:58:12 -0500 Subject: [PATCH 090/167] Abort load state if it uses a different dsp engine, instead of crashing. --- Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp | 9 +++++++++ Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp | 9 +++++++++ Source/Core/Core/Src/State.cpp | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp index b22be91104..dac977922b 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp @@ -27,6 +27,7 @@ #include "UCodes/UCodes.h" #include "../AudioInterface.h" #include "ConfigManager.h" +#include "Core.h" DSPHLE::DSPHLE() { m_InitMixer = false; @@ -130,6 +131,14 @@ void DSPHLE::SwapUCode(u32 _crc) void DSPHLE::DoState(PointerWrap &p) { + bool isHLE = true; + p.Do(isHLE); + if (isHLE != true && p.GetMode() == PointerWrap::MODE_READ) + { + Core::DisplayMessage("Save states made with the LLE audio engine are incompatible with the HLE DSP engine. Aborting load state.", 3000); + p.SetMode(PointerWrap::MODE_VERIFY); + return; + } bool prevInitMixer = m_InitMixer; p.Do(m_InitMixer); if (prevInitMixer != m_InitMixer && p.GetMode() == PointerWrap::MODE_READ) diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp index 92053053de..2dbb7a8292 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp @@ -26,6 +26,7 @@ #include "IniFile.h" #include "ConfigManager.h" #include "CPUDetect.h" +#include "Core.h" #include "DSPLLEGlobals.h" // Local #include "DSP/DSPInterpreter.h" @@ -56,6 +57,14 @@ Common::Event ppcEvent; void DSPLLE::DoState(PointerWrap &p) { + bool isHLE = false; + p.Do(isHLE); + if (isHLE != false && p.GetMode() == PointerWrap::MODE_READ) + { + Core::DisplayMessage("Save states made with the HLE audio engine are incompatible with the LLE DSP engine. Aborting load state.", 3000); + p.SetMode(PointerWrap::MODE_VERIFY); + return; + } p.Do(g_dsp.r); p.Do(g_dsp.pc); #if PROFILE diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 084a94e5f6..0facf2f387 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 13; +static const u32 STATE_VERSION = 14; struct StateHeader { From e5c53e371f5ea96504b7c903239c2059b2f288bc Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Mon, 25 Feb 2013 18:12:25 -0500 Subject: [PATCH 091/167] Make error message for loading save state with wrong dsp engine shorter. --- Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp | 2 +- Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp index dac977922b..6d2a1f9097 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp @@ -135,7 +135,7 @@ void DSPHLE::DoState(PointerWrap &p) p.Do(isHLE); if (isHLE != true && p.GetMode() == PointerWrap::MODE_READ) { - Core::DisplayMessage("Save states made with the LLE audio engine are incompatible with the HLE DSP engine. Aborting load state.", 3000); + Core::DisplayMessage("State is incompatible with current DSP engine. Aborting load state.", 3000); p.SetMode(PointerWrap::MODE_VERIFY); return; } diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp index 2dbb7a8292..2cbf39f457 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp @@ -61,7 +61,7 @@ void DSPLLE::DoState(PointerWrap &p) p.Do(isHLE); if (isHLE != false && p.GetMode() == PointerWrap::MODE_READ) { - Core::DisplayMessage("Save states made with the HLE audio engine are incompatible with the LLE DSP engine. Aborting load state.", 3000); + Core::DisplayMessage("State is incompatible with current DSP engine. Aborting load state.", 3000); p.SetMode(PointerWrap::MODE_VERIFY); return; } From 415a2f17c95db405309d9d259134a40f21a3582d Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Mon, 25 Feb 2013 20:05:02 -0500 Subject: [PATCH 092/167] Begin implementing save states to video software. Kind of works, sometimes. --- .../Plugin_VideoSoftware/Src/EfbInterface.cpp | 7 +++++++ .../Plugins/Plugin_VideoSoftware/Src/EfbInterface.h | 1 + .../Plugin_VideoSoftware/Src/OpcodeDecoder.cpp | 12 ++++++++++++ .../Plugin_VideoSoftware/Src/OpcodeDecoder.h | 3 +++ .../Plugin_VideoSoftware/Src/SWCommandProcessor.cpp | 5 +++++ .../Plugin_VideoSoftware/Src/SWVertexLoader.cpp | 13 ++++++++++++- .../Plugin_VideoSoftware/Src/SWVertexLoader.h | 3 ++- Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp | 10 ++++++++-- .../Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp | 7 +++++++ Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.h | 2 ++ 10 files changed, 59 insertions(+), 4 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp index 6722ec7935..8fdc0425a4 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp @@ -28,6 +28,7 @@ u8 efb[EFB_WIDTH*EFB_HEIGHT*6]; namespace EfbInterface { + u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4]; inline u32 GetColorOffset(u16 x, u16 y) @@ -40,6 +41,12 @@ namespace EfbInterface return (x + y * EFB_WIDTH) * 3 + DEPTH_BUFFER_START; } + void DoState(PointerWrap &p) + { + p.DoArray(efb, EFB_WIDTH*EFB_HEIGHT*6); + p.DoArray(efbColorTexture, EFB_WIDTH*EFB_HEIGHT*4); + } + void SetPixelAlphaOnly(u32 offset, u8 a) { switch (bpmem.zcontrol.pixel_format) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.h b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.h index 15d19e7783..fdad69567c 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.h @@ -47,6 +47,7 @@ namespace EfbInterface void UpdateColorTexture(); extern u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4]; // RGBA format + void DoState(PointerWrap &p); } #endif diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp index 0091e4eaca..396a5a54af 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp @@ -46,6 +46,18 @@ static bool inObjectStream; static u8 lastPrimCmd; +void DoState(PointerWrap &p) +{ + p.Do(minCommandSize); + vertexLoader.DoState(p); + p.Do(streamSize); + p.Do(streamAddress); + p.Do(readOpcode); + p.Do(inObjectStream); + p.Do(lastPrimCmd); + //p.Do(currentFunction); +} + void DecodePrimitiveStream(u32 iBufferSize) { u32 vertexSize = vertexLoader.GetVertexSize(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.h b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.h index 635fcc24ee..53715b2832 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.h @@ -20,6 +20,7 @@ #define _OPCODEDECODER_H_ #include "CommonTypes.h" +#include "ChunkFile.h" namespace OpcodeDecoder { @@ -57,6 +58,8 @@ namespace OpcodeDecoder bool CommandRunnable(u32 iBufferSize); void Run(u32 iBufferSize); + + void DoState(PointerWrap &p); } #endif diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp index b9afc1abb5..97a99ff710 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp @@ -57,6 +57,11 @@ CPReg cpreg; // shared between gfx and emulator thread void DoState(PointerWrap &p) { p.Do(cpreg); + p.Do(readPos); + p.Do(writePos); + p.Do(et_UpdateInterrupts); + p.Do(interruptSet); + p.Do(interruptWaiting); } // does it matter that there is no synchronization between threads during writes? diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp index cc5ee66772..3142fc4262 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp @@ -328,4 +328,15 @@ void SWVertexLoader::LoadTexCoord(SWVertexLoader *vertexLoader, InputVertexData vertexLoader->m_texCoordLoader[index](); } - +void SWVertexLoader::DoState(PointerWrap &p) +{ + p.DoArray(m_AttributeLoaders, sizeof m_AttributeLoaders); + p.Do(m_VertexSize); + p.Do(m_CurrentVat); + p.Do(m_positionLoader); + p.Do(m_normalLoader); + p.DoArray(m_colorLoader, sizeof m_colorLoader); + p.Do(m_NumAttributeLoaders); + m_SetupUnit->DoState(p); + p.Do(m_TexGenSpecialCase); +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.h b/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.h index 91a0d8e911..e05346a7a5 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.h @@ -22,6 +22,7 @@ #include "NativeVertexFormat.h" #include "CPMemLoader.h" +#include "ChunkFile.h" class SetupUnit; @@ -69,7 +70,7 @@ public: u32 GetVertexSize() { return m_VertexSize; } void LoadVertex(); - + void DoState(PointerWrap &p); }; #endif diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 332e83d0e8..096315af4e 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -39,6 +39,8 @@ #include "FileUtil.h" #include "VideoBackend.h" #include "Core.h" +#include "OpcodeDecoder.h" +#include "SWVertexLoader.h" #define VSYNC_ENABLED 0 @@ -93,9 +95,13 @@ bool VideoSoftware::Initialize(void *&window_handle) return true; } -void VideoSoftware::DoState(PointerWrap&) +void VideoSoftware::DoState(PointerWrap& p) { - // NYI + // TODO: incomplete + SWCommandProcessor::DoState(p); + SWPixelEngine::DoState(p); + EfbInterface::DoState(p); + OpcodeDecoder::DoState(p); } void VideoSoftware::CheckInvalidState() diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp index 6e0fab57d8..57d69af7bd 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp @@ -169,3 +169,10 @@ void SetupUnit::SetupLineStrip() void SetupUnit::SetupPoint() {} + +void SetupUnit::DoState(PointerWrap &p) +{ + p.Do(m_PrimType); + p.Do(m_VertexCounter); + p.DoArray(m_Vertices, sizeof m_Vertices); +} \ No newline at end of file diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.h b/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.h index 45a575afcb..f337de21a2 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.h @@ -21,6 +21,7 @@ #include "Common.h" #include "NativeVertexFormat.h" +#include "ChunkFile.h" class SetupUnit { @@ -45,6 +46,7 @@ public: OutputVertexData* GetVertex() { return m_VertWritePointer; } void SetupVertex(); + void DoState(PointerWrap &p); }; #endif From db838e759b8935e213fa225be88ac0bfc78c27f7 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Mon, 25 Feb 2013 23:49:24 -0500 Subject: [PATCH 093/167] Improve VideoSoftware save states. They are fairly stable, but not perfect. OpcodeDecoder::DoState() needs to be fixed. --- .../Plugin_VideoSoftware/Src/Clipper.cpp | 7 +++++ .../Plugin_VideoSoftware/Src/Clipper.h | 3 ++ .../Src/NativeVertexFormat.h | 13 +++++++++ .../Src/OpcodeDecoder.cpp | 10 ++++--- .../Plugin_VideoSoftware/Src/Rasterizer.cpp | 22 ++++++++++++++ .../Plugin_VideoSoftware/Src/Rasterizer.h | 9 ++++++ .../Src/SWCommandProcessor.cpp | 4 +++ .../Src/SWPixelEngine.cpp | 2 ++ .../Src/SWVertexLoader.cpp | 2 +- .../Plugin_VideoSoftware/Src/SWmain.cpp | 13 +++++++++ .../Plugin_VideoSoftware/Src/SetupUnit.cpp | 29 +++++++++++++------ .../Plugins/Plugin_VideoSoftware/Src/Tev.cpp | 28 ++++++++++++++++++ Source/Plugins/Plugin_VideoSoftware/Src/Tev.h | 3 ++ .../Plugins/Plugin_VideoSoftware/Src/Vec3.h | 7 +++++ 14 files changed, 138 insertions(+), 14 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp index e9a3525d84..c4755b50bf 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.cpp @@ -65,6 +65,13 @@ namespace Clipper OutputVertexData ClippedVertices[NUM_CLIPPED_VERTICES]; OutputVertexData *Vertices[NUM_INDICES]; + void DoState(PointerWrap &p) + { + p.DoArray(m_ViewOffset,2); + for (int i = 0; i< NUM_CLIPPED_VERTICES; ++i) + ClippedVertices[i].DoState(p); + } + void Init() { for (int i = 0; i < NUM_CLIPPED_VERTICES; ++i) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.h b/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.h index 5e5dd4d02c..babc8b4e88 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Clipper.h @@ -21,6 +21,7 @@ #include "Common.h" #include "NativeVertexFormat.h" +#include "ChunkFile.h" namespace Clipper @@ -36,6 +37,8 @@ namespace Clipper bool CullTest(OutputVertexData *v0, OutputVertexData *v1, OutputVertexData *v2, bool &backface); void PerspectiveDivide(OutputVertexData *vertex); + + void DoState(PointerWrap &p); } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/NativeVertexFormat.h b/Source/Plugins/Plugin_VideoSoftware/Src/NativeVertexFormat.h index d19844105f..e2d87e207e 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/NativeVertexFormat.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/NativeVertexFormat.h @@ -19,6 +19,7 @@ #define _NATIVEVERTEXFORMAT_H #include "Vec3.h" +#include "ChunkFile.h" #ifdef WIN32 #define LOADERDECL __cdecl @@ -92,6 +93,18 @@ struct OutputVertexData #undef LINTERP #undef LINTERP_INT } + void DoState(PointerWrap &p) + { + mvPosition.DoState(p); + p.Do(projectedPosition); + screenPosition.DoState(p); + for (int i = 0; i < 3;++i) + normal[i].DoState(p); + p.DoArray(color, sizeof color); + for (int i = 0; i < 8;++i) + texCoords[i].DoState(p); + } + }; #endif diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp index 396a5a54af..4401916e1f 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp @@ -35,7 +35,6 @@ typedef void (*DecodingFunction)(u32); namespace OpcodeDecoder { - static DecodingFunction currentFunction = NULL; static u32 minCommandSize; static u16 streamSize; @@ -49,12 +48,15 @@ static u8 lastPrimCmd; void DoState(PointerWrap &p) { p.Do(minCommandSize); - vertexLoader.DoState(p); - p.Do(streamSize); - p.Do(streamAddress); + // Not sure what is wrong with this. Something(s) in here is causing dolphin to crash/hang when loading states saved from another run of dolphin. Doesn't seem too important anyway... + //vertexLoader.DoState(p); p.Do(readOpcode); p.Do(inObjectStream); p.Do(lastPrimCmd); + p.Do(streamSize); + p.Do(streamAddress); + // not sure how to save this... It seems to be the only thing left that is really important. + // uncommenting this will prevent all error messages, and any crashes/hangs on load, but then obviously it'll segfault once you restart dolphin. //p.Do(currentFunction); } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp index 225400e08b..5eed912dcb 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp @@ -62,6 +62,28 @@ s32 scissorBottom = 0; Tev tev; RasterBlock rasterBlock; +void DoState(PointerWrap &p) +{ + ZSlope.DoState(p); + WSlope.DoState(p); + for (int i=0;i<2;++i) + for (int n=0; n<4; ++n) + ColorSlopes[i][n].DoState(p); + for (int i=0;i<8;++i) + for (int n=0; n<3; ++n) + TexSlopes[i][n].DoState(p); + p.Do(vertex0X); + p.Do(vertex0Y); + p.Do(vertexOffsetX); + p.Do(vertexOffsetY); + p.Do(scissorLeft); + p.Do(scissorTop); + p.Do(scissorRight); + p.Do(scissorBottom); + tev.DoState(p); + p.Do(rasterBlock); +} + void Init() { tev.Init(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.h b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.h index f8850571a9..784c4a8d62 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.h @@ -19,6 +19,7 @@ #define _RASTERIZER_H_ #include "NativeVertexFormat.h" +#include "ChunkFile.h" namespace Rasterizer { @@ -37,6 +38,12 @@ namespace Rasterizer float f0; float GetValue(float dx, float dy) { return f0 + (dfdx * dx) + (dfdy * dy); } + void DoState(PointerWrap &p) + { + p.Do(dfdx); + p.Do(dfdy); + p.Do(f0); + } }; struct RasterBlockPixel @@ -53,6 +60,8 @@ namespace Rasterizer s32 TextureLod[16]; bool TextureLinear[16]; }; + + void DoState(PointerWrap &p); } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp index 97a99ff710..c15a02f93e 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp @@ -57,11 +57,15 @@ CPReg cpreg; // shared between gfx and emulator thread void DoState(PointerWrap &p) { p.Do(cpreg); + p.DoArray(commandBuffer, commandBufferSize); p.Do(readPos); p.Do(writePos); p.Do(et_UpdateInterrupts); p.Do(interruptSet); p.Do(interruptWaiting); + + // Is this right? + p.DoArray(g_pVideoData,writePos); } // does it matter that there is no synchronization between threads during writes? diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp index 33a6164b01..e9d2c1fe96 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp @@ -53,6 +53,8 @@ void DoState(PointerWrap &p) p.Do(pereg); p.Do(g_bSignalTokenInterrupt); p.Do(g_bSignalFinishInterrupt); + p.Do(et_SetTokenOnMainThread); + p.Do(et_SetFinishOnMainThread); } void UpdateInterrupts(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp index 3142fc4262..1c1eeb2005 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWVertexLoader.cpp @@ -332,7 +332,7 @@ void SWVertexLoader::DoState(PointerWrap &p) { p.DoArray(m_AttributeLoaders, sizeof m_AttributeLoaders); p.Do(m_VertexSize); - p.Do(m_CurrentVat); + p.Do(*m_CurrentVat); p.Do(m_positionLoader); p.Do(m_normalLoader); p.DoArray(m_colorLoader, sizeof m_colorLoader); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 096315af4e..d78b8ba13b 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -102,6 +102,19 @@ void VideoSoftware::DoState(PointerWrap& p) SWPixelEngine::DoState(p); EfbInterface::DoState(p); OpcodeDecoder::DoState(p); + Clipper::DoState(p); + p.Do(swxfregs); + p.Do(bpmem); + + // CP Memory + p.DoArray(arraybases, 16); + p.DoArray(arraystrides, 16); + p.Do(MatrixIndexA); + p.Do(MatrixIndexB); + p.Do(g_VtxDesc.Hex); + p.DoArray(g_VtxAttr, 8); + p.DoMarker("CP Memory"); + } void VideoSoftware::CheckInvalidState() diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp index 57d69af7bd..d2185e31d5 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SetupUnit.cpp @@ -25,13 +25,13 @@ void SetupUnit::Init(u8 primitiveType) { - m_PrimType = primitiveType; + m_PrimType = primitiveType; - m_VertexCounter = 0; - m_VertPointer[0] = &m_Vertices[0]; - m_VertPointer[1] = &m_Vertices[1]; - m_VertPointer[2] = &m_Vertices[2]; - m_VertWritePointer = m_VertPointer[0]; + m_VertexCounter = 0; + m_VertPointer[0] = &m_Vertices[0]; + m_VertPointer[1] = &m_Vertices[1]; + m_VertPointer[2] = &m_Vertices[2]; + m_VertWritePointer = m_VertPointer[0]; } void SetupUnit::SetupVertex() @@ -172,7 +172,18 @@ void SetupUnit::SetupPoint() void SetupUnit::DoState(PointerWrap &p) { - p.Do(m_PrimType); + // TODO: some or all of this is making the save states stop working once dolphin is closed...sometimes (usually) + // I have no idea what specifically is wrong, or if this is even important. Disabling it doesn't seem to make any noticible difference... +/* p.Do(m_PrimType); p.Do(m_VertexCounter); - p.DoArray(m_Vertices, sizeof m_Vertices); -} \ No newline at end of file + for (int i = 0; i < 3; ++i) + m_Vertices[i].DoState(p); + + if (p.GetMode() == PointerWrap::MODE_READ) + { + m_VertPointer[0] = &m_Vertices[0]; + m_VertPointer[1] = &m_Vertices[1]; + m_VertPointer[2] = &m_Vertices[2]; + m_VertWritePointer = m_VertPointer[0]; + }*/ +} diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp index 927f8931e9..0f4b4fce20 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp @@ -827,3 +827,31 @@ void Tev::SetRegColor(int reg, int comp, bool konst, s16 color) Reg[reg][comp] = color; } } + +void Tev::DoState(PointerWrap &p) +{ + p.DoArray(Reg, sizeof(Reg)); + + p.DoArray(KonstantColors, sizeof(KonstantColors)); + p.DoArray(TexColor,4); + p.DoArray(RasColor,4); + p.DoArray(StageKonst,4); + p.DoArray(Zero16,4); + + p.DoArray(FixedConstants,9); + p.Do(AlphaBump); + p.DoArray(IndirectTex, sizeof(IndirectTex)); + p.Do(TexCoord); + + p.DoArray(m_BiasLUT,4); + p.DoArray(m_ScaleLShiftLUT,4); + p.DoArray(m_ScaleRShiftLUT,4); + + p.DoArray(Position,3); + p.DoArray(Color, sizeof(Color)); + p.DoArray(Uv, 8); + p.DoArray(IndirectLod,4); + p.DoArray(IndirectLinear,4); + p.DoArray(TextureLod,16); + p.DoArray(TextureLinear,16); +} diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.h b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.h index bdd265170c..1d1bc8d2ba 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.h @@ -19,6 +19,7 @@ #define _TEV_H_ #include "BPMemLoader.h" +#include "ChunkFile.h" class Tev { @@ -96,6 +97,8 @@ public: void SetRegColor(int reg, int comp, bool konst, s16 color); enum { ALP_C, BLU_C, GRN_C, RED_C }; + + void DoState(PointerWrap &p); }; #endif diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Vec3.h b/Source/Plugins/Plugin_VideoSoftware/Src/Vec3.h index 3a36a13307..80460edd60 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Vec3.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Vec3.h @@ -20,6 +20,7 @@ #include #include +#include "ChunkFile.h" class Vec3 { @@ -111,6 +112,12 @@ public: { memset((void *)this,0,sizeof(float)*3); } + void DoState(PointerWrap &p) + { + p.Do(x); + p.Do(y); + p.Do(z); + } }; #endif From 717b9768750dfef39120d4457a832ce7558bd879 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 26 Feb 2013 13:49:00 -0600 Subject: [PATCH 094/167] ARM Support without GLSL --- CMakeLists.txt | 344 +-- Source/Core/AudioCommon/CMakeLists.txt | 5 + Source/Core/AudioCommon/Src/AudioCommon.cpp | 7 +- .../Core/AudioCommon/Src/OpenSLESStream.cpp | 145 ++ Source/Core/AudioCommon/Src/OpenSLESStream.h | 48 + Source/Core/Common/CMakeLists.txt | 23 +- Source/Core/Common/Common.vcxproj | 9 +- Source/Core/Common/Common.vcxproj.filters | 9 +- Source/Core/Common/Src/ArmCPUDetect.cpp | 160 ++ Source/Core/Common/Src/ArmEmitter.cpp | 967 ++++++++ Source/Core/Common/Src/ArmEmitter.h | 587 +++++ Source/Core/Common/Src/CPUDetect.h | 23 +- Source/Core/Common/Src/Common.h | 6 +- Source/Core/Common/Src/CommonFuncs.h | 14 +- Source/Core/Common/Src/CommonPaths.h | 5 + Source/Core/Common/Src/FPURoundMode.h | 51 + Source/Core/Common/Src/FileUtil.cpp | 5 +- .../Core/Common/Src/GenericFPURoundMode.cpp | 41 + Source/Core/Common/Src/LogManager.cpp | 7 +- Source/Core/Common/Src/MathUtil.cpp | 24 - Source/Core/Common/Src/MathUtil.h | 13 +- Source/Core/Common/Src/MemArena.cpp | 34 + Source/Core/Common/Src/MemoryUtil.cpp | 5 +- Source/Core/Common/Src/StdConditionVariable.h | 2 +- Source/Core/Common/Src/StdMutex.h | 2 +- Source/Core/Common/Src/StdThread.h | 2 +- Source/Core/Common/Src/StringUtil.cpp | 38 +- Source/Core/Common/Src/Thread.cpp | 2 +- Source/Core/Common/Src/Thread.h | 2 - .../Core/Common/Src/{ABI.cpp => x64ABI.cpp} | 2 +- Source/Core/Common/Src/{ABI.h => x64ABI.h} | 0 .../Src/{CPUDetect.cpp => x64CPUDetect.cpp} | 6 +- Source/Core/Common/Src/x64Emitter.cpp | 2 +- Source/Core/Common/Src/x64Emitter.h | 2 +- Source/Core/Common/Src/x64FPURoundMode.cpp | 120 + .../Common/Src/{Thunk.cpp => x64Thunk.cpp} | 3 +- Source/Core/Core/CMakeLists.txt | 36 +- Source/Core/Core/Core.vcxproj | 12 +- Source/Core/Core/Core.vcxproj.filters | 9 +- Source/Core/Core/Src/ArmMemTools.cpp | 103 + Source/Core/Core/Src/ConfigManager.h | 2 +- Source/Core/Core/Src/Core.cpp | 7 +- Source/Core/Core/Src/DSP/DSPEmitter.cpp | 2 +- Source/Core/Core/Src/DSP/DSPHWInterface.cpp | 2 + .../Core/Src/DSP/Jit/DSPJitArithmetic.cpp | 2 +- Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp | 2 +- Source/Core/Core/Src/DSP/Jit/DSPJitCCUtil.cpp | 2 +- Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp | 2 +- .../Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp | 2 +- Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp | 2 +- .../Core/Src/DSP/Jit/DSPJitMultiplier.cpp | 2 +- Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp | 2 +- Source/Core/Core/Src/HW/Memmap.cpp | 126 - Source/Core/Core/Src/HW/Memmap.h | 5 - .../Interpreter/Interpreter_FloatingPoint.cpp | 4 +- .../Interpreter/Interpreter_LoadStore.cpp | 21 +- .../Interpreter_SystemRegisters.cpp | 51 +- .../Interpreter/Interpreter_Tables.cpp | 2 +- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 4 +- Source/Core/Core/Src/PowerPC/Jit64/Jit.h | 2 +- Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp | 6 +- Source/Core/Core/Src/PowerPC/Jit64/JitAsm.h | 1 - .../Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp | 2 +- .../PowerPC/Jit64/Jit_LoadStoreFloating.cpp | 2 +- .../Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp | 2 +- .../Src/PowerPC/Jit64/Jit_SystemRegisters.cpp | 2 +- .../Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp | 10 +- .../Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp | 2 +- Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h | 2 +- .../Core/Src/PowerPC/Jit64IL/JitILAsm.cpp | 8 +- .../Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp | 2 +- .../Jit64IL/JitIL_LoadStoreFloating.cpp | 2 +- .../PowerPC/Jit64IL/JitIL_LoadStorePaired.cpp | 2 +- .../PowerPC/Jit64IL/JitIL_SystemRegisters.cpp | 2 +- Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp | 498 ++++ Source/Core/Core/Src/PowerPC/JitArm32/Jit.h | 186 ++ .../Core/Src/PowerPC/JitArm32/JitArmCache.cpp | 46 + .../Core/Src/PowerPC/JitArm32/JitArmCache.h | 33 + .../Src/PowerPC/JitArm32/JitArm_BackPatch.cpp | 164 ++ .../Src/PowerPC/JitArm32/JitArm_Branch.cpp | 347 +++ .../PowerPC/JitArm32/JitArm_FloatingPoint.cpp | 80 + .../Src/PowerPC/JitArm32/JitArm_Integer.cpp | 297 +++ .../Src/PowerPC/JitArm32/JitArm_LoadStore.cpp | 414 ++++ .../JitArm32/JitArm_LoadStoreFloating.cpp | 72 + .../JitArm32/JitArm_SystemRegisters.cpp | 111 + .../Src/PowerPC/JitArm32/JitArm_Tables.cpp | 502 ++++ .../Core/Src/PowerPC/JitArm32/JitArm_Tables.h | 29 + .../Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp | 174 ++ .../Core/Core/Src/PowerPC/JitArm32/JitAsm.h | 43 + .../Core/Src/PowerPC/JitArm32/JitRegCache.cpp | 167 ++ .../Core/Src/PowerPC/JitArm32/JitRegCache.h | 92 + .../Src/PowerPC/JitCommon/JitAsmCommon.cpp | 4 +- .../Core/Src/PowerPC/JitCommon/JitAsmCommon.h | 25 +- .../Src/PowerPC/JitCommon/JitBackpatch.cpp | 4 +- .../Core/Src/PowerPC/JitCommon/JitBackpatch.h | 4 + .../Core/Core/Src/PowerPC/JitCommon/JitBase.h | 26 +- .../Core/Src/PowerPC/JitCommon/JitCache.cpp | 94 +- .../Core/Src/PowerPC/JitCommon/JitCache.h | 16 +- .../Core/Src/PowerPC/JitCommon/Jit_Util.cpp | 2 +- Source/Core/Core/Src/PowerPC/JitInterface.cpp | 350 +++ Source/Core/Core/Src/PowerPC/JitInterface.h | 56 + Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp | 3 +- Source/Core/Core/Src/PowerPC/PPCCache.cpp | 7 +- Source/Core/Core/Src/PowerPC/PPCTables.cpp | 18 +- Source/Core/Core/Src/PowerPC/PowerPC.cpp | 70 +- Source/Core/Core/Src/PowerPC/Profiler.cpp | 78 +- Source/Core/Core/Src/PowerPC/Profiler.h | 9 + .../Src/{MemTools.cpp => x64MemTools.cpp} | 12 +- Source/Core/DiscIO/Src/BannerLoader.cpp | 6 + Source/Core/DolphinWX/CMakeLists.txt | 187 +- .../DolphinWX/Src/Debugger/CodeWindow.cpp | 14 +- Source/Core/DolphinWX/Src/Frame.cpp | 2 +- Source/Core/DolphinWX/Src/GLInterface.h | 13 +- .../Src/GLInterface/{EGL.cpp => EGL_X11.cpp} | 2 +- .../Src/GLInterface/{EGL.h => EGL_X11.h} | 0 .../DolphinWX/Src/GLInterface/InterfaceBase.h | 10 +- Source/Core/DolphinWX/Src/MainAndroid.cpp | 149 ++ Source/Core/VideoCommon/CMakeLists.txt | 10 +- Source/Core/VideoCommon/Src/Fifo.cpp | 6 +- .../Core/VideoCommon/Src/GenericDLCache.cpp | 52 + .../VideoCommon/Src/GenericTextureDecoder.cpp | 2182 +++++++++++++++++ Source/Core/VideoCommon/Src/VertexLoader.cpp | 18 +- Source/Core/VideoCommon/Src/VertexLoader.h | 7 + .../Src/{DLCache.cpp => x64DLCache.cpp} | 2 +- ...xtureDecoder.cpp => x64TextureDecoder.cpp} | 93 - Source/Core/VideoCommon/VideoCommon.vcxproj | 10 +- .../VideoCommon/VideoCommon.vcxproj.filters | 12 +- .../Src/NativeVertexFormat.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp | 4 +- .../Src/NativeVertexFormat.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 4 + .../Src/OpcodeDecoder.cpp | 6 +- .../Src/SWCommandProcessor.cpp | 6 +- 133 files changed, 9048 insertions(+), 948 deletions(-) create mode 100644 Source/Core/AudioCommon/Src/OpenSLESStream.cpp create mode 100644 Source/Core/AudioCommon/Src/OpenSLESStream.h create mode 100644 Source/Core/Common/Src/ArmCPUDetect.cpp create mode 100644 Source/Core/Common/Src/ArmEmitter.cpp create mode 100644 Source/Core/Common/Src/ArmEmitter.h create mode 100644 Source/Core/Common/Src/FPURoundMode.h create mode 100644 Source/Core/Common/Src/GenericFPURoundMode.cpp rename Source/Core/Common/Src/{ABI.cpp => x64ABI.cpp} (99%) rename Source/Core/Common/Src/{ABI.h => x64ABI.h} (100%) rename Source/Core/Common/Src/{CPUDetect.cpp => x64CPUDetect.cpp} (98%) create mode 100644 Source/Core/Common/Src/x64FPURoundMode.cpp rename Source/Core/Common/Src/{Thunk.cpp => x64Thunk.cpp} (98%) create mode 100644 Source/Core/Core/Src/ArmMemTools.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/Jit.h create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.h create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.h create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.h create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.h create mode 100644 Source/Core/Core/Src/PowerPC/JitInterface.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitInterface.h rename Source/Core/Core/Src/{MemTools.cpp => x64MemTools.cpp} (96%) rename Source/Core/DolphinWX/Src/GLInterface/{EGL.cpp => EGL_X11.cpp} (99%) rename Source/Core/DolphinWX/Src/GLInterface/{EGL.h => EGL_X11.h} (100%) create mode 100644 Source/Core/DolphinWX/Src/MainAndroid.cpp create mode 100644 Source/Core/VideoCommon/Src/GenericDLCache.cpp create mode 100644 Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp rename Source/Core/VideoCommon/Src/{DLCache.cpp => x64DLCache.cpp} (99%) rename Source/Core/VideoCommon/Src/{TextureDecoder.cpp => x64TextureDecoder.cpp} (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4598eaa9e2..ea531f030c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,9 +106,22 @@ if(DOLPHIN_IS_STABLE) else() set(DOLPHIN_VERSION_PATCH ${DOLPHIN_WC_REVISION}) endif() +message(${CMAKE_SYSTEM_PROCESSOR}) +if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm") + set(_M_GENERIC 1) + set(_M_ARM 1) + add_definitions(-marm -march=armv7-a) + add_definitions(-D_M_ARM=1) + add_definitions(-D_M_GENERIC=1) +endif() +# Set these next two lines to test generic +#set(_M_GENERIC 1) +#add_definitions(-D_M_GENERIC=1) # Various compile flags -add_definitions(-msse2) +if(NOT _M_GENERIC) + add_definitions(-msse2) +endif() include(CheckCXXCompilerFlag) macro(check_and_add_flag var flag) @@ -258,135 +271,141 @@ if(USE_EGL) endif() add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE) +option(ANDROID "Enables a build for Android" OFF) +if(ANDROID) + message("Building for Android") + add_definitions(-DANDROID) +endif() ######################################## # Dependency checking # # TODO: We should have options for dependencies included in the externals to # override autodetection of system libraries and force the usage of the # externals. +if(NOT ANDROID) + include(CheckLib) -include(CheckLib) - -include(FindOpenGL) -include_directories(${OPENGL_INCLUDE_DIR}) -if(NOT OPENGL_GLU_FOUND) - message(FATAL_ERROR "GLU is required but not found") -endif() - -if(OPENMP) - include(FindOpenMP OPTIONAL) - if(OPENMP_FOUND) - message("OpenMP parallelization enabled") - add_definitions("${OpenMP_CXX_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}") + include(FindOpenGL) + include_directories(${OPENGL_INCLUDE_DIR}) + if(NOT OPENGL_GLU_FOUND) + message(FATAL_ERROR "GLU is required but not found") endif() -endif() -if(NOT OPENMP_FOUND) - add_definitions(-Wno-unknown-pragmas) - message("OpenMP parallelization disabled") -endif() -include(FindALSA OPTIONAL) -if(ALSA_FOUND) - add_definitions(-DHAVE_ALSA=1) - message("ALSA found, enabling ALSA sound backend") -else() - add_definitions(-DHAVE_ALSA=0) - message("ALSA NOT found, disabling ALSA sound backend") -endif(ALSA_FOUND) + if(OPENMP) + include(FindOpenMP OPTIONAL) + if(OPENMP_FOUND) + message("OpenMP parallelization enabled") + add_definitions("${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_CXX_FLAGS}") + endif() + endif() + if(NOT OPENMP_FOUND) + add_definitions(-Wno-unknown-pragmas) + message("OpenMP parallelization disabled") + endif() -check_lib(AO ao QUIET) -if(AO_FOUND) - add_definitions(-DHAVE_AO=1) - message("ao found, enabling ao sound backend") -else() - add_definitions(-DHAVE_AO=0) - message("ao NOT found, disabling ao sound backend") -endif(AO_FOUND) + include(FindALSA OPTIONAL) + if(ALSA_FOUND) + add_definitions(-DHAVE_ALSA=1) + message("ALSA found, enabling ALSA sound backend") + else() + add_definitions(-DHAVE_ALSA=0) + message("ALSA NOT found, disabling ALSA sound backend") + endif(ALSA_FOUND) -check_lib(BLUEZ bluez QUIET) -if(BLUEZ_FOUND) - add_definitions(-DHAVE_BLUEZ=1) - message("bluez found, enabling bluetooth support") -else() - add_definitions(-DHAVE_BLUEZ=0) - message("bluez NOT found, disabling bluetooth support") -endif(BLUEZ_FOUND) + check_lib(AO ao QUIET) + if(AO_FOUND) + add_definitions(-DHAVE_AO=1) + message("ao found, enabling ao sound backend") + else() + add_definitions(-DHAVE_AO=0) + message("ao NOT found, disabling ao sound backend") + endif(AO_FOUND) -check_lib(PULSEAUDIO libpulse-simple QUIET) -if(PULSEAUDIO_FOUND) - add_definitions(-DHAVE_PULSEAUDIO=1) - message("PulseAudio found, enabling PulseAudio sound backend") -else() - add_definitions(-DHAVE_PULSEAUDIO=0) - message("PulseAudio NOT found, disabling PulseAudio sound backend") -endif(PULSEAUDIO_FOUND) + check_lib(BLUEZ bluez QUIET) + if(BLUEZ_FOUND) + add_definitions(-DHAVE_BLUEZ=1) + message("bluez found, enabling bluetooth support") + else() + add_definitions(-DHAVE_BLUEZ=0) + message("bluez NOT found, disabling bluetooth support") + endif(BLUEZ_FOUND) -include(FindOpenAL OPTIONAL) -if(OPENAL_FOUND) - add_definitions(-DHAVE_OPENAL=1) - include_directories(${OPENAL_INCLUDE_DIR}) - message("OpenAL found, enabling OpenAL sound backend") -else() - add_definitions(-DHAVE_OPENAL=0) - message("OpenAL NOT found, disabling OpenAL sound backend") -endif(OPENAL_FOUND) + check_lib(PULSEAUDIO libpulse QUIET) + if(PULSEAUDIO_FOUND) + add_definitions(-DHAVE_PULSEAUDIO=1) + message("PulseAudio found, enabling PulseAudio sound backend") + else() + add_definitions(-DHAVE_PULSEAUDIO=0) + message("PulseAudio NOT found, disabling PulseAudio sound backend") + endif(PULSEAUDIO_FOUND) + + include(FindOpenAL OPTIONAL) + if(OPENAL_FOUND) + add_definitions(-DHAVE_OPENAL=1) + include_directories(${OPENAL_INCLUDE_DIR}) + message("OpenAL found, enabling OpenAL sound backend") + else() + add_definitions(-DHAVE_OPENAL=0) + message("OpenAL NOT found, disabling OpenAL sound backend") + endif(OPENAL_FOUND) # Note: We do not need to explicitly check for X11 as it is done in the cmake # FindOpenGL module on linux. -if(UNIX AND NOT APPLE) + if(UNIX AND NOT APPLE) + if(X11_FOUND) + add_definitions(-DHAVE_X11=1) + include_directories(${X11_INCLUDE_DIR}) + message("X11 found") + else() + message(FATAL_ERROR "X11 is required but not found") + endif(X11_FOUND) + else() + add_definitions(-DHAVE_X11=0) + endif() + if(X11_FOUND) - add_definitions(-DHAVE_X11=1) - include_directories(${X11_INCLUDE_DIR}) - message("X11 found") + check_lib(XRANDR Xrandr) + endif() + if(XRANDR_FOUND) + add_definitions(-DHAVE_XRANDR=1) else() - message(FATAL_ERROR "X11 is required but not found") - endif(X11_FOUND) -else() - add_definitions(-DHAVE_X11=0) -endif() + add_definitions(-DHAVE_XRANDR=0) + endif(XRANDR_FOUND) -if(X11_FOUND) - check_lib(XRANDR Xrandr) -endif() -if(XRANDR_FOUND) - add_definitions(-DHAVE_XRANDR=1) -else() - add_definitions(-DHAVE_XRANDR=0) -endif(XRANDR_FOUND) + if(ENCODE_FRAMEDUMPS) + check_libav() + endif() -if(ENCODE_FRAMEDUMPS) - check_libav() -endif() - -include(CheckCXXSourceRuns) -set(CMAKE_REQUIRED_LIBRARIES portaudio) -CHECK_CXX_SOURCE_RUNS( - "#include - int main(int argc, char **argv) - { if(Pa_GetVersion() >= 1890) return 0; else return 1; }" - PORTAUDIO) -if(PORTAUDIO) - message("PortAudio found, enabling mic support") - add_definitions(-DHAVE_PORTAUDIO=1) - set(PORTAUDIO_FOUND TRUE) -else() - message("PortAudio not found, disabling mic support") - add_definitions(-DHAVE_PORTAUDIO=0) - set(PORTAUDIO_FOUND FALSE) -endif(PORTAUDIO) - -if(OPROFILING) - check_lib(OPROFILE opagent opagent.h) - check_lib(BFD bfd bfd.h) - if(OPROFILE_FOUND AND BFD_FOUND) - message("oprofile found, enabling profiling support") - add_definitions(-DUSE_OPROFILE=1) + include(CheckCXXSourceRuns) + set(CMAKE_REQUIRED_LIBRARIES portaudio) + CHECK_CXX_SOURCE_RUNS( + "#include + int main(int argc, char **argv) + { if(Pa_GetVersion() >= 1890) return 0; else return 1; }" + PORTAUDIO) + if(PORTAUDIO) + message("PortAudio found, enabling mic support") + add_definitions(-DHAVE_PORTAUDIO=1) + set(PORTAUDIO_FOUND TRUE) else() - message(FATAL_ERROR "oprofile or bfd not found. Can't build profiling support.") + message("PortAudio not found, disabling mic support") + add_definitions(-DHAVE_PORTAUDIO=0) + set(PORTAUDIO_FOUND FALSE) + endif(PORTAUDIO) + + option(OPROFILING "Enable profiling" OFF) + if(OPROFILING) + check_lib(OPROFILE opagent opagent.h) + check_lib(BFD bfd bfd.h) + if(OPROFILE_FOUND AND BFD_FOUND) + message("oprofile found, enabling profiling support") + add_definitions(-DUSE_OPROFILE=1) + else() + message(FATAL_ERROR "oprofile or bfd not found. Can't build profiling support.") + endif() endif() endif() - ######################################## # Setup include directories (and make sure they are preferred over the Externals) # @@ -401,7 +420,6 @@ include_directories(Source/Core/InputCommon/Src) include_directories(Source/Core/VideoCommon/Src) include_directories(Source/Core/VideoUICommon/Src) - ######################################## # Process externals and setup their include directories # @@ -415,7 +433,7 @@ include_directories(Source/Core/VideoUICommon/Src) add_subdirectory(Externals/Bochs_disasm) include_directories(Externals/Bochs_disasm) -if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ANDROID) check_lib(LZO lzo2 lzo/lzo1x.h QUIET) endif() if(LZO_FOUND) @@ -440,15 +458,16 @@ if(OPENAL_FOUND) endif() endif() -if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - include(FindSDL2 OPTIONAL) -endif() -if(SDL2_FOUND) - message("Using shared SDL2") - include_directories(${SDL2_INCLUDE_DIR}) -else(SDL2_FOUND) - # SDL2 not found, try SDL +if(NOT ANDROID) if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + include(FindSDL2 OPTIONAL) + endif() + if(SDL2_FOUND) + message("Using shared SDL2") + include_directories(${SDL2_INCLUDE_DIR}) + else(SDL2_FOUND) + # SDL2 not found, try SDL + if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") include(FindSDL OPTIONAL) endif() if(SDL_FOUND) @@ -460,12 +479,13 @@ else(SDL2_FOUND) include_directories(Externals/SDL/SDL Externals/SDL Externals/SDL/include) add_subdirectory(Externals/SDL) endif(SDL_FOUND) -endif(SDL2_FOUND) + endif(SDL2_FOUND) +endif() set(SFML_FIND_VERSION TRUE) set(SFML_FIND_VERSION_MAJOR 1) set(SFML_FIND_VERSION_MINOR 5) -if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ANDROID) include(FindSFML OPTIONAL) endif() if(SFML_FOUND AND NOT SFML_VERSION_MAJOR) # SFML 1.x doesn't define SFML_VERSION_MAJOR @@ -476,7 +496,7 @@ else() include_directories(Externals/SFML/include) endif() -if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ANDROID) check_lib(SOIL SOIL SOIL/SOIL.h QUIET) endif() if(SOIL_FOUND) @@ -506,26 +526,19 @@ if(WIN32) find_library(GLEW glew32s PATHS Externals/GLew) include_directories(Externals/GLew/include) else() - if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - check_lib(GLEW GLEW GL/glew.h) + if(NOT ANDROID) + if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + check_lib(GLEW GLEW GL/glew.h) + endif() + if(NOT GLEW_FOUND) + message("Using static GLEW from Externals") + add_subdirectory(Externals/GLew) + include_directories(Externals/GLew/include) + endif(NOT GLEW_FOUND) endif() - if(NOT GLEW_FOUND) - message("Using static GLEW from Externals") - add_subdirectory(Externals/GLew) - include_directories(Externals/GLew/include) - endif(NOT GLEW_FOUND) - - if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - check_lib(CG Cg Cg/cg.h) - endif() - if(NOT CG_FOUND) - message("Using static Cg from Externals") - include_directories(Externals) - endif(NOT CG_FOUND) - check_lib(CGGL CgGL Cg/cgGL.h) endif() -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT ANDROID) find_library(CL OpenCL) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-weak_framework,OpenCL") else() @@ -533,10 +546,25 @@ else() add_subdirectory(Externals/CLRun) endif() -if(NOT DISABLE_WX) +if(NOT DISABLE_WX AND NOT ANDROID) include(FindwxWidgets OPTIONAL) FIND_PACKAGE(wxWidgets COMPONENTS core aui adv) + if(wxWidgets_FOUND) + EXECUTE_PROCESS( + COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" + ${wxWidgets_CONFIG_OPTIONS} --version + OUTPUT_VARIABLE wxWidgets_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + message("Found wxWidgets version ${wxWidgets_VERSION}") + if(${wxWidgets_VERSION} VERSION_LESS "2.8.9") + message("At least 2.8.9 is required; ignoring found version") + unset(wxWidgets_FOUND) + endif() + endif(wxWidgets_FOUND) + if(wxWidgets_FOUND) EXECUTE_PROCESS( COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" @@ -557,26 +585,26 @@ if(NOT DISABLE_WX) endif() endif(wxWidgets_FOUND) - if(UNIX AND NOT APPLE) - # There is a bug in the FindGTK module in cmake version 2.8.2 that - # does not find gdk-pixbuf-2.0. On the other hand some 2.8.3 - # users have complained that pkg-config does not find - # gdk-pixbuf-2.0. On yet another hand, cmake version 2.8.3 in - # Ubuntu Natty does not find the glib libraries correctly. - # Ugly!!! - execute_process(COMMAND lsb_release -c -s - OUTPUT_VARIABLE DIST_NAME - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) - if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} - VERSION_EQUAL 2.8.2 OR "${DIST_NAME}" STREQUAL "natty") - check_lib(GTK2 gtk+-2.0 gtk.h REQUIRED) - else() - include(FindGTK2) - if(GTK2_FOUND) - include_directories(${GTK2_INCLUDE_DIRS}) + if(UNIX AND NOT APPLE) + # There is a bug in the FindGTK module in cmake version 2.8.2 that + # does not find gdk-pixbuf-2.0. On the other hand some 2.8.3 + # users have complained that pkg-config does not find + # gdk-pixbuf-2.0. On yet another hand, cmake version 2.8.3 in + # Ubuntu Natty does not find the glib libraries correctly. + # Ugly!!! + execute_process(COMMAND lsb_release -c -s + OUTPUT_VARIABLE DIST_NAME + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} + VERSION_EQUAL 2.8.2 OR "${DIST_NAME}" STREQUAL "natty") + check_lib(GTK2 gtk+-2.0 gtk.h REQUIRED) + else() + include(FindGTK2) + if(GTK2_FOUND) + include_directories(${GTK2_INCLUDE_DIRS}) + endif() endif() endif() - endif() if(wxWidgets_FOUND) include(${wxWidgets_USE_FILE}) @@ -608,7 +636,7 @@ if(NOT DISABLE_WX) set(wxWidgets_LIBRARIES "wx") endif(wxWidgets_FOUND) add_definitions(-DHAVE_WX=1) -endif(NOT DISABLE_WX) +endif(NOT DISABLE_WX AND NOT ANDROID) ######################################## @@ -682,4 +710,4 @@ list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_BINARY_DIR}") # CPack must be included after the CPACK_* variables are set in order for those # variables to take effect. -include(CPack) +Include(CPack) diff --git a/Source/Core/AudioCommon/CMakeLists.txt b/Source/Core/AudioCommon/CMakeLists.txt index 3b6d0cea4d..939956460d 100644 --- a/Source/Core/AudioCommon/CMakeLists.txt +++ b/Source/Core/AudioCommon/CMakeLists.txt @@ -6,6 +6,11 @@ set(SRCS Src/AudioCommon.cpp set(LIBS "") +if(ANDROID) + set(SRCS ${SRCS} Src/OpenSLESStream.cpp) + set(LIBS ${LIBS} OpenSLES) +endif(ANDROID) + if(ALSA_FOUND) set(SRCS ${SRCS} Src/AlsaSoundStream.cpp) set(LIBS ${LIBS} ${ALSA_LIBRARIES}) diff --git a/Source/Core/AudioCommon/Src/AudioCommon.cpp b/Source/Core/AudioCommon/Src/AudioCommon.cpp index e14b9ac45e..2f299d0edb 100644 --- a/Source/Core/AudioCommon/Src/AudioCommon.cpp +++ b/Source/Core/AudioCommon/Src/AudioCommon.cpp @@ -26,6 +26,7 @@ #include "CoreAudioSoundStream.h" #include "OpenALStream.h" #include "PulseAudioStream.h" +#include "OpenSLESStream.h" #include "../../Core/Src/Movie.h" #include "../../Core/Src/ConfigManager.h" @@ -55,7 +56,8 @@ namespace AudioCommon soundStream = new CoreAudioSound(mixer); else if (backend == BACKEND_PULSEAUDIO && PulseAudio::isValid()) soundStream = new PulseAudio(mixer); - + else if (backend == BACKEND_OPENSLES && OpenSLESStream::isValid()) + soundStream = new OpenSLESStream(mixer); if (soundStream != NULL) { UpdateSoundStream(); @@ -116,7 +118,8 @@ namespace AudioCommon backends.push_back(BACKEND_PULSEAUDIO); if (OpenALStream::isValid()) backends.push_back(BACKEND_OPENAL); - + if (OpenSLESStream::isValid()) + backends.push_back(BACKEND_OPENSLES); return backends; } diff --git a/Source/Core/AudioCommon/Src/OpenSLESStream.cpp b/Source/Core/AudioCommon/Src/OpenSLESStream.cpp new file mode 100644 index 0000000000..b0913a1895 --- /dev/null +++ b/Source/Core/AudioCommon/Src/OpenSLESStream.cpp @@ -0,0 +1,145 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifdef ANDROID +#include "Common.h" +#include +#include "OpenSLESStream.h" + +#include +#include + +// engine interfaces +static SLObjectItf engineObject; +static SLEngineItf engineEngine; +static SLObjectItf outputMixObject; + +// buffer queue player interfaces +static SLObjectItf bqPlayerObject = NULL; +static SLPlayItf bqPlayerPlay; +static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; +static SLMuteSoloItf bqPlayerMuteSolo; +static SLVolumeItf bqPlayerVolume; +static CMixer *g_mixer; +#define BUFFER_SIZE 512 +#define BUFFER_SIZE_IN_SAMPLES (BUFFER_SIZE / 2) + +// Double buffering. +static short buffer[2][BUFFER_SIZE]; +static int curBuffer = 0; + +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { + assert(bq == bqPlayerBufferQueue); + assert(NULL == context); + + short *nextBuffer = buffer[curBuffer]; + int nextSize = sizeof(buffer[0]); + + SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize); + + // Comment from sample code: + // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT, + // which for this code example would indicate a programming error + assert(SL_RESULT_SUCCESS == result); + + curBuffer ^= 1; // Switch buffer + // Render to the fresh buffer + g_mixer->Mix(reinterpret_cast(buffer[curBuffer]), BUFFER_SIZE_IN_SAMPLES); +} +bool OpenSLESStream::Start() +{ + SLresult result; + // create engine + result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); + assert(SL_RESULT_SUCCESS == result); + result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); + assert(SL_RESULT_SUCCESS == result); + result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); + assert(SL_RESULT_SUCCESS == result); + result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0); + assert(SL_RESULT_SUCCESS == result); + result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE); + assert(SL_RESULT_SUCCESS == result); + + SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2}; + SLDataFormat_PCM format_pcm = { + SL_DATAFORMAT_PCM, + 2, + SL_SAMPLINGRATE_44_1, + SL_PCMSAMPLEFORMAT_FIXED_16, + SL_PCMSAMPLEFORMAT_FIXED_16, + SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, + SL_BYTEORDER_LITTLEENDIAN + }; + + SLDataSource audioSrc = {&loc_bufq, &format_pcm}; + + // configure audio sink + SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject}; + SLDataSink audioSnk = {&loc_outmix, NULL}; + + // create audio player + const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME}; + const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; + result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req); + assert(SL_RESULT_SUCCESS == result); + + result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE, + &bqPlayerBufferQueue); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL); + assert(SL_RESULT_SUCCESS == result); + result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING); + assert(SL_RESULT_SUCCESS == result); + + // Render and enqueue a first buffer. (or should we just play the buffer empty?) + curBuffer = 0; + + result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[curBuffer])); + if (SL_RESULT_SUCCESS != result) { + return false; + } + curBuffer ^= 1; + g_mixer = m_mixer; + return true; +} + +void OpenSLESStream::Stop() +{ + if (bqPlayerObject != NULL) { + (*bqPlayerObject)->Destroy(bqPlayerObject); + bqPlayerObject = NULL; + bqPlayerPlay = NULL; + bqPlayerBufferQueue = NULL; + bqPlayerMuteSolo = NULL; + bqPlayerVolume = NULL; + } + if (outputMixObject != NULL) { + (*outputMixObject)->Destroy(outputMixObject); + outputMixObject = NULL; + } + if (engineObject != NULL) { + (*engineObject)->Destroy(engineObject); + engineObject = NULL; + engineEngine = NULL; + } +} +#endif diff --git a/Source/Core/AudioCommon/Src/OpenSLESStream.h b/Source/Core/AudioCommon/Src/OpenSLESStream.h new file mode 100644 index 0000000000..f49160c4bc --- /dev/null +++ b/Source/Core/AudioCommon/Src/OpenSLESStream.h @@ -0,0 +1,48 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _OPENSLSTREAM_H_ +#define _OPENSLSTREAM_H_ + +#include "Thread.h" +#include "SoundStream.h" + +class OpenSLESStream : public SoundStream +{ +#ifdef ANDROID +public: + OpenSLESStream(CMixer *mixer, void *hWnd = NULL) + : SoundStream(mixer) + {}; + + virtual ~OpenSLESStream() {}; + + virtual bool Start(); + virtual void Stop(); + static bool isValid() { return true; } + virtual bool usesMixer() const { return true; } + +private: + std::thread thread; + Common::Event soundSyncEvent; +#else +public: + OpenSLESStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {} +#endif // HAVE_OPENSL +}; + +#endif diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 92d2bec668..480a08a0fc 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -1,9 +1,7 @@ -set(SRCS Src/ABI.cpp - Src/BreakPoints.cpp +set(SRCS Src/BreakPoints.cpp Src/CDUtils.cpp Src/ColorUtil.cpp Src/ConsoleListener.cpp - Src/CPUDetect.cpp Src/FileSearch.cpp Src/FileUtil.cpp Src/Hash.cpp @@ -20,10 +18,10 @@ set(SRCS Src/ABI.cpp Src/SymbolDB.cpp Src/SysConf.cpp Src/Thread.cpp - Src/Thunk.cpp Src/Timer.cpp Src/Version.cpp Src/VideoBackendBase.cpp + Src/x64ABI.cpp Src/x64Analyzer.cpp Src/x64Emitter.cpp Src/Crypto/aes_cbc.cpp @@ -33,6 +31,23 @@ set(SRCS Src/ABI.cpp Src/Crypto/md5.cpp Src/Crypto/sha1.cpp) +if(_M_ARM) #ARM + set(SRCS ${SRCS} + Src/ArmCPUDetect.cpp + Src/ArmEmitter.cpp) +else() + if(NOT _M_GENERIC) #X86 + set(SRCS ${SRCS} + Src/x64FPURoundMode.cpp + Src/x64Thunk.cpp + ) + endif() + set(SRCS ${SRCS} Src/x64CPUDetect.cpp) +endif() +if(_M_GENERIC) #Generic + set(SRCS ${SRCS} + Src/GenericFPURoundMode.cpp) +endif() if(WIN32) set(SRCS ${SRCS} Src/ExtendedTrace.cpp) endif(WIN32) diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 0128a75a09..626a4df909 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -158,12 +158,10 @@ - - @@ -195,15 +193,17 @@ - + + + + - @@ -251,6 +251,7 @@ + diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters index 8b05ecbba4..d427b70cdd 100644 --- a/Source/Core/Common/Common.vcxproj.filters +++ b/Source/Core/Common/Common.vcxproj.filters @@ -1,11 +1,9 @@  - - @@ -23,7 +21,6 @@ - @@ -53,9 +50,12 @@ Crypto + + + + - @@ -121,6 +121,7 @@ + diff --git a/Source/Core/Common/Src/ArmCPUDetect.cpp b/Source/Core/Common/Src/ArmCPUDetect.cpp new file mode 100644 index 0000000000..c03ab08c48 --- /dev/null +++ b/Source/Core/Common/Src/ArmCPUDetect.cpp @@ -0,0 +1,160 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "CPUDetect.h" +#include "StringUtil.h" + +const char procfile[] = "/proc/cpuinfo"; + +char *GetCPUString() +{ + const char marker[] = "Hardware\t: "; + char *cpu_string = 0; + // Count the number of processor lines in /proc/cpuinfo + char buf[1024]; + FILE *fp; + + fp = fopen(procfile, "r"); + if (!fp) + return 0; + + while (fgets(buf, sizeof(buf), fp)) + { + if (strncmp(buf, marker, sizeof(marker) - 1)) + continue; + cpu_string = buf + sizeof(marker) - 1; + cpu_string = strndup(cpu_string, strlen(cpu_string) - 1); // Strip the newline + break; + } + return cpu_string; +} +bool CheckCPUFeature(const char *feature) +{ + const char marker[] = "Features\t: "; + char buf[1024]; + FILE *fp; + + fp = fopen(procfile, "r"); + if (!fp) + return 0; + + while (fgets(buf, sizeof(buf), fp)) + { + if (strncmp(buf, marker, sizeof(marker) - 1)) + continue; + char *featurestring = buf + sizeof(marker) - 1; + char *token = strtok(featurestring, " "); + while (token != NULL) + { + if (strstr(token, feature)) + return true; + token = strtok(NULL, " "); + } + } + return false; +} +int GetCoreCount() +{ + const char marker[] = "processor\t: "; + int cores = 0; + char buf[1024]; + FILE *fp; + + fp = fopen(procfile, "r"); + if (!fp) + return 0; + + while (fgets(buf, sizeof(buf), fp)) + { + if (strncmp(buf, marker, sizeof(marker) - 1)) + continue; + ++cores; + } + return cores; +} + +CPUInfo cpu_info; + +CPUInfo::CPUInfo() { + Detect(); +} + +// Detects the various cpu features +void CPUInfo::Detect() +{ + // Set some defaults here + // When ARMv8 cpus come out, these need to be updated. + HTT = false; + OS64bit = false; + CPU64bit = false; + Mode64bit = false; + vendor = VENDOR_ARM; + + // Get the information about the CPU + strncpy(cpu_string, GetCPUString(), sizeof(cpu_string)); + num_cores = GetCoreCount(); + bSwp = CheckCPUFeature("swp"); + bHalf = CheckCPUFeature("half"); + bThumb = CheckCPUFeature("thumb"); + bFastMult = CheckCPUFeature("fastmult"); + bVFP = CheckCPUFeature("vfp"); + bEDSP = CheckCPUFeature("edsp"); + bThumbEE = CheckCPUFeature("thumbee"); + bNEON = CheckCPUFeature("neon"); + bVFPv3 = CheckCPUFeature("vfpv3"); + bTLS = CheckCPUFeature("tls"); + bVFPv4 = CheckCPUFeature("vfpv4"); + bIDIVa = CheckCPUFeature("idiva"); + bIDIVt = CheckCPUFeature("idivt"); + // These two are ARMv8 specific. + bFP = CheckCPUFeature("fp"); + bASIMD = CheckCPUFeature("asimd"); + + +#if defined(__ARM_ARCH_7A__) + bArmV7 = true; +#else + bArmV7 = false; +#endif +} + +// Turn the cpu info into a string we can show +std::string CPUInfo::Summarize() +{ + std::string sum; + if (num_cores == 1) + sum = StringFromFormat("%s, %i core", cpu_string, num_cores); + else + sum = StringFromFormat("%s, %i cores", cpu_string, num_cores); + + if (bSwp) sum += ", SWP"; + if (bHalf) sum += ", Half"; + if (bThumb) sum += ", Thumb"; + if (bFastMult) sum += ", FastMult"; + if (bVFP) sum += ", VFP"; + if (bEDSP) sum += ", EDSP"; + if (bThumbEE) sum += ", ThumbEE"; + if (bNEON) sum += ", NEON"; + if (bVFPv3) sum += ", VFPv3"; + if (bTLS) sum += ", TLS"; + if (bVFPv4) sum += ", VFPv4"; + if (bIDIVa) sum += ", IDIVa"; + if (bIDIVt) sum += ", IDIVt"; + + return sum; +} diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp new file mode 100644 index 0000000000..6463dbe2ef --- /dev/null +++ b/Source/Core/Common/Src/ArmEmitter.cpp @@ -0,0 +1,967 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "ArmEmitter.h" +#include "CPUDetect.h" + +#include +#include + +// For cache flushing on Symbian/Blackberry +#ifdef __SYMBIAN32__ +#include +#endif + +#ifdef BLACKBERRY +#include +#endif + +namespace ArmGen +{ + +inline u32 RotR(u32 a, int amount) { + if (!amount) return a; + return (a >> amount) | (a << (32 - amount)); +} + +inline u32 RotL(u32 a, int amount) { + if (!amount) return a; + return (a << amount) | (a >> (32 - amount)); +} + +bool TryMakeOperand2(u32 imm, Operand2 &op2) { + // Just brute force it. + for (int i = 0; i < 16; i++) { + int mask = RotR(0xFF, i * 2); + if ((imm & mask) == imm) { + op2 = Operand2((u8)(RotL(imm, i * 2)), (u8)i); + return true; + } + } + return false; +} + +bool TryMakeOperand2_AllowInverse(u32 imm, Operand2 &op2, bool *inverse) +{ + if (!TryMakeOperand2(imm, op2)) { + *inverse = true; + return TryMakeOperand2(~imm, op2); + } else { + *inverse = false; + return true; + } +} + +bool TryMakeOperand2_AllowNegation(s32 imm, Operand2 &op2, bool *negated) +{ + if (!TryMakeOperand2(imm, op2)) { + *negated = true; + return TryMakeOperand2(-imm, op2); + } else { + *negated = false; + return true; + } +} + +void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize) +{ + Operand2 op2; + bool inverse; + if (!optimize) + { + // Only used in backpatch atm + // Only support ARMv7 right now + if (cpu_info.bArmV7) { + MOVW(reg, val & 0xFFFF); + MOVT(reg, val, true); + } + else + { + // ARMv6 version won't use backpatch for now + // Run again with optimizations + MOVI2R(reg, val); + } + } else if (TryMakeOperand2_AllowInverse(val, op2, &inverse)) { + if (!inverse) + MOV(reg, op2); + else + MVN(reg, op2); + } else { + if (cpu_info.bArmV7) { + // ARMv7 - can use MOVT/MOVW, best choice + MOVW(reg, val & 0xFFFF); + if(val & 0xFFFF0000) + MOVT(reg, val, true); + } else { + // ARMv6 - fallback sequence. + // TODO: Optimize further. Can for example choose negation etc. + // Literal pools is another way to do this but much more complicated + // so I can't really be bothered for an outdated CPU architecture like ARMv6. + bool first = true; + int shift = 16; + for (int i = 0; i < 4; i++) { + if (val & 0xFF) { + if (first) { + MOV(reg, Operand2((u8)val, (u8)(shift & 0xF))); + first = false; + } else { + ORR(reg, reg, Operand2((u8)val, (u8)(shift & 0xF))); + } + } + shift -= 4; + val >>= 8; + } + } + } +} +// Moves IMM to memory location +void ARMXEmitter::ARMABI_MOVI2M(Operand2 op, Operand2 val) +{ + // This moves imm to a memory location + MOVW(R14, val); MOVT(R14, val, true); + MOVW(R12, op); MOVT(R12, op, true); + STR(R12, R14); // R10 is what we want to store +} +void ARMXEmitter::QuickCallFunction(ARMReg reg, void *func) { + MOVI2R(reg, (u32)(func)); + BL(reg); +} + +void ARMXEmitter::SetCodePtr(u8 *ptr) +{ + code = ptr; + startcode = code; +} + +const u8 *ARMXEmitter::GetCodePtr() const +{ + return code; +} + +u8 *ARMXEmitter::GetWritableCodePtr() +{ + return code; +} + +void ARMXEmitter::ReserveCodeSpace(u32 bytes) +{ + for (u32 i = 0; i < bytes/4; i++) + Write32(0xE1200070); //bkpt 0 +} + +const u8 *ARMXEmitter::AlignCode16() +{ + ReserveCodeSpace((-(s32)code) & 15); + return code; +} + +const u8 *ARMXEmitter::AlignCodePage() +{ + ReserveCodeSpace((-(s32)code) & 4095); + return code; +} + +void ARMXEmitter::FlushIcache() +{ + FlushIcacheSection(lastCacheFlushEnd, code); + lastCacheFlushEnd = code; +} + +void ARMXEmitter::FlushIcacheSection(u8 *start, u8 *end) +{ +#ifdef __SYMBIAN32__ + User::IMB_Range( start, end); +#elif defined(BLACKBERRY) + msync(start, end - start, MS_SYNC | MS_INVALIDATE_ICACHE); +#else +#ifndef _WIN32 +#ifdef ANDROID + __builtin___clear_cache (start, end); +#else + // If on Linux, we HAVE to clear from start addr or else everything gets /really/ unstable + __builtin___clear_cache (startcode, end); +#endif +#endif +#endif +} + +void ARMXEmitter::SetCC(CCFlags cond) +{ + condition = cond << 28; +} + +void ARMXEmitter::NOP(int count) +{ + for (int i = 0; i < count; i++) { + Write32(condition | 0x01A00000); + } +} + +void ARMXEmitter::SETEND(bool BE) +{ + //SETEND is non-conditional + Write32( 0xF1010000 | (BE << 9)); +} +void ARMXEmitter::BKPT(u16 arg) +{ + Write32(condition | 0x01200070 | (arg << 4 & 0x000FFF00) | (arg & 0x0000000F)); +} +void ARMXEmitter::YIELD() +{ + Write32(condition | 0x0320F001); +} + +FixupBranch ARMXEmitter::B() +{ + FixupBranch branch; + branch.type = 0; // Zero for B + branch.ptr = code; + branch.condition = condition; + //We'll write NOP here for now. + Write32(condition | 0x01A00000); + return branch; +} +FixupBranch ARMXEmitter::BL() +{ + FixupBranch branch; + branch.type = 1; // Zero for B + branch.ptr = code; + branch.condition = condition; + //We'll write NOP here for now. + Write32(condition | 0x01A00000); + return branch; +} + +FixupBranch ARMXEmitter::B_CC(CCFlags Cond) +{ + FixupBranch branch; + branch.type = 0; // Zero for B + branch.ptr = code; + branch.condition = Cond << 28; + //We'll write NOP here for now. + Write32(condition | 0x01A00000); + return branch; +} +void ARMXEmitter::B_CC(CCFlags Cond, const void *fnptr) +{ + s32 distance = (s32)fnptr - (s32(code) + 8); + _assert_msg_(DYNA_REC, distance > -33554432 + && distance <= 33554432, + "B_CC out of range (%p calls %p)", code, fnptr); + + Write32((Cond << 28) | 0x0A000000 | ((distance >> 2) & 0x00FFFFFF)); +} +FixupBranch ARMXEmitter::BL_CC(CCFlags Cond) +{ + FixupBranch branch; + branch.type = 1; // Zero for B + branch.ptr = code; + branch.condition = Cond << 28; + //We'll write NOP here for now. + Write32(condition | 0x01A00000); + return branch; +} +void ARMXEmitter::SetJumpTarget(FixupBranch const &branch) +{ + s32 distance = (s32(code) - 8) - (s32)branch.ptr; + _assert_msg_(DYNA_REC, distance > -33554432 + && distance <= 33554432, + "SetJumpTarget out of range (%p calls %p)", code, + branch.ptr); + if(branch.type == 0) // B + *(u32*)branch.ptr = (u32)(branch.condition | (10 << 24) | ((distance >> 2) & + 0x00FFFFFF)); + else // BL + *(u32*)branch.ptr = (u32)(branch.condition | 0x0B000000 | ((distance >> 2) + & 0x00FFFFFF)); +} +void ARMXEmitter::B (const void *fnptr) +{ + s32 distance = (s32)fnptr - (s32(code) + 8); + _assert_msg_(DYNA_REC, distance > -33554432 + && distance <= 33554432, + "B out of range (%p calls %p)", code, fnptr); + + Write32(condition | 0x0A000000 | ((distance >> 2) & 0x00FFFFFF)); +} + +void ARMXEmitter::B(ARMReg src) +{ + Write32(condition | 0x12FFF10 | src); +} + +void ARMXEmitter::BL(const void *fnptr) +{ + s32 distance = (s32)fnptr - (s32(code) + 8); + _assert_msg_(DYNA_REC, distance > -33554432 + && distance <= 33554432, + "BL out of range (%p calls %p)", code, fnptr); + Write32(condition | 0x0B000000 | ((distance >> 2) & 0x00FFFFFF)); +} +void ARMXEmitter::BL(ARMReg src) +{ + Write32(condition | 0x12FFF30 | src); +} +void ARMXEmitter::PUSH(const int num, ...) +{ + u16 RegList = 0; + u8 Reg; + int i; + va_list vl; + va_start(vl, num); + for (i=0;i> 16 : Rm); } + +void ARMXEmitter::WriteInstruction (u32 Op, ARMReg Rd, ARMReg Rn, Operand2 Rm, bool SetFlags) // This can get renamed later +{ + s32 op = InstOps[Op][Rm.GetType()]; // Type always decided by last operand + u32 Data = Rm.GetData(); + if (Rm.GetType() == TYPE_IMM) + { + switch (Op) + { + // MOV cases that support IMM16 + case 16: + case 17: + Data = Rm.Imm16(); + break; + default: + break; + } + } + if (op == -1) + _assert_msg_(DYNA_REC, false, "%s not yet support %d", InstNames[Op], Rm.GetType()); + Write32(condition | (op << 21) | (SetFlags ? (1 << 20) : 0) | Rn << 16 | Rd << 12 | Data); +} + +// Data Operations +void ARMXEmitter::WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARMReg r1, ARMReg r2) +{ + Write32(condition | (0x7 << 24) | (Op << 20) | (dest << 16) | (Op2 << 12) | (r1 << 8) | (Op3 << 5) | (1 << 4) | r2); +} +void ARMXEmitter::UDIV(ARMReg dest, ARMReg dividend, ARMReg divisor) +{ + if (!cpu_info.bIDIVa) + PanicAlert("Trying to use integer divide on hardware that doesn't support it. Bad programmer."); + WriteSignedMultiply(3, 0xF, 0, dest, divisor, dividend); +} +void ARMXEmitter::SDIV(ARMReg dest, ARMReg dividend, ARMReg divisor) +{ + if (!cpu_info.bIDIVa) + PanicAlert("Trying to use integer divide on hardware that doesn't support it. Bad programmer."); + WriteSignedMultiply(1, 0xF, 0, dest, divisor, dividend); +} +void ARMXEmitter::LSL (ARMReg dest, ARMReg src, Operand2 op2) { WriteShiftedDataOp(0, false, dest, src, op2);} +void ARMXEmitter::LSLS(ARMReg dest, ARMReg src, Operand2 op2) { WriteShiftedDataOp(0, true, dest, src, op2);} +void ARMXEmitter::LSL (ARMReg dest, ARMReg src, ARMReg op2) { WriteShiftedDataOp(1, false, dest, src, op2);} +void ARMXEmitter::LSLS(ARMReg dest, ARMReg src, ARMReg op2) { WriteShiftedDataOp(1, true, dest, src, op2);} +void ARMXEmitter::MUL (ARMReg dest, ARMReg src, ARMReg op2) +{ + Write32(condition | (dest << 16) | (src << 8) | (9 << 4) | op2); +} +void ARMXEmitter::MULS(ARMReg dest, ARMReg src, ARMReg op2) +{ + Write32(condition | (1 << 20) | (dest << 16) | (src << 8) | (9 << 4) | op2); +} + +void ARMXEmitter::Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rm, ARMReg rn) { + Write32(condition | (op << 20) | (destHi << 16) | (destLo << 12) | (rm << 8) | (9 << 4) | rn); +} + +void ARMXEmitter::UMULL(ARMReg destLo, ARMReg destHi, ARMReg rm, ARMReg rn) +{ + Write4OpMultiply(0x8, destLo, destHi, rn, rm); +} + +void ARMXEmitter::SMULL(ARMReg destLo, ARMReg destHi, ARMReg rm, ARMReg rn) +{ + Write4OpMultiply(0xC, destLo, destHi, rn, rm); +} +void ARMXEmitter::SXTB (ARMReg dest, ARMReg op2) +{ + Write32(condition | (0x6AF << 16) | (dest << 12) | (7 << 4) | op2); +} +void ARMXEmitter::SXTH (ARMReg dest, ARMReg op2, u8 rotation) +{ + SXTAH(dest, (ARMReg)15, op2, rotation); +} +void ARMXEmitter::SXTAH(ARMReg dest, ARMReg src, ARMReg op2, u8 rotation) +{ + // bits ten and 11 are the rotation amount, see 8.8.232 for more + // information + Write32(condition | (0x6B << 20) | (src << 16) | (dest << 12) | (rotation << 10) | (7 << 4) | op2); +} +void ARMXEmitter::REV (ARMReg dest, ARMReg src ) +{ + Write32(condition | (107 << 20) | (15 << 16) | (dest << 12) | (243 << 4) | src); +} +void ARMXEmitter::REV16(ARMReg dest, ARMReg src) +{ + Write32(condition | (0x3DF << 16) | (dest << 12) | (0xFD << 4) | src); +} + +void ARMXEmitter::_MSR (bool write_nzcvq, bool write_g, Operand2 op2) +{ + Write32(condition | (0x320F << 12) | (write_nzcvq << 19) | (write_g << 18) | op2.Imm12Mod()); +} +void ARMXEmitter::_MSR (bool write_nzcvq, bool write_g, ARMReg src) +{ + Write32(condition | (0x120F << 12) | (write_nzcvq << 19) | (write_g << 18) | src); +} +void ARMXEmitter::MRS (ARMReg dest) +{ + Write32(condition | (16 << 20) | (15 << 16) | (dest << 12)); +} +void ARMXEmitter::WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2) +{ + if (op2.GetData() == 0) // Don't index + Write32(condition | 0x01800000 | (op << 20) | (dest << 16) | (src << 12) | op2.Imm12()); + else + Write32(condition | (op << 20) | (3 << 23) | (dest << 16) | (src << 12) | op2.Imm12()); +} +void ARMXEmitter::STR (ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x40, dest, src, op);} +void ARMXEmitter::STRB(ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x44, dest, src, op);} +void ARMXEmitter::STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) +{ + Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (dest << 16) | (base << 12) | offset); +} +void ARMXEmitter::LDREX(ARMReg dest, ARMReg base) +{ + Write32(condition | (25 << 20) | (base << 16) | (dest << 12) | 0xF9F); +} +void ARMXEmitter::STREX(ARMReg dest, ARMReg base, ARMReg op) +{ + _assert_msg_(DYNA_REC, (dest != base && dest != op), "STREX dest can't be other two registers"); + Write32(condition | (24 << 20) | (base << 16) | (dest << 12) | (0xF9 << 4) | op); +} +void ARMXEmitter::DMB () +{ + Write32(0xF57FF05E); +} +void ARMXEmitter::SVC(Operand2 op) +{ + Write32(condition | (0x0F << 24) | op.Imm24()); +} + +void ARMXEmitter::LDR (ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x41, src, dest, op);} +void ARMXEmitter::LDRH(ARMReg dest, ARMReg src, Operand2 op) +{ + u8 Imm = op.Imm8(); + Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F)); +} +void ARMXEmitter::LDRB(ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x45, src, dest, op);} + +void ARMXEmitter::LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) +{ + Write32(condition | (0x61 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | offset); +} +void ARMXEmitter::WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList) +{ + Write32(condition | (op << 20) | (WriteBack << 21) | (dest << 16) | RegList); +} +void ARMXEmitter::STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...) +{ + u16 RegList = 0; + u8 Reg; + int i; + va_list vl; + va_start(vl, Regnum); + for (i=0;i= S0) + { + if (Reg >= D0) + { + if (Reg >= Q0) + return (ARMReg)((Reg - Q0) * 2); // Always gets encoded as a double register + return (ARMReg)(Reg - D0); + } + return (ARMReg)(Reg - S0); + } + return Reg; +} +// NEON Specific +void ARMXEmitter::VADD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd >= D0, "Pass invalid register to VADD(integer)"); + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use VADD(integer) when CPU doesn't support it"); + + bool register_quad = Vd >= Q0; + + // Gets encoded as a double register + Vd = SubBase(Vd); + Vn = SubBase(Vn); + Vm = SubBase(Vm); + + Write32((0xF2 << 24) | ((Vd & 0x10) << 18) | (Size << 20) | ((Vn & 0xF) << 16) \ + | ((Vd & 0xF) << 12) | (0x8 << 8) | ((Vn & 0x10) << 3) | (register_quad << 6) \ + | ((Vm & 0x10) << 2) | (Vm & 0xF)); + +} +void ARMXEmitter::VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd >= Q0, "Pass invalid register to VSUB(integer)"); + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use VSUB(integer) when CPU doesn't support it"); + + // Gets encoded as a double register + Vd = SubBase(Vd); + Vn = SubBase(Vn); + Vm = SubBase(Vm); + + Write32((0xF3 << 24) | ((Vd & 0x10) << 18) | (Size << 20) | ((Vn & 0xF) << 16) \ + | ((Vd & 0xF) << 12) | (0x8 << 8) | ((Vn & 0x10) << 3) | (1 << 6) \ + | ((Vm & 0x10) << 2) | (Vm & 0xF)); + +} + +// VFP Specific + +void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 op) +{ + _assert_msg_(DYNA_REC, Dest >= S0 && Dest <= D31, "Passed Invalid dest register to VLDR"); + _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid Base register to VLDR"); + _assert_msg_(DYNA_REC, !(op & 3), "Offset needs to be word aligned"); + bool single_reg = Dest < D0; + + Dest = SubBase(Dest); + + if (single_reg) + { + Write32(NO_COND | (0x1B << 23) | ((Dest & 0x1) << 22) | (1 << 20) | (Base << 16) \ + | ((Dest & 0x1E) << 11) | (10 << 8) | (op >> 2)); + + } + else + { + Write32(NO_COND | (0x1B << 23) | ((Dest & 0x10) << 18) | (1 << 20) | (Base << 16) \ + | ((Dest & 0xF) << 12) | (11 << 8) | (op >> 2)); + } +} +void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 op) +{ + _assert_msg_(DYNA_REC, Src >= S0 && Src <= D31, "Passed invalid src register to VSTR"); + _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid base register to VSTR"); + _assert_msg_(DYNA_REC, !(op & 3), "Offset needs to be word aligned"); + bool single_reg = Src < D0; + + Src = SubBase(Src); + + if (single_reg) + { + Write32(NO_COND | (0x1B << 23) | ((Src & 0x1) << 22) | (Base << 16) \ + | ((Src & 0x1E) << 11) | (10 << 8) | (op >> 2)); + + } + else + { + Write32(NO_COND | (0x1B << 23) | ((Src & 0x10) << 18) | (Base << 16) \ + | ((Src & 0xF) << 12) | (11 << 8) | (op >> 2)); + } +} +void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd < Q0, "Passed invalid Vd to VCMP"); + bool single_reg = Vd < D0; + + Vd = SubBase(Vd); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x34 << 16) | ((Vd & 0x1E) << 11) \ + | (0x2B << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x34 << 16) | ((Vd & 0xF) << 12) \ + | (0x2F << 6) | ((Vm & 0x10) << 1) | (Vm & 0xF)); + } +} +void ARMXEmitter::VCMP(ARMReg Vd) +{ + _assert_msg_(DYNA_REC, Vd < Q0, "Passed invalid Vd to VCMP"); + bool single_reg = Vd < D0; + + Vd = SubBase(Vd); + + if (single_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x35 << 16) | ((Vd & 0x1E) << 11) \ + | (0x2B << 6)); + } + else + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x35 << 16) | ((Vd & 0xF) << 12) \ + | (0x2F << 6)); + } +} +void ARMXEmitter::VDIV(ARMReg Vd, ARMReg Vn, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd < Q0, "Pased invalid dest register to VSQRT"); + _assert_msg_(DYNA_REC, Vn < Q0, "Passed invalid Vn to VSQRT"); + _assert_msg_(DYNA_REC, Vm < Q0, "Passed invalid Vm to VSQRT"); + bool single_reg = Vd < D0; + + Vd = SubBase(Vd); + Vn = SubBase(Vn); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x1) << 22) | ((Vn & 0x1E) << 15) \ + | ((Vd & 0x1E) << 11) | (0xA << 8) | ((Vn & 0x1) << 7) | ((Vm & 0x1) << 5) \ + | (Vm >> 1)); + } + else + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16) \ + | ((Vd & 0xF) << 12) | (0xB << 8) | ((Vn & 0x10) << 3) | ((Vm & 0x10) << 2) \ + | (Vm & 0xF)); + } +} +void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd < Q0, "Pased invalid dest register to VSQRT"); + _assert_msg_(DYNA_REC, Vm < Q0, "Passed invalid Vm to VSQRT"); + bool single_reg = Vd < D0; + + Vd = SubBase(Vd); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x31 << 16) \ + | ((Vd & 0x1E) << 11) | (0x2B << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x31 << 16) \ + | ((Vd & 0xF) << 12) | (0x2F << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } +} +// VFP and ASIMD +void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd < Q0, "VABS doesn't currently support Quad reg"); + _assert_msg_(DYNA_REC, Vd >= S0, "VABS doesn't support ARM Regs"); + bool single_reg = Vd < D0; + + Vd = SubBase(Vd); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0xEB << 20) | ((Vd & 0x1) << 6) | ((Vd & 0x1E) << 11) \ + | (0xAC << 4) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + Write32(NO_COND | (0xEB << 20) | ((Vd & 0x10) << 18) | ((Vd & 0xF) << 12) \ + | (0xBC << 4) | ((Vm & 0x10) << 1) | (Vm & 0xF)); + } +} +void ARMXEmitter::VADD(ARMReg Vd, ARMReg Vn, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VADD"); + _assert_msg_(DYNA_REC, Vn >= S0, "Passed invalid Vn to VADD"); + _assert_msg_(DYNA_REC, Vm >= S0, "Passed invalid Vm to VADD"); + bool single_reg = Vd < D0; + bool double_reg = Vd < Q0; + + Vd = SubBase(Vd); + Vn = SubBase(Vn); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1C << 23) | ((Vd & 0x1) << 22) | (0x3 << 20) \ + | ((Vn & 0x1E) << 15) | ((Vd & 0x1E) << 11) | (0x5 << 9) \ + | ((Vn & 0x1) << 7) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + if (double_reg) + { + Write32(NO_COND | (0x1C << 23) | ((Vd & 0x10) << 18) | (0x3 << 20) \ + | ((Vn & 0xF) << 16) | ((Vd & 0xF) << 12) | (0xB << 8) \ + | ((Vn & 0x10) << 3) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } + else + { + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VADD with Quad Reg without support!"); + Write32((0xF2 << 24) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16) \ + | ((Vd & 0xF) << 12) | (0xD << 8) | ((Vn & 0x10) << 3) \ + | (1 << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } + } +} +void ARMXEmitter::VSUB(ARMReg Vd, ARMReg Vn, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VSUB"); + _assert_msg_(DYNA_REC, Vn >= S0, "Passed invalid Vn to VSUB"); + _assert_msg_(DYNA_REC, Vm >= S0, "Passed invalid Vm to VSUB"); + bool single_reg = Vd < D0; + bool double_reg = Vd < Q0; + + Vd = SubBase(Vd); + Vn = SubBase(Vn); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1C << 23) | ((Vd & 0x1) << 22) | (0x3 << 20) \ + | ((Vn & 0x1E) << 15) | ((Vd & 0x1E) << 11) | (0x5 << 9) \ + | ((Vn & 0x1) << 7) | (1 << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + if (double_reg) + { + Write32(NO_COND | (0x1C << 23) | ((Vd & 0x10) << 18) | (0x3 << 20) \ + | ((Vn & 0xF) << 16) | ((Vd & 0xF) << 12) | (0xB << 8) \ + | ((Vn & 0x10) << 3) | (1 << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } + else + { + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VADD with Quad Reg without support!"); + Write32((0xF2 << 24) | (1 << 21) | ((Vd & 0x10) << 18) | ((Vn & 0xF) << 16) \ + | ((Vd & 0xF) << 12) | (0xD << 8) | ((Vn & 0x10) << 3) \ + | (1 << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } + } +} + +void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src, bool high) +{ + _assert_msg_(DYNA_REC, Src < S0, "This VMOV doesn't support SRC other than ARM Reg"); + _assert_msg_(DYNA_REC, Dest >= D0, "This VMOV doesn't support DEST other than VFP"); + + Dest = SubBase(Dest); + + Write32(NO_COND | (0xE << 24) | (high << 21) | ((Dest & 0xF) << 16) | (Src << 12) \ + | (11 << 8) | ((Dest & 0x10) << 3) | (1 << 4)); +} +void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) +{ + if (Dest > R15) + { + if (Src < S0) + { + if (Dest < D0) + { + // Moving to a Neon register FROM ARM Reg + Dest = (ARMReg)(Dest - S0); + Write32(NO_COND | (0xE0 << 20) | ((Dest & 0x1E) << 15) | (Src << 12) \ + | (0xA << 8) | ((Dest & 0x1) << 7) | (1 << 4)); + return; + } + else + { + // Move 64bit from Arm reg + _assert_msg_(DYNA_REC, false, "This VMOV doesn't support moving 64bit ARM to NEON"); + return; + } + } + } + else + { + if (Src > R15) + { + if (Src < D0) + { + // Moving to ARM Reg from Neon Register + Src = (ARMReg)(Src - S0); + Write32(NO_COND | (0xE1 << 20) | ((Src & 0x1E) << 15) | (Dest << 12) \ + | (0xA << 8) | ((Src & 0x1) << 7) | (1 << 4)); + return; + } + else + { + // Move 64bit To Arm reg + _assert_msg_(DYNA_REC, false, "This VMOV doesn't support moving 64bit ARM From NEON"); + return; + } + } + else + { + // Move Arm reg to Arm reg + _assert_msg_(DYNA_REC, false, "VMOV doesn't support moving ARM registers"); + } + } + // Moving NEON registers + int SrcSize = Src < D0 ? 1 : Src < Q0 ? 2 : 4; + int DestSize = Dest < D0 ? 1 : Dest < Q0 ? 2 : 4; + bool Single = DestSize == 1; + bool Quad = DestSize == 4; + + _assert_msg_(DYNA_REC, SrcSize == DestSize, "VMOV doesn't support moving different register sizes"); + + Dest = SubBase(Dest); + Src = SubBase(Src); + + if (Single) + { + Write32(NO_COND | (0x1D << 23) | ((Dest & 0x1) << 22) | (0x3 << 20) | ((Dest & 0x1E) << 11) \ + | (0x5 << 9) | (1 << 6) | ((Src & 0x1) << 5) | ((Src & 0x1E) >> 1)); + } + else + { + // Double and quad + if (Quad) + { + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use quad registers when you don't support ASIMD."); + // Gets encoded as a Double register + Write32((0xF2 << 24) | ((Dest & 0x10) << 18) | (2 << 20) | ((Src & 0xF) << 16) \ + | ((Dest & 0xF) << 12) | (1 << 8) | ((Src & 0x10) << 3) | (1 << 6) \ + | ((Src & 0x10) << 1) | (1 << 4) | (Src & 0xF)); + + } + else + { + Write32(NO_COND | (0x1D << 23) | ((Dest & 0x10) << 18) | (0x3 << 20) | ((Dest & 0xF) << 12) \ + | (0x2D << 6) | ((Src & 0x10) << 1) | (Src & 0xF)); + } + } +} + +} diff --git a/Source/Core/Common/Src/ArmEmitter.h b/Source/Core/Common/Src/ArmEmitter.h new file mode 100644 index 0000000000..13635867a9 --- /dev/null +++ b/Source/Core/Common/Src/ArmEmitter.h @@ -0,0 +1,587 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// WARNING - THIS LIBRARY IS NOT THREAD SAFE!!! + +#ifndef _DOLPHIN_ARM_CODEGEN_ +#define _DOLPHIN_ARM_CODEGEN_ + +#include "Common.h" +#include "MemoryUtil.h" +#if defined(__SYMBIAN32__) || defined(PANDORA) +#include +#endif + +#undef _IP +#undef R0 +#undef _SP +#undef _LR +#undef _PC + +namespace ArmGen +{ +enum ARMReg +{ + // GPRs + R0 = 0, R1, R2, R3, R4, R5, + R6, R7, R8, R9, R10, R11, + + // SPRs + // R13 - R15 are SP, LR, and PC. + // Almost always referred to by name instead of register number + R12 = 12, R13 = 13, R14 = 14, R15 = 15, + _IP = 12, _SP = 13, _LR = 14, _PC = 15, + + + // VFP single precision registers + S0, S1, S2, S3, S4, S5, S6, + S7, S8, S9, S10, S11, S12, S13, + S14, S15, S16, S17, S18, S19, S20, + S21, S22, S23, S24, S25, S26, S27, + S28, S29, S30, S31, + + // VFP Double Precision registers + D0, D1, D2, D3, D4, D5, D6, D7, + D8, D9, D10, D11, D12, D13, D14, D15, + D16, D17, D18, D19, D20, D21, D22, D23, + D24, D25, D26, D27, D28, D29, D30, D31, + + // ASIMD Quad-Word registers + Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, + Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15, + INVALID_REG = 0xFFFFFFFF +}; + +enum CCFlags +{ + CC_EQ = 0, // Equal + CC_NEQ, // Not equal + CC_CS, // Carry Set + CC_CC, // Carry Clear + CC_MI, // Minus (Negative) + CC_PL, // Plus + CC_VS, // Overflow + CC_VC, // No Overflow + CC_HI, // Unsigned higher + CC_LS, // Unsigned lower or same + CC_GE, // Signed greater than or equal + CC_LT, // Signed less than + CC_GT, // Signed greater than + CC_LE, // Signed less than or equal + CC_AL, // Always (unconditional) 14 + CC_HS = CC_CS, // Alias of CC_CS Unsigned higher or same + CC_LO = CC_CC, // Alias of CC_CC Unsigned lower +}; +const u32 NO_COND = 0xE0000000; + +enum ShiftType +{ + ST_LSL = 0, + ST_ASL = 0, + ST_LSR = 1, + ST_ASR = 2, + ST_ROR = 3, + ST_RRX = 4 +}; +enum IntegerSize +{ + I_I8 = 0, + I_I16, + I_I32, + I_I64 +}; + +enum +{ + NUMGPRs = 13, +}; + +class ARMXEmitter; + +enum OpType +{ + TYPE_IMM = 0, + TYPE_REG, + TYPE_IMMSREG, + TYPE_RSR, + TYPE_MEM +}; + +// This is no longer a proper operand2 class. Need to split up. +class Operand2 +{ + friend class ARMXEmitter; +protected: + u32 Value; + +private: + OpType Type; + + // IMM types + u8 Rotation; // Only for u8 values + + // Register types + u8 IndexOrShift; + ShiftType Shift; +public: + OpType GetType() + { + return Type; + } + Operand2() {} + Operand2(u32 imm, OpType type = TYPE_IMM) + { + Type = type; + Value = imm; + Rotation = 0; + } + + Operand2(ARMReg Reg) + { + Type = TYPE_REG; + Value = Reg; + Rotation = 0; + } + Operand2(u8 imm, u8 rotation) + { + Type = TYPE_IMM; + Value = imm; + Rotation = rotation; + } + Operand2(ARMReg base, ShiftType type, ARMReg shift) // RSR + { + Type = TYPE_RSR; + _assert_msg_(DYNA_REC, type != ST_RRX, "Invalid Operand2: RRX does not take a register shift amount"); + IndexOrShift = shift; + Shift = type; + Value = base; + } + + Operand2(u8 shift, ShiftType type, ARMReg base)// For IMM shifted register + { + if(shift == 32) shift = 0; + switch (type) + { + case ST_LSL: + _assert_msg_(DYNA_REC, shift < 32, "Invalid Operand2: LSL %u", shift); + break; + case ST_LSR: + _assert_msg_(DYNA_REC, shift <= 32, "Invalid Operand2: LSR %u", shift); + if (!shift) + type = ST_LSL; + if (shift == 32) + shift = 0; + break; + case ST_ASR: + _assert_msg_(DYNA_REC, shift < 32, "Invalid Operand2: LSR %u", shift); + if (!shift) + type = ST_LSL; + if (shift == 32) + shift = 0; + break; + case ST_ROR: + _assert_msg_(DYNA_REC, shift < 32, "Invalid Operand2: ROR %u", shift); + if (!shift) + type = ST_LSL; + break; + case ST_RRX: + _assert_msg_(DYNA_REC, shift == 0, "Invalid Operand2: RRX does not take an immediate shift amount"); + type = ST_ROR; + break; + } + IndexOrShift = shift; + Shift = type; + Value = base; + Type = TYPE_IMMSREG; + } + const u32 GetData() + { + switch(Type) + { + case TYPE_IMM: + return Imm12Mod(); // This'll need to be changed later + case TYPE_REG: + return Rm(); + case TYPE_IMMSREG: + return IMMSR(); + case TYPE_RSR: + return RSR(); + default: + _assert_msg_(DYNA_REC, false, "GetData with Invalid Type"); + return 0; + } + } + const u32 IMMSR() // IMM shifted register + { + _assert_msg_(DYNA_REC, Type = TYPE_IMMSREG, "IMMSR must be imm shifted register"); + return ((IndexOrShift & 0x1f) << 7 | (Shift << 5) | Value); + } + const u32 RSR() // Register shifted register + { + _assert_msg_(DYNA_REC, Type == TYPE_RSR, "RSR must be RSR Of Course"); + return (IndexOrShift << 8) | (Shift << 5) | 0x10 | Value; + } + const u32 Rm() + { + _assert_msg_(DYNA_REC, Type == TYPE_REG, "Rm must be with Reg"); + return Value; + } + + const u32 Imm5() + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm5 not IMM value"); + return ((Value & 0x0000001F) << 7); + } + const u32 Imm8() + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8Rot not IMM value"); + return Value & 0xFF; + } + const u32 Imm8Rot() // IMM8 with Rotation + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8Rot not IMM value"); + _assert_msg_(DYNA_REC, (Rotation & 0xE1) != 0, "Invalid Operand2: immediate rotation %u", Rotation); + return (1 << 25) | (Rotation << 7) | (Value & 0x000000FF); + } + const u32 Imm12() + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm12 not IMM"); + return (Value & 0x00000FFF); + } + + const u32 Imm12Mod() + { + // This is a IMM12 with the top four bits being rotation and the + // bottom eight being a IMM. This is for instructions that need to + // expand a 8bit IMM to a 32bit value and gives you some rotation as + // well. + // Each rotation rotates to the right by 2 bits + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm12Mod not IMM"); + return ((Rotation & 0xF) << 8) | (Value & 0xFF); + } + const u32 Imm16() + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); + return ( (Value & 0xF000) << 4) | (Value & 0x0FFF); + } + const u32 Imm16Low() + { + return Imm16(); + } + const u32 Imm16High() // Returns high 16bits + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); + return ( ((Value >> 16) & 0xF000) << 4) | ((Value >> 16) & 0x0FFF); + } + const u32 Imm24() + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); + return (Value & 0x0FFFFFFF); + } + // NEON and ASIMD specific + const u32 Imm8ASIMD() + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8ASIMD not IMM"); + return ((Value & 0x80) << 17) | ((Value & 0x70) << 12) | (Value & 0xF); + } + const u32 Imm8VFP() + { + _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8VFP not IMM"); + return ((Value & 0xF0) << 12) | (Value & 0xF); + } +}; + +// Use these when you don't know if an imm can be represented as an operand2. +// This lets you generate both an optimal and a fallback solution by checking +// the return value, which will be false if these fail to find a Operand2 that +// represents your 32-bit imm value. +bool TryMakeOperand2(u32 imm, Operand2 &op2); +bool TryMakeOperand2_AllowInverse(u32 imm, Operand2 &op2, bool *inverse); +bool TryMakeOperand2_AllowNegation(s32 imm, Operand2 &op2, bool *negated); + +inline Operand2 R(ARMReg Reg) { return Operand2(Reg, TYPE_REG); } +inline Operand2 IMM(u32 Imm) { return Operand2(Imm, TYPE_IMM); } +inline Operand2 Mem(void *ptr) { return Operand2((u32)ptr, TYPE_IMM); } +//usage: struct {int e;} s; STRUCT_OFFSET(s,e) +#define STRUCT_OFF(str,elem) ((u32)((u32)&(str).elem-(u32)&(str))) + + +struct FixupBranch +{ + u8 *ptr; + u32 condition; // Remembers our codition at the time + int type; //0 = B 1 = BL +}; + +typedef const u8* JumpTarget; + +class ARMXEmitter +{ + friend struct OpArg; // for Write8 etc +private: + u8 *code, *startcode; + u8 *lastCacheFlushEnd; + u32 condition; + + void WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2); + void WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList); + void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, ARMReg op2); + void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2); + void WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARMReg r1, ARMReg r2); + + void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); + + // New Ops + void WriteInstruction(u32 op, ARMReg Rd, ARMReg Rn, Operand2 Rm, bool SetFlags = false); + +protected: + inline void Write32(u32 value) {*(u32*)code = value; code+=4;} + +public: + ARMXEmitter() : code(0), startcode(0), lastCacheFlushEnd(0) { + condition = CC_AL << 28; + } + ARMXEmitter(u8 *code_ptr) { + code = code_ptr; + lastCacheFlushEnd = code_ptr; + startcode = code_ptr; + condition = CC_AL << 28; + } + virtual ~ARMXEmitter() {} + + void SetCodePtr(u8 *ptr); + void ReserveCodeSpace(u32 bytes); + const u8 *AlignCode16(); + const u8 *AlignCodePage(); + const u8 *GetCodePtr() const; + void FlushIcache(); + void FlushIcacheSection(u8 *start, u8 *end); + u8 *GetWritableCodePtr(); + + void SetCC(CCFlags cond = CC_AL); + + // Special purpose instructions + + // Dynamic Endian Switching + void SETEND(bool BE); + // Debug Breakpoint + void BKPT(u16 arg); + + // Hint instruction + void YIELD(); + + // Do nothing + void NOP(int count = 1); //nop padding - TODO: fast nop slides, for amd and intel (check their manuals) + +#ifdef CALL +#undef CALL +#endif + + // Branching + FixupBranch B(); + FixupBranch B_CC(CCFlags Cond); + void B_CC(CCFlags Cond, const void *fnptr); + FixupBranch BL(); + FixupBranch BL_CC(CCFlags Cond); + void SetJumpTarget(FixupBranch const &branch); + + void B (const void *fnptr); + void B (ARMReg src); + void BL(const void *fnptr); + void BL(ARMReg src); + + void PUSH(const int num, ...); + void POP(const int num, ...); + + // New Data Ops + void AND (ARMReg Rd, ARMReg Rn, Operand2 Rm); + void ANDS(ARMReg Rd, ARMReg Rn, Operand2 Rm); + void EOR (ARMReg dest, ARMReg src, Operand2 op2); + void EORS(ARMReg dest, ARMReg src, Operand2 op2); + void SUB (ARMReg dest, ARMReg src, Operand2 op2); + void SUBS(ARMReg dest, ARMReg src, Operand2 op2); + void RSB (ARMReg dest, ARMReg src, Operand2 op2); + void RSBS(ARMReg dest, ARMReg src, Operand2 op2); + void ADD (ARMReg dest, ARMReg src, Operand2 op2); + void ADDS(ARMReg dest, ARMReg src, Operand2 op2); + void ADC (ARMReg dest, ARMReg src, Operand2 op2); + void ADCS(ARMReg dest, ARMReg src, Operand2 op2); + void LSL (ARMReg dest, ARMReg src, Operand2 op2); + void LSL (ARMReg dest, ARMReg src, ARMReg op2); + void LSLS(ARMReg dest, ARMReg src, Operand2 op2); + void LSLS(ARMReg dest, ARMReg src, ARMReg op2); + void SBC (ARMReg dest, ARMReg src, Operand2 op2); + void SBCS(ARMReg dest, ARMReg src, Operand2 op2); + void REV (ARMReg dest, ARMReg src); + void REV16 (ARMReg dest, ARMReg src); + void RSC (ARMReg dest, ARMReg src, Operand2 op2); + void RSCS(ARMReg dest, ARMReg src, Operand2 op2); + void TST ( ARMReg src, Operand2 op2); + void TEQ ( ARMReg src, Operand2 op2); + void CMP ( ARMReg src, Operand2 op2); + void CMN ( ARMReg src, Operand2 op2); + void ORR (ARMReg dest, ARMReg src, Operand2 op2); + void ORRS(ARMReg dest, ARMReg src, Operand2 op2); + void MOV (ARMReg dest, Operand2 op2); + void MOVS(ARMReg dest, Operand2 op2); + void BIC (ARMReg dest, ARMReg src, Operand2 op2); // BIC = ANDN + void BICS(ARMReg dest, ARMReg src, Operand2 op2); + void MVN (ARMReg dest, Operand2 op2); + void MVNS(ARMReg dest, Operand2 op2); + void MOVW(ARMReg dest, Operand2 op2); + void MOVT(ARMReg dest, Operand2 op2, bool TopBits = false); + + // UDIV and SDIV are only available on CPUs that have + // the idiva hardare capacity + void UDIV(ARMReg dest, ARMReg dividend, ARMReg divisor); + void SDIV(ARMReg dest, ARMReg dividend, ARMReg divisor); + + void MUL (ARMReg dest, ARMReg src, ARMReg op2); + void MULS(ARMReg dest, ARMReg src, ARMReg op2); + + void UMULL(ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); + void SMULL(ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); + + void SXTB(ARMReg dest, ARMReg op2); + void SXTH(ARMReg dest, ARMReg op2, u8 rotation = 0); + void SXTAH(ARMReg dest, ARMReg src, ARMReg op2, u8 rotation = 0); + // Using just MSR here messes with our defines on the PPC side of stuff (when this code was in dolphin...) + // Just need to put an underscore here, bit annoying. + void _MSR (bool nzcvq, bool g, Operand2 op2); + void _MSR (bool nzcvq, bool g, ARMReg src ); + void MRS (ARMReg dest); + + // Memory load/store operations + void LDR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + // Offset adds to the base register in LDR + void LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); + void LDRH(ARMReg dest, ARMReg src, Operand2 op = 0); + void LDRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); + void STR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + // Offset adds on to the destination register in STR + void STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); + + void STRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); + void STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); + void LDMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); + + // Exclusive Access operations + void LDREX(ARMReg dest, ARMReg base); + // dest contains the result if the instruction managed to store the value + void STREX(ARMReg dest, ARMReg base, ARMReg op); + void DMB (); + void SVC(Operand2 op); + + // NEON and ASIMD instructions + // None of these will be created with conditional since ARM + // is deprecating conditional execution of ASIMD instructions. + // ASIMD instructions don't even have a conditional encoding. + + // Subtracts the base from the register to give us the real one + ARMReg SubBase(ARMReg Reg); + // NEON Only + void VADD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); + void VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); + + // VFP Only + void VLDR(ARMReg Dest, ARMReg Base, u16 op); + void VSTR(ARMReg Src, ARMReg Base, u16 op); + void VCMP(ARMReg Vd, ARMReg Vm); + // Compares against zero + void VCMP(ARMReg Vd); + void VDIV(ARMReg Vd, ARMReg Vn, ARMReg Vm); + void VSQRT(ARMReg Vd, ARMReg Vm); + + // NEON and VFP + void VABS(ARMReg Vd, ARMReg Vm); + void VADD(ARMReg Vd, ARMReg Vn, ARMReg Vm); + void VSUB(ARMReg Vd, ARMReg Vn, ARMReg Vm); + + void VMOV(ARMReg Dest, ARMReg Src, bool high); + void VMOV(ARMReg Dest, ARMReg Src); + + void QuickCallFunction(ARMReg scratchreg, void *func); + // Utility functions + void MOVI2R(ARMReg reg, u32 val, bool optimize = true); + void ARMABI_MOVI2M(Operand2 op, Operand2 val); +}; // class ARMXEmitter + + +// Everything that needs to generate X86 code should inherit from this. +// You get memory management for free, plus, you can use all the MOV etc functions without +// having to prefix them with gen-> or something similar. +class ARMXCodeBlock : public ARMXEmitter +{ +protected: + u8 *region; + size_t region_size; + +public: + ARMXCodeBlock() : region(NULL), region_size(0) {} + virtual ~ARMXCodeBlock() { if (region) FreeCodeSpace(); } + + // Call this before you generate any code. + void AllocCodeSpace(int size) + { + region_size = size; + region = (u8*)AllocateExecutableMemory(region_size); + SetCodePtr(region); + } + + // Always clear code space with breakpoints, so that if someone accidentally executes + // uninitialized, it just breaks into the debugger. + void ClearCodeSpace() + { + // x86/64: 0xCC = breakpoint + memset(region, 0xCC, region_size); + ResetCodePtr(); + } + + // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. + void FreeCodeSpace() + { + FreeMemoryPages(region, region_size); + region = NULL; + region_size = 0; + } + + bool IsInSpace(u8 *ptr) + { + return ptr >= region && ptr < region + region_size; + } + + // Cannot currently be undone. Will write protect the entire code region. + // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). + void WriteProtect() + { + WriteProtectMemory(region, region_size, true); + } + + void ResetCodePtr() + { + SetCodePtr(region); + } + + size_t GetSpaceLeft() const + { + return region_size - (GetCodePtr() - region); + } +}; + +} // namespace + +#endif // _DOLPHIN_INTEL_CODEGEN_ diff --git a/Source/Core/Common/Src/CPUDetect.h b/Source/Core/Common/Src/CPUDetect.h index 928b34c109..351120e3a2 100644 --- a/Source/Core/Common/Src/CPUDetect.h +++ b/Source/Core/Common/Src/CPUDetect.h @@ -25,7 +25,8 @@ enum CPUVendor { VENDOR_INTEL = 0, VENDOR_AMD = 1, - VENDOR_OTHER = 2, + VENDOR_ARM = 2, + VENDOR_OTHER = 3, }; struct CPUInfo @@ -55,6 +56,26 @@ struct CPUInfo bool bAES; bool bLAHFSAHF64; bool bLongMode; + + // ARM specific CPUInfo + bool bSwp; + bool bHalf; + bool bThumb; + bool bFastMult; + bool bVFP; + bool bEDSP; + bool bThumbEE; + bool bNEON; + bool bVFPv3; + bool bTLS; + bool bVFPv4; + bool bIDIVa; + bool bIDIVt; + bool bArmV7; // enable MOVT, MOVW etc + + // ARMv8 specific + bool bFP; + bool bASIMD; // Call Detect() explicit CPUInfo(); diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h index 0132915a5c..904095e255 100644 --- a/Source/Core/Common/Src/Common.h +++ b/Source/Core/Common/Src/Common.h @@ -133,7 +133,9 @@ private: // wxWidgets does not have a true dummy macro for this. #define _trans(a) a -#if defined __GNUC__ +#if defined _M_GENERIC +# define _M_SSE 0x0 +#elif defined __GNUC__ # if defined __SSE4_2__ # define _M_SSE 0x402 # elif defined __SSE4_1__ @@ -144,7 +146,7 @@ private: # define _M_SSE 0x300 # endif #elif (_MSC_VER >= 1500) || __INTEL_COMPILER // Visual Studio 2008 -# define _M_SSE 0x402 +# define _M_SSE 0x402 #endif // Host communication. diff --git a/Source/Core/Common/Src/CommonFuncs.h b/Source/Core/Common/Src/CommonFuncs.h index 585fe0999a..7c6bcdc703 100644 --- a/Source/Core/Common/Src/CommonFuncs.h +++ b/Source/Core/Common/Src/CommonFuncs.h @@ -35,7 +35,7 @@ template<> struct CompileTimeAssert {}; #define b32(x) (b16(x) | (b16(x) >>16) ) #define ROUND_UP_POW2(x) (b32(x - 1) + 1) -#if defined __GNUC__ && !defined __SSSE3__ +#if defined __GNUC__ && !defined __SSSE3__ && !defined _M_GENERIC #include static __inline __m128i __attribute__((__always_inline__)) _mm_shuffle_epi8(__m128i a, __m128i mask) @@ -60,6 +60,8 @@ _mm_shuffle_epi8(__m128i a, __m128i mask) // go to debugger mode #ifdef GEKKO #define Crash() + #elif defined _M_GENERIC + #define Crash() { exit(1); } #else #define Crash() {asm ("int $3");} #endif @@ -136,6 +138,15 @@ inline u8 swap8(u8 _data) {return _data;} inline u16 swap16(u16 _data) {return _byteswap_ushort(_data);} inline u32 swap32(u32 _data) {return _byteswap_ulong (_data);} inline u64 swap64(u64 _data) {return _byteswap_uint64(_data);} +#elif _M_ARM +#ifdef ANDROID +#undef swap16 +#undef swap32 +#undef swap64 +#endif +inline u16 swap16 (u16 _data) { u32 data = _data; __asm__ ("rev16 %0, %1\n" : "=l" (data) : "l" (data)); return (u16)data;} +inline u32 swap32 (u32 _data) {__asm__ ("rev %0, %1\n" : "=l" (_data) : "l" (_data)); return _data;} +inline u64 swap64(u64 _data) {return ((u64)swap32(_data) << 32) | swap32(_data >> 32);} #elif __linux__ inline u16 swap16(u16 _data) {return bswap_16(_data);} inline u32 swap32(u32 _data) {return bswap_32(_data);} @@ -161,7 +172,6 @@ inline u64 swap64(u64 data) {return ((u64)swap32(data) << 32) | swap32(data >> 3 inline u16 swap16(const u8* _pData) {return swap16(*(const u16*)_pData);} inline u32 swap32(const u8* _pData) {return swap32(*(const u32*)_pData);} inline u64 swap64(const u8* _pData) {return swap64(*(const u64*)_pData);} - } // Namespace Common #endif // _COMMONFUNCS_H_ diff --git a/Source/Core/Common/Src/CommonPaths.h b/Source/Core/Common/Src/CommonPaths.h index 9e14d7cf7e..cab7ce3762 100644 --- a/Source/Core/Common/Src/CommonPaths.h +++ b/Source/Core/Common/Src/CommonPaths.h @@ -36,6 +36,9 @@ // You can use the File::GetUserPath() util for this #define USERDATA_DIR "Contents/Resources/User" #define DOLPHIN_DATA_DIR "Library/Application Support/Dolphin" +#elif defined ANDROID + #define USERDATA_DIR "user" + #define DOLPHIN_DATA_DIR "/sdcard/dolphin-emu" #else #define USERDATA_DIR "user" #ifdef USER_DIR @@ -52,6 +55,8 @@ #define SYSDATA_DIR "Contents/Resources/Sys" #define SHARED_USER_DIR File::GetBundleDirectory() + \ DIR_SEP USERDATA_DIR DIR_SEP +#elif defined ANDROID + #define SYSDATA_DIR "/sdcard/dolphin-emu" #else #ifdef DATA_DIR #define SYSDATA_DIR DATA_DIR "sys" diff --git a/Source/Core/Common/Src/FPURoundMode.h b/Source/Core/Common/Src/FPURoundMode.h new file mode 100644 index 0000000000..acfd89c313 --- /dev/null +++ b/Source/Core/Common/Src/FPURoundMode.h @@ -0,0 +1,51 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#ifndef FPU_ROUND_MODE_H_ +#define FPU_ROUND_MODE_H_ +#include "Common.h" + +namespace FPURoundMode +{ + enum RoundModes + { + ROUND_NEAR = 0, + ROUND_CHOP, + ROUND_UP, + ROUND_DOWN + }; + enum PrecisionModes { + PREC_24 = 0, + PREC_53, + PREC_64 + }; + void SetRoundMode(u32 mode); + + void SetPrecisionMode(u32 mode); + + void SetSIMDMode(u32 mode); + + /* + There are two different flavors of float to int conversion: + _mm_cvtps_epi32() and _mm_cvttps_epi32(). The first rounds + according to the MXCSR rounding bits. The second one always + uses round towards zero. + */ + void SaveSIMDState(); + void LoadSIMDState(); + void LoadDefaultSIMDState(); +} +#endif diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp index 491db88e41..f42c204396 100644 --- a/Source/Core/Common/Src/FileUtil.cpp +++ b/Source/Core/Common/Src/FileUtil.cpp @@ -668,9 +668,10 @@ std::string &GetUserPath(const unsigned int DirIDX, const std::string &newPath) if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; else - paths[D_USER_IDX] = std::string(getenv("HOME") ? getenv("HOME") : getenv("PWD")) + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP; + paths[D_USER_IDX] = std::string(getenv("HOME") ? + getenv("HOME") : getenv("PWD") ? + getenv("PWD") : "") + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP; #endif - INFO_LOG(COMMON, "GetUserPath: Setting user directory to %s:", paths[D_USER_IDX].c_str()); paths[D_GCUSER_IDX] = paths[D_USER_IDX] + GC_USER_DIR DIR_SEP; paths[D_WIIROOT_IDX] = paths[D_USER_IDX] + WII_USER_DIR; diff --git a/Source/Core/Common/Src/GenericFPURoundMode.cpp b/Source/Core/Common/Src/GenericFPURoundMode.cpp new file mode 100644 index 0000000000..cc878291a1 --- /dev/null +++ b/Source/Core/Common/Src/GenericFPURoundMode.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "FPURoundMode.h" + +// Generic, do nothing +namespace FPURoundMode +{ + void SetRoundMode(u32 mode) + { + } + void SetPrecisionMode(u32 mode) + { + } + void SetSIMDMode(u32 mode) + { + } + void SaveSIMDState() + { + } + void LoadSIMDState() + { + } + void LoadDefaultSIMDState() + { + } +} diff --git a/Source/Core/Common/Src/LogManager.cpp b/Source/Core/Common/Src/LogManager.cpp index a79c413cf8..3beae08c15 100644 --- a/Source/Core/Common/Src/LogManager.cpp +++ b/Source/Core/Common/Src/LogManager.cpp @@ -17,6 +17,9 @@ #include +#ifdef ANDROID +#include "Host.h" +#endif #include "LogManager.h" #include "ConsoleListener.h" #include "Timer.h" @@ -132,7 +135,9 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type, Common::Timer::GetTimeFormatted().c_str(), file, line, level_to_char[(int)level], log->GetShortName(), temp); - +#ifdef ANDROID + Host_SysMessage(msg); +#endif log->Trigger(level, msg); } diff --git a/Source/Core/Common/Src/MathUtil.cpp b/Source/Core/Common/Src/MathUtil.cpp index e078db2e9d..b97d55e62c 100644 --- a/Source/Core/Common/Src/MathUtil.cpp +++ b/Source/Core/Common/Src/MathUtil.cpp @@ -21,13 +21,6 @@ #include #include -namespace { - -static u32 saved_sse_state = _mm_getcsr(); -static const u32 default_sse_state = _mm_getcsr(); - -} - namespace MathUtil { @@ -114,23 +107,6 @@ u32 ClassifyFloat(float fvalue) } // namespace -void LoadDefaultSSEState() -{ - _mm_setcsr(default_sse_state); -} - - -void LoadSSEState() -{ - _mm_setcsr(saved_sse_state); -} - - -void SaveSSEState() -{ - saved_sse_state = _mm_getcsr(); -} - inline void MatrixMul(int n, const float *a, const float *b, float *result) { for (int i = 0; i < n; ++i) diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h index a6290ff602..114a91bf3c 100644 --- a/Source/Core/Common/Src/MathUtil.h +++ b/Source/Core/Common/Src/MathUtil.h @@ -20,8 +20,8 @@ #include "Common.h" -#include #include +#include "FPURoundMode.h" namespace MathUtil { @@ -147,17 +147,6 @@ struct Rectangle inline float pow2f(float x) {return x * x;} inline double pow2(double x) {return x * x;} - -/* - There are two different flavors of float to int conversion: - _mm_cvtps_epi32() and _mm_cvttps_epi32(). The first rounds - according to the MXCSR rounding bits. The second one always - uses round towards zero. - */ - -void SaveSSEState(); -void LoadSSEState(); -void LoadDefaultSSEState(); float MathFloatVectorSum(const std::vector&); #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) diff --git a/Source/Core/Common/Src/MemArena.cpp b/Source/Core/Common/Src/MemArena.cpp index 1dcdef6672..0a2b9e0306 100644 --- a/Source/Core/Common/Src/MemArena.cpp +++ b/Source/Core/Common/Src/MemArena.cpp @@ -27,6 +27,10 @@ #include #include #include +#ifdef ANDROID +#include +#include +#endif #endif #if defined(__APPLE__) @@ -34,11 +38,41 @@ static const char* ram_temp_file = "/tmp/gc_mem.tmp"; #elif !defined(_WIN32) // non OSX unixes static const char* ram_temp_file = "/dev/shm/gc_mem.tmp"; #endif +#ifdef ANDROID +#define ASHMEM_DEVICE "/dev/ashmem" + +int AshmemCreateFileMapping(const char *name, size_t size) +{ + int fd, ret; + fd = open(ASHMEM_DEVICE, O_RDWR); + if (fd < 0) + return fd; + + // We don't really care if we can't set the name, it is optional + ret = ioctl(fd, ASHMEM_SET_NAME, name); + + ret = ioctl(fd, ASHMEM_SET_SIZE, size); + if (ret < 0) + { + close(fd); + NOTICE_LOG(MEMMAP, "Ashmem returned error: 0x%08x", ret); + return ret; + } + return fd; +} +#endif void MemArena::GrabLowMemSpace(size_t size) { #ifdef _WIN32 hMemoryMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD)(size), NULL); +#elif defined(ANDROID) + fd = AshmemCreateFileMapping("Dolphin-emu", size); + if (fd < 0) + { + NOTICE_LOG(MEMMAP, "Ashmem allocation failed"); + return; + } #else mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; fd = open(ram_temp_file, O_RDWR | O_CREAT, mode); diff --git a/Source/Core/Common/Src/MemoryUtil.cpp b/Source/Core/Common/Src/MemoryUtil.cpp index 0888746d42..ff50347799 100644 --- a/Source/Core/Common/Src/MemoryUtil.cpp +++ b/Source/Core/Common/Src/MemoryUtil.cpp @@ -117,9 +117,12 @@ void* AllocateAlignedMemory(size_t size,size_t alignment) void* ptr = _aligned_malloc(size,alignment); #else void* ptr = NULL; +#ifdef ANDROID + ptr = memalign(alignment, size); +#else if (posix_memalign(&ptr, alignment, size) != 0) ERROR_LOG(MEMMAP, "Failed to allocate aligned memory"); -; +#endif #endif // printf("Mapped memory at %p (size %ld)\n", ptr, diff --git a/Source/Core/Common/Src/StdConditionVariable.h b/Source/Core/Common/Src/StdConditionVariable.h index 1b81766ee0..11de6536b4 100644 --- a/Source/Core/Common/Src/StdConditionVariable.h +++ b/Source/Core/Common/Src/StdConditionVariable.h @@ -5,7 +5,7 @@ #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ +#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !ANDROID // GCC 4.4 provides #include #else diff --git a/Source/Core/Common/Src/StdMutex.h b/Source/Core/Common/Src/StdMutex.h index 8949e905ac..8a5d22f928 100644 --- a/Source/Core/Common/Src/StdMutex.h +++ b/Source/Core/Common/Src/StdMutex.h @@ -5,7 +5,7 @@ #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ +#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !ANDROID // GCC 4.4 provides #include #else diff --git a/Source/Core/Common/Src/StdThread.h b/Source/Core/Common/Src/StdThread.h index fea058c874..6897235658 100644 --- a/Source/Core/Common/Src/StdThread.h +++ b/Source/Core/Common/Src/StdThread.h @@ -5,7 +5,7 @@ #define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z)) #define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ +#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !ANDROID // GCC 4.4 provides #ifndef _GLIBCXX_USE_SCHED_YIELD #define _GLIBCXX_USE_SCHED_YIELD diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index e5c70b2c6b..6ef3d91a73 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -245,7 +245,7 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st while(1) { const int pos = result.find(src); - if (pos == -1) break; + if (pos == 16) break; result.replace(pos, src.size(), dest); } return result; @@ -263,25 +263,25 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st const char HEX2DEC[256] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ - /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1, + /* 0 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* 1 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* 2 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* 3 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,16,16, 16,16,16,16, - /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + /* 4 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, + /* 5 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* 6 */ 16,10,11,12, 13,14,15,16, 16,16,16,16, 16,16,16,16, + /* 7 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, - /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + /* 8 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* 9 */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* A */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* B */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, - /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1 + /* C */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* D */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* E */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16, + /* F */ 16,16,16,16, 16,16,16,16, 16,16,16,16, 16,16,16,16 }; std::string UriDecode(const std::string & sSrc) @@ -303,8 +303,8 @@ std::string UriDecode(const std::string & sSrc) if (*pSrc == '%') { char dec1, dec2; - if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)]) - && -1 != (dec2 = HEX2DEC[*(pSrc + 2)])) + if (16 != (dec1 = HEX2DEC[*(pSrc + 1)]) + && 16 != (dec2 = HEX2DEC[*(pSrc + 2)])) { *pEnd++ = (dec1 << 4) + dec2; pSrc += 3; diff --git a/Source/Core/Common/Src/Thread.cpp b/Source/Core/Common/Src/Thread.cpp index 73f83c204f..3e8440b74f 100644 --- a/Source/Core/Common/Src/Thread.cpp +++ b/Source/Core/Common/Src/Thread.cpp @@ -105,7 +105,7 @@ void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) #ifdef __APPLE__ thread_policy_set(pthread_mach_thread_np(thread), THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); -#elif defined __linux__ || defined BSD4_4 +#elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID) cpu_set_t cpu_set; CPU_ZERO(&cpu_set); diff --git a/Source/Core/Common/Src/Thread.h b/Source/Core/Common/Src/Thread.h index e711fcab5c..8b38be1de1 100644 --- a/Source/Core/Common/Src/Thread.h +++ b/Source/Core/Common/Src/Thread.h @@ -33,8 +33,6 @@ #define INFINITE 0xffffffff #endif -#include - //for gettimeofday and struct time(spec|val) #include #include diff --git a/Source/Core/Common/Src/ABI.cpp b/Source/Core/Common/Src/x64ABI.cpp similarity index 99% rename from Source/Core/Common/Src/ABI.cpp rename to Source/Core/Common/Src/x64ABI.cpp index 63a8e76934..cd2f410dbf 100644 --- a/Source/Core/Common/Src/ABI.cpp +++ b/Source/Core/Common/Src/x64ABI.cpp @@ -17,7 +17,7 @@ #include "Common.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; diff --git a/Source/Core/Common/Src/ABI.h b/Source/Core/Common/Src/x64ABI.h similarity index 100% rename from Source/Core/Common/Src/ABI.h rename to Source/Core/Common/Src/x64ABI.h diff --git a/Source/Core/Common/Src/CPUDetect.cpp b/Source/Core/Common/Src/x64CPUDetect.cpp similarity index 98% rename from Source/Core/Common/Src/CPUDetect.cpp rename to Source/Core/Common/Src/x64CPUDetect.cpp index 282929e7b2..2898b91bec 100644 --- a/Source/Core/Common/Src/CPUDetect.cpp +++ b/Source/Core/Common/Src/x64CPUDetect.cpp @@ -30,7 +30,9 @@ #else //#include +#ifndef _M_GENERIC #include +#endif #if defined __FreeBSD__ #include @@ -39,7 +41,9 @@ static inline void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { -#ifdef _LP64 +#if defined _M_GENERIC + (*eax) = (*ebx) = (*ecx) = (*edx) = 0; +#elif defined _LP64 // Note: EBX is reserved on Mac OS X and in PIC on Linux, so it has to // restored at the end of the asm block. __asm__ ( diff --git a/Source/Core/Common/Src/x64Emitter.cpp b/Source/Core/Common/Src/x64Emitter.cpp index 5f8d0a66f1..9f15845875 100644 --- a/Source/Core/Common/Src/x64Emitter.cpp +++ b/Source/Core/Common/Src/x64Emitter.cpp @@ -17,7 +17,7 @@ #include "Common.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "CPUDetect.h" namespace Gen diff --git a/Source/Core/Common/Src/x64Emitter.h b/Source/Core/Common/Src/x64Emitter.h index 3b699c81a0..6b8c59b5a5 100644 --- a/Source/Core/Common/Src/x64Emitter.h +++ b/Source/Core/Common/Src/x64Emitter.h @@ -757,7 +757,7 @@ public: region_size = 0; } - bool IsInCodeSpace(u8 *ptr) + bool IsInSpace(u8 *ptr) { return ptr >= region && ptr < region + region_size; } diff --git a/Source/Core/Common/Src/x64FPURoundMode.cpp b/Source/Core/Common/Src/x64FPURoundMode.cpp new file mode 100644 index 0000000000..0beefd860a --- /dev/null +++ b/Source/Core/Common/Src/x64FPURoundMode.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "FPURoundMode.h" + +#ifndef _WIN32 +static const unsigned short FPU_ROUND_NEAR = 0 << 10; +static const unsigned short FPU_ROUND_DOWN = 1 << 10; +static const unsigned short FPU_ROUND_UP = 2 << 10; +static const unsigned short FPU_ROUND_CHOP = 3 << 10; +static const unsigned short FPU_ROUND_MASK = 3 << 10; +#include +#endif + +const u32 MASKS = 0x1F80; // mask away the interrupts. +const u32 DAZ = 0x40; +const u32 FTZ = 0x8000; + +namespace FPURoundMode +{ + // Get the default SSE states here. + static u32 saved_sse_state = _mm_getcsr(); + static const u32 default_sse_state = _mm_getcsr(); + + void SetRoundMode(u32 mode) + { + // Set FPU rounding mode to mimic the PowerPC's + #ifdef _M_IX86 + // This shouldn't really be needed anymore since we use SSE + #ifdef _WIN32 + const int table[4] = + { + _RC_NEAR, + _RC_CHOP, + _RC_UP, + _RC_DOWN + }; + _set_controlfp(_MCW_RC, table[mode]); + #else + const unsigned short table[4] = + { + FPU_ROUND_NEAR, + FPU_ROUND_CHOP, + FPU_ROUND_UP, + FPU_ROUND_DOWN + }; + unsigned short _mode; + asm ("fstcw %0" : "=m" (_mode) : ); + _mode = (_mode & ~FPU_ROUND_MASK) | table[mode]; + asm ("fldcw %0" : : "m" (_mode)); + #endif + #endif + } + + void SetPrecisionMode(u32 mode) + { + #ifdef _M_IX86 + // sets the floating-point lib to 53-bit + // PowerPC has a 53bit floating pipeline only + // eg: sscanf is very sensitive + #ifdef _WIN32 + _control87(_PC_53, MCW_PC); + #else + const unsigned short table[4] = { + 0 << 8, // FPU_PREC_24 + 2 << 8, // FPU_PREC_53 + 3 << 8, // FPU_PREC_64 + 3 << 8, // FPU_PREC_MASK + }; + unsigned short _mode; + asm ("fstcw %0" : : "m" (_mode)); + _mode = (_mode & ~table[4]) | table[mode]; + asm ("fldcw %0" : : "m" (_mode)); + #endif + #else + //x64 doesn't need this - fpu is done with SSE + //but still - set any useful sse options here + #endif + } + void SetSIMDMode(u32 mode) + { + static const u32 ssetable[4] = + { + (0 << 13) | MASKS, + (3 << 13) | MASKS, + (2 << 13) | MASKS, + (1 << 13) | MASKS, + }; + u32 csr = ssetable[mode]; + _mm_setcsr(csr); + } + + void SaveSIMDState() + { + saved_sse_state = _mm_getcsr(); + } + void LoadSIMDState() + { + _mm_setcsr(saved_sse_state); + } + void LoadDefaultSIMDState() + { + _mm_setcsr(default_sse_state); + } +} diff --git a/Source/Core/Common/Src/Thunk.cpp b/Source/Core/Common/Src/x64Thunk.cpp similarity index 98% rename from Source/Core/Common/Src/Thunk.cpp rename to Source/Core/Common/Src/x64Thunk.cpp index 1792df3e77..b9fd54f354 100644 --- a/Source/Core/Common/Src/Thunk.cpp +++ b/Source/Core/Common/Src/x64Thunk.cpp @@ -18,9 +18,8 @@ #include #include "Common.h" -#include "x64Emitter.h" #include "MemoryUtil.h" -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #define THUNK_ARENA_SIZE 1024*1024*1 diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 6ffeeaec3a..b8976f42ea 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -9,7 +9,6 @@ set(SRCS Src/ActionReplay.cpp Src/DSPEmulator.cpp Src/GeckoCodeConfig.cpp Src/GeckoCode.cpp - Src/MemTools.cpp Src/Movie.cpp Src/NetPlay.cpp Src/NetPlayClient.cpp @@ -153,6 +152,7 @@ set(SRCS Src/ActionReplay.cpp Src/PowerPC/PPCTables.cpp Src/PowerPC/Profiler.cpp Src/PowerPC/SignatureDB.cpp + Src/PowerPC/JitInterface.cpp Src/PowerPC/Interpreter/Interpreter_Branch.cpp Src/PowerPC/Interpreter/Interpreter.cpp Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -162,6 +162,15 @@ set(SRCS Src/ActionReplay.cpp Src/PowerPC/Interpreter/Interpreter_Paired.cpp Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp Src/PowerPC/Interpreter/Interpreter_Tables.cpp + Src/PowerPC/JitCommon/JitAsmCommon.cpp + Src/PowerPC/JitCommon/JitBackpatch.cpp + Src/PowerPC/JitCommon/JitBase.cpp + Src/PowerPC/JitCommon/JitCache.cpp + Src/PowerPC/JitCommon/Jit_Util.cpp) + +if(NOT _M_GENERIC) + set(SRCS ${SRCS} + Src/x64MemTools.cpp Src/PowerPC/Jit64IL/IR.cpp Src/PowerPC/Jit64IL/IR_X86.cpp Src/PowerPC/Jit64IL/JitILAsm.cpp @@ -186,12 +195,25 @@ set(SRCS Src/ActionReplay.cpp Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp Src/PowerPC/Jit64/Jit_Paired.cpp Src/PowerPC/Jit64/JitRegCache.cpp - Src/PowerPC/Jit64/Jit_SystemRegisters.cpp - Src/PowerPC/JitCommon/JitAsmCommon.cpp - Src/PowerPC/JitCommon/JitBackpatch.cpp - Src/PowerPC/JitCommon/JitBase.cpp - Src/PowerPC/JitCommon/JitCache.cpp - Src/PowerPC/JitCommon/Jit_Util.cpp) + Src/PowerPC/Jit64/Jit_SystemRegisters.cpp) +endif() +if(_M_ARM) + set(SRCS ${SRCS} + Src/ArmMemTools.cpp + Src/PowerPC/JitArm32/Jit.cpp + Src/PowerPC/JitArm32/JitAsm.cpp + Src/PowerPC/JitArm32/JitArm_BackPatch.cpp + Src/PowerPC/JitArm32/JitArm_Tables.cpp + Src/PowerPC/JitArm32/JitArmCache.cpp + Src/PowerPC/JitArm32/JitRegCache.cpp + Src/PowerPC/JitArm32/JitFPRCache.cpp + Src/PowerPC/JitArm32/JitArm_Branch.cpp + Src/PowerPC/JitArm32/JitArm_Integer.cpp + Src/PowerPC/JitArm32/JitArm_LoadStore.cpp + Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp + Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp + Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp) +endif() set(LIBS bdisasm inputcommon videosoftware sfml-network) diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index bd3d97f11b..1dd547b2ea 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -332,7 +332,7 @@ - + @@ -378,6 +378,7 @@ + @@ -387,10 +388,10 @@ - false - false - false - + false + false + false + Create Create @@ -563,6 +564,7 @@ + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index 246dafd972..b4f3f47be7 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -5,9 +5,8 @@ - - + @@ -562,6 +561,9 @@ HW %28Flipper/Hollywood%29\GCMemcard + + PowerPC + @@ -1048,6 +1050,9 @@ HW %28Flipper/Hollywood%29\GCMemcard + + PowerPC + diff --git a/Source/Core/Core/Src/ArmMemTools.cpp b/Source/Core/Core/Src/ArmMemTools.cpp new file mode 100644 index 0000000000..34a0c34b7d --- /dev/null +++ b/Source/Core/Core/Src/ArmMemTools.cpp @@ -0,0 +1,103 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#include +#include +#ifdef ANDROID +#include +#else +#include // Look in here for the context definition. +#include +#endif + +#include "Common.h" +#include "MemTools.h" +#include "HW/Memmap.h" +#include "PowerPC/PowerPC.h" +#include "PowerPC/JitInterface.h" +#include "PowerPC/JitCommon/JitBase.h" + +namespace EMM +{ +#ifdef ANDROID +typedef struct sigcontext mcontext_t; +typedef struct ucontext { + uint32_t uc_flags; + struct ucontext* uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + // Other fields are not used by Google Breakpad. Don't define them. +} ucontext_t; +#endif + +void sigsegv_handler(int signal, siginfo_t *info, void *raw_context) +{ + if (signal != SIGSEGV) + { + // We are not interested in other signals - handle it as usual. + return; + } + ucontext_t *context = (ucontext_t *)raw_context; + int sicode = info->si_code; + if (sicode != SEGV_MAPERR && sicode != SEGV_ACCERR) + { + // Huh? Return. + return; + } + + + // Get all the information we can out of the context. + mcontext_t *ctx = &context->uc_mcontext; + + void *fault_memory_ptr = (void*)ctx->arm_r10; + u8 *fault_instruction_ptr = (u8 *)ctx->arm_pc; + + if (!JitInterface::IsInCodeSpace(fault_instruction_ptr)) { + // Let's not prevent debugging. + return; + } + + u64 bad_address = (u64)fault_memory_ptr; + u64 memspace_bottom = (u64)Memory::base; + if (bad_address < memspace_bottom) { + PanicAlertT("Exception handler - access below memory space. %08llx%08llx", + bad_address >> 32, bad_address); + } + + u32 em_address = (u32)(bad_address - memspace_bottom); + + int access_type = 0; + + CONTEXT fake_ctx; + fake_ctx.reg_pc = ctx->arm_pc; + const u8 *new_rip = jit->BackPatch(fault_instruction_ptr, access_type, em_address, &fake_ctx); + if (new_rip) { + ctx->arm_pc = fake_ctx.reg_pc; + } +} + +void InstallExceptionHandler() +{ + struct sigaction sa; + sa.sa_handler = 0; + sa.sa_sigaction = &sigsegv_handler; + sa.sa_flags = SA_SIGINFO; + sigemptyset(&sa.sa_mask); + sigaction(SIGSEGV, &sa, NULL); +} +} // namespace diff --git a/Source/Core/Core/Src/ConfigManager.h b/Source/Core/Core/Src/ConfigManager.h index 0c4ceffa9f..4a36b37335 100644 --- a/Source/Core/Core/Src/ConfigManager.h +++ b/Source/Core/Core/Src/ConfigManager.h @@ -35,7 +35,7 @@ #define BACKEND_OPENAL "OpenAL" #define BACKEND_PULSEAUDIO "Pulse" #define BACKEND_XAUDIO2 "XAudio2" - +#define BACKEND_OPENSLES "OpenSLES" struct SConfig : NonCopyable { // Wii Devices diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index a6c07eeaaa..f7337def45 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -54,7 +54,6 @@ #include "IPC_HLE/WII_IPC_HLE_Device_usb.h" #include "PowerPC/PowerPC.h" -#include "PowerPC/JitCommon/JitBase.h" #include "DSPEmulator.h" #include "ConfigManager.h" @@ -140,7 +139,7 @@ void DisplayMessage(const char *message, int time_in_ms) if (_CoreParameter.bRenderToMain && SConfig::GetInstance().m_InterfaceStatusbar) { - Host_UpdateStatusBar(message); + Host_UpdateStatusBar(message); } else Host_UpdateTitle(message); @@ -189,7 +188,7 @@ bool IsGPUThread() return IsCPUThread(); } } - + // This is called from the GUI thread. See the booting call schedule in // BootManager.cpp bool Init() @@ -310,7 +309,7 @@ void CpuThread() g_video_backend->Video_Prepare(); } - #if defined(_M_X64) + #if defined(_M_X64) || _M_ARM EMM::InstallExceptionHandler(); // Let's run under memory watch #endif diff --git a/Source/Core/Core/Src/DSP/DSPEmitter.cpp b/Source/Core/Core/Src/DSP/DSPEmitter.cpp index 2ce441bf31..12dac52e31 100644 --- a/Source/Core/Core/Src/DSP/DSPEmitter.cpp +++ b/Source/Core/Core/Src/DSP/DSPEmitter.cpp @@ -25,7 +25,7 @@ #include "DSPAnalyzer.h" #include "Jit/DSPJitUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #define MAX_BLOCK_SIZE 250 #define DSP_IDLE_SKIP_CYCLES 0x1000 diff --git a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp index f2cbbc2b9f..e4c81e4a7a 100644 --- a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp +++ b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp @@ -252,7 +252,9 @@ static void gdsp_idma_out(u16 dsp_addr, u32 addr, u32 size) ERROR_LOG(DSPLLE, "*** idma_out IRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)", dsp_addr / 2, addr, size); } +#if _M_SSE >= 0x301 static const __m128i s_mask = _mm_set_epi32(0x0E0F0C0DL, 0x0A0B0809L, 0x06070405L, 0x02030001L); +#endif // TODO: These should eat clock cycles. static void gdsp_ddma_in(u16 dsp_addr, u32 addr, u32 size) diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp index 0b75431de6..185ada8ba3 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitArithmetic.cpp @@ -25,7 +25,7 @@ #include "DSPJitUtil.h" #endif #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; // CLR $acR diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp index 8ca770e35d..252550b84c 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp @@ -21,7 +21,7 @@ #include "../DSPAnalyzer.h" #include "DSPJitUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitCCUtil.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitCCUtil.cpp index e382b6114a..be7675378d 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitCCUtil.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitCCUtil.cpp @@ -24,7 +24,7 @@ #include "../DSPEmitter.h" #include "DSPJitUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; // In: RAX: s64 _Value diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp index 8203f7cde1..40e39a89e9 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp @@ -18,7 +18,7 @@ #include "../DSPEmitter.h" #include "DSPJitUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp index a784e2dd2d..248ed8f945 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp @@ -22,7 +22,7 @@ #include "../DSPEmitter.h" #include "DSPJitUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; // SRS @M, $(0x18+S) diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp index 8d8a635536..d0bf7a3822 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp @@ -20,7 +20,7 @@ #include "../DSPEmitter.h" #include "DSPJitUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; //clobbers: diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitMultiplier.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitMultiplier.cpp index 1323de002d..0dcbf41877 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitMultiplier.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitMultiplier.cpp @@ -27,7 +27,7 @@ #include "DSPJitUtil.h" #endif #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; // Returns s64 in RAX diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp index b9e166f698..2fb18f83da 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp @@ -20,7 +20,7 @@ #include "../DSPEmitter.h" #include "DSPJitUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" using namespace Gen; diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp index 88f6b2c358..6a6fb14212 100644 --- a/Source/Core/Core/Src/HW/Memmap.cpp +++ b/Source/Core/Core/Src/HW/Memmap.cpp @@ -419,132 +419,6 @@ u32 Read_Instruction(const u32 em_address) return inst.hex; } -u32 Read_Opcode_JIT_Uncached(const u32 _Address) -{ - u8* iCache; - u32 addr; - if (_Address & JIT_ICACHE_VMEM_BIT) - { - iCache = jit->GetBlockCache()->GetICacheVMEM(); - addr = _Address & JIT_ICACHE_MASK; - } - else if (_Address & JIT_ICACHE_EXRAM_BIT) - { - iCache = jit->GetBlockCache()->GetICacheEx(); - addr = _Address & JIT_ICACHEEX_MASK; - } - else - { - iCache = jit->GetBlockCache()->GetICache(); - addr = _Address & JIT_ICACHE_MASK; - } - u32 inst = *(u32*)(iCache + addr); - if (inst == JIT_ICACHE_INVALID_WORD) - { - u32 cache_block_start = addr & ~0x1f; - u32 mem_block_start = _Address & ~0x1f; - u8 *pMem = Memory::GetPointer(mem_block_start); - memcpy(iCache + cache_block_start, pMem, 32); - inst = *(u32*)(iCache + addr); - } - inst = Common::swap32(inst); - - if ((inst & 0xfc000000) == 0) - { - inst = jit->GetBlockCache()->GetOriginalFirstOp(inst); - } - - return inst; -} - -u32 Read_Opcode_JIT(u32 _Address) -{ -#ifdef FAST_ICACHE - if (bMMU && !bFakeVMEM && (_Address & ADDR_MASK_MEM1)) - { - _Address = Memory::TranslateAddress(_Address, FLAG_OPCODE); - if (_Address == 0) - { - return 0; - } - } - u32 inst = 0; - - // Bypass the icache for the external interrupt exception handler - if ( (_Address & 0x0FFFFF00) == 0x00000500 ) - inst = Read_Opcode_JIT_Uncached(_Address); - else - inst = PowerPC::ppcState.iCache.ReadInstruction(_Address); -#else - u32 inst = Memory::ReadUnchecked_U32(_Address); -#endif - return inst; -} - -// The following function is deprecated in favour of FAST_ICACHE -u32 Read_Opcode_JIT_LC(const u32 _Address) -{ -#ifdef JIT_UNLIMITED_ICACHE - if ((_Address & ~JIT_ICACHE_MASK) != 0x80000000 && (_Address & ~JIT_ICACHE_MASK) != 0x00000000 && - (_Address & ~JIT_ICACHE_MASK) != 0x7e000000 && // TLB area - (_Address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (_Address & ~JIT_ICACHEEX_MASK) != 0x10000000) - { - PanicAlertT("iCacheJIT: Reading Opcode from %x. Please report.", _Address); - ERROR_LOG(MEMMAP, "iCacheJIT: Reading Opcode from %x. Please report.", _Address); - return 0; - } - u8* iCache; - u32 addr; - if (_Address & JIT_ICACHE_VMEM_BIT) - { - iCache = jit->GetBlockCache()->GetICacheVMEM(); - addr = _Address & JIT_ICACHE_MASK; - } - else if (_Address & JIT_ICACHE_EXRAM_BIT) - { - iCache = jit->GetBlockCache()->GetICacheEx(); - addr = _Address & JIT_ICACHEEX_MASK; - } - else - { - iCache = jit->GetBlockCache()->GetICache(); - addr = _Address & JIT_ICACHE_MASK; - } - u32 inst = *(u32*)(iCache + addr); - if (inst == JIT_ICACHE_INVALID_WORD) - inst = Memory::ReadUnchecked_U32(_Address); - else - inst = Common::swap32(inst); -#else - u32 inst = Memory::ReadUnchecked_U32(_Address); -#endif - if ((inst & 0xfc000000) == 0) - { - inst = jit->GetBlockCache()->GetOriginalFirstOp(inst); - } - return inst; -} - -// WARNING! No checks! -// We assume that _Address is cached -void Write_Opcode_JIT(const u32 _Address, const u32 _Value) -{ -#ifdef JIT_UNLIMITED_ICACHE - if (_Address & JIT_ICACHE_VMEM_BIT) - { - *(u32*)(jit->GetBlockCache()->GetICacheVMEM() + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value); - } - else if (_Address & JIT_ICACHE_EXRAM_BIT) - { - *(u32*)(jit->GetBlockCache()->GetICacheEx() + (_Address & JIT_ICACHEEX_MASK)) = Common::swap32(_Value); - } - else - *(u32*)(jit->GetBlockCache()->GetICache() + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value); -#else - Memory::WriteUnchecked_U32(_Value, _Address); -#endif -} - void WriteBigEData(const u8 *_pData, const u32 _Address, const u32 _iSize) { memcpy(GetPointer(_Address), _pData, _iSize); diff --git a/Source/Core/Core/Src/HW/Memmap.h b/Source/Core/Core/Src/HW/Memmap.h index 42ceb737ca..8662804185 100644 --- a/Source/Core/Core/Src/HW/Memmap.h +++ b/Source/Core/Core/Src/HW/Memmap.h @@ -119,11 +119,6 @@ inline u32 ReadFast32(const u32 _Address) // used by interpreter to read instructions, uses iCache u32 Read_Opcode(const u32 _Address); -// used by JIT to read instructions -u32 Read_Opcode_JIT(const u32 _Address); -// used by JIT. uses iCacheJIT. Reads in the "Locked cache" mode -u32 Read_Opcode_JIT_LC(const u32 _Address); -void Write_Opcode_JIT(const u32 _Address, const u32 _Value); // this is used by Debugger a lot. // For now, just reads from memory! u32 Read_Instruction(const u32 _Address); diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index 1d6ea2e70d..ffaea0e868 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -28,8 +28,6 @@ #undef _interlockedbittestandreset #undef _interlockedbittestandset64 #undef _interlockedbittestandreset64 -#else -#include #endif #include "../../Core.h" @@ -514,4 +512,4 @@ void Interpreter::fsqrtx(UGeckoInstruction _inst) rPS0(_inst.FD) = sqrt(b); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); -} \ No newline at end of file +} diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp index 5e665eb38e..8e406dbfab 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -24,8 +24,7 @@ #include "Interpreter.h" #include "../../Core.h" -#include "../JitCommon/JitBase.h" -#include "../JitCommon/JitCache.h" +#include "../JitInterface.h" #include "Interpreter_FPUtils.h" @@ -363,34 +362,24 @@ void Interpreter::dcbf(UGeckoInstruction _inst) { NPC = PC + 12; }*/ - // Invalidate the jit block cache on dcbf - if (jit) - { u32 address = Helper_Get_EA_X(_inst); - jit->GetBlockCache()->InvalidateICache(address & ~0x1f, 32); - } + JitInterface::InvalidateICache(address & ~0x1f, 32); } void Interpreter::dcbi(UGeckoInstruction _inst) { // Removes a block from data cache. Since we don't emulate the data cache, we don't need to do anything to the data cache // However, we invalidate the jit block cache on dcbi - if (jit) - { u32 address = Helper_Get_EA_X(_inst); - jit->GetBlockCache()->InvalidateICache(address & ~0x1f, 32); - } + JitInterface::InvalidateICache(address & ~0x1f, 32); } void Interpreter::dcbst(UGeckoInstruction _inst) { // Cache line flush. Since we don't emulate the data cache, we don't need to do anything. // Invalidate the jit block cache on dcbst in case new code has been loaded via the data cache - if (jit) - { u32 address = Helper_Get_EA_X(_inst); - jit->GetBlockCache()->InvalidateICache(address & ~0x1f, 32); - } + JitInterface::InvalidateICache(address & ~0x1f, 32); } void Interpreter::dcbt(UGeckoInstruction _inst) @@ -409,7 +398,7 @@ void Interpreter::dcbz(UGeckoInstruction _inst) // HACK but works... we think if (!Core::g_CoreStartupParameter.bDCBZOFF) Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32); - if (!jit) + if (!JitInterface::GetCore()) PowerPC::CheckExceptions(); } diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 5a199b56c8..ff65f52471 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -26,13 +26,6 @@ #undef _interlockedbittestandreset #undef _interlockedbittestandset64 #undef _interlockedbittestandreset64 -#else -static const unsigned short FPU_ROUND_NEAR = 0 << 10; -static const unsigned short FPU_ROUND_DOWN = 1 << 10; -static const unsigned short FPU_ROUND_UP = 2 << 10; -static const unsigned short FPU_ROUND_CHOP = 3 << 10; -static const unsigned short FPU_ROUND_MASK = 3 << 10; -#include #endif #include "CPUDetect.h" @@ -43,6 +36,7 @@ static const unsigned short FPU_ROUND_MASK = 3 << 10; #include "../../HW/SystemTimers.h" #include "../../Core.h" #include "Interpreter.h" +#include "FPURoundMode.h" #include "Interpreter_FPUtils.h" @@ -61,38 +55,11 @@ mffsx: 80036650 (huh?) // That is, set rounding mode etc when entering jit code or the interpreter loop // Restore rounding mode when calling anything external -const u32 MASKS = 0x1F80; // mask away the interrupts. -const u32 DAZ = 0x40; -const u32 FTZ = 0x8000; - static void FPSCRtoFPUSettings(UReg_FPSCR fp) { - // Set FPU rounding mode to mimic the PowerPC's -#ifdef _M_IX86 - // This shouldn't really be needed anymore since we use SSE -#ifdef _WIN32 - const int table[4] = - { - _RC_NEAR, - _RC_CHOP, - _RC_UP, - _RC_DOWN - }; - _set_controlfp(_MCW_RC, table[fp.RN]); -#else - const unsigned short table[4] = - { - FPU_ROUND_NEAR, - FPU_ROUND_CHOP, - FPU_ROUND_UP, - FPU_ROUND_DOWN - }; - unsigned short mode; - asm ("fstcw %0" : "=m" (mode) : ); - mode = (mode & ~FPU_ROUND_MASK) | table[fp.RN]; - asm ("fldcw %0" : : "m" (mode)); -#endif -#endif + + FPURoundMode::SetRoundMode(fp.RN); + if (fp.VE || fp.OE || fp.UE || fp.ZE || fp.XE) { //PanicAlert("FPSCR - exceptions enabled. Please report. VE=%i OE=%i UE=%i ZE=%i XE=%i", @@ -101,14 +68,6 @@ static void FPSCRtoFPUSettings(UReg_FPSCR fp) } // Also corresponding SSE rounding mode setting - static const u32 ssetable[4] = - { - (0 << 13) | MASKS, - (3 << 13) | MASKS, - (2 << 13) | MASKS, - (1 << 13) | MASKS, - }; - u32 csr = ssetable[FPSCR.RN]; if (FPSCR.NI) { // Either one of these two breaks Beyond Good & Evil. @@ -116,7 +75,7 @@ static void FPSCRtoFPUSettings(UReg_FPSCR fp) // csr |= DAZ; // csr |= FTZ; } - _mm_setcsr(csr); + FPURoundMode::SetSIMDMode(FPSCR.RN); } void Interpreter::mtfsb0x(UGeckoInstruction _inst) diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp index 07219218a2..fee8ed70d8 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp @@ -267,7 +267,7 @@ static GekkoOPTemplate table31[] = {19, Interpreter::mfcr, {"mfcr", OPTYPE_SYSTEM, FL_OUT_D, 0, 0, 0, 0}}, {83, Interpreter::mfmsr, {"mfmsr", OPTYPE_SYSTEM, FL_OUT_D, 0, 0, 0, 0}}, {144, Interpreter::mtcrf, {"mtcrf", OPTYPE_SYSTEM, 0, 0, 0, 0, 0}}, - {146, Interpreter::mtmsr, {"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK, 0, 0, 0, 0}}, + {146, Interpreter::mtmsr, {"mtmsr", OPTYPE_SYSTEM, FL_IN_S | FL_ENDBLOCK, 0, 0, 0, 0}}, {210, Interpreter::mtsr, {"mtsr", OPTYPE_SYSTEM, 0, 0, 0, 0, 0}}, {242, Interpreter::mtsrin, {"mtsrin", OPTYPE_SYSTEM, 0, 0, 0, 0, 0}}, {339, Interpreter::mfspr, {"mfspr", OPTYPE_SPR, FL_OUT_D, 0, 0, 0, 0}}, diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 900a8475f7..710984571e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -24,7 +24,7 @@ #include "Common.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #include "../../HLE/HLE.h" #include "../../Core.h" @@ -357,7 +357,7 @@ void Jit64::WriteExternalExceptionExit() MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExternalExceptions)); - SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); + SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount)); JMP(asm_routines.dispatcher, true); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 1ebd476134..1d856d6291 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -62,7 +62,7 @@ if (js.memcheck) \ SetJumpTarget(memException); -class Jit64 : public JitBase +class Jit64 : public Jitx86Base { private: GPRRegCache gpr; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp index f7082cd1cc..df27a3a641 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp @@ -15,7 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "ABI.h" +#include "x64ABI.h" #include "x64Emitter.h" #include "../../HW/Memmap.h" @@ -24,7 +24,7 @@ #include "../../CoreTiming.h" #include "MemoryUtil.h" -#include "ABI.h" +#include "x64ABI.h" #include "Jit.h" #include "../JitCommon/JitCache.h" @@ -204,7 +204,7 @@ void Jit64AsmRoutineManager::Generate() MOV(32, M(&NPC), R(EAX)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExternalExceptions)); SetJumpTarget(noExtException); - + TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); J_CC(CC_Z, outerLoop, true); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.h b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.h index e8df0877f7..19e1f41ba8 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/JitAsm.h @@ -18,7 +18,6 @@ #ifndef _JIT64ASM_H #define _JIT64ASM_H -#include "x64Emitter.h" #include "../JitCommon/JitAsmCommon.h" // In Dolphin, we don't use inline assembly. Instead, we generate all machine-near diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp index 04e4d09cc9..7c1d60ad09 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp @@ -28,7 +28,7 @@ #include "../../HW/Memmap.h" #include "../PPCTables.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Jit.h" #include "JitAsm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp index 9f61e097b8..5766eb3177 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStoreFloating.cpp @@ -27,7 +27,7 @@ #include "../PPCTables.h" #include "CPUDetect.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Jit.h" #include "JitAsm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp index 3b14179cd4..924758ab3a 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStorePaired.cpp @@ -28,7 +28,7 @@ #include "../PPCTables.h" #include "CPUDetect.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Jit.h" #include "JitAsm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp index 14827129f8..0b6c0462d9 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp @@ -23,7 +23,7 @@ #include "../PowerPC.h" #include "../PPCTables.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #include "Jit.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index ce47e2c3ac..3638ba8da6 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -1991,8 +1991,10 @@ void JitIL::WriteCode() { } void ProfiledReJit() { - jit->SetCodePtr(jit->js.rewriteStart); - DoWriteCode(&((JitIL *)jit)->ibuild, (JitIL *)jit, true, false); - jit->js.curBlock->codeSize = (int)(jit->GetCodePtr() - jit->js.rewriteStart); - jit->GetBlockCache()->FinalizeBlock(jit->js.curBlock->blockNum, jit->jo.enableBlocklink, jit->js.curBlock->normalEntry); + JitIL *jitil = (JitIL *)jit; + jitil->SetCodePtr(jitil->js.rewriteStart); + DoWriteCode(&jitil->ibuild, jitil, true, false); + jitil->js.curBlock->codeSize = (int)(jitil->GetCodePtr() - jitil->js.rewriteStart); + jitil->GetBlockCache()->FinalizeBlock(jitil->js.curBlock->blockNum, jitil->jo.enableBlocklink, + jitil->js.curBlock->normalEntry); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index d56c9ffee8..dc21228858 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -19,7 +19,7 @@ #include "Common.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #include "../../HLE/HLE.h" #include "../../Core.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h index fdda098e44..8c579fa4bd 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h @@ -57,7 +57,7 @@ #define DISABLE64 #endif -class JitIL : public JitBase +class JitIL : public Jitx86Base { private: diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp index 74c290aa9c..aaa155072e 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp @@ -15,7 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "ABI.h" +#include "x64ABI.h" #include "x64Emitter.h" #include "../../HW/Memmap.h" @@ -25,7 +25,7 @@ #include "MemoryUtil.h" #include "CPUDetect.h" -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #include "../../HW/GPFifo.h" @@ -211,14 +211,14 @@ void JitILAsmRoutineManager::Generate() doTiming = GetCodePtr(); ABI_CallFunction(reinterpret_cast(&CoreTiming::Advance)); - + testExceptions = GetCodePtr(); MOV(32, R(EAX), M(&PC)); MOV(32, M(&NPC), R(EAX)); ABI_CallFunction(reinterpret_cast(&PowerPC::CheckExceptions)); MOV(32, R(EAX), M(&NPC)); MOV(32, M(&PC), R(EAX)); - + TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); J_CC(CC_Z, outer_loop, true); //Landing pad for drec space diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp index 45ceda694a..96902434a6 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStore.cpp @@ -27,7 +27,7 @@ #include "../../HW/Memmap.h" #include "../PPCTables.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "JitIL.h" #include "JitILAsm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStoreFloating.cpp index e06d289cc4..c74abfd8e9 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStoreFloating.cpp @@ -27,7 +27,7 @@ #include "../PPCTables.h" #include "CPUDetect.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "JitIL.h" #include "JitILAsm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStorePaired.cpp index 2f0a0762fd..6e86804bec 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_LoadStorePaired.cpp @@ -25,7 +25,7 @@ #include "../PPCTables.h" #include "CPUDetect.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "JitIL.h" #include "JitILAsm.h" diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp index f3e25dc2dd..70a6ea4843 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_SystemRegisters.cpp @@ -23,7 +23,7 @@ #include "../PowerPC.h" #include "../PPCTables.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #include "JitIL.h" diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp new file mode 100644 index 0000000000..e4b0ffd714 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp @@ -0,0 +1,498 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include + +#include "Common.h" +#include "../../HLE/HLE.h" +#include "../../Core.h" +#include "../../PatchEngine.h" +#include "../../CoreTiming.h" +#include "../../ConfigManager.h" +#include "../PowerPC.h" +#include "../Profiler.h" +#include "../PPCTables.h" +#include "../PPCAnalyst.h" +#include "../../HW/Memmap.h" +#include "../../HW/GPFifo.h" +#include "Jit.h" +#include "JitArm_Tables.h" +#include "ArmEmitter.h" +#include "../JitInterface.h" + +using namespace ArmGen; +using namespace PowerPC; + +static int CODE_SIZE = 1024*1024*32; +namespace CPUCompare +{ + extern u32 m_BlockStart; +} + +void JitArm::Init() +{ + AllocCodeSpace(CODE_SIZE); + blocks.Init(); + asm_routines.Init(); + // TODO: Investigate why the register cache crashes when only doing Init with + // the pointer to this. Seems for some reason it doesn't set the emitter pointer + // In the class for some reason? + gpr.Init(this); + gpr.SetEmitter(this); + fpr.Init(this); + fpr.SetEmitter(this); + jo.enableBlocklink = true; + jo.optimizeGatherPipe = false; +} + +void JitArm::ClearCache() +{ + ClearCodeSpace(); + blocks.Clear(); +} + +void JitArm::Shutdown() +{ + FreeCodeSpace(); + blocks.Shutdown(); + asm_routines.Shutdown(); +} + +// This is only called by Default() in this file. It will execute an instruction with the interpreter functions. +void JitArm::WriteCallInterpreter(UGeckoInstruction inst) +{ + gpr.Flush(); + fpr.Flush(); + Interpreter::_interpreterInstruction instr = GetInterpreterOp(inst); + MOVI2R(R0, inst.hex); + MOVI2R(R12, (u32)instr); + BL(R12); +} +void JitArm::unknown_instruction(UGeckoInstruction inst) +{ + PanicAlert("unknown_instruction %08x - Fix me ;)", inst.hex); +} + +void JitArm::Default(UGeckoInstruction _inst) +{ + WriteCallInterpreter(_inst.hex); +} + +void JitArm::HLEFunction(UGeckoInstruction _inst) +{ + gpr.Flush(); + fpr.Flush(); + MOVI2R(R0, js.compilerPC); + MOVI2R(R1, _inst.hex); + QuickCallFunction(R14, (void*)&HLE::Execute); + ARMReg rA = gpr.GetReg(); + LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, npc)); + WriteExitDestInR(rA); +} + +void JitArm::DoNothing(UGeckoInstruction _inst) +{ + // Yup, just don't do anything. +} + +static const bool ImHereDebug = false; +static const bool ImHereLog = false; +static std::map been_here; + +static void ImHere() +{ + static File::IOFile f; + if (ImHereLog) + { + if (!f) + { + f.Open("log32.txt", "w"); + } + fprintf(f.GetHandle(), "%08x\n", PC); + } + if (been_here.find(PC) != been_here.end()) + { + been_here.find(PC)->second++; + if ((been_here.find(PC)->second) & 1023) + return; + } + DEBUG_LOG(DYNA_REC, "I'm here - PC = %08x , LR = %08x", PC, LR); + been_here[PC] = 1; +} + +void JitArm::Cleanup() +{ + if (jo.optimizeGatherPipe && js.fifoBytesThisBlock > 0) + QuickCallFunction(R14, (void*)&GPFifo::CheckGatherPipe); +} +void JitArm::DoDownCount() +{ + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + MOVI2R(rA, (u32)&CoreTiming::downcount); + LDR(rB, rA); + if(js.downcountAmount < 255) // We can enlarge this if we used rotations + { + SUBS(rB, rB, js.downcountAmount); + STR(rA, rB); + } + else + { + ARMReg rC = gpr.GetReg(false); + MOVI2R(rC, js.downcountAmount); + SUBS(rB, rB, rC); + STR(rA, rB); + } + gpr.Unlock(rA, rB); +} +void JitArm::WriteExitDestInR(ARMReg Reg) +{ + STR(R9, Reg, STRUCT_OFF(PowerPC::ppcState, pc)); + Cleanup(); + DoDownCount(); + MOVI2R(Reg, (u32)asm_routines.dispatcher); + B(Reg); + gpr.Unlock(Reg); +} +void JitArm::WriteRfiExitDestInR(ARMReg Reg) +{ + STR(R9, Reg, STRUCT_OFF(PowerPC::ppcState, pc)); + Cleanup(); + DoDownCount(); + + MOVI2R(Reg, (u32)asm_routines.testExceptions); + B(Reg); + gpr.Unlock(Reg); // This was locked in the instruction beforehand +} +void JitArm::WriteExceptionExit() +{ + ARMReg A = gpr.GetReg(false); + Cleanup(); + DoDownCount(); + + MOVI2R(A, (u32)asm_routines.testExceptions); + B(A); +} +void JitArm::WriteExit(u32 destination, int exit_num) +{ + Cleanup(); + + DoDownCount(); + //If nobody has taken care of this yet (this can be removed when all branches are done) + JitBlock *b = js.curBlock; + b->exitAddress[exit_num] = destination; + b->exitPtrs[exit_num] = GetWritableCodePtr(); + + // Link opportunity! + int block = blocks.GetBlockNumberFromStartAddress(destination); + if (block >= 0 && jo.enableBlocklink) + { + // It exists! Joy of joy! + B(blocks.GetBlock(block)->checkedEntry); + b->linkStatus[exit_num] = true; + } + else + { + ARMReg A = gpr.GetReg(false); + MOVI2R(A, destination); + STR(R9, A, STRUCT_OFF(PowerPC::ppcState, pc)); + MOVI2R(A, (u32)asm_routines.dispatcher); + B(A); + } +} + +void STACKALIGN JitArm::Run() +{ + CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; + pExecAddr(); +} + +void JitArm::SingleStep() +{ + CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; + pExecAddr(); +} + +void JitArm::Trace() +{ + char regs[500] = ""; + char fregs[750] = ""; + +#ifdef JIT_LOG_GPR + for (int i = 0; i < 32; i++) + { + char reg[50]; + sprintf(reg, "r%02d: %08x ", i, PowerPC::ppcState.gpr[i]); + strncat(regs, reg, 500); + } +#endif + +#ifdef JIT_LOG_FPR + for (int i = 0; i < 32; i++) + { + char reg[50]; + sprintf(reg, "f%02d: %016x ", i, riPS0(i)); + strncat(fregs, reg, 750); + } +#endif + + DEBUG_LOG(DYNA_REC, "JITARM PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s", + PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], + PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, + PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs); +} + +void JitArm::PrintDebug(UGeckoInstruction inst, u32 level) +{ + if (level > 0) + printf("Start: %08x OP '%s' Info\n", (u32)GetCodePtr(), PPCTables::GetInstructionName(inst)); + if (level > 1) + { + GekkoOPInfo* Info = GetOpInfo(inst.hex); + printf("\tOuts\n"); + if (Info->flags & FL_OUT_A) + printf("\t-OUT_A: %x\n", inst.RA); + if(Info->flags & FL_OUT_D) + printf("\t-OUT_D: %x\n", inst.RD); + printf("\tIns\n"); + // A, AO, B, C, S + if(Info->flags & FL_IN_A) + printf("\t-IN_A: %x\n", inst.RA); + if(Info->flags & FL_IN_A0) + printf("\t-IN_A0: %x\n", inst.RA); + if(Info->flags & FL_IN_B) + printf("\t-IN_B: %x\n", inst.RB); + if(Info->flags & FL_IN_C) + printf("\t-IN_C: %x\n", inst.RC); + if(Info->flags & FL_IN_S) + printf("\t-IN_S: %x\n", inst.RS); + } +} + +void STACKALIGN JitArm::Jit(u32 em_address) +{ + if (GetSpaceLeft() < 0x10000 || blocks.IsFull() || Core::g_CoreStartupParameter.bJITNoBlockCache) + { + ClearCache(); + } + + int block_num = blocks.AllocateBlock(em_address); + JitBlock *b = blocks.GetBlock(block_num); + const u8* BlockPtr = DoJit(em_address, &code_buffer, b); + blocks.FinalizeBlock(block_num, jo.enableBlocklink, BlockPtr); +} +void JitArm::Break(UGeckoInstruction inst) +{ + BKPT(0x4444); +} + +const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlock *b) +{ + int blockSize = code_buf->GetSize(); + + // Memory exception on instruction fetch + bool memory_exception = false; + + // A broken block is a block that does not end in a branch + bool broken_block = false; + + if (Core::g_CoreStartupParameter.bEnableDebugging) + { + // Comment out the following to disable breakpoints (speed-up) + blockSize = 1; + broken_block = true; + Trace(); + } + + if (em_address == 0) + { + Core::SetState(Core::CORE_PAUSE); + PanicAlert("ERROR: Compiling at 0. LR=%08x CTR=%08x", LR, CTR); + } + + if (Core::g_CoreStartupParameter.bMMU && (em_address & JIT_ICACHE_VMEM_BIT)) + { + if (!Memory::TranslateAddress(em_address, Memory::FLAG_OPCODE)) + { + // Memory exception occurred during instruction fetch + memory_exception = true; + } + } + + + int size = 0; + js.isLastInstruction = false; + js.blockStart = em_address; + js.fifoBytesThisBlock = 0; + js.curBlock = b; + js.block_flags = 0; + js.cancel = false; + + // Analyze the block, collect all instructions it is made of (including inlining, + // if that is enabled), reorder instructions for optimal performance, and join joinable instructions. + u32 nextPC = em_address; + u32 merged_addresses[32]; + const int capacity_of_merged_addresses = sizeof(merged_addresses) / sizeof(merged_addresses[0]); + int size_of_merged_addresses = 0; + if (!memory_exception) + { + // If there is a memory exception inside a block (broken_block==true), compile up to that instruction. + nextPC = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses, capacity_of_merged_addresses, size_of_merged_addresses); + } + PPCAnalyst::CodeOp *ops = code_buf->codebuffer; + + const u8 *start = GetCodePtr(); + b->checkedEntry = start; + b->runCount = 0; + + // Downcount flag check, Only valid for linked blocks + { + FixupBranch skip = B_CC(CC_PL); + ARMABI_MOVI2M((u32)&PC, js.blockStart); + ARMReg rA = gpr.GetReg(false); + MOVI2R(rA, (u32)asm_routines.doTiming); + B(rA); + SetJumpTarget(skip); + } + + const u8 *normalEntry = GetCodePtr(); + b->normalEntry = normalEntry; + + if(ImHereDebug) + QuickCallFunction(R14, (void *)&ImHere); //Used to get a trace of the last few blocks before a crash, sometimes VERY useful + + if (js.fpa.any) + { + // This block uses FPU - needs to add FP exception bailout + ARMReg A = gpr.GetReg(); + ARMReg C = gpr.GetReg(); + Operand2 Shift(2, 10); // 1 << 13 + MOVI2R(C, js.blockStart); // R3 + LDR(A, R9, STRUCT_OFF(PowerPC::ppcState, msr)); + TST(A, Shift); + FixupBranch b1 = B_CC(CC_NEQ); + STR(R9, C, STRUCT_OFF(PowerPC::ppcState, pc)); + MOVI2R(A, (u32)asm_routines.fpException); + B(A); + SetJumpTarget(b1); + gpr.Unlock(A, C); + } + // Conditionally add profiling code. + if (Profiler::g_ProfileBlocks) { + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + MOVI2R(rA, (u32)&b->runCount); // Load in to register + LDR(rB, rA); // Load the actual value in to R11. + ADD(rB, rB, 1); // Add one to the value + STR(rA, rB); // Now store it back in the memory location + // get start tic + PROFILER_QUERY_PERFORMANCE_COUNTER(&b->ticStart); + gpr.Unlock(rA, rB); + } + gpr.Start(js.gpa); + fpr.Start(js.fpa); + js.downcountAmount = 0; + if (!Core::g_CoreStartupParameter.bEnableDebugging) + { + for (int i = 0; i < size_of_merged_addresses; ++i) + { + const u32 address = merged_addresses[i]; + js.downcountAmount += PatchEngine::GetSpeedhackCycles(address); + } + } + + js.skipnext = false; + js.blockSize = size; + js.compilerPC = nextPC; + // Translate instructions + for (int i = 0; i < (int)size; i++) + { + js.compilerPC = ops[i].address; + js.op = &ops[i]; + js.instructionNumber = i; + const GekkoOPInfo *opinfo = ops[i].opinfo; + js.downcountAmount += (opinfo->numCyclesMinusOne + 1); + + if (i == (int)size - 1) + { + // WARNING - cmp->branch merging will screw this up. + js.isLastInstruction = true; + js.next_inst = 0; + if (Profiler::g_ProfileBlocks) { + // CAUTION!!! push on stack regs you use, do your stuff, then pop + PROFILER_VPUSH; + // get end tic + PROFILER_QUERY_PERFORMANCE_COUNTER(&b->ticStop); + // tic counter += (end tic - start tic) + PROFILER_ADD_DIFF_LARGE_INTEGER(&b->ticCounter, &b->ticStop, &b->ticStart); + PROFILER_VPOP; + } + } + else + { + // help peephole optimizations + js.next_inst = ops[i + 1].inst; + js.next_compilerPC = ops[i + 1].address; + } + if (jo.optimizeGatherPipe && js.fifoBytesThisBlock >= 32) + { + js.fifoBytesThisBlock -= 32; + // TODO: This needs thunkmanager for ARM + //ARMABI_CallFunction(thunks.ProtectFunction((void *)&GPFifo::CheckGatherPipe, 0)); + } + if (Core::g_CoreStartupParameter.bEnableDebugging) + { + // Add run count + ARMReg RA = gpr.GetReg(); + ARMReg RB = gpr.GetReg(); + MOVI2R(RA, (u32)&opinfo->runCount); + LDR(RB, RA); + ADD(RB, RB, 1); + STR(RA, RB); + gpr.Unlock(RA, RB); + } + if (!ops[i].skip) + { + PrintDebug(ops[i].inst, 0); + if (js.memcheck && (opinfo->flags & FL_USE_FPU)) + { + // Don't do this yet + BKPT(0x7777); + } + JitArmTables::CompileInstruction(ops[i]); + if (js.memcheck && (opinfo->flags & FL_LOADSTORE)) + { + // Don't do this yet + BKPT(0x666); + } + } + } + if (memory_exception) + BKPT(0x500); + if (broken_block) + { + printf("Broken Block going to 0x%08x\n", nextPC); + WriteExit(nextPC, 0); + } + + b->flags = js.block_flags; + b->codeSize = (u32)(GetCodePtr() - normalEntry); + b->originalSize = size; + FlushIcache(); + return start; +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h new file mode 100644 index 0000000000..c736ae77a1 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -0,0 +1,186 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// ======================== +// See comments in Jit.cpp. +// ======================== + +// Mystery: Capcom vs SNK 800aa278 + +// CR flags approach: +// * Store that "N+Z flag contains CR0" or "S+Z flag contains CR3". +// * All flag altering instructions flush this +// * A flush simply does a conditional write to the appropriate CRx. +// * If flag available, branch code can become absolutely trivial. + +// Settings +// ---------- +#ifndef _JITARM_H +#define _JITARM_H +#include "../CPUCoreBase.h" +#include "../PPCAnalyst.h" +#include "JitArmCache.h" +#include "JitRegCache.h" +#include "JitFPRCache.h" +#include "JitAsm.h" +#include "../JitCommon/JitBase.h" + +// Use these to control the instruction selection +// #define INSTRUCTION_START Default(inst); return; +// #define INSTRUCTION_START PPCTables::CountInstruction(inst); +#define INSTRUCTION_START +#define JITDISABLE(type) \ + if (Core::g_CoreStartupParameter.bJITOff || \ + Core::g_CoreStartupParameter.bJIT##type##Off) \ + {Default(inst); return;} + +class JitArm : public JitBase, public ArmGen::ARMXCodeBlock +{ +private: + JitArmBlockCache blocks; + + JitArmAsmRoutineManager asm_routines; + + // TODO: Make arm specific versions of these, shouldn't be too hard to + // make it so we allocate some space at the start(?) of code generation + // and keep the registers in a cache. Will burn this bridge when we get to + // it. + ArmRegCache gpr; + ArmFPRCache fpr; + + PPCAnalyst::CodeBuffer code_buffer; + void DoDownCount(); + + void PrintDebug(UGeckoInstruction inst, u32 level); + + void Helper_UpdateCR1(ARMReg value); +public: + JitArm() : code_buffer(32000) {} + ~JitArm() {} + + void Init(); + void Shutdown(); + + // Jit! + + void Jit(u32 em_address); + const u8* DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlock *b); + + JitBaseBlockCache *GetBlockCache() { return &blocks; } + + const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx); + + bool IsInCodeSpace(u8 *ptr) { return IsInSpace(ptr); } + + void Trace(); + + void ClearCache(); + + const u8 *GetDispatcher() { + return asm_routines.dispatcher; + } + CommonAsmRoutinesBase *GetAsmRoutines() { + return &asm_routines; + } + + const char *GetName() { + return "JITARM"; + } + // Run! + + void Run(); + void SingleStep(); + + // Utilities for use by opcodes + + void WriteExit(u32 destination, int exit_num); + void WriteExitDestInR(ARMReg Reg); + void WriteRfiExitDestInR(ARMReg Reg); + void WriteExceptionExit(); + void WriteCallInterpreter(UGeckoInstruction _inst); + void Cleanup(); + + void GenerateRC(int cr = 0); + void ComputeRC(int cr = 0); + + // TODO: This shouldn't be here + void StoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset); + void LoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset); + + // OPCODES + void unknown_instruction(UGeckoInstruction _inst); + void Default(UGeckoInstruction _inst); + void DoNothing(UGeckoInstruction _inst); + void HLEFunction(UGeckoInstruction _inst); + + void DynaRunTable4(UGeckoInstruction _inst); + void DynaRunTable19(UGeckoInstruction _inst); + void DynaRunTable31(UGeckoInstruction _inst); + void DynaRunTable59(UGeckoInstruction _inst); + void DynaRunTable63(UGeckoInstruction _inst); + + // Breakin shit + void Break(UGeckoInstruction _inst); + // Branch + void bx(UGeckoInstruction _inst); + void bcx(UGeckoInstruction _inst); + void bclrx(UGeckoInstruction _inst); + void sc(UGeckoInstruction _inst); + void rfi(UGeckoInstruction _inst); + void bcctrx(UGeckoInstruction _inst); + + // Integer + void addi(UGeckoInstruction _inst); + void addis(UGeckoInstruction _inst); + void addx(UGeckoInstruction _inst); + void cmp (UGeckoInstruction _inst); + void cmpi(UGeckoInstruction _inst); + void cmpli(UGeckoInstruction _inst); + void negx(UGeckoInstruction _inst); + void mulli(UGeckoInstruction _inst); + void ori(UGeckoInstruction _inst); + void oris(UGeckoInstruction _inst); + void orx(UGeckoInstruction _inst); + void rlwimix(UGeckoInstruction _inst); + void rlwinmx(UGeckoInstruction _inst); + void extshx(UGeckoInstruction inst); + void extsbx(UGeckoInstruction inst); + + // System Registers + void mtmsr(UGeckoInstruction _inst); + void mtspr(UGeckoInstruction _inst); + void mfspr(UGeckoInstruction _inst); + + // LoadStore + void icbi(UGeckoInstruction _inst); + void lbz(UGeckoInstruction _inst); + void lhz(UGeckoInstruction _inst); + void lwz(UGeckoInstruction _inst); + void lwzx(UGeckoInstruction _inst); + void stw(UGeckoInstruction _inst); + void stwu(UGeckoInstruction _inst); + + // Floating point + void fabsx(UGeckoInstruction _inst); + void faddx(UGeckoInstruction _inst); + void fmrx(UGeckoInstruction _inst); + + // Floating point loadStore + void lfs(UGeckoInstruction _inst); +}; + +#endif // _JIT64_H diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp new file mode 100644 index 0000000000..296ca736a9 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp @@ -0,0 +1,46 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// Enable define below to enable oprofile integration. For this to work, +// it requires at least oprofile version 0.9.4, and changing the build +// system to link the Dolphin executable against libopagent. Since the +// dependency is a little inconvenient and this is possibly a slight +// performance hit, it's not enabled by default, but it's useful for +// locating performance issues. + +#include "../JitInterface.h" +#include "JitArmCache.h" + + +using namespace ArmGen; + + void JitArmBlockCache::WriteLinkBlock(u8* location, const u8* address) + { + ARMXEmitter emit(location); + emit.B(address); + } + void JitArmBlockCache::WriteDestroyBlock(const u8* location, u32 address) + { + ARMXEmitter emit((u8 *)location); + emit.MOVI2R(R10, (u32)&PC); + emit.MOVI2R(R11, address); + emit.MOVI2R(R12, (u32)jit->GetAsmRoutines()->dispatcher); + emit.STR(R10, R11); + emit.B(R12); + } + + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.h b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.h new file mode 100644 index 0000000000..103947d5ad --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.h @@ -0,0 +1,33 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _JITARMCACHE_H +#define _JITARMCACHE_H + +#include "../JitCommon/JitCache.h" + + +typedef void (*CompiledCode)(); + +class JitArmBlockCache : public JitBaseBlockCache +{ +private: + void WriteLinkBlock(u8* location, const u8* address); + void WriteDestroyBlock(const u8* location, u32 address); +}; + +#endif diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp new file mode 100644 index 0000000000..677dc238a8 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_BackPatch.cpp @@ -0,0 +1,164 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include + +#include "Common.h" + +#include "../../HW/Memmap.h" +#include "Jit.h" +#include "../JitCommon/JitBackpatch.h" +#include "StringUtil.h" + +#ifdef _M_X64 +static void BackPatchError(const std::string &text, u8 *codePtr, u32 emAddress) { + u64 code_addr = (u64)codePtr; + disassembler disasm; + char disbuf[256]; + memset(disbuf, 0, 256); +#ifdef _M_IX86 + disasm.disasm32(0, code_addr, codePtr, disbuf); +#else + disasm.disasm64(0, code_addr, codePtr, disbuf); +#endif + PanicAlert("%s\n\n" + "Error encountered accessing emulated address %08x.\n" + "Culprit instruction: \n%s\nat %#llx", + text.c_str(), emAddress, disbuf, code_addr); + return; +} +#endif + +// This generates some fairly heavy trampolines, but: +// 1) It's really necessary. We don't know anything about the context. +// 2) It doesn't really hurt. Only instructions that access I/O will get these, and there won't be +// that many of them in a typical program/game. +bool DisamLoadStore(const u32 inst, ARMReg &rD, u8 &accessSize, bool &Store) +{ + u8 op = (inst >> 20) & 0xFF; + printf("op: 0x%08x\n", op); + switch (op) + { + case 0x58: // STR + { + rD = (ARMReg)((inst >> 16) & 0xF); + Store = true; + accessSize = 32; + } + break; + case 0x59: // LDR + { + rD = (ARMReg)((inst >> 16) & 0xF); + Store = false; + accessSize = 32; + } + break; + case 0x05: // LDRH + { + rD = (ARMReg)((inst >> 16) & 0xF); + Store = false; + accessSize = 16; + } + break; + case 0x45 + 0x18: // LDRB + { + rD = (ARMReg)((inst >> 16) & 0xF); + Store = false; + accessSize = 8; + } + break; + case 0x44 + 0x18: // STRB + default: + return false; + } + return true; +} +const u8 *JitArm::BackPatch(u8 *codePtr, int accessType, u32 emAddress, void *ctx_void) +{ + // TODO: This ctx needs to be filled with our information + CONTEXT *ctx = (CONTEXT *)ctx_void; + + // We need to get the destination register before we start + u32 Value = *(u32*)codePtr; + ARMReg rD; + u8 accessSize; + bool Store; + + if (!DisamLoadStore(Value, rD, accessSize, Store)) + { + printf("Invalid backpatch at location 0x%08x(0x%08x)\n", ctx->reg_pc, Value); + exit(0); + } + + if (Store) + { + const u32 ARMREGOFFSET = 4 * 7; + ARMXEmitter emitter(codePtr - ARMREGOFFSET); + switch (accessSize) + { + case 8: // 8bit + //emitter.MOVI2R(R14, (u32)&Memory::Write_U8, false); // 1-2 + return 0; + break; + case 16: // 16bit + //emitter.MOVI2R(R14, (u32)&Memory::Write_U16, false); // 1-2 + return 0; + break; + case 32: // 32bit + emitter.MOVI2R(R14, (u32)&Memory::Write_U32, false); // 1-2 + break; + } + emitter.PUSH(4, R0, R1, R2, R3); // 3 + emitter.MOV(R0, rD); // Value - 4 + emitter.MOV(R1, R10); // Addr- 5 + emitter.BL(R14); // 6 + emitter.POP(4, R0, R1, R2, R3); // 7 + emitter.NOP(1); // 8 + u32 newPC = ctx->reg_pc - (ARMREGOFFSET + 4 * 4); + ctx->reg_pc = newPC; + emitter.FlushIcache(); + return codePtr; + } + else + { + const u32 ARMREGOFFSET = 4 * 6; + ARMXEmitter emitter(codePtr - ARMREGOFFSET); + switch (accessSize) + { + case 8: // 8bit + emitter.MOVI2R(R14, (u32)&Memory::Read_U8, false); // 2 + break; + case 16: // 16bit + emitter.MOVI2R(R14, (u32)&Memory::Read_U16, false); // 2 + break; + case 32: // 32bit + emitter.MOVI2R(R14, (u32)&Memory::Read_U32, false); // 2 + break; + } + emitter.PUSH(4, R0, R1, R2, R3); // 3 + emitter.MOV(R0, R10); // 4 + emitter.BL(R14); // 5 + emitter.MOV(R14, R0); // 6 + emitter.POP(4, R0, R1, R2, R3); // 7 + emitter.MOV(rD, R14); // 8 + ctx->reg_pc -= ARMREGOFFSET + (4 * 4); + emitter.FlushIcache(); + return codePtr; + } + return 0; +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp new file mode 100644 index 0000000000..27d5c23141 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp @@ -0,0 +1,347 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#include "Common.h" +#include "Thunk.h" + +#include "../../Core.h" +#include "../PowerPC.h" +#include "../../CoreTiming.h" +#include "../PPCTables.h" +#include "ArmEmitter.h" + +#include "Jit.h" +#include "JitRegCache.h" +#include "JitAsm.h" + +// The branches are known good, or at least reasonably good. +// No need for a disable-mechanism. + +// If defined, clears CR0 at blr and bl-s. If the assumption that +// flags never carry over between functions holds, then the task for +// an optimizer becomes much easier. + +// #define ACID_TEST + +// Zelda and many more games seem to pass the Acid Test. + + +using namespace ArmGen; +void JitArm::sc(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Branch) + + gpr.Flush(); + fpr.Flush(); + + ARMABI_MOVI2M((u32)&PC, js.compilerPC + 4); // Destroys R12 and R14 + ARMReg rA = gpr.GetReg(); + LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + ORR(rA, rA, EXCEPTION_SYSCALL); + STR(R9, rA, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + gpr.Unlock(rA); + + WriteExceptionExit(); +} + +void JitArm::rfi(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Branch) + + gpr.Flush(); + fpr.Flush(); + + // See Interpreter rfi for details + const u32 mask = 0x87C0FFFF; + const u32 clearMSR13 = 0xFFFBFFFF; // Mask used to clear the bit MSR[13] + // MSR = ((MSR & ~mask) | (SRR1 & mask)) & clearMSR13; + // R0 = MSR location + // R1 = MSR contents + // R2 = Mask + // R3 = Mask + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + ARMReg rC = gpr.GetReg(); + ARMReg rD = gpr.GetReg(); + MOVI2R(rA, (u32)&MSR); + MOVI2R(rB, (~mask) & clearMSR13); + MOVI2R(rC, mask & clearMSR13); + + LDR(rD, rA); + + AND(rD, rD, rB); // rD = Masked MSR + STR(rA, rD); + + MOVI2R(rB, (u32)&SRR1); + LDR(rB, rB); // rB contains SRR1 here + + AND(rB, rB, rC); // rB contains masked SRR1 here + ORR(rB, rD, rB); // rB = Masked MSR OR masked SRR1 + + STR(rA, rB); // STR rB in to rA + + MOVI2R(rA, (u32)&SRR0); + LDR(rA, rA); + + gpr.Unlock(rB, rC, rD); + WriteRfiExitDestInR(rA); // rA gets unlocked here + //AND(32, M(&MSR), Imm32((~mask) & clearMSR13)); + //MOV(32, R(EAX), M(&SRR1)); + //AND(32, R(EAX), Imm32(mask & clearMSR13)); + //OR(32, M(&MSR), R(EAX)); + // NPC = SRR0; + //MOV(32, R(EAX), M(&SRR0)); + //WriteRfiExitDestInEAX(); +} + +void JitArm::bx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Branch) + // We must always process the following sentence + // even if the blocks are merged by PPCAnalyst::Flatten(). + if (inst.LK) + ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + + // If this is not the last instruction of a block, + // we will skip the rest process. + // Because PPCAnalyst::Flatten() merged the blocks. + if (!js.isLastInstruction) { + return; + } + + gpr.Flush(); + fpr.Flush(); + + u32 destination; + if (inst.AA) + destination = SignExt26(inst.LI << 2); + else + destination = js.compilerPC + SignExt26(inst.LI << 2); + #ifdef ACID_TEST + // TODO: Not implemented yet. + //if (inst.LK) + //AND(32, M(&PowerPC::ppcState.cr), Imm32(~(0xFF000000))); + #endif + if (destination == js.compilerPC) + { + //PanicAlert("Idle loop detected at %08x", destination); + // CALL(ProtectFunction(&CoreTiming::Idle, 0)); + // JMP(Asm::testExceptions, true); + // make idle loops go faster + js.downcountAmount += 8; + } + WriteExit(destination, 0); +} + +void JitArm::bcx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Branch) + // USES_CR + _assert_msg_(DYNA_REC, js.isLastInstruction, "bcx not last instruction of block"); + + gpr.Flush(); + fpr.Flush(); + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + FixupBranch pCTRDontBranch; + if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) // Decrement and test CTR + { + MOVI2R(rA, (u32)&CTR); + LDR(rB, rA); + SUBS(rB, rB, 1); + STR(rA, rB); + + //SUB(32, M(&CTR), Imm8(1)); + if (inst.BO & BO_BRANCH_IF_CTR_0) + pCTRDontBranch = B_CC(CC_NEQ); + else + pCTRDontBranch = B_CC(CC_EQ); + } + + FixupBranch pConditionDontBranch; + if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit + { + LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + TST(rA, 8 >> (inst.BI & 3)); + + //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3))); + if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch + pConditionDontBranch = B_CC(CC_EQ); // Zero + else + pConditionDontBranch = B_CC(CC_NEQ); // Not Zero + } + gpr.Unlock(rA, rB); + if (inst.LK) + ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); // Careful, destroys R14, R12 + + u32 destination; + if(inst.AA) + destination = SignExt16(inst.BD << 2); + else + destination = js.compilerPC + SignExt16(inst.BD << 2); + WriteExit(destination, 0); + + if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) + SetJumpTarget( pConditionDontBranch ); + if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) + SetJumpTarget( pCTRDontBranch ); + + WriteExit(js.compilerPC + 4, 1); +} +void JitArm::bcctrx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Branch) + + gpr.Flush(); + fpr.Flush(); + + // bcctrx doesn't decrement and/or test CTR + _dbg_assert_msg_(POWERPC, inst.BO_2 & BO_DONT_DECREMENT_FLAG, "bcctrx with decrement and test CTR option is invalid!"); + + if (inst.BO_2 & BO_DONT_CHECK_CONDITION) + { + // BO_2 == 1z1zz -> b always + + //NPC = CTR & 0xfffffffc; + if(inst.LK_3) + ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + MOVI2R(rA, (u32)&CTR); + MVN(rB, 0x3); // 0xFFFFFFFC + LDR(rA, rA); + AND(rA, rA, rB); + gpr.Unlock(rB); + WriteExitDestInR(rA); + } + else + { + // Rare condition seen in (just some versions of?) Nintendo's NES Emulator + + // BO_2 == 001zy -> b if false + // BO_2 == 011zy -> b if true + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + + LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + TST(rA, 8 >> (inst.BI & 3)); + CCFlags branch; + if (inst.BO_2 & BO_BRANCH_IF_TRUE) + branch = CC_EQ; + else + branch = CC_NEQ; + FixupBranch b = B_CC(branch); + + MOVI2R(rA, (u32)&CTR); + LDR(rA, rA); + MVN(rB, 0x3); // 0xFFFFFFFC + AND(rA, rA, rB); + + if (inst.LK_3){ + ARMReg rC = gpr.GetReg(false); + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rB, (u32)&LR); + MOVI2R(rC, Jumpto); + STR(rB, rC); + //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + } + gpr.Unlock(rB); // rA gets unlocked in WriteExitDestInR + WriteExitDestInR(rA); + + SetJumpTarget(b); + WriteExit(js.compilerPC + 4, 1); + } +} +void JitArm::bclrx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Branch) + if (!js.isLastInstruction && + (inst.BO & (1 << 4)) && (inst.BO & (1 << 2))) { + if (inst.LK) + { + ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + } + return; + } + gpr.Flush(); + fpr.Flush(); + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + FixupBranch pCTRDontBranch; + if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) // Decrement and test CTR + { + MOVI2R(rA, (u32)&CTR); + LDR(rB, rA); + SUBS(rB, rB, 1); + STR(rA, rB); + + //SUB(32, M(&CTR), Imm8(1)); + if (inst.BO & BO_BRANCH_IF_CTR_0) + pCTRDontBranch = B_CC(CC_NEQ); + else + pCTRDontBranch = B_CC(CC_EQ); + } + + FixupBranch pConditionDontBranch; + if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit + { + LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + TST(rA, 8 >> (inst.BI & 3)); + //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3))); + if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch + pConditionDontBranch = B_CC(CC_EQ); // Zero + else + pConditionDontBranch = B_CC(CC_NEQ); // Not Zero + } + + // This below line can be used to prove that blr "eats flags" in practice. + // This observation will let us do a lot of fun observations. + #ifdef ACID_TEST + // TODO: Not yet implemented + // AND(32, M(&PowerPC::ppcState.cr), Imm32(~(0xFF000000))); + #endif + + //MOV(32, R(EAX), M(&LR)); + //AND(32, R(EAX), Imm32(0xFFFFFFFC)); + MOVI2R(rA, (u32)&LR); + MVN(rB, 0x3); // 0xFFFFFFFC + LDR(rA, rA); + AND(rA, rA, rB); + if (inst.LK){ + ARMReg rC = gpr.GetReg(false); + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rB, (u32)&LR); + MOVI2R(rC, Jumpto); + STR(rB, rC); + //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + } + gpr.Unlock(rB); // rA gets unlocked in WriteExitDestInR + WriteExitDestInR(rA); + + if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) + SetJumpTarget( pConditionDontBranch ); + if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) + SetJumpTarget( pCTRDontBranch ); + WriteExit(js.compilerPC + 4, 1); +} diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp new file mode 100644 index 0000000000..fe4c0e3f22 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_FloatingPoint.cpp @@ -0,0 +1,80 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "Thunk.h" + +#include "../../Core.h" +#include "../PowerPC.h" +#include "../../ConfigManager.h" +#include "../../CoreTiming.h" +#include "../PPCTables.h" +#include "ArmEmitter.h" +#include "../../HW/Memmap.h" + + +#include "Jit.h" +#include "JitRegCache.h" +#include "JitFPRCache.h" +#include "JitAsm.h" + +void JitArm::Helper_UpdateCR1(ARMReg value) +{ + // Should just update exception flags, not do any compares. + PanicAlert("CR1"); +} + +void JitArm::fabsx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + + ARMReg vD = fpr.R0(inst.FD); + ARMReg vB = fpr.R0(inst.FB); + + VABS(vD, vB); + + if (inst.Rc) Helper_UpdateCR1(vD); +} + +void JitArm::faddx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + + ARMReg vD = fpr.R0(inst.FD); + ARMReg vA = fpr.R0(inst.FA); + ARMReg vB = fpr.R0(inst.FB); + + VADD(vD, vA, vB); + if (inst.Rc) Helper_UpdateCR1(vD); +} + +void JitArm::fmrx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(FloatingPoint) + Default(inst); return; + + ARMReg vD = fpr.R0(inst.FD); + ARMReg vB = fpr.R0(inst.FB); + + VMOV(vD, vB); + + if (inst.Rc) Helper_UpdateCR1(vD); +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp new file mode 100644 index 0000000000..63c96b21fd --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -0,0 +1,297 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#include "Common.h" +#include "Thunk.h" + +#include "../../Core.h" +#include "../PowerPC.h" +#include "../../CoreTiming.h" +#include "../PPCTables.h" +#include "ArmEmitter.h" + +#include "Jit.h" +#include "JitRegCache.h" +#include "JitAsm.h" +extern u32 Helper_Mask(u8 mb, u8 me); +// ADDI and RLWINMX broken for now + +// Assumes that Sign and Zero flags were set by the last operation. Preserves all flags and registers. +// Jit64 ComputerRC is signed +// JIT64 GenerateRC is unsigned +void JitArm::GenerateRC(int cr) { + ARMReg rB = gpr.GetReg(); + + MOV(rB, 0x4); // Result > 0 + SetCC(CC_EQ); MOV(rB, 0x2); // Result == 0 + SetCC(CC_MI); MOV(rB, 0x8); // Result < 0 + SetCC(); + + STRB(R9, rB, STRUCT_OFF(PowerPC::ppcState, cr_fast) + cr); + gpr.Unlock(rB); +} +void JitArm::ComputeRC(int cr) { + ARMReg rB = gpr.GetReg(); + + MOV(rB, 0x2); // Result == 0 + SetCC(CC_LT); MOV(rB, 0x8); // Result < 0 + SetCC(CC_GT); MOV(rB, 0x4); // Result > 0 + SetCC(); + + STRB(R9, rB, STRUCT_OFF(PowerPC::ppcState, cr_fast) + cr); + gpr.Unlock(rB); +} + +void JitArm::addi(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RD = gpr.R(inst.RD); + + if (inst.RA) + { + ARMReg rA = gpr.GetReg(false); + ARMReg RA = gpr.R(inst.RA); + MOVI2R(rA, (u32)inst.SIMM_16); + ADD(RD, RA, rA); + } + else + MOVI2R(RD, inst.SIMM_16); +} +void JitArm::addis(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RD = gpr.R(inst.RD); + if (inst.RA) + { + ARMReg rA = gpr.GetReg(false); + ARMReg RA = gpr.R(inst.RA); + MOVI2R(rA, inst.SIMM_16 << 16); + ADD(RD, RA, rA); + } + else + MOVI2R(RD, inst.SIMM_16 << 16); +} +void JitArm::addx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RA = gpr.R(inst.RA); + ARMReg RB = gpr.R(inst.RB); + ARMReg RD = gpr.R(inst.RD); + ADDS(RD, RA, RB); + if (inst.Rc) ComputeRC(); +} +// Wrong - 28/10/2012 +void JitArm::mulli(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + Default(inst); return; + ARMReg RA = gpr.R(inst.RA); + ARMReg RD = gpr.R(inst.RD); + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, inst.SIMM_16); + MUL(RD, RA, rA); + gpr.Unlock(rA); +} +void JitArm::ori(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RA = gpr.R(inst.RA); + ARMReg RS = gpr.R(inst.RS); + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, inst.UIMM); + ORR(RA, RS, rA); + gpr.Unlock(rA); +} +void JitArm::oris(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RA = gpr.R(inst.RA); + ARMReg RS = gpr.R(inst.RS); + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, inst.UIMM << 16); + ORR(RA, RS, rA); + gpr.Unlock(rA); +} +void JitArm::orx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg rA = gpr.R(inst.RA); + ARMReg rS = gpr.R(inst.RS); + ARMReg rB = gpr.R(inst.RB); + ORRS(rA, rS, rB); + if (inst.Rc) + ComputeRC(); +} + +void JitArm::extshx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + ARMReg RA, RS; + RA = gpr.R(inst.RA); + RS = gpr.R(inst.RS); + SXTH(RA, RS); + if (inst.Rc){ + CMP(RA, 0); + ComputeRC(); + } +} +void JitArm::extsbx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + ARMReg RA, RS; + RA = gpr.R(inst.RA); + RS = gpr.R(inst.RS); + SXTB(RA, RS); + if (inst.Rc){ + CMP(RA, 0); + ComputeRC(); + } +} +void JitArm::cmp (UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RA = gpr.R(inst.RA); + ARMReg RB = gpr.R(inst.RB); + int crf = inst.CRFD; + CMP(RA, RB); + ComputeRC(crf); +} +void JitArm::cmpi(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RA = gpr.R(inst.RA); + ARMReg rA = gpr.GetReg(); + int crf = inst.CRFD; + MOVI2R(rA, inst.SIMM_16); + CMP(RA, rA); + gpr.Unlock(rA); + ComputeRC(crf); +} +void JitArm::cmpli(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + ARMReg RA = gpr.R(inst.RA); + ARMReg rA = gpr.GetReg(); + int crf = inst.CRFD; + MOVI2R(rA, (u32)inst.UIMM); + CMP(RA, rA); + + // Unsigned GenerateRC() + + MOV(rA, 0x2); // Result == 0 + SetCC(CC_LO); MOV(rA, 0x8); // Result < 0 + SetCC(CC_HI); MOV(rA, 0x4); // Result > 0 + SetCC(); + + STRB(R9, rA, STRUCT_OFF(PowerPC::ppcState, cr_fast) + crf); + gpr.Unlock(rA); + +} +// Wrong - 27/10/2012 +void JitArm::negx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + Default(inst);return; + ARMReg RA = gpr.R(inst.RA); + ARMReg RD = gpr.R(inst.RD); + + RSBS(RD, RA, 0); + if (inst.Rc) + { + GenerateRC(); + } + if (inst.OE) + { + BKPT(0x333); + //GenerateOverflow(); + } +} +void JitArm::rlwimix(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + u32 mask = Helper_Mask(inst.MB,inst.ME); + ARMReg RA = gpr.R(inst.RA); + ARMReg RS = gpr.R(inst.RS); + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + MOVI2R(rA, mask); + + Operand2 Shift(32 - inst.SH, ST_ROR, RS); // This rotates left, while ARM has only rotate right, so swap it. + if (inst.Rc) + { + BIC (rB, RA, rA); // RA & ~mask + AND (rA, rA, Shift); + ORRS(RA, rB, rA); + GenerateRC(); + } + else + { + BIC (rB, RA, rA); // RA & ~mask + AND (rA, rA, Shift); + ORR(RA, rB, rA); + } + gpr.Unlock(rA, rB); +} +void JitArm::rlwinmx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(Integer) + + u32 mask = Helper_Mask(inst.MB,inst.ME); + ARMReg RA = gpr.R(inst.RA); + ARMReg RS = gpr.R(inst.RS); + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, mask); + + Operand2 Shift(32 - inst.SH, ST_ROR, RS); // This rotates left, while ARM has only rotate right, so swap it. + if (inst.Rc) + { + ANDS(RA, rA, Shift); + GenerateRC(); + } + else + AND (RA, rA, Shift); + gpr.Unlock(rA); + + //m_GPR[inst.RA] = _rotl(m_GPR[inst.RS],inst.SH) & mask; +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp new file mode 100644 index 0000000000..80c8a96cbb --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp @@ -0,0 +1,414 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "Thunk.h" + +#include "../../Core.h" +#include "../PowerPC.h" +#include "../../ConfigManager.h" +#include "../../CoreTiming.h" +#include "../PPCTables.h" +#include "ArmEmitter.h" +#include "../../HW/Memmap.h" + + +#include "Jit.h" +#include "JitRegCache.h" +#include "JitAsm.h" + +#ifdef ANDROID +#define FASTMEM 0 +#else +#define FASTMEM 0 +#endif +void JitArm::stw(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg RS = gpr.R(inst.RS); +#if FASTMEM + // R10 contains the dest address + ARMReg Value = R11; + ARMReg RA; + if (inst.RA) + RA = gpr.R(inst.RA); + MOV(Value, RS); + if (inst.RA) + { + MOVI2R(R10, inst.SIMM_16, false); + ADD(R10, R10, RA); + } + else + { + MOVI2R(R10, (u32)inst.SIMM_16, false); + NOP(1); + } + StoreFromReg(R10, Value, 32, 0); +#else + ARMReg ValueReg = gpr.GetReg(); + ARMReg Addr = gpr.GetReg(); + ARMReg Function = gpr.GetReg(); + + MOV(ValueReg, RS); + if (inst.RA) + { + MOVI2R(Addr, inst.SIMM_16); + ARMReg RA = gpr.R(inst.RA); + ADD(Addr, Addr, RA); + } + else + MOVI2R(Addr, (u32)inst.SIMM_16); + + MOVI2R(Function, (u32)&Memory::Write_U32); + PUSH(4, R0, R1, R2, R3); + MOV(R0, ValueReg); + MOV(R1, Addr); + BL(Function); + POP(4, R0, R1, R2, R3); + gpr.Unlock(ValueReg, Addr, Function); +#endif +} +void JitArm::stwu(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg RA = gpr.R(inst.RA); + ARMReg RS = gpr.R(inst.RS); + ARMReg ValueReg = gpr.GetReg(); + ARMReg Addr = gpr.GetReg(); + ARMReg Function = gpr.GetReg(); + + MOVI2R(Addr, inst.SIMM_16); + ADD(Addr, Addr, RA); + + // Check and set the update before writing since calling a function can + // mess with the "special registers R11+ which may cause some issues. + LDR(Function, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + CMP(Function, EXCEPTION_DSI); + FixupBranch DoNotWrite = B_CC(CC_EQ); + MOV(RA, Addr); + SetJumpTarget(DoNotWrite); + + MOV(ValueReg, RS); + + MOVI2R(Function, (u32)&Memory::Write_U32); + PUSH(4, R0, R1, R2, R3); + MOV(R0, ValueReg); + MOV(R1, Addr); + BL(Function); + POP(4, R0, R1, R2, R3); + + gpr.Unlock(ValueReg, Addr, Function); +} +void JitArm::StoreFromReg(ARMReg dest, ARMReg value, int accessSize, s32 offset) +{ + ARMReg rA = gpr.GetReg(); + + // All this gets replaced on backpatch + MOVI2R(rA, Memory::MEMVIEW32_MASK, false); // 1-2 + AND(dest, dest, rA); // 3 + MOVI2R(rA, (u32)Memory::base, false); // 4-5 + ADD(dest, dest, rA); // 6 + switch (accessSize) + { + case 32: + REV(value, value); // 7 + break; + case 16: + REV16(value, value); + break; + case 8: + NOP(1); + break; + } + switch (accessSize) + { + case 32: + STR(dest, value); // 8 + break; + case 16: + // Not implemented + break; + case 8: + // Not implemented + break; + } + gpr.Unlock(rA); +} +void JitArm::LoadToReg(ARMReg dest, ARMReg addr, int accessSize, s32 offset) +{ + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, offset, false); // -3 + ADD(addr, addr, rA); // - 1 + + // All this gets replaced on backpatch + MOVI2R(rA, Memory::MEMVIEW32_MASK, false); // 2 + AND(addr, addr, rA); // 3 + MOVI2R(rA, (u32)Memory::base, false); // 5 + ADD(addr, addr, rA); // 6 + switch (accessSize) + { + case 32: + LDR(dest, addr); // 7 + break; + case 16: + LDRH(dest, addr); + break; + case 8: + LDRB(dest, addr); + break; + } + switch (accessSize) + { + case 32: + REV(dest, dest); // 9 + break; + case 16: + REV16(dest, dest); + break; + case 8: + NOP(1); + break; + + } + gpr.Unlock(rA); +} +void JitArm::lbz(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + ARMReg RD = gpr.R(inst.RD); + LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); +#if FASTMEM + // Backpatch route + // Gets loaded in to RD + // Address is in R10 + gpr.Unlock(rA, rB); + if (inst.RA) + { + ARMReg RA = gpr.R(inst.RA); + MOV(R10, RA); // - 4 + } + else + MOV(R10, 0); // - 4 + LoadToReg(RD, R10, 8, inst.SIMM_16); +#else + + if (inst.RA) + { + MOVI2R(rB, inst.SIMM_16); + ARMReg RA = gpr.R(inst.RA); + ADD(rB, rB, RA); + } + else + MOVI2R(rB, (u32)inst.SIMM_16); + + MOVI2R(rA, (u32)&Memory::Read_U8); + PUSH(4, R0, R1, R2, R3); + MOV(R0, rB); + BL(rA); + MOV(rA, R0); + POP(4, R0, R1, R2, R3); + MOV(RD, rA); + gpr.Unlock(rA, rB); +#endif + SetJumpTarget(DoNotLoad); +} + +void JitArm::lhz(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + ARMReg RD = gpr.R(inst.RD); + LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); +#if 0 // FASTMEM + // Backpatch route + // Gets loaded in to RD + // Address is in R10 + gpr.Unlock(rA, rB); + if (inst.RA) + { + ARMReg RA = gpr.R(inst.RA); + printf("lhz jump to here: 0x%08x\n", (u32)GetCodePtr()); + MOV(R10, RA); // - 4 + } + else + { + printf("lhz jump to here: 0x%08x\n", (u32)GetCodePtr()); + MOV(R10, 0); // - 4 + } + LoadToReg(RD, R10, 16, (u32)inst.SIMM_16); +#else + + if (inst.RA) + { + MOVI2R(rB, inst.SIMM_16); + ARMReg RA = gpr.R(inst.RA); + ADD(rB, rB, RA); + } + else + MOVI2R(rB, (u32)inst.SIMM_16); + + MOVI2R(rA, (u32)&Memory::Read_U16); + PUSH(4, R0, R1, R2, R3); + MOV(R0, rB); + BL(rA); + MOV(rA, R0); + POP(4, R0, R1, R2, R3); + MOV(RD, rA); + gpr.Unlock(rA, rB); +#endif + SetJumpTarget(DoNotLoad); +} +void JitArm::lwz(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + ARMReg RD = gpr.R(inst.RD); + LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); + +#if FASTMEM + // Backpatch route + // Gets loaded in to RD + // Address is in R10 + gpr.Unlock(rA, rB); + if (inst.RA) + { + ARMReg RA = gpr.R(inst.RA); + MOV(R10, RA); // - 4 + } + else + MOV(R10, 0); // - 4 + LoadToReg(RD, R10, 32, (u32)inst.SIMM_16); +#else + if (inst.RA) + { + MOVI2R(rB, inst.SIMM_16); + ARMReg RA = gpr.R(inst.RA); + ADD(rB, rB, RA); + } + else + MOVI2R(rB, (u32)inst.SIMM_16); + + MOVI2R(rA, (u32)&Memory::Read_U32); + PUSH(4, R0, R1, R2, R3); + MOV(R0, rB); + BL(rA); + MOV(rA, R0); + POP(4, R0, R1, R2, R3); + MOV(RD, rA); + gpr.Unlock(rA, rB); +#endif + SetJumpTarget(DoNotLoad); + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && + (inst.hex & 0xFFFF0000) == 0x800D0000 && + (Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 || + (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) && + Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8) + { + gpr.Flush(); + fpr.Flush(); + + // if it's still 0, we can wait until the next event + TST(RD, RD); + FixupBranch noIdle = B_CC(CC_NEQ); + rA = gpr.GetReg(); + + MOVI2R(rA, (u32)&PowerPC::OnIdle); + MOVI2R(R0, PowerPC::ppcState.gpr[inst.RA] + (s32)(s16)inst.SIMM_16); + BL(rA); + + gpr.Unlock(rA); + WriteExceptionExit(); + + SetJumpTarget(noIdle); + + //js.compilerPC += 8; + return; + } +} +void JitArm::lwzx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStore) + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + + ARMReg RB = gpr.R(inst.RB); + ARMReg RD = gpr.R(inst.RD); + LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); +#if FASTMEM + // Backpatch route + // Gets loaded in to RD + // Address is in R10 + gpr.Unlock(rA, rB); + if (inst.RA) + { + ARMReg RA = gpr.R(inst.RA); + ADD(R10, RA, RB); // - 4 + } + else + MOV(R10, RB); // -4 + LoadToReg(RD, R10, 32, 0); +#else + if (inst.RA) + { + ARMReg RA = gpr.R(inst.RA); + ADD(rB, RA, RB); + } + else + MOV(rB, RB); + + MOVI2R(rA, (u32)&Memory::Read_U32); + PUSH(4, R0, R1, R2, R3); + MOV(R0, rB); + BL(rA); + MOV(rA, R0); + POP(4, R0, R1, R2, R3); + MOV(RD, rA); + gpr.Unlock(rA, rB); +#endif + SetJumpTarget(DoNotLoad); + //// u32 temp = Memory::Read_U32(_inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB]); +} +void JitArm::icbi(UGeckoInstruction inst) +{ + Default(inst); + WriteExit(js.compilerPC + 4, 0); +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp new file mode 100644 index 0000000000..d9e320ab22 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -0,0 +1,72 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "Thunk.h" + +#include "../../Core.h" +#include "../PowerPC.h" +#include "../../ConfigManager.h" +#include "../../CoreTiming.h" +#include "../PPCTables.h" +#include "ArmEmitter.h" +#include "../../HW/Memmap.h" + + +#include "Jit.h" +#include "JitRegCache.h" +#include "JitFPRCache.h" +#include "JitAsm.h" + +void JitArm::lfs(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(LoadStoreFloating) + Default(inst); return; + + ARMReg rA = gpr.GetReg(); + ARMReg rB = gpr.GetReg(); + LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + CMP(rA, EXCEPTION_DSI); + FixupBranch DoNotLoad = B_CC(CC_EQ); + + if (inst.RA) + { + MOVI2R(rB, inst.SIMM_16); + ARMReg RA = gpr.R(inst.RA); + ADD(rB, rB, RA); + } + else + MOVI2R(rB, (u32)inst.SIMM_16); + + MOVI2R(rA, (u32)&Memory::Read_U32); + PUSH(4, R0, R1, R2, R3); + MOV(R0, rB); + BL(rA); + MOV(rA, R0); + POP(4, R0, R1, R2, R3); + + ARMReg v0 = fpr.R0(inst.FD, false); + ARMReg v1 = fpr.R1(inst.FD, false); + + VMOV(v0, rA, false); + VMOV(v1, rA, false); + + gpr.Unlock(rA, rB); + SetJumpTarget(DoNotLoad); +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp new file mode 100644 index 0000000000..a99114df67 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp @@ -0,0 +1,111 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#include "Common.h" +#include "Thunk.h" + +#include "../../Core.h" +#include "../PowerPC.h" +#include "../../CoreTiming.h" +#include "../PPCTables.h" +#include "ArmEmitter.h" + +#include "Jit.h" +#include "JitRegCache.h" +#include "JitAsm.h" + +void JitArm::mtspr(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(SystemRegisters) + + u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F); + ARMReg RD = gpr.R(inst.RD); + + switch (iIndex) + { + case SPR_LR: + case SPR_CTR: + case SPR_XER: + // These are safe to do the easy way, see the bottom of this function. + break; + + case SPR_GQR0: + case SPR_GQR0 + 1: + case SPR_GQR0 + 2: + case SPR_GQR0 + 3: + case SPR_GQR0 + 4: + case SPR_GQR0 + 5: + case SPR_GQR0 + 6: + case SPR_GQR0 + 7: + // Prevent recompiler from compiling in old quantizer values. + // If the value changed, destroy all blocks using this quantizer + // This will create a little bit of block churn, but hopefully not too bad. + { + /* + MOV(32, R(EAX), M(&PowerPC::ppcState.spr[iIndex])); // Load old value + CMP(32, R(EAX), gpr.R(inst.RD)); + FixupBranch skip_destroy = J_CC(CC_E, false); + int gqr = iIndex - SPR_GQR0; + ABI_CallFunctionC(ProtectFunction(&Jit64::DestroyBlocksWithFlag, 1), (u32)BLOCK_USE_GQR0 << gqr); + SetJumpTarget(skip_destroy);*/ + } + // TODO - break block if quantizers are written to. + default: + Default(inst); + return; + } + + // OK, this is easy. + ARMReg rA = gpr.GetReg(false); + MOVI2R(rA, (u32)&PowerPC::ppcState.spr); + STR(rA, RD, iIndex * 4); +} + +void JitArm::mfspr(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(SystemRegisters) + + u32 iIndex = (inst.SPRU << 5) | (inst.SPRL & 0x1F); + ARMReg RD = gpr.R(inst.RD); + switch (iIndex) + { + case SPR_WPAR: + case SPR_DEC: + case SPR_TL: + case SPR_TU: + Default(inst); + return; + default: + ARMReg rA = gpr.GetReg(false); + MOVI2R(rA, (u32)&PowerPC::ppcState.spr); + LDR(RD, rA, iIndex * 4); + break; + } +} +void JitArm::mtmsr(UGeckoInstruction inst) +{ + INSTRUCTION_START + // Don't interpret this, if we do we get thrown out + //JITDISABLE(SystemRegisters) + + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, (u32)&MSR); + STR(rA, gpr.R(inst.RS)); + gpr.Unlock(rA); + WriteExit(js.compilerPC + 4, 0); +} diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp new file mode 100644 index 0000000000..1929705df2 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.cpp @@ -0,0 +1,502 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Jit.h" +#include "../JitInterface.h" +#include "JitArm_Tables.h" + +// Should be moved in to the Jit class +typedef void (JitArm::*_Instruction) (UGeckoInstruction instCode); + +static _Instruction dynaOpTable[64]; +static _Instruction dynaOpTable4[1024]; +static _Instruction dynaOpTable19[1024]; +static _Instruction dynaOpTable31[1024]; +static _Instruction dynaOpTable59[32]; +static _Instruction dynaOpTable63[1024]; + +void JitArm::DynaRunTable4(UGeckoInstruction _inst) {(this->*dynaOpTable4 [_inst.SUBOP10])(_inst);} +void JitArm::DynaRunTable19(UGeckoInstruction _inst) {(this->*dynaOpTable19[_inst.SUBOP10])(_inst);} +void JitArm::DynaRunTable31(UGeckoInstruction _inst) {(this->*dynaOpTable31[_inst.SUBOP10])(_inst);} +void JitArm::DynaRunTable59(UGeckoInstruction _inst) {(this->*dynaOpTable59[_inst.SUBOP5 ])(_inst);} +void JitArm::DynaRunTable63(UGeckoInstruction _inst) {(this->*dynaOpTable63[_inst.SUBOP10])(_inst);} + +struct GekkoOPTemplate +{ + int opcode; + _Instruction Inst; + //GekkoOPInfo opinfo; // Doesn't need opinfo, Interpreter fills it out +}; + +static GekkoOPTemplate primarytable[] = +{ + {4, &JitArm::DynaRunTable4}, //"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0}}, + {19, &JitArm::DynaRunTable19}, //"RunTable19", OPTYPE_SUBTABLE | (19<<24), 0}}, + {31, &JitArm::DynaRunTable31}, //"RunTable31", OPTYPE_SUBTABLE | (31<<24), 0}}, + {59, &JitArm::DynaRunTable59}, //"RunTable59", OPTYPE_SUBTABLE | (59<<24), 0}}, + {63, &JitArm::DynaRunTable63}, //"RunTable63", OPTYPE_SUBTABLE | (63<<24), 0}}, + + {16, &JitArm::bcx}, //"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {18, &JitArm::bx}, //"bx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + + {1, &JitArm::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {2, &JitArm::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}}, + {3, &JitArm::Break}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {17, &JitArm::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, + + {7, &JitArm::mulli}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}}, + {8, &JitArm::Default}, //"subfic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, + {10, &JitArm::cmpli}, //"cmpli", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, + {11, &JitArm::cmpi}, //"cmpi", OPTYPE_INTEGER, FL_IN_A | FL_SET_CRn}}, + {12, &JitArm::Default}, //"addic", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CA}}, + {13, &JitArm::Default}, //"addic_rc", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_SET_CR0}}, + {14, &JitArm::addi}, //"addi", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, + {15, &JitArm::addis}, //"addis", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A0}}, + + {20, &JitArm::rlwimix}, //"rlwimix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_A | FL_IN_S | FL_RC_BIT}}, + {21, &JitArm::rlwinmx}, //"rlwinmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {23, &JitArm::Default}, //"rlwnmx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_IN_B | FL_RC_BIT}}, + + {24, &JitArm::ori}, //"ori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {25, &JitArm::oris}, //"oris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {26, &JitArm::Default}, //"xori", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {27, &JitArm::Default}, //"xoris", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S}}, + {28, &JitArm::Default}, //"andi_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, + {29, &JitArm::Default}, //"andis_rc", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_SET_CR0}}, + + {32, &JitArm::lwz}, //"lwz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {33, &JitArm::Default}, //"lwzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {34, &JitArm::lbz}, //"lbz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {35, &JitArm::Default}, //"lbzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {40, &JitArm::lhz}, //"lhz", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {41, &JitArm::Default}, //"lhzu", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + {42, &JitArm::Default}, //"lha", OPTYPE_LOAD, FL_OUT_D | FL_IN_A}}, + {43, &JitArm::Default}, //"lhau", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A}}, + + {44, &JitArm::Default}, //"sth", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, + {45, &JitArm::Default}, //"sthu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + {36, &JitArm::stw}, //"stw", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, + {37, &JitArm::stwu}, //"stwu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + {38, &JitArm::Default}, //"stb", OPTYPE_STORE, FL_IN_A | FL_IN_S}}, + {39, &JitArm::Default}, //"stbu", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_S}}, + + {46, &JitArm::Default}, //"lmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, + {47, &JitArm::Default}, //"stmw", OPTYPE_SYSTEM, FL_EVIL, 10}}, + + {48, &JitArm::lfs}, //"lfs", OPTYPE_LOADFP, FL_IN_A}}, + {49, &JitArm::Default}, //"lfsu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, + {50, &JitArm::Default}, //"lfd", OPTYPE_LOADFP, FL_IN_A}}, + {51, &JitArm::Default}, //"lfdu", OPTYPE_LOADFP, FL_OUT_A | FL_IN_A}}, + + {52, &JitArm::Default}, //"stfs", OPTYPE_STOREFP, FL_IN_A}}, + {53, &JitArm::Default}, //"stfsu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, + {54, &JitArm::Default}, //"stfd", OPTYPE_STOREFP, FL_IN_A}}, + {55, &JitArm::Default}, //"stfdu", OPTYPE_STOREFP, FL_OUT_A | FL_IN_A}}, + + {56, &JitArm::Default}, //"psq_l", OPTYPE_PS, FL_IN_A}}, + {57, &JitArm::Default}, //"psq_lu", OPTYPE_PS, FL_OUT_A | FL_IN_A}}, + {60, &JitArm::Default}, //"psq_st", OPTYPE_PS, FL_IN_A}}, + {61, &JitArm::Default}, //"psq_stu", OPTYPE_PS, FL_OUT_A | FL_IN_A}}, + + //missing: 0, 5, 6, 9, 22, 30, 62, 58 + {0, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {5, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {6, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {9, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {22, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {30, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {62, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, + {58, &JitArm::Default}, //"unknown_instruction", OPTYPE_UNKNOWN, 0}}, +}; + +static GekkoOPTemplate table4[] = +{ //SUBOP10 + {0, &JitArm::Default}, //"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}}, + {32, &JitArm::Default}, //"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}}, + {40, &JitArm::Default}, //"ps_neg", OPTYPE_PS, FL_RC_BIT}}, + {136, &JitArm::Default}, //"ps_nabs", OPTYPE_PS, FL_RC_BIT}}, + {264, &JitArm::Default}, //"ps_abs", OPTYPE_PS, FL_RC_BIT}}, + {64, &JitArm::Default}, //"ps_cmpu1", OPTYPE_PS, FL_RC_BIT}}, + {72, &JitArm::Default}, //"ps_mr", OPTYPE_PS, FL_RC_BIT}}, + {96, &JitArm::Default}, //"ps_cmpo1", OPTYPE_PS, FL_RC_BIT}}, + {528, &JitArm::Default}, //"ps_merge00", OPTYPE_PS, FL_RC_BIT}}, + {560, &JitArm::Default}, //"ps_merge01", OPTYPE_PS, FL_RC_BIT}}, + {592, &JitArm::Default}, //"ps_merge10", OPTYPE_PS, FL_RC_BIT}}, + {624, &JitArm::Default}, //"ps_merge11", OPTYPE_PS, FL_RC_BIT}}, + + {1014, &JitArm::Default}, //"dcbz_l", OPTYPE_SYSTEM, 0}}, +}; + +static GekkoOPTemplate table4_2[] = +{ + {10, &JitArm::Default}, //"ps_sum0", OPTYPE_PS, 0}}, + {11, &JitArm::Default}, //"ps_sum1", OPTYPE_PS, 0}}, + {12, &JitArm::Default}, //"ps_muls0", OPTYPE_PS, 0}}, + {13, &JitArm::Default}, //"ps_muls1", OPTYPE_PS, 0}}, + {14, &JitArm::Default}, //"ps_madds0", OPTYPE_PS, 0}}, + {15, &JitArm::Default}, //"ps_madds1", OPTYPE_PS, 0}}, + {18, &JitArm::Default}, //"ps_div", OPTYPE_PS, 0, 16}}, + {20, &JitArm::Default}, //"ps_sub", OPTYPE_PS, 0}}, + {21, &JitArm::Default}, //"ps_add", OPTYPE_PS, 0}}, + {23, &JitArm::Default}, //"ps_sel", OPTYPE_PS, 0}}, + {24, &JitArm::Default}, //"ps_res", OPTYPE_PS, 0}}, + {25, &JitArm::Default}, //"ps_mul", OPTYPE_PS, 0}}, + {26, &JitArm::Default}, //"ps_rsqrte", OPTYPE_PS, 0, 1}}, + {28, &JitArm::Default}, //"ps_msub", OPTYPE_PS, 0}}, + {29, &JitArm::Default}, //"ps_madd", OPTYPE_PS, 0}}, + {30, &JitArm::Default}, //"ps_nmsub", OPTYPE_PS, 0}}, + {31, &JitArm::Default}, //"ps_nmadd", OPTYPE_PS, 0}}, +}; + + +static GekkoOPTemplate table4_3[] = +{ + {6, &JitArm::Default}, //"psq_lx", OPTYPE_PS, 0}}, + {7, &JitArm::Default}, //"psq_stx", OPTYPE_PS, 0}}, + {38, &JitArm::Default}, //"psq_lux", OPTYPE_PS, 0}}, + {39, &JitArm::Default}, //"psq_stux", OPTYPE_PS, 0}}, +}; + +static GekkoOPTemplate table19[] = +{ + {528, &JitArm::bcctrx}, //"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, + {16, &JitArm::bclrx}, //"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, + {257, &JitArm::Default}, //"crand", OPTYPE_CR, FL_EVIL}}, + {129, &JitArm::Default}, //"crandc", OPTYPE_CR, FL_EVIL}}, + {289, &JitArm::Default}, //"creqv", OPTYPE_CR, FL_EVIL}}, + {225, &JitArm::Default}, //"crnand", OPTYPE_CR, FL_EVIL}}, + {33, &JitArm::Default}, //"crnor", OPTYPE_CR, FL_EVIL}}, + {449, &JitArm::Default}, //"cror", OPTYPE_CR, FL_EVIL}}, + {417, &JitArm::Default}, //"crorc", OPTYPE_CR, FL_EVIL}}, + {193, &JitArm::Default}, //"crxor", OPTYPE_CR, FL_EVIL}}, + + {150, &JitArm::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}}, + {0, &JitArm::Default}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}}, + + {50, &JitArm::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}}, + {18, &JitArm::Break}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}} +}; + + +static GekkoOPTemplate table31[] = +{ + {28, &JitArm::Default}, //"andx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {60, &JitArm::Default}, //"andcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {444, &JitArm::orx}, //"orx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {124, &JitArm::Default}, //"norx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {316, &JitArm::Default}, //"xorx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {412, &JitArm::Default}, //"orcx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {476, &JitArm::Default}, //"nandx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {284, &JitArm::Default}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}}, + {0, &JitArm::cmp}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, + {32, &JitArm::Default}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, + {26, &JitArm::Default}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {922, &JitArm::extshx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {954, &JitArm::extsbx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}}, + {536, &JitArm::Default}, //"srwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {792, &JitArm::Default}, //"srawx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {824, &JitArm::Default}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + {24, &JitArm::Default}, //"slwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}}, + + {54, &JitArm::Default}, //"dcbst", OPTYPE_DCACHE, 0, 4}}, + {86, &JitArm::Default}, //"dcbf", OPTYPE_DCACHE, 0, 4}}, + {246, &JitArm::Default}, //"dcbtst", OPTYPE_DCACHE, 0, 1}}, + {278, &JitArm::Default}, //"dcbt", OPTYPE_DCACHE, 0, 1}}, + {470, &JitArm::Default}, //"dcbi", OPTYPE_DCACHE, 0, 4}}, + {758, &JitArm::Default}, //"dcba", OPTYPE_DCACHE, 0, 4}}, + {1014, &JitArm::Default}, //"dcbz", OPTYPE_DCACHE, 0, 4}}, + + //load word + {23, &JitArm::lwzx}, //"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {55, &JitArm::Default}, //"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //load halfword + {279, &JitArm::Default}, //"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {311, &JitArm::Default}, //"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //load halfword signextend + {343, &JitArm::Default}, //"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {375, &JitArm::Default}, //"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //load byte + {87, &JitArm::Default}, //"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {119, &JitArm::Default}, //"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //load byte reverse + {534, &JitArm::Default}, //"lwbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + {790, &JitArm::Default}, //"lhbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, + + // Conditional load/store (Wii SMP) + {150, &JitArm::Default}, //"stwcxd", OPTYPE_STORE, FL_EVIL | FL_SET_CR0}}, + {20, &JitArm::Default}, //"lwarx", OPTYPE_LOAD, FL_EVIL | FL_OUT_D | FL_IN_A0B | FL_SET_CR0}}, + + //load string (interpret these) + {533, &JitArm::Default}, //"lswx", OPTYPE_LOAD, FL_EVIL | FL_IN_A | FL_OUT_D}}, + {597, &JitArm::Default}, //"lswi", OPTYPE_LOAD, FL_EVIL | FL_IN_AB | FL_OUT_D}}, + + //store word + {151, &JitArm::Default}, //"stwx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {183, &JitArm::Default}, //"stwux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //store halfword + {407, &JitArm::Default}, //"sthx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {439, &JitArm::Default}, //"sthux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //store byte + {215, &JitArm::Default}, //"stbx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {247, &JitArm::Default}, //"stbux", OPTYPE_STORE, FL_OUT_A | FL_IN_A | FL_IN_B}}, + + //store bytereverse + {662, &JitArm::Default}, //"stwbrx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, + {918, &JitArm::Default}, //"sthbrx", OPTYPE_STORE, FL_IN_A | FL_IN_B}}, + + {661, &JitArm::Default}, //"stswx", OPTYPE_STORE, FL_EVIL}}, + {725, &JitArm::Default}, //"stswi", OPTYPE_STORE, FL_EVIL}}, + + // fp load/store + {535, &JitArm::Default}, //"lfsx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, + {567, &JitArm::Default}, //"lfsux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, + {599, &JitArm::Default}, //"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, + {631, &JitArm::Default}, //"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, + + {663, &JitArm::Default}, //"stfsx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, + {695, &JitArm::Default}, //"stfsux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, + {727, &JitArm::Default}, //"stfdx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, + {759, &JitArm::Default}, //"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, + {983, &JitArm::Default}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, + + {19, &JitArm::Default}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}}, + {83, &JitArm::Default}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}}, + {144, &JitArm::Default}, //"mtcrf", OPTYPE_SYSTEM, 0}}, + {146, &JitArm::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}}, + {210, &JitArm::Default}, //"mtsr", OPTYPE_SYSTEM, 0}}, + {242, &JitArm::Default}, //"mtsrin", OPTYPE_SYSTEM, 0}}, + {339, &JitArm::mfspr}, //"mfspr", OPTYPE_SPR, FL_OUT_D}}, + {467, &JitArm::mtspr}, //"mtspr", OPTYPE_SPR, 0, 2}}, + {371, &JitArm::Default}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}}, + {512, &JitArm::Default}, //"mcrxr", OPTYPE_SYSTEM, 0}}, + {595, &JitArm::Default}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}}, + {659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}}, + + {4, &JitArm::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, + {598, &JitArm::Default}, //"sync", OPTYPE_SYSTEM, 0, 2}}, + {982, &JitArm::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}}, + + // Unused instructions on GC + {310, &JitArm::Default}, //"eciwx", OPTYPE_INTEGER, FL_RC_BIT}}, + {438, &JitArm::Default}, //"ecowx", OPTYPE_INTEGER, FL_RC_BIT}}, + {854, &JitArm::Default}, //"eieio", OPTYPE_INTEGER, FL_RC_BIT}}, + {306, &JitArm::Default}, //"tlbie", OPTYPE_SYSTEM, 0}}, + {370, &JitArm::Default}, //"tlbia", OPTYPE_SYSTEM, 0}}, + {566, &JitArm::Default}, //"tlbsync", OPTYPE_SYSTEM, 0}}, +}; + +static GekkoOPTemplate table31_2[] = +{ + {266, &JitArm::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {778, &JitArm::addx}, //"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {10, &JitArm::Default}, //"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {138, &JitArm::Default}, //"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {234, &JitArm::Default}, //"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {202, &JitArm::Default}, //"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {491, &JitArm::Default}, //"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, + {1003, &JitArm::Default}, //"divwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, + {459, &JitArm::Default}, //"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, + {971, &JitArm::Default}, //"divwuox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, + {75, &JitArm::Default}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {11, &JitArm::Default}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {235, &JitArm::Default}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {747, &JitArm::Default}, //"mullwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {104, &JitArm::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {40, &JitArm::Default}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {552, &JitArm::Default}, //"subox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, + {8, &JitArm::Default}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}}, + {136, &JitArm::Default}, //"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {232, &JitArm::Default}, //"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, + {200, &JitArm::Default}, //"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, +}; + +static GekkoOPTemplate table59[] = +{ + {18, &JitArm::Default}, //{"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}}, + {20, &JitArm::Default}, //"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {21, &JitArm::Default}, //"faddsx", OPTYPE_FPU, FL_RC_BIT_F}}, +// {22, &JitArm::Default}, //"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko + {24, &JitArm::Default}, //"fresx", OPTYPE_FPU, FL_RC_BIT_F}}, + {25, &JitArm::Default}, //"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {28, &JitArm::Default}, //"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {29, &JitArm::Default}, //"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {30, &JitArm::Default}, //"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {31, &JitArm::Default}, //"fnmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, +}; + +static GekkoOPTemplate table63[] = +{ + {264, &JitArm::fabsx}, //"fabsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {32, &JitArm::Default}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}}, + {0, &JitArm::Default}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}}, + {14, &JitArm::Default}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}}, + {15, &JitArm::Default}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}}, + {72, &JitArm::fmrx}, //"fmrx", OPTYPE_FPU, FL_RC_BIT_F}}, + {136, &JitArm::Default}, //"fnabsx", OPTYPE_FPU, FL_RC_BIT_F}}, + {40, &JitArm::Default}, //"fnegx", OPTYPE_FPU, FL_RC_BIT_F}}, + {12, &JitArm::Default}, //"frspx", OPTYPE_FPU, FL_RC_BIT_F}}, + + {64, &JitArm::Default}, //"mcrfs", OPTYPE_SYSTEMFP, 0}}, + {583, &JitArm::Default}, //"mffsx", OPTYPE_SYSTEMFP, 0}}, + {70, &JitArm::Default}, //"mtfsb0x", OPTYPE_SYSTEMFP, 0, 2}}, + {38, &JitArm::Default}, //"mtfsb1x", OPTYPE_SYSTEMFP, 0, 2}}, + {134, &JitArm::Default}, //"mtfsfix", OPTYPE_SYSTEMFP, 0, 2}}, + {711, &JitArm::Default}, //"mtfsfx", OPTYPE_SYSTEMFP, 0, 2}}, +}; + +static GekkoOPTemplate table63_2[] = +{ + {18, &JitArm::Default}, //"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}}, + {20, &JitArm::Default}, //"fsubx", OPTYPE_FPU, FL_RC_BIT_F}}, + {21, &JitArm::faddx}, //"faddx", OPTYPE_FPU, FL_RC_BIT_F}}, + {22, &JitArm::Default}, //"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}}, + {23, &JitArm::Default}, //"fselx", OPTYPE_FPU, FL_RC_BIT_F}}, + {25, &JitArm::Default}, //"fmulx", OPTYPE_FPU, FL_RC_BIT_F}}, + {26, &JitArm::Default}, //"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}}, + {28, &JitArm::Default}, //"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, + {29, &JitArm::Default}, //"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, + {30, &JitArm::Default}, //"fnmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, + {31, &JitArm::Default}, //"fnmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, +}; + + +namespace JitArmTables +{ + +void CompileInstruction(PPCAnalyst::CodeOp & op) +{ + JitArm *jitarm = (JitArm *)jit; + (jitarm->*dynaOpTable[op.inst.OPCD])(op.inst); + GekkoOPInfo *info = op.opinfo; + if (info) { +#ifdef OPLOG + if (!strcmp(info->opname, OP_TO_LOG)){ ///"mcrfs" + rsplocations.push_back(jit.js.compilerPC); + } +#endif + info->compileCount++; + info->lastUse = jit->js.compilerPC; + } +} + +void InitTables() +{ + // once initialized, tables are read-only + static bool initialized = false; + if (initialized) + return; + + //clear + for (int i = 0; i < 32; i++) + { + dynaOpTable59[i] = &JitArm::unknown_instruction; + } + + for (int i = 0; i < 1024; i++) + { + dynaOpTable4 [i] = &JitArm::unknown_instruction; + dynaOpTable19[i] = &JitArm::unknown_instruction; + dynaOpTable31[i] = &JitArm::unknown_instruction; + dynaOpTable63[i] = &JitArm::unknown_instruction; + } + + for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++) + { + dynaOpTable[primarytable[i].opcode] = primarytable[i].Inst; + } + + for (int i = 0; i < 32; i++) + { + int fill = i << 5; + for (int j = 0; j < (int)(sizeof(table4_2) / sizeof(GekkoOPTemplate)); j++) + { + int op = fill+table4_2[j].opcode; + dynaOpTable4[op] = table4_2[j].Inst; + } + } + + for (int i = 0; i < 16; i++) + { + int fill = i << 6; + for (int j = 0; j < (int)(sizeof(table4_3) / sizeof(GekkoOPTemplate)); j++) + { + int op = fill+table4_3[j].opcode; + dynaOpTable4[op] = table4_3[j].Inst; + } + } + + for (int i = 0; i < (int)(sizeof(table4) / sizeof(GekkoOPTemplate)); i++) + { + int op = table4[i].opcode; + dynaOpTable4[op] = table4[i].Inst; + } + + for (int i = 0; i < (int)(sizeof(table31) / sizeof(GekkoOPTemplate)); i++) + { + int op = table31[i].opcode; + dynaOpTable31[op] = table31[i].Inst; + } + + for (int i = 0; i < 1; i++) + { + int fill = i << 9; + for (int j = 0; j < (int)(sizeof(table31_2) / sizeof(GekkoOPTemplate)); j++) + { + int op = fill + table31_2[j].opcode; + dynaOpTable31[op] = table31_2[j].Inst; + } + } + + for (int i = 0; i < (int)(sizeof(table19) / sizeof(GekkoOPTemplate)); i++) + { + int op = table19[i].opcode; + dynaOpTable19[op] = table19[i].Inst; + } + + for (int i = 0; i < (int)(sizeof(table59) / sizeof(GekkoOPTemplate)); i++) + { + int op = table59[i].opcode; + dynaOpTable59[op] = table59[i].Inst; + } + + for (int i = 0; i < (int)(sizeof(table63) / sizeof(GekkoOPTemplate)); i++) + { + int op = table63[i].opcode; + dynaOpTable63[op] = table63[i].Inst; + } + + for (int i = 0; i < 32; i++) + { + int fill = i << 5; + for (int j = 0; j < (int)(sizeof(table63_2) / sizeof(GekkoOPTemplate)); j++) + { + int op = fill + table63_2[j].opcode; + dynaOpTable63[op] = table63_2[j].Inst; + } + } + + initialized = true; + +} + +} // namespace diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.h b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.h new file mode 100644 index 0000000000..4904ce3984 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Tables.h @@ -0,0 +1,29 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef JITARM_TABLES_H +#define JITARM_TABLES_H + +#include "../Gekko.h" +#include "../PPCTables.h" + +namespace JitArmTables +{ + void CompileInstruction(PPCAnalyst::CodeOp & op); + void InitTables(); +} +#endif diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp new file mode 100644 index 0000000000..e45058b57b --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp @@ -0,0 +1,174 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + + +#include "../../HW/Memmap.h" + +#include "../PowerPC.h" +#include "../../CoreTiming.h" +#include "MemoryUtil.h" + +#include "Jit.h" +#include "../JitCommon/JitCache.h" + +#include "../../HW/GPFifo.h" +#include "../../Core.h" +#include "JitAsm.h" +#include "ArmEmitter.h" + +using namespace ArmGen; + +//TODO - make an option +//#if _DEBUG +// bool enableDebug = false; +//#else +// bool enableDebug = false; +//#endif + +JitArmAsmRoutineManager asm_routines; + +void JitArmAsmRoutineManager::Generate() +{ + enterCode = GetCodePtr(); + PUSH(2, R11, _LR); // R11 is frame pointer in Debug. + + MOVI2R(R0, (u32)&CoreTiming::downcount); + MOVI2R(R9, (u32)&PowerPC::ppcState); + + FixupBranch skipToRealDispatcher = B(); + dispatcher = GetCodePtr(); + printf("Dispatcher is %p\n", dispatcher); + + // Downcount Check + // The result of slice decrementation should be in flags if somebody jumped here + // IMPORTANT - We jump on negative, not carry!!! + FixupBranch bail = B_CC(CC_MI); + + SetJumpTarget(skipToRealDispatcher); + dispatcherNoCheck = GetCodePtr(); + + // This block of code gets the address of the compiled block of code + // It runs though to the compiling portion if it isn't found + LDR(R12, R9, STRUCT_OFF(PowerPC::ppcState, pc));// Load the current PC into R12 + + MOVI2R(R14, JIT_ICACHE_MASK); // Potential for optimization + AND(R12, R12, R14); // R12 contains PC & JIT_ICACHE_MASK here. + // Confirmed good to this point 08-03-12 + + MOVI2R(R14, (u32)jit->GetBlockCache()->GetICache()); + // Confirmed That this loads the base iCache Location correctly 08-04-12 + + LDR(R12, R14, R12, true, true); // R12 contains iCache[PC & JIT_ICACHE_MASK] here + // R12 Confirmed this is the correct iCache Location loaded. + TST(R12, 0xFC); // Test to see if it is a JIT block. + + SetCC(CC_EQ); // Only run next part if R12 is zero + // Success, it is our Jitblock. + MOVI2R(R14, (u32)jit->GetBlockCache()->GetCodePointers()); + // LDR R14 right here to get CodePointers()[0] pointer. + REV(R12, R12); // Reversing this gives us our JITblock. + LSL(R12, R12, 2); // Multiply by four because address locations are u32 in size + LDR(R14, R14, R12, true, true); // Load the block address in to R14 + + B(R14); + + FixupBranch NextBlock = B(); // Jump to end so we can start a new block + SetCC(); // Return to always executing codes + + // If we get to this point, that means that we don't have the block cached to execute + // So call ArmJit to compile the block and then execute it. + MOVI2R(R14, (u32)&Jit); + LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, pc)); + BL(R14); + + B(dispatcherNoCheck); + + // fpException() + // Floating Point Exception Check, Jumped to if false + fpException = GetCodePtr(); + LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + ORR(R0, R0, EXCEPTION_FPU_UNAVAILABLE); + STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); + LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, npc)); + STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, pc)); + B(dispatcher); + + SetJumpTarget(bail); + doTiming = GetCodePtr(); + // XXX: In JIT64, Advance() gets called /after/ the exception checking + // once it jumps back to the start of outerLoop + QuickCallFunction(R14, (void*)&CoreTiming::Advance); + + // Does exception checking + testExceptions = GetCodePtr(); + LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, npc)); + QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); + LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, npc)); + STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, pc)); + // Check the state pointer to see if we are exiting + // Gets checked on every exception check + MOVI2R(R0, (u32)PowerPC::GetStatePtr()); + MVN(R1, 0); + LDR(R0, R0); + TST(R0, R1); + FixupBranch Exit = B_CC(CC_NEQ); + + SetJumpTarget(NextBlock); + B(dispatcher); + + SetJumpTarget(Exit); + + POP(2, R11, _PC); + FlushIcache(); +} + +void JitArmAsmRoutineManager::GenerateCommon() +{ +/* fifoDirectWrite8 = AlignCode4(); + GenFifoWrite(8); + fifoDirectWrite16 = AlignCode4(); + GenFifoWrite(16); + fifoDirectWrite32 = AlignCode4(); + GenFifoWrite(32); + fifoDirectWriteFloat = AlignCode4(); + GenFifoFloatWrite(); + fifoDirectWriteXmm64 = AlignCode4(); + GenFifoXmm64Write(); + + GenQuantizedLoads(); + GenQuantizedStores(); + GenQuantizedSingleStores(); +*/ + //CMPSD(R(XMM0), M(&zero), + // TODO + + // Fast write routines - special case the most common hardware write + // TODO: use this. + // Even in x86, the param values will be in the right registers. + /* + const u8 *fastMemWrite8 = AlignCode16(); + CMP(32, R(ABI_PARAM2), Imm32(0xCC008000)); + FixupBranch skip_fast_write = J_CC(CC_NE, false); + MOV(32, EAX, M(&m_gatherPipeCount)); + MOV(8, MDisp(EAX, (u32)&m_gatherPipe), ABI_PARAM1); + ADD(32, 1, M(&m_gatherPipeCount)); + RET(); + SetJumpTarget(skip_fast_write); + CALL((void *)&Memory::Write_U8);*/ +} diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.h b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.h new file mode 100644 index 0000000000..9a61e9e653 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.h @@ -0,0 +1,43 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _JITARMASM_H +#define _JITARMASM_H +#include "ArmEmitter.h" +#include "../JitCommon/JitAsmCommon.h" +using namespace ArmGen; +class JitArmAsmRoutineManager : public CommonAsmRoutinesBase, public ARMXCodeBlock +{ +private: + void Generate(); + void GenerateCommon(); + +public: + void Init() { + AllocCodeSpace(8192); + Generate(); + WriteProtect(); + } + + void Shutdown() { + FreeCodeSpace(); + } +}; + +extern JitArmAsmRoutineManager asm_routines; + +#endif // _JIT64ASM_H diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp new file mode 100644 index 0000000000..9c6ffdbac4 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp @@ -0,0 +1,167 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "JitRegCache.h" + +ArmRegCache::ArmRegCache() +{ + emit = 0; +} + +void ArmRegCache::Init(ARMXEmitter *emitter) +{ + emit = emitter; + ARMReg *PPCRegs = GetPPCAllocationOrder(NUMPPCREG); + ARMReg *Regs = GetAllocationOrder(NUMARMREG); + for(u8 a = 0; a < 32; ++a) + { + // This gives us the memory locations of the gpr registers so we can + // load them. + regs[a].location = (u8*)&PowerPC::ppcState.gpr[a]; + regs[a].UsesLeft = 0; + } + for(u8 a = 0; a < NUMPPCREG; ++a) + { + ArmCRegs[a].PPCReg = 33; + ArmCRegs[a].Reg = PPCRegs[a]; + ArmCRegs[a].LastLoad = 0; + } + for(u8 a = 0; a < NUMARMREG; ++a) + { + ArmRegs[a].Reg = Regs[a]; + ArmRegs[a].free = true; + } +} +void ArmRegCache::Start(PPCAnalyst::BlockRegStats &stats) +{ + for(u8 a = 0; a < NUMPPCREG; ++a) + { + ArmCRegs[a].PPCReg = 33; + ArmCRegs[a].LastLoad = 0; + } + for(u8 a = 0; a < 32; ++a) + regs[a].UsesLeft = stats.GetTotalNumAccesses(a); +} +ARMReg *ArmRegCache::GetPPCAllocationOrder(int &count) +{ + // This will return us the allocation order of the registers we can use on + // the ppc side. + static ARMReg allocationOrder[] = + { + R0, R1, R2, R3, R4, R5, R6, R7, R8 + }; + count = sizeof(allocationOrder) / sizeof(const int); + return allocationOrder; +} +ARMReg *ArmRegCache::GetAllocationOrder(int &count) +{ + // This will return us the allocation order of the registers we can use on + // the host side. + static ARMReg allocationOrder[] = + { + R14, R12, R11, R10 + }; + count = sizeof(allocationOrder) / sizeof(const int); + return allocationOrder; +} + +ARMReg ArmRegCache::GetReg(bool AutoLock) +{ + for(u8 a = 0; a < NUMARMREG; ++a) + if(ArmRegs[a].free) + { + // Alright, this one is free + if (AutoLock) + ArmRegs[a].free = false; + return ArmRegs[a].Reg; + } + // Uh Oh, we have all them locked.... + _assert_msg_(_DYNA_REC_, false, "All available registers are locked dumb dumb"); + return R0; +} +void ArmRegCache::Lock(ARMReg Reg) +{ + for(u8 RegNum = 0; RegNum < NUMARMREG; ++RegNum) + if(ArmRegs[RegNum].Reg == Reg) + { + _assert_msg_(_DYNA_REC, ArmRegs[RegNum].free, "This register is already locked"); + ArmRegs[RegNum].free = false; + } + _assert_msg_(_DYNA_REC, false, "Register %d can't be used with lock", Reg); +} +void ArmRegCache::Unlock(ARMReg R0, ARMReg R1, ARMReg R2, ARMReg R3) +{ + for(u8 RegNum = 0; RegNum < NUMARMREG; ++RegNum) + { + if(ArmRegs[RegNum].Reg == R0) + { + _assert_msg_(_DYNA_REC, !ArmRegs[RegNum].free, "This register is already unlocked"); + ArmRegs[RegNum].free = true; + } + if( R1 != INVALID_REG && ArmRegs[RegNum].Reg == R1) ArmRegs[RegNum].free = true; + if( R2 != INVALID_REG && ArmRegs[RegNum].Reg == R2) ArmRegs[RegNum].free = true; + if( R3 != INVALID_REG && ArmRegs[RegNum].Reg == R3) ArmRegs[RegNum].free = true; + } +} + +ARMReg ArmRegCache::R(u32 preg) +{ + u32 HighestUsed = 0; + u8 Num = 0; + for(u8 a = 0; a < NUMPPCREG; ++a){ + ++ArmCRegs[a].LastLoad; + if (ArmCRegs[a].LastLoad > HighestUsed) + { + HighestUsed = ArmCRegs[a].LastLoad; + Num = a; + } + } + // Check if already Loaded + for(u8 a = 0; a < NUMPPCREG; ++a) + if (ArmCRegs[a].PPCReg == preg) + { + ArmCRegs[a].LastLoad = 0; + return ArmCRegs[a].Reg; + } + // Check if we have a free register + for (u8 a = 0; a < NUMPPCREG; ++a) + if (ArmCRegs[a].PPCReg == 33) + { + emit->LDR(ArmCRegs[a].Reg, R9, STRUCT_OFF(PowerPC::ppcState, gpr) + preg * 4); + ArmCRegs[a].PPCReg = preg; + ArmCRegs[a].LastLoad = 0; + return ArmCRegs[a].Reg; + } + // Alright, we couldn't get a free space, dump that least used register + emit->STR(R9, ArmCRegs[Num].Reg, STRUCT_OFF(PowerPC::ppcState, gpr) + ArmCRegs[Num].PPCReg * 4); + emit->LDR(ArmCRegs[Num].Reg, R9, STRUCT_OFF(PowerPC::ppcState, gpr) + preg * 4); + ArmCRegs[Num].PPCReg = preg; + ArmCRegs[Num].LastLoad = 0; + return ArmCRegs[Num].Reg; +} + +void ArmRegCache::Flush() +{ + for(u8 a = 0; a < NUMPPCREG; ++a) + if (ArmCRegs[a].PPCReg != 33) + { + emit->STR(R9, ArmCRegs[a].Reg, STRUCT_OFF(PowerPC::ppcState, gpr) + ArmCRegs[a].PPCReg * 4); + ArmCRegs[a].PPCReg = 33; + ArmCRegs[a].LastLoad = 0; + } +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.h b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.h new file mode 100644 index 0000000000..7292ce1581 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.h @@ -0,0 +1,92 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _JITARMREGCACHE_H +#define _JITARMREGCACHE_H + +#include "ArmEmitter.h" +#include "../Gekko.h" +#include "../PPCAnalyst.h" + +using namespace ArmGen; +// This ARM Register cache actually pre loads the most used registers before +// the block to increase speed since every memory load requires two +// instructions to load it. We are going to use R0-RMAX as registers for the +// use of PPC Registers. +// Allocation order as follows +#define ARMREGS 16 +// Allocate R0 to R9 for PPC first. +// For General registers on the host side, start with R14 and go down as we go +// R13 is reserved for our stack pointer, don't ever use that. Unless you save +// it +// So we have R14, R12, R11, R10 to work with instructions + +struct PPCCachedReg +{ + const u8 *location; + u32 UsesLeft; +}; +struct JRCPPC +{ + u32 PPCReg; // Tied to which PPC Register + bool PS1; + ARMReg Reg; // Tied to which ARM Register + u32 LastLoad; +}; +struct JRCReg +{ + ARMReg Reg; // Which reg this is. + bool free; +}; +class ArmRegCache +{ +private: + PPCCachedReg regs[32]; + JRCPPC ArmCRegs[ARMREGS]; + JRCReg ArmRegs[ARMREGS]; // Four registers remaining + + int NUMPPCREG; + int NUMARMREG; + + ARMReg *GetAllocationOrder(int &count); + ARMReg *GetPPCAllocationOrder(int &count); + +protected: + ARMXEmitter *emit; + +public: + ArmRegCache(); + ~ArmRegCache() {} + + void Init(ARMXEmitter *emitter); + void Start(PPCAnalyst::BlockRegStats &stats); + + void SetEmitter(ARMXEmitter *emitter) {emit = emitter;} + + ARMReg GetReg(bool AutoLock = true); // Return a ARM register we can use. + void Lock(ARMReg reg); + void Unlock(ARMReg R0, ARMReg R1 = INVALID_REG, ARMReg R2 = INVALID_REG, ARMReg R3 = + INVALID_REG); + void Flush(); + ARMReg R(u32 preg); // Returns a cached register + +}; + + + + +#endif diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.cpp index 34b9a681e9..7f509dbf0e 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.cpp @@ -15,7 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #include "CPUDetect.h" #include "x64Emitter.h" @@ -26,7 +26,7 @@ #include "../../CoreTiming.h" #include "MemoryUtil.h" -#include "ABI.h" +#include "x64ABI.h" #include "../JitCommon/JitCache.h" #include "../../HW/GPFifo.h" diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h index cbec27d2aa..a610a03326 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h @@ -21,16 +21,8 @@ #include "../JitCommon/Jit_Util.h" #include "Thunk.h" -class CommonAsmRoutines : public EmuCodeBlock { -protected: - void GenQuantizedLoads(); - void GenQuantizedStores(); - void GenQuantizedSingleStores(); - +class CommonAsmRoutinesBase { public: - void GenFifoWrite(int size); - void GenFifoXmm64Write(); - void GenFifoFloatWrite(); const u8 *fifoDirectWrite8; const u8 *fifoDirectWrite16; @@ -72,8 +64,23 @@ public: // In: XMM0: Bottom 32-bit slot holds the float to be written. const u8 **singleStoreQuantized; +}; + +class CommonAsmRoutines : public CommonAsmRoutinesBase, public EmuCodeBlock +{ +protected: + void GenQuantizedLoads(); + void GenQuantizedStores(); + void GenQuantizedSingleStores(); + +public: + void GenFifoWrite(int size); + void GenFifoXmm64Write(); + void GenFifoFloatWrite(); + private: ThunkManager thunks; + }; #endif diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp index 3042cfedba..76e791a94c 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.cpp @@ -25,7 +25,7 @@ #include "../../HW/Memmap.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "Thunk.h" #include "x64Analyzer.h" @@ -160,7 +160,7 @@ const u8 *TrampolineCache::GetWriteTrampoline(const InstructionInfo &info) // 1) It's really necessary. We don't know anything about the context. // 2) It doesn't really hurt. Only instructions that access I/O will get these, and there won't be // that many of them in a typical program/game. -const u8 *JitBase::BackPatch(u8 *codePtr, int accessType, u32 emAddress, void *ctx_void) +const u8 *Jitx86Base::BackPatch(u8 *codePtr, int accessType, u32 emAddress, void *ctx_void) { #ifdef _M_X64 CONTEXT *ctx = (CONTEXT *)ctx_void; diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h index 4b880eb86d..871a112c6c 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBackpatch.h @@ -34,6 +34,9 @@ // from the real context. struct CONTEXT { + #ifdef _M_ARM + u32 reg_pc; + #else #ifdef _M_X64 u64 Rip; u64 Rax; @@ -41,6 +44,7 @@ u32 Eip; u32 Eax; #endif + #endif }; #endif diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h index 5352c06d04..158171be0f 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h @@ -32,12 +32,9 @@ #define JIT_OPCODE 0 -class JitBase : public CPUCoreBase, public EmuCodeBlock +class JitBase : public CPUCoreBase { protected: - JitBlockCache blocks; - TrampolineCache trampolines; - struct JitOptions { bool optimizeStack; @@ -85,14 +82,29 @@ public: // This should probably be removed from public: JitOptions jo; JitState js; - - JitBlockCache *GetBlockCache() { return &blocks; } + + virtual JitBaseBlockCache *GetBlockCache() = 0; virtual void Jit(u32 em_address) = 0; + virtual const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx) = 0; + + virtual const CommonAsmRoutinesBase *GetAsmRoutines() = 0; + + virtual bool IsInCodeSpace(u8 *ptr) = 0; +}; + +class Jitx86Base : public JitBase, public EmuCodeBlock +{ +protected: + JitBlockCache blocks; + TrampolineCache trampolines; +public: + JitBlockCache *GetBlockCache() { return &blocks; } + const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx); - virtual const CommonAsmRoutines *GetAsmRoutines() = 0; + bool IsInCodeSpace(u8 *ptr) { return IsInSpace(ptr); } }; extern JitBase *jit; diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index d409518bf9..415b37ca61 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -32,15 +32,13 @@ #include "MemoryUtil.h" #include "../../HW/Memmap.h" +#include "../JitInterface.h" #include "../../CoreTiming.h" #include "../PowerPC.h" #include "../PPCTables.h" #include "../PPCAnalyst.h" -#include "x64Emitter.h" -#include "x64Analyzer.h" - #include "JitCache.h" #include "JitBase.h" @@ -68,12 +66,12 @@ bool JitBlock::ContainsAddress(u32 em_address) return (em_address >= originalAddress && em_address < originalAddress + 4 * originalSize); } - bool JitBlockCache::IsFull() const + bool JitBaseBlockCache::IsFull() const { return GetNumBlocks() >= MAX_NUM_BLOCKS - 1; } - void JitBlockCache::Init() + void JitBaseBlockCache::Init() { MAX_NUM_BLOCKS = 65536*2; @@ -91,11 +89,11 @@ bool JitBlock::ContainsAddress(u32 em_address) } else { - PanicAlert("JitBlockCache::Init() - iCache is already initialized"); + PanicAlert("JitBaseBlockCache::Init() - iCache is already initialized"); } if (iCache == 0 || iCacheEx == 0 || iCacheVMEM == 0) { - PanicAlert("JitBlockCache::Init() - unable to allocate iCache"); + PanicAlert("JitBaseBlockCache::Init() - unable to allocate iCache"); } memset(iCache, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE); memset(iCacheEx, JIT_ICACHE_INVALID_BYTE, JIT_ICACHEEX_SIZE); @@ -104,7 +102,7 @@ bool JitBlock::ContainsAddress(u32 em_address) Clear(); } - void JitBlockCache::Shutdown() + void JitBaseBlockCache::Shutdown() { delete[] blocks; delete[] blockCodePointers; @@ -133,7 +131,7 @@ bool JitBlock::ContainsAddress(u32 em_address) // This clears the JIT cache. It's called from JitCache.cpp when the JIT cache // is full and when saving and loading states. - void JitBlockCache::Clear() + void JitBaseBlockCache::Clear() { if (IsFull()) Core::DisplayMessage("Clearing block cache.", 3000); @@ -151,7 +149,7 @@ bool JitBlock::ContainsAddress(u32 em_address) memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS); } - void JitBlockCache::ClearSafe() + void JitBaseBlockCache::ClearSafe() { #ifdef JIT_UNLIMITED_ICACHE memset(iCache, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE); @@ -160,7 +158,7 @@ bool JitBlock::ContainsAddress(u32 em_address) #endif } - /*void JitBlockCache::DestroyBlocksWithFlag(BlockFlag death_flag) + /*void JitBaseBlockCache::DestroyBlocksWithFlag(BlockFlag death_flag) { for (int i = 0; i < num_blocks; i++) { @@ -171,23 +169,23 @@ bool JitBlock::ContainsAddress(u32 em_address) } }*/ - void JitBlockCache::Reset() + void JitBaseBlockCache::Reset() { Shutdown(); Init(); } - JitBlock *JitBlockCache::GetBlock(int no) + JitBlock *JitBaseBlockCache::GetBlock(int no) { return &blocks[no]; } - int JitBlockCache::GetNumBlocks() const + int JitBaseBlockCache::GetNumBlocks() const { return num_blocks; } - bool JitBlockCache::RangeIntersect(int s1, int e1, int s2, int e2) const + bool JitBaseBlockCache::RangeIntersect(int s1, int e1, int s2, int e2) const { // check if any endpoint is inside the other range if ((s1 >= s2 && s1 <= e2) || @@ -199,7 +197,7 @@ bool JitBlock::ContainsAddress(u32 em_address) return false; } - int JitBlockCache::AllocateBlock(u32 em_address) + int JitBaseBlockCache::AllocateBlock(u32 em_address) { JitBlock &b = blocks[num_blocks]; b.invalid = false; @@ -215,12 +213,12 @@ bool JitBlock::ContainsAddress(u32 em_address) return num_blocks - 1; } - void JitBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr) + void JitBaseBlockCache::FinalizeBlock(int block_num, bool block_link, const u8 *code_ptr) { blockCodePointers[block_num] = code_ptr; JitBlock &b = blocks[block_num]; - b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress); - Memory::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num); + b.originalFirstOpcode = JitInterface::Read_Opcode_JIT(b.originalAddress); + JitInterface::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num); // Convert the logical address to a physical address for the block map u32 pAddr = b.originalAddress & 0x1FFFFFFF; @@ -264,29 +262,29 @@ bool JitBlock::ContainsAddress(u32 em_address) #endif } - const u8 **JitBlockCache::GetCodePointers() + const u8 **JitBaseBlockCache::GetCodePointers() { return blockCodePointers; } #ifdef JIT_UNLIMITED_ICACHE - u8* JitBlockCache::GetICache() + u8* JitBaseBlockCache::GetICache() { return iCache; } - u8* JitBlockCache::GetICacheEx() + u8* JitBaseBlockCache::GetICacheEx() { return iCacheEx; } - u8* JitBlockCache::GetICacheVMEM() + u8* JitBaseBlockCache::GetICacheVMEM() { return iCacheVMEM; } #endif - int JitBlockCache::GetBlockNumberFromStartAddress(u32 addr) + int JitBaseBlockCache::GetBlockNumberFromStartAddress(u32 addr) { if (!blocks) return -1; @@ -317,24 +315,24 @@ bool JitBlock::ContainsAddress(u32 em_address) return inst; } - void JitBlockCache::GetBlockNumbersFromAddress(u32 em_address, std::vector *block_numbers) + void JitBaseBlockCache::GetBlockNumbersFromAddress(u32 em_address, std::vector *block_numbers) { for (int i = 0; i < num_blocks; i++) if (blocks[i].ContainsAddress(em_address)) block_numbers->push_back(i); } - u32 JitBlockCache::GetOriginalFirstOp(int block_num) + u32 JitBaseBlockCache::GetOriginalFirstOp(int block_num) { if (block_num >= num_blocks) { - //PanicAlert("JitBlockCache::GetOriginalFirstOp - block_num = %u is out of range", block_num); + //PanicAlert("JitBaseBlockCache::GetOriginalFirstOp - block_num = %u is out of range", block_num); return block_num; } return blocks[block_num].originalFirstOpcode; } - CompiledCode JitBlockCache::GetCompiledCodeFromBlock(int block_num) + CompiledCode JitBaseBlockCache::GetCompiledCodeFromBlock(int block_num) { return (CompiledCode)blockCodePointers[block_num]; } @@ -345,7 +343,7 @@ bool JitBlock::ContainsAddress(u32 em_address) //Can be faster by doing a queue for blocks to link up, and only process those //Should probably be done - void JitBlockCache::LinkBlockExits(int i) + void JitBaseBlockCache::LinkBlockExits(int i) { JitBlock &b = blocks[i]; if (b.invalid) @@ -360,8 +358,7 @@ bool JitBlock::ContainsAddress(u32 em_address) int destinationBlock = GetBlockNumberFromStartAddress(b.exitAddress[e]); if (destinationBlock != -1) { - XEmitter emit(b.exitPtrs[e]); - emit.JMP(blocks[destinationBlock].checkedEntry, true); + WriteLinkBlock(b.exitPtrs[e], blocks[destinationBlock].checkedEntry); b.linkStatus[e] = true; } } @@ -370,7 +367,7 @@ bool JitBlock::ContainsAddress(u32 em_address) using namespace std; - void JitBlockCache::LinkBlock(int i) + void JitBaseBlockCache::LinkBlock(int i) { LinkBlockExits(i); JitBlock &b = blocks[i]; @@ -386,7 +383,7 @@ bool JitBlock::ContainsAddress(u32 em_address) } } - void JitBlockCache::UnlinkBlock(int i) + void JitBaseBlockCache::UnlinkBlock(int i) { JitBlock &b = blocks[i]; pair::iterator, multimap::iterator> ppp; @@ -403,7 +400,7 @@ bool JitBlock::ContainsAddress(u32 em_address) } } - void JitBlockCache::DestroyBlock(int block_num, bool invalidate) + void JitBaseBlockCache::DestroyBlock(int block_num, bool invalidate) { if (block_num < 0 || block_num >= num_blocks) { @@ -419,7 +416,7 @@ bool JitBlock::ContainsAddress(u32 em_address) } b.invalid = true; #ifdef JIT_UNLIMITED_ICACHE - Memory::Write_Opcode_JIT(b.originalAddress, b.originalFirstOpcode?b.originalFirstOpcode:JIT_ICACHE_INVALID_WORD); + JitInterface::Write_Opcode_JIT(b.originalAddress, b.originalFirstOpcode?b.originalFirstOpcode:JIT_ICACHE_INVALID_WORD); #else if (Memory::ReadFast32(b.originalAddress) == block_num) Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress); @@ -430,18 +427,10 @@ bool JitBlock::ContainsAddress(u32 em_address) // Send anyone who tries to run this block back to the dispatcher. // Not entirely ideal, but .. pretty good. // Spurious entrances from previously linked blocks can only come through checkedEntry - XEmitter emit((u8 *)b.checkedEntry); - emit.MOV(32, M(&PC), Imm32(b.originalAddress)); - emit.JMP(jit->GetAsmRoutines()->dispatcher, true); - // this is not needed really - /* - emit.SetCodePtr((u8 *)blockCodePointers[blocknum]); - emit.MOV(32, M(&PC), Imm32(b.originalAddress)); - emit.JMP(asm_routines.dispatcher, true); - */ + WriteDestroyBlock(b.checkedEntry, b.originalAddress); } - void JitBlockCache::InvalidateICache(u32 address, const u32 length) + void JitBaseBlockCache::InvalidateICache(u32 address, const u32 length) { // Convert the logical address to a physical address for the block map u32 pAddr = address & 0x1FFFFFFF; @@ -449,7 +438,7 @@ bool JitBlock::ContainsAddress(u32 em_address) // Optimize the common case of length == 32 which is used by Interpreter::dcb* bool destroy_block = true; if (length == 32) - { + { if (!valid_block[pAddr / 32]) destroy_block = false; else @@ -462,7 +451,7 @@ bool JitBlock::ContainsAddress(u32 em_address) { std::map, u32>::iterator it1 = block_map.lower_bound(std::make_pair(pAddr, 0)), it2 = it1; while (it2 != block_map.end() && it2->first.second < pAddr + length) - { + { #ifdef JIT_UNLIMITED_ICACHE JitBlock &b = blocks[it2->second]; if (b.originalAddress & JIT_ICACHE_VMEM_BIT) @@ -516,3 +505,14 @@ bool JitBlock::ContainsAddress(u32 em_address) } #endif } + void JitBlockCache::WriteLinkBlock(u8* location, const u8* address) + { + XEmitter emit(location); + emit.JMP(address, true); + } + void JitBlockCache::WriteDestroyBlock(const u8* location, u32 address) + { + XEmitter emit((u8 *)location); + emit.MOV(32, M(&PC), Imm32(address)); + emit.JMP(jit->GetAsmRoutines()->dispatcher, true); + } diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h index 4214f33875..b148cb8090 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h @@ -78,7 +78,8 @@ struct JitBlock typedef void (*CompiledCode)(); -class JitBlockCache + +class JitBaseBlockCache { const u8 **blockCodePointers; JitBlock *blocks; @@ -97,9 +98,13 @@ class JitBlockCache void LinkBlockExits(int i); void LinkBlock(int i); void UnlinkBlock(int i); + + // Virtual for overloaded + virtual void WriteLinkBlock(u8* location, const u8* address) = 0; + virtual void WriteDestroyBlock(const u8* location, u32 address) = 0; public: - JitBlockCache() : + JitBaseBlockCache() : blockCodePointers(0), blocks(0), num_blocks(0), #ifdef JIT_UNLIMITED_ICACHE iCache(0), iCacheEx(0), iCacheVMEM(0), @@ -146,4 +151,11 @@ public: //void DestroyBlocksWithFlag(BlockFlag death_flag); }; +// x86 BlockCache +class JitBlockCache : public JitBaseBlockCache +{ +private: + void WriteLinkBlock(u8* location, const u8* address); + void WriteDestroyBlock(const u8* location, u32 address); +}; #endif diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp index cc1327c695..f5c4cb022b 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp @@ -25,7 +25,7 @@ #include "../../HW/Memmap.h" #include "../PPCTables.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "JitBase.h" #include "Jit_Util.h" diff --git a/Source/Core/Core/Src/PowerPC/JitInterface.cpp b/Source/Core/Core/Src/PowerPC/JitInterface.cpp new file mode 100644 index 0000000000..8fcdd9837f --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitInterface.cpp @@ -0,0 +1,350 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include + +#ifdef _WIN32 +#include +#endif + +#include "JitInterface.h" +#include "JitCommon/JitBase.h" + +#ifndef _M_GENERIC +#include "Jit64IL/JitIL.h" +#include "Jit64/Jit.h" +#include "Jit64/Jit64_Tables.h" +#include "Jit64IL/JitIL_Tables.h" +#endif + +#ifdef _M_ARM +#include "JitArm32/Jit.h" +#include "JitArm32/JitArm_Tables.h" +#endif + +#include "Profiler.h" +#include "PPCSymbolDB.h" +#include "HW/Memmap.h" +#include "ConfigManager.h" + +bool bFakeVMEM = false; +bool bMMU = false; + +namespace JitInterface +{ + void DoState(PointerWrap &p) + { + if (jit && p.GetMode() == PointerWrap::MODE_READ) + jit->GetBlockCache()->ClearSafe(); + } + CPUCoreBase *InitJitCore(int core) + { + bFakeVMEM = SConfig::GetInstance().m_LocalCoreStartupParameter.iTLBHack == 1; + bMMU = SConfig::GetInstance().m_LocalCoreStartupParameter.bMMU; + + CPUCoreBase *ptr = NULL; + switch(core) + { + #ifndef _M_GENERIC + case 1: + { + ptr = new Jit64(); + break; + } + case 2: + { + ptr = new JitIL(); + break; + } + #endif + #ifdef _M_ARM + case 3: + { + ptr = new JitArm(); + break; + } + #endif + default: + { + PanicAlert("Unrecognizable cpu_core: %d", core); + return NULL; + break; + } + } + jit = static_cast(ptr); + jit->Init(); + return ptr; + } + void InitTables(int core) + { + switch(core) + { + #ifndef _M_GENERIC + case 1: + { + Jit64Tables::InitTables(); + break; + } + case 2: + { + JitILTables::InitTables(); + break; + } + #endif + #ifdef _M_ARM + case 3: + { + JitArmTables::InitTables(); + break; + } + #endif + default: + { + PanicAlert("Unrecognizable cpu_core: %d", core); + break; + } + } + } + CPUCoreBase *GetCore() + { + return jit; + } + + void WriteProfileResults(const char *filename) + { + // Can't really do this with no jit core available + #ifndef _M_GENERIC + + std::vector stats; + stats.reserve(jit->GetBlockCache()->GetNumBlocks()); + u64 cost_sum = 0; + #ifdef _WIN32 + u64 timecost_sum = 0; + u64 countsPerSec; + QueryPerformanceFrequency((LARGE_INTEGER *)&countsPerSec); + #endif + for (int i = 0; i < jit->GetBlockCache()->GetNumBlocks(); i++) + { + const JitBlock *block = jit->GetBlockCache()->GetBlock(i); + // Rough heuristic. Mem instructions should cost more. + u64 cost = block->originalSize * (block->runCount / 4); + #ifdef _WIN32 + u64 timecost = block->ticCounter; + #endif + // Todo: tweak. + if (block->runCount >= 1) + stats.push_back(BlockStat(i, cost)); + cost_sum += cost; + #ifdef _WIN32 + timecost_sum += timecost; + #endif + } + + sort(stats.begin(), stats.end()); + File::IOFile f(filename, "w"); + if (!f) + { + PanicAlert("failed to open %s", filename); + return; + } + fprintf(f.GetHandle(), "origAddr\tblkName\tcost\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n"); + for (unsigned int i = 0; i < stats.size(); i++) + { + const JitBlock *block = jit->GetBlockCache()->GetBlock(stats[i].blockNum); + if (block) + { + std::string name = g_symbolDB.GetDescription(block->originalAddress); + double percent = 100.0 * (double)stats[i].cost / (double)cost_sum; + #ifdef _WIN32 + double timePercent = 100.0 * (double)block->ticCounter / (double)timecost_sum; + fprintf(f.GetHandle(), "%08x\t%s\t%llu\t%llu\t%.2lf\t%llf\t%lf\t%i\n", + block->originalAddress, name.c_str(), stats[i].cost, + block->ticCounter, percent, timePercent, + (double)block->ticCounter*1000.0/(double)countsPerSec, block->codeSize); + #else + fprintf(f.GetHandle(), "%08x\t%s\t%llu\t???\t%.2lf\t???\t???\t%i\n", + block->originalAddress, name.c_str(), stats[i].cost, percent, block->codeSize); + #endif + } + } + #endif + } + bool IsInCodeSpace(u8 *ptr) + { + return jit->IsInCodeSpace(ptr); + } + const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx) + { + return jit->BackPatch(codePtr, accessType, em_address, ctx); + } + + void ClearCache() + { + if (jit) + jit->ClearCache(); + } + void ClearSafe() + { + if (jit) + jit->GetBlockCache()->ClearSafe(); + } + + void InvalidateICache(u32 address, u32 size) + { + if (jit) + jit->GetBlockCache()->InvalidateICache(address, size); + } + + + // Memory functions + u32 Read_Opcode_JIT_Uncached(const u32 _Address) + { + u8* iCache; + u32 addr; + if (_Address & JIT_ICACHE_VMEM_BIT) + { + iCache = jit->GetBlockCache()->GetICacheVMEM(); + addr = _Address & JIT_ICACHE_MASK; + } + else if (_Address & JIT_ICACHE_EXRAM_BIT) + { + iCache = jit->GetBlockCache()->GetICacheEx(); + addr = _Address & JIT_ICACHEEX_MASK; + } + else + { + iCache = jit->GetBlockCache()->GetICache(); + addr = _Address & JIT_ICACHE_MASK; + } + u32 inst = *(u32*)(iCache + addr); + if (inst == JIT_ICACHE_INVALID_WORD) + { + u32 cache_block_start = addr & ~0x1f; + u32 mem_block_start = _Address & ~0x1f; + u8 *pMem = Memory::GetPointer(mem_block_start); + memcpy(iCache + cache_block_start, pMem, 32); + inst = *(u32*)(iCache + addr); + } + inst = Common::swap32(inst); + + if ((inst & 0xfc000000) == 0) + { + inst = jit->GetBlockCache()->GetOriginalFirstOp(inst); + } + + return inst; + } + + u32 Read_Opcode_JIT(u32 _Address) + { + #ifdef FAST_ICACHE + if (bMMU && !bFakeVMEM && (_Address & Memory::ADDR_MASK_MEM1)) + { + _Address = Memory::TranslateAddress(_Address, Memory::FLAG_OPCODE); + if (_Address == 0) + { + return 0; + } + } + u32 inst = 0; + + // Bypass the icache for the external interrupt exception handler + if ( (_Address & 0x0FFFFF00) == 0x00000500 ) + inst = Read_Opcode_JIT_Uncached(_Address); + else + inst = PowerPC::ppcState.iCache.ReadInstruction(_Address); + #else + u32 inst = Memory::ReadUnchecked_U32(_Address); + #endif + return inst; + } + + // The following function is deprecated in favour of FAST_ICACHE + u32 Read_Opcode_JIT_LC(const u32 _Address) + { + #ifdef JIT_UNLIMITED_ICACHE + if ((_Address & ~JIT_ICACHE_MASK) != 0x80000000 && (_Address & ~JIT_ICACHE_MASK) != 0x00000000 && + (_Address & ~JIT_ICACHE_MASK) != 0x7e000000 && // TLB area + (_Address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (_Address & ~JIT_ICACHEEX_MASK) != 0x10000000) + { + PanicAlertT("iCacheJIT: Reading Opcode from %x. Please report.", _Address); + ERROR_LOG(MEMMAP, "iCacheJIT: Reading Opcode from %x. Please report.", _Address); + return 0; + } + u8* iCache; + u32 addr; + if (_Address & JIT_ICACHE_VMEM_BIT) + { + iCache = jit->GetBlockCache()->GetICacheVMEM(); + addr = _Address & JIT_ICACHE_MASK; + } + else if (_Address & JIT_ICACHE_EXRAM_BIT) + { + iCache = jit->GetBlockCache()->GetICacheEx(); + addr = _Address & JIT_ICACHEEX_MASK; + } + else + { + iCache = jit->GetBlockCache()->GetICache(); + addr = _Address & JIT_ICACHE_MASK; + } + u32 inst = *(u32*)(iCache + addr); + if (inst == JIT_ICACHE_INVALID_WORD) + inst = Memory::ReadUnchecked_U32(_Address); + else + inst = Common::swap32(inst); + #else + u32 inst = Memory::ReadUnchecked_U32(_Address); + #endif + if ((inst & 0xfc000000) == 0) + { + inst = jit->GetBlockCache()->GetOriginalFirstOp(inst); + } + return inst; + } + + // WARNING! No checks! + // We assume that _Address is cached + void Write_Opcode_JIT(const u32 _Address, const u32 _Value) + { + #ifdef JIT_UNLIMITED_ICACHE + if (_Address & JIT_ICACHE_VMEM_BIT) + { + *(u32*)(jit->GetBlockCache()->GetICacheVMEM() + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value); + } + else if (_Address & JIT_ICACHE_EXRAM_BIT) + { + *(u32*)(jit->GetBlockCache()->GetICacheEx() + (_Address & JIT_ICACHEEX_MASK)) = Common::swap32(_Value); + } + else + *(u32*)(jit->GetBlockCache()->GetICache() + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value); + #else + Memory::WriteUnchecked_U32(_Value, _Address); + #endif + } + + + void Shutdown() + { + if (jit) + { + jit->Shutdown(); + delete jit; + jit = NULL; + } + } +} diff --git a/Source/Core/Core/Src/PowerPC/JitInterface.h b/Source/Core/Core/Src/PowerPC/JitInterface.h new file mode 100644 index 0000000000..a01c3dfa6e --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitInterface.h @@ -0,0 +1,56 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "ChunkFile.h" +#include "CPUCoreBase.h" + +namespace JitInterface +{ + void DoState(PointerWrap &p); + + CPUCoreBase *InitJitCore(int core); + void InitTables(int core); + CPUCoreBase *GetCore(); + + // Debugging + void WriteProfileResults(const char *filename); + + // Memory Utilities + bool IsInCodeSpace(u8 *ptr); + const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx); + + // used by JIT to read instructions + u32 Read_Opcode_JIT(const u32 _Address); + // used by JIT. uses iCacheJIT. Reads in the "Locked cache" mode + u32 Read_Opcode_JIT_LC(const u32 _Address); + void Write_Opcode_JIT(const u32 _Address, const u32 _Value); + + // Clearing CodeCache + void ClearCache(); + + void ClearSafe(); + + void InvalidateICache(u32 address, u32 size); + + void Shutdown(); +} +extern bool bFakeVMEM; +extern bool bMMU; + +#ifdef _M_ARM +#include "JitArm32/Jit.h" +#endif diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index fa9f278c29..15a85568de 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -21,6 +21,7 @@ #include "StringUtil.h" #include "Interpreter/Interpreter.h" #include "../HW/Memmap.h" +#include "JitInterface.h" #include "PPCTables.h" #include "PPCSymbolDB.h" #include "SignatureDB.h" @@ -368,7 +369,7 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, } else { - inst = Memory::Read_Opcode_JIT(address); + inst = JitInterface::Read_Opcode_JIT(address); } } diff --git a/Source/Core/Core/Src/PowerPC/PPCCache.cpp b/Source/Core/Core/Src/PowerPC/PPCCache.cpp index 6956e9db1c..a0e4c666a4 100644 --- a/Source/Core/Core/Src/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCCache.cpp @@ -20,6 +20,7 @@ #include "PowerPC.h" #include "JitCommon/JitBase.h" #include "JitCommon/JitCache.h" +#include "JitInterface.h" namespace PowerPC { @@ -76,8 +77,7 @@ namespace PowerPC memset(lookup_table_ex, 0xff, sizeof(lookup_table_ex)); memset(lookup_table_vmem, 0xff, sizeof(lookup_table_vmem)); #endif - if (jit) - jit->GetBlockCache()->ClearSafe(); + JitInterface::ClearSafe(); } void InstructionCache::Init() @@ -109,8 +109,7 @@ namespace PowerPC } #endif valid[set] = 0; - if (jit) - jit->GetBlockCache()->InvalidateICache(addr & ~0x1f, 32); + JitInterface::InvalidateICache(addr & ~0x1f, 32); } u32 InstructionCache::ReadInstruction(u32 addr) diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index d96089cebb..a6975f5860 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -24,11 +24,7 @@ #include "FileUtil.h" #include "Interpreter/Interpreter.h" #include "Interpreter/Interpreter_Tables.h" -#include "Jit64IL/JitIL_Tables.h" -#include "Jit64/Jit64_Tables.h" - -#include "Jit64IL/JitIL.h" -#include "Jit64/Jit.h" +#include "JitInterface.h" struct op_inf { @@ -165,19 +161,9 @@ void InitTables(int cpu_core) // Interpreter break; } - case 1: - { - Jit64Tables::InitTables(); - break; - } - case 2: - { - JitILTables::InitTables(); - break; - } default: { - PanicAlert("Unrecognizable cpu_core: %d", cpu_core); + JitInterface::InitTables(cpu_core); break; } } diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 8a7b817212..d4447331e7 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -29,12 +29,10 @@ #include "../HW/SystemTimers.h" #include "Interpreter/Interpreter.h" -#include "JitCommon/JitBase.h" -#include "Jit64IL/JitIL.h" -#include "Jit64/Jit.h" #include "PowerPC.h" #include "PPCTables.h" #include "CPUCoreBase.h" +#include "JitInterface.h" #include "../Host.h" #include "HW/EXI.h" @@ -87,8 +85,7 @@ void DoState(PointerWrap &p) // SystemTimers::DecrementerSet(); // SystemTimers::TimeBaseSet(); - if (jit && p.GetMode() == PointerWrap::MODE_READ) - jit->GetBlockCache()->ClearSafe(); + JitInterface::DoState(p); } void ResetRegisters() @@ -131,28 +128,18 @@ void ResetRegisters() void Init(int cpu_core) { - enum { - FPU_PREC_24 = 0 << 8, - FPU_PREC_53 = 2 << 8, - FPU_PREC_64 = 3 << 8, - FPU_PREC_MASK = 3 << 8, - }; -#ifdef _M_IX86 - // sets the floating-point lib to 53-bit - // PowerPC has a 53bit floating pipeline only - // eg: sscanf is very sensitive -#ifdef _WIN32 - _control87(_PC_53, MCW_PC); -#else - unsigned short _mode; - asm ("fstcw %0" : : "m" (_mode)); - _mode = (_mode & ~FPU_PREC_MASK) | FPU_PREC_53; - asm ("fldcw %0" : : "m" (_mode)); -#endif -#else - //x64 doesn't need this - fpu is done with SSE - //but still - set any useful sse options here -#endif + FPURoundMode::SetPrecisionMode(FPURoundMode::PREC_53); + + memset(ppcState.mojs, 0, sizeof(ppcState.mojs)); + memset(ppcState.sr, 0, sizeof(ppcState.sr)); + ppcState.DebugCount = 0; + ppcState.dtlb_last = 0; + ppcState.dtlb_last = 0; + memset(ppcState.dtlb_va, 0, sizeof(ppcState.dtlb_va)); + memset(ppcState.dtlb_pa, 0, sizeof(ppcState.dtlb_pa)); + ppcState.itlb_last = 0; + memset(ppcState.itlb_va, 0, sizeof(ppcState.itlb_va)); + memset(ppcState.itlb_pa, 0, sizeof(ppcState.itlb_pa)); memset(ppcState.mojs, 0, sizeof(ppcState.mojs)); memset(ppcState.sr, 0, sizeof(ppcState.sr)); @@ -179,27 +166,13 @@ void Init(int cpu_core) cpu_core_base = interpreter; break; } - case 1: - { - cpu_core_base = new Jit64(); - break; - } - case 2: - { - cpu_core_base = new JitIL(); - break; - } - default: - { - PanicAlert("Unrecognizable cpu_core: %d", cpu_core); - break; - } + default: + cpu_core_base = JitInterface::InitJitCore(cpu_core); + break; } if (cpu_core_base != interpreter) { - jit = static_cast(cpu_core_base); - jit->Init(); mode = MODE_JIT; } else @@ -213,12 +186,7 @@ void Init(int cpu_core) void Shutdown() { - if (jit) - { - jit->Shutdown(); - delete jit; - jit = NULL; - } + JitInterface::Shutdown(); interpreter->Shutdown(); cpu_core_base = NULL; state = CPU_POWERDOWN; @@ -244,7 +212,7 @@ void SetMode(CoreMode new_mode) case MODE_JIT: // Switching from interpreter to JIT. // Don't really need to do much. It'll work, the cache will refill itself. - cpu_core_base = jit; + cpu_core_base = JitInterface::GetCore(); break; } } diff --git a/Source/Core/Core/Src/PowerPC/Profiler.cpp b/Source/Core/Core/Src/PowerPC/Profiler.cpp index 3636b00717..fc8942f09b 100644 --- a/Source/Core/Core/Src/PowerPC/Profiler.cpp +++ b/Source/Core/Core/Src/PowerPC/Profiler.cpp @@ -15,17 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include "JitCommon/JitBase.h" - -#include -#include - -#ifdef _WIN32 -#include -#endif - -#include "PPCSymbolDB.h" -#include "FileUtil.h" +#include "JitInterface.h" namespace Profiler { @@ -33,73 +23,9 @@ namespace Profiler bool g_ProfileBlocks; bool g_ProfileInstructions; -struct BlockStat -{ - BlockStat(int bn, u64 c) : blockNum(bn), cost(c) {} - int blockNum; - u64 cost; - - bool operator <(const BlockStat &other) const - { return cost > other.cost; } -}; - void WriteProfileResults(const char *filename) { - std::vector stats; - stats.reserve(jit->GetBlockCache()->GetNumBlocks()); - u64 cost_sum = 0; -#ifdef _WIN32 - u64 timecost_sum = 0; - u64 countsPerSec; - QueryPerformanceFrequency((LARGE_INTEGER *)&countsPerSec); -#endif - for (int i = 0; i < jit->GetBlockCache()->GetNumBlocks(); i++) - { - const JitBlock *block = jit->GetBlockCache()->GetBlock(i); - if (block && !block->invalid) - { - // Rough heuristic. Mem instructions should cost more. - u64 cost = block->originalSize * (block->runCount / 4); -#ifdef _WIN32 - u64 timecost = block->ticCounter; -#endif - // Todo: tweak. - if (block->runCount >= 1) - stats.push_back(BlockStat(i, cost)); - cost_sum += cost; -#ifdef _WIN32 - timecost_sum += timecost; -#endif - } - } - - sort(stats.begin(), stats.end()); - File::IOFile f(filename, "w"); - if (!f) - { - PanicAlert("failed to open %s", filename); - return; - } - fprintf(f.GetHandle(), "origAddr\tblkName\tcost\trunCount\ttimeCost\tpercent\ttimePercent\tOvAllinBlkTime(ms)\tblkCodeSize\n"); - for (unsigned int i = 0; i < stats.size(); i++) - { - const JitBlock *block = jit->GetBlockCache()->GetBlock(stats[i].blockNum); - if (block && !block->invalid) - { - std::string name = g_symbolDB.GetDescription(block->originalAddress); - double percent = 100.0 * (double)stats[i].cost / (double)cost_sum; -#ifdef _WIN32 - double timePercent = 100.0 * (double)block->ticCounter / (double)timecost_sum; - fprintf(f.GetHandle(), "%08x\t%s\t%llu\t%llu\t%llu\t%.2lf\t%llf\t%lf\t%i\n", - block->originalAddress, name.c_str(), stats[i].cost, block->runCount, - block->ticCounter, percent, timePercent, - (double)block->ticCounter*1000.0/(double)countsPerSec, block->codeSize); -#else - fprintf(f.GetHandle(), "%08x\t%s\t%llu\t???\t%.2lf\t???\t???\t%i\n", - block->originalAddress, name.c_str(), stats[i].cost, percent, block->codeSize); -#endif - } - } + JitInterface::WriteProfileResults(filename); } } // namespace diff --git a/Source/Core/Core/Src/PowerPC/Profiler.h b/Source/Core/Core/Src/PowerPC/Profiler.h index ada130e90f..b8beeaae72 100644 --- a/Source/Core/Core/Src/PowerPC/Profiler.h +++ b/Source/Core/Core/Src/PowerPC/Profiler.h @@ -57,6 +57,15 @@ #define PROFILER_VPOP #endif +struct BlockStat +{ + BlockStat(int bn, u64 c) : blockNum(bn), cost(c) {} + int blockNum; + u64 cost; + + bool operator <(const BlockStat &other) const + { return cost > other.cost; } +}; namespace Profiler { diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/x64MemTools.cpp similarity index 96% rename from Source/Core/Core/Src/MemTools.cpp rename to Source/Core/Core/Src/x64MemTools.cpp index bb6fef6439..fff26b3cb3 100644 --- a/Source/Core/Core/Src/MemTools.cpp +++ b/Source/Core/Core/Src/x64MemTools.cpp @@ -52,8 +52,10 @@ #include "MemTools.h" #include "HW/Memmap.h" #include "PowerPC/PowerPC.h" +#include "PowerPC/JitInterface.h" +#ifndef _M_GENERIC #include "PowerPC/JitCommon/JitBase.h" -#include "PowerPC/JitCommon/JitBackpatch.h" +#endif #include "x64Analyzer.h" namespace EMM @@ -77,7 +79,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) PVOID codeAddr = pPtrs->ExceptionRecord->ExceptionAddress; unsigned char *codePtr = (unsigned char*)codeAddr; - if (!jit->IsInCodeSpace(codePtr)) { + if (!JitInterface::IsInCodeSpace(codePtr)) { // Let's not prevent debugging. return (DWORD)EXCEPTION_CONTINUE_SEARCH; } @@ -107,7 +109,7 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs) //We could emulate the memory accesses here, but then they would still be around to take up //execution resources. Instead, we backpatch into a generic memory call and retry. - const u8 *new_rip = jit->BackPatch(codePtr, accessType, emAddress, ctx); + const u8 *new_rip = JitInterface::BackPatch(codePtr, accessType, emAddress, ctx); // Rip/Eip needs to be updated. if (new_rip) @@ -182,6 +184,7 @@ void print_trace(const char * msg) void sigsegv_handler(int signal, siginfo_t *info, void *raw_context) { +#ifndef _M_GENERIC if (signal != SIGSEGV) { // We are not interested in other signals - handle it as usual. @@ -203,7 +206,7 @@ void sigsegv_handler(int signal, siginfo_t *info, void *raw_context) #else u8 *fault_instruction_ptr = (u8 *)CREG_EIP(ctx); #endif - if (!jit->IsInCodeSpace(fault_instruction_ptr)) { + if (!JitInterface::IsInCodeSpace(fault_instruction_ptr)) { // Let's not prevent debugging. return; } @@ -240,6 +243,7 @@ void sigsegv_handler(int signal, siginfo_t *info, void *raw_context) CREG_EIP(ctx) = fake_ctx.Eip; #endif } +#endif } void InstallExceptionHandler() diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp index 6451c73670..2350896c9c 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.cpp +++ b/Source/Core/DiscIO/Src/BannerLoader.cpp @@ -27,7 +27,9 @@ #include #else #include +#ifndef ANDROID #include +#endif #include #endif @@ -131,6 +133,9 @@ bool IBannerLoader::CopyBeUnicodeToString( std::string& _rDestination, const u16 delete[] buffer; } } +#else +#ifdef ANDROID + return false; #else if (_src) { @@ -193,6 +198,7 @@ bool IBannerLoader::CopyBeUnicodeToString( std::string& _rDestination, const u16 delete[] src_buffer_start; iconv_close(conv_desc); } +#endif #endif return returnCode; } diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt index 858e05bbfd..c3cdccccfc 100644 --- a/Source/Core/DolphinWX/CMakeLists.txt +++ b/Source/Core/DolphinWX/CMakeLists.txt @@ -10,21 +10,21 @@ set(LIBS core ${GTK2_LIBRARIES} ${XRANDR_LIBRARIES} ${X11_LIBRARIES}) - -if(SDL2_FOUND) - # Using shared SDL2 - set(LIBS ${LIBS} ${SDL2_LIBRARY}) -else(SDL2_FOUND) - if(SDL_FOUND) - # Using shared SDL - set(LIBS ${LIBS} ${SDL_LIBRARY}) - else(SDL_FOUND) - # Using static SDL from Externals - set(LIBS ${LIBS} SDL) +if(NOT ANDROID) + if(SDL2_FOUND) + # Using shared SDL2 + set(LIBS ${LIBS} ${SDL2_LIBRARY}) + else(SDL2_FOUND) + if(SDL_FOUND) + # Using shared SDL + set(LIBS ${LIBS} ${SDL_LIBRARY}) + else(SDL_FOUND) + # Using static SDL from Externals + set(LIBS ${LIBS} SDL) + endif() endif() endif() - if(LIBAV_FOUND) set(LIBS ${LIBS} ${LIBAV_LIBRARIES}) endif() @@ -79,13 +79,18 @@ if(wxWidgets_FOUND) set(WXLIBS ${wxWidgets_LIBRARIES}) else() - set(SRCS - Src/MainNoGUI.cpp) + if(ANDROID) + set(SRCS Src/MainAndroid.cpp) + else() + set(SRCS Src/MainNoGUI.cpp) + endif() endif() if(USE_EGL) - set(SRCS ${SRCS} Src/GLInterface/EGL.cpp - Src/GLInterface/X11_Util.cpp) + if(NOT ANDROID) + set(SRCS ${SRCS} Src/GLInterface/EGL_X11.cpp + Src/GLInterface/X11_Util.cpp) + endif() else() if(WIN32) set(SRCS ${SRCS} Src/GLInterface/GLW.cpp) @@ -127,7 +132,9 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set_source_files_properties(${RESOURCES} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) else() - set(SRCS ${SRCS} Src/X11Utils.cpp) + if(NOT ANDROID) + set(SRCS ${SRCS} Src/X11Utils.cpp) + endif() endif() if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD" OR @@ -146,75 +153,85 @@ else() set(DOLPHIN_EXE ${DOLPHIN_EXE_BASE}-nogui) endif() -add_executable(${DOLPHIN_EXE} ${SRCS}) -target_link_libraries(${DOLPHIN_EXE} ${LIBS} ${WXLIBS}) - -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - include(BundleUtilities) - set(BUNDLE_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${DOLPHIN_EXE}.app) - - # Ask for an application bundle. - set_target_properties(${DOLPHIN_EXE} PROPERTIES - MACOSX_BUNDLE true - MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in - ) - - # Install Cg framework into application bundle. - copy_resolved_framework_into_bundle( - # Our framework in "Externals" does not have "Versions/Current/" in - # its path; work around the missing directory levels using "././". - "${CMAKE_SOURCE_DIR}/Externals/Cg/Cg.framework/././Cg" - "${BUNDLE_PATH}/Contents/Frameworks/Cg.framework/././Cg" - ) - - # Fix up the bundle after it is finished. - # There does not seem to be an easy way to run CMake commands post-build, - # so we invoke CMake again on a generated script. - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/postprocess_bundle.cmake " - include(BundleUtilities) - message(\"Fixing up application bundle: ${BUNDLE_PATH}\") - set(BU_CHMOD_BUNDLE_ITEMS ON) - fixup_bundle(\"${BUNDLE_PATH}\" \"\" \"\") - ") - add_custom_command(TARGET ${DOLPHIN_EXE} POST_BUILD - COMMAND ${CMAKE_COMMAND} -P postprocess_bundle.cmake - ) - - # Copy data files into application bundle. - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/copy_data_into_bundle.cmake " - file(INSTALL ${CMAKE_SOURCE_DIR}/Data/Sys ${CMAKE_SOURCE_DIR}/Data/User - DESTINATION ${BUNDLE_PATH}/Contents/Resources - ) - file(GLOB TRANSLATION_FILES RELATIVE ${CMAKE_BINARY_DIR} - ${CMAKE_BINARY_DIR}/*.gmo - ) - foreach(TRANSLATION_FILE \${TRANSLATION_FILES}) - string(REPLACE \".gmo\" \".lproj\" TRANSLATION_DIR - \${TRANSLATION_FILE} - ) - # It would be better to copy to the new name as a single action, - # but I can't figure out a way to let CMake do that. - file(COPY ${CMAKE_BINARY_DIR}/\${TRANSLATION_FILE} - DESTINATION ${BUNDLE_PATH}/Contents/Resources/\${TRANSLATION_DIR} - NO_SOURCE_PERMISSIONS - ) - file(RENAME - ${BUNDLE_PATH}/Contents/Resources/\${TRANSLATION_DIR}/\${TRANSLATION_FILE} - ${BUNDLE_PATH}/Contents/Resources/\${TRANSLATION_DIR}/dolphin-emu.mo - ) - endforeach(TRANSLATION_FILE) - ") - add_custom_target(CopyDataIntoBundle ALL - COMMAND ${CMAKE_COMMAND} -P copy_data_into_bundle.cmake - VERBATIM - ) - - # Install bundle into systemwide /Applications directory. - install(DIRECTORY ${BUNDLE_PATH} DESTINATION /Applications - USE_SOURCE_PERMISSIONS - ) +if(ANDROID) + add_library(${DOLPHIN_EXE} SHARED ${SRCS}) + target_link_libraries(${DOLPHIN_EXE} + log + android + "-Wl,--whole-archive" + ${LIBS} + "-Wl,--no-whole-archive" + ) else() - install(TARGETS ${DOLPHIN_EXE} RUNTIME DESTINATION ${bindir}) + add_executable(${DOLPHIN_EXE} ${SRCS}) + target_link_libraries(${DOLPHIN_EXE} ${LIBS} ${WXLIBS}) + if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + include(BundleUtilities) + set(BUNDLE_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${DOLPHIN_EXE}.app) + + # Ask for an application bundle. + set_target_properties(${DOLPHIN_EXE} PROPERTIES + MACOSX_BUNDLE true + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in + ) + + # Install Cg framework into application bundle. + copy_resolved_framework_into_bundle( + # Our framework in "Externals" does not have "Versions/Current/" in + # its path; work around the missing directory levels using "././". + "${CMAKE_SOURCE_DIR}/Externals/Cg/Cg.framework/././Cg" + "${BUNDLE_PATH}/Contents/Frameworks/Cg.framework/././Cg" + ) + + # Fix up the bundle after it is finished. + # There does not seem to be an easy way to run CMake commands post-build, + # so we invoke CMake again on a generated script. + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/postprocess_bundle.cmake " + include(BundleUtilities) + message(\"Fixing up application bundle: ${BUNDLE_PATH}\") + set(BU_CHMOD_BUNDLE_ITEMS ON) + fixup_bundle(\"${BUNDLE_PATH}\" \"\" \"\") + ") + add_custom_command(TARGET ${DOLPHIN_EXE} POST_BUILD + COMMAND ${CMAKE_COMMAND} -P postprocess_bundle.cmake + ) + + # Copy data files into application bundle. + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/copy_data_into_bundle.cmake " + file(INSTALL ${CMAKE_SOURCE_DIR}/Data/Sys ${CMAKE_SOURCE_DIR}/Data/User + DESTINATION ${BUNDLE_PATH}/Contents/Resources + ) + file(GLOB TRANSLATION_FILES RELATIVE ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/*.gmo + ) + foreach(TRANSLATION_FILE \${TRANSLATION_FILES}) + string(REPLACE \".gmo\" \".lproj\" TRANSLATION_DIR + \${TRANSLATION_FILE} + ) + # It would be better to copy to the new name as a single action, + # but I can't figure out a way to let CMake do that. + file(COPY ${CMAKE_BINARY_DIR}/\${TRANSLATION_FILE} + DESTINATION ${BUNDLE_PATH}/Contents/Resources/\${TRANSLATION_DIR} + NO_SOURCE_PERMISSIONS + ) + file(RENAME + ${BUNDLE_PATH}/Contents/Resources/\${TRANSLATION_DIR}/\${TRANSLATION_FILE} + ${BUNDLE_PATH}/Contents/Resources/\${TRANSLATION_DIR}/dolphin-emu.mo + ) + endforeach(TRANSLATION_FILE) + ") + add_custom_target(CopyDataIntoBundle ALL + COMMAND ${CMAKE_COMMAND} -P copy_data_into_bundle.cmake + VERBATIM + ) + + # Install bundle into systemwide /Applications directory. + install(DIRECTORY ${BUNDLE_PATH} DESTINATION /Applications + USE_SOURCE_PERMISSIONS + ) + else() + install(TARGETS ${DOLPHIN_EXE} RUNTIME DESTINATION ${bindir}) + endif() endif() set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} ${DOLPHIN_EXE}) diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp index 1c0776862c..601faeaec6 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp @@ -38,6 +38,7 @@ #include "LogManager.h" #include "HW/CPU.h" #include "PowerPC/PowerPC.h" +#include "PowerPC/JitInterface.h" #include "Debugger/PPCDebugInterface.h" #include "Debugger/Debugger_SymbolMap.h" #include "PowerPC/PPCAnalyst.h" @@ -45,8 +46,6 @@ #include "PowerPC/PPCSymbolDB.h" #include "PowerPC/SignatureDB.h" #include "PowerPC/PPCTables.h" -#include "PowerPC/JitCommon/JitBase.h" -#include "PowerPC/JitCommon/JitCache.h" // for ClearCache() #include "ConfigManager.h" @@ -260,8 +259,7 @@ void CCodeWindow::SingleStep() { if (CCPU::IsStepping()) { - if (jit) - jit->GetBlockCache()->InvalidateICache(PC, 4); + JitInterface::InvalidateICache(PC, 4); CCPU::StepOpcode(&sync_event); wxThread::Sleep(20); // need a short wait here @@ -492,10 +490,8 @@ void CCodeWindow::OnCPUMode(wxCommandEvent& event) } // Clear the JIT cache to enable these changes - if (jit) - { - jit->ClearCache(); - } + JitInterface::ClearCache(); + // Update UpdateButtonStates(); } @@ -509,7 +505,7 @@ void CCodeWindow::OnJitMenu(wxCommandEvent& event) break; case IDM_CLEARCODECACHE: - jit->ClearCache(); + JitInterface::ClearCache(); break; case IDM_SEARCHINSTRUCTION: diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index 46b3a1e8e5..b0b53cc5ea 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -704,7 +704,7 @@ bool IsHotkey(wxKeyEvent &event, int Id) { return (event.GetKeyCode() != WXK_NONE && event.GetKeyCode() == SConfig::GetInstance().m_LocalCoreStartupParameter.iHotkey[Id] && - event.GetModifiers() == SConfig::GetInstance().m_LocalCoreStartupParameter.iHotkeyModifier[Id]); + event.GetModifiers() == SConfig::GetInstance().m_LocalCoreStartupParameter.iHotkeyModifier[Id]); } int GetCmdForHotkey(unsigned int key) diff --git a/Source/Core/DolphinWX/Src/GLInterface.h b/Source/Core/DolphinWX/Src/GLInterface.h index a81f17104c..70b4942e94 100644 --- a/Source/Core/DolphinWX/Src/GLInterface.h +++ b/Source/Core/DolphinWX/Src/GLInterface.h @@ -18,9 +18,11 @@ #define _GLINTERFACE_H_ #include "Thread.h" - -#if defined(USE_EGL) && USE_EGL -#include "GLInterface/EGL.h" +#ifdef ANDROID +#include +#include +#elif defined(USE_EGL) && USE_EGL +#include "GLInterface/EGL_X11.h" #elif defined(USE_WX) && USE_WX #include "GLInterface/WX.h" #elif defined(__APPLE__) @@ -29,10 +31,13 @@ #include "GLInterface/WGL.h" #elif defined(HAVE_X11) && HAVE_X11 #include "GLInterface/GLX.h" +#else +#error Platform doesnt have a GLInterface #endif typedef struct { -#if defined(USE_EGL) && USE_EGL // This is currently a X11/EGL implementation for desktop +#ifdef ANDROID +#elif defined(USE_EGL) && USE_EGL // This is currently a X11/EGL implementation for desktop int screen; Display *dpy; Display *evdpy; diff --git a/Source/Core/DolphinWX/Src/GLInterface/EGL.cpp b/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp similarity index 99% rename from Source/Core/DolphinWX/Src/GLInterface/EGL.cpp rename to Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp index 304eb92059..c092aced64 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/EGL.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp @@ -19,7 +19,7 @@ #include "RenderBase.h" #include "../GLInterface.h" -#include "EGL.h" +#include "EGL_X11.h" // Show the current FPS void cInterfaceEGL::UpdateFPSDisplay(const char *text) diff --git a/Source/Core/DolphinWX/Src/GLInterface/EGL.h b/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.h similarity index 100% rename from Source/Core/DolphinWX/Src/GLInterface/EGL.h rename to Source/Core/DolphinWX/Src/GLInterface/EGL_X11.h diff --git a/Source/Core/DolphinWX/Src/GLInterface/InterfaceBase.h b/Source/Core/DolphinWX/Src/GLInterface/InterfaceBase.h index c2d1ffc54b..1c00a1fd89 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/InterfaceBase.h +++ b/Source/Core/DolphinWX/Src/GLInterface/InterfaceBase.h @@ -23,11 +23,11 @@ protected: u32 s_backbuffer_width; u32 s_backbuffer_height; public: - virtual void Swap() = 0; - virtual void UpdateFPSDisplay(const char *Text) = 0; - virtual bool Create(void *&window_handle) = 0; - virtual bool MakeCurrent() = 0; - virtual void Shutdown() = 0; + virtual void Swap() {} + virtual void UpdateFPSDisplay(const char *Text) {} + virtual bool Create(void *&window_handle) { return true; } + virtual bool MakeCurrent() { return true; } + virtual void Shutdown() {} virtual void SwapInterval(int Interval) { } virtual u32 GetBackBufferWidth() { return s_backbuffer_width; } diff --git a/Source/Core/DolphinWX/Src/MainAndroid.cpp b/Source/Core/DolphinWX/Src/MainAndroid.cpp new file mode 100644 index 0000000000..ca2119921d --- /dev/null +++ b/Source/Core/DolphinWX/Src/MainAndroid.cpp @@ -0,0 +1,149 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +#include +#include +#include + +#include "Common.h" +#include "FileUtil.h" + +#include "Core.h" +#include "Host.h" +#include "CPUDetect.h" +#include "Thread.h" + +#include "PowerPC/PowerPC.h" +#include "HW/Wiimote.h" + +#include "VideoBackendBase.h" +#include "ConfigManager.h" +#include "LogManager.h" +#include "BootManager.h" + +#include +#include +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Dolphinemu", __VA_ARGS__)) + +bool rendererHasFocus = true; +bool running = true; + +void Host_NotifyMapLoaded() {} +void Host_RefreshDSPDebuggerWindow() {} + +void Host_ShowJitResults(unsigned int address){} + +Common::Event updateMainFrameEvent; +void Host_Message(int Id) +{ +} + +void* Host_GetRenderHandle() +{ + return NULL; +} + +void* Host_GetInstance() { return NULL; } + +void Host_UpdateTitle(const char* title){}; + +void Host_UpdateLogDisplay(){} + +void Host_UpdateDisasmDialog(){} + +void Host_UpdateMainFrame() +{ +} + +void Host_UpdateBreakPointView(){} + +bool Host_GetKeyState(int keycode) +{ + return false; +} + +void Host_GetRenderWindowSize(int& x, int& y, int& width, int& height) +{ + x = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos; + y = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos; + width = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth; + height = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight; +} + +void Host_RequestRenderWindowSize(int width, int height) {} +void Host_SetStartupDebuggingParameters() +{ +} + +bool Host_RendererHasFocus() +{ + return true; +} + +void Host_ConnectWiimote(int wm_idx, bool connect) {} + +void Host_SetWaitCursor(bool enable){} + +void Host_UpdateStatusBar(const char* _pText, int Filed){} + +void Host_SysMessage(const char *fmt, ...) +{ + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + size_t len = strlen(msg); + if (msg[len - 1] != '\n') { + msg[len - 1] = '\n'; + msg[len] = '\0'; + } + LOGI(msg); +} + +void Host_SetWiiMoteConnectionState(int _State) {} + +#ifdef __cplusplus +extern "C" +{ +#endif +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_dolphinemuactivity_main(JNIEnv *env, jobject obj) +{ + LogManager::Init(); + SConfig::Init(); + VideoBackend::PopulateList(); + VideoBackend::ActivateBackend(SConfig::GetInstance(). + m_LocalCoreStartupParameter.m_strVideoBackend); + WiimoteReal::LoadSettings(); + + // No use running the loop when booting fails + if (BootManager::BootCore("")) + { + while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) + updateMainFrameEvent.Wait(); + } + + WiimoteReal::Shutdown(); + VideoBackend::ClearList(); + SConfig::Shutdown(); + LogManager::Shutdown(); +} + +#ifdef __cplusplus +} +#endif diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 6ed8e29c6b..cba3666399 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -3,7 +3,6 @@ set(SRCS Src/BPFunctions.cpp Src/BPStructs.cpp Src/CPMemory.cpp Src/CommandProcessor.cpp - Src/DLCache.cpp Src/Debugger.cpp Src/Fifo.cpp Src/FPSCounter.cpp @@ -24,7 +23,6 @@ set(SRCS Src/BPFunctions.cpp Src/Statistics.cpp Src/TextureCacheBase.cpp Src/TextureConversionShader.cpp - Src/TextureDecoder.cpp Src/VertexLoader.cpp Src/VertexLoaderManager.cpp Src/VertexLoader_Color.cpp @@ -41,6 +39,14 @@ set(SRCS Src/BPFunctions.cpp Src/memcpy_amd.cpp) set(LIBS core) + +if(NOT _M_GENERIC) + set(SRCS ${SRCS} Src/x64TextureDecoder.cpp + Src/x64DLCache.cpp) +else() + set(SRCS ${SRCS} Src/GenericTextureDecoder.cpp + Src/GenericDLCache.cpp) +endif() if(NOT ${CL} STREQUAL CL-NOTFOUND) list(APPEND LIBS ${CL}) endif() diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 50aa21ebbf..413b163ced 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -222,11 +222,11 @@ void RunGpu() { u8 *uData = Memory::GetPointer(fifo.CPReadPointer); - SaveSSEState(); - LoadDefaultSSEState(); + FPURoundMode::SaveSIMDState(); + FPURoundMode::LoadDefaultSIMDState(); ReadDataFromFifo(uData, 32); OpcodeDecoder_Run(g_bSkipCurrentFrame); - LoadSSEState(); + FPURoundMode::LoadSIMDState(); //DEBUG_LOG(COMMANDPROCESSOR, "Fifo wraps to base"); diff --git a/Source/Core/VideoCommon/Src/GenericDLCache.cpp b/Source/Core/VideoCommon/Src/GenericDLCache.cpp new file mode 100644 index 0000000000..5e27deb469 --- /dev/null +++ b/Source/Core/VideoCommon/Src/GenericDLCache.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2003-2009 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +// TODO: Handle cache-is-full condition :p + + +#include "Common.h" +#include "DLCache.h" + +namespace DLCache +{ + +void Init() +{ +} + +void Shutdown() +{ +} + +void Clear() +{ +} + +void ProgressiveCleanup() +{ +} +} // namespace + +// NOTE - outside the namespace on purpose. +bool HandleDisplayList(u32 address, u32 size) +{ + return false; +} + +void IncrementCheckContextId() +{ +} diff --git a/Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp b/Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp new file mode 100644 index 0000000000..ad7cfeebf9 --- /dev/null +++ b/Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp @@ -0,0 +1,2182 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +//#include "VideoCommon.h" // to get debug logs + +#include "CPUDetect.h" +#include "TextureDecoder.h" +#include "OpenCL.h" +#include "OpenCL/OCLTextureDecoder.h" +#include "VideoConfig.h" + +#include "LookUpTables.h" + +#include + + + +bool TexFmt_Overlay_Enable=false; +bool TexFmt_Overlay_Center=false; + +extern const char* texfmt[]; +extern const unsigned char sfont_map[]; +extern const unsigned char sfont_raw[][9*10]; + +// TRAM +// STATE_TO_SAVE + GC_ALIGNED16(u8 texMem[TMEM_SIZE]); + + +// Gamecube/Wii texture decoder + +// Decodes all known Gamecube/Wii texture formats. +// by ector + +int TexDecoder_GetTexelSizeInNibbles(int format) +{ + switch (format & 0x3f) { + case GX_TF_I4: return 1; + case GX_TF_I8: return 2; + case GX_TF_IA4: return 2; + case GX_TF_IA8: return 4; + case GX_TF_RGB565: return 4; + case GX_TF_RGB5A3: return 4; + case GX_TF_RGBA8: return 8; + case GX_TF_C4: return 1; + case GX_TF_C8: return 2; + case GX_TF_C14X2: return 4; + case GX_TF_CMPR: return 1; + case GX_CTF_R4: return 1; + case GX_CTF_RA4: return 2; + case GX_CTF_RA8: return 4; + case GX_CTF_YUVA8: return 8; + case GX_CTF_A8: return 2; + case GX_CTF_R8: return 2; + case GX_CTF_G8: return 2; + case GX_CTF_B8: return 2; + case GX_CTF_RG8: return 4; + case GX_CTF_GB8: return 4; + + case GX_TF_Z8: return 2; + case GX_TF_Z16: return 4; + case GX_TF_Z24X8: return 8; + + case GX_CTF_Z4: return 1; + case GX_CTF_Z8M: return 2; + case GX_CTF_Z8L: return 2; + case GX_CTF_Z16L: return 4; + default: return 1; + } +} + +int TexDecoder_GetTextureSizeInBytes(int width, int height, int format) +{ + return (width * height * TexDecoder_GetTexelSizeInNibbles(format)) / 2; +} + +int TexDecoder_GetBlockWidthInTexels(u32 format) +{ + switch (format) + { + case GX_TF_I4: return 8; + case GX_TF_I8: return 8; + case GX_TF_IA4: return 8; + case GX_TF_IA8: return 4; + case GX_TF_RGB565: return 4; + case GX_TF_RGB5A3: return 4; + case GX_TF_RGBA8: return 4; + case GX_TF_C4: return 8; + case GX_TF_C8: return 8; + case GX_TF_C14X2: return 4; + case GX_TF_CMPR: return 8; + case GX_CTF_R4: return 8; + case GX_CTF_RA4: return 8; + case GX_CTF_RA8: return 4; + case GX_CTF_A8: return 8; + case GX_CTF_R8: return 8; + case GX_CTF_G8: return 8; + case GX_CTF_B8: return 8; + case GX_CTF_RG8: return 4; + case GX_CTF_GB8: return 4; + case GX_TF_Z8: return 8; + case GX_TF_Z16: return 4; + case GX_TF_Z24X8: return 4; + case GX_CTF_Z4: return 8; + case GX_CTF_Z8M: return 8; + case GX_CTF_Z8L: return 8; + case GX_CTF_Z16L: return 4; + default: + ERROR_LOG(VIDEO, "Unsupported Texture Format (%08x)! (GetBlockWidthInTexels)", format); + return 8; + } +} + +int TexDecoder_GetBlockHeightInTexels(u32 format) +{ + switch (format) + { + case GX_TF_I4: return 8; + case GX_TF_I8: return 4; + case GX_TF_IA4: return 4; + case GX_TF_IA8: return 4; + case GX_TF_RGB565: return 4; + case GX_TF_RGB5A3: return 4; + case GX_TF_RGBA8: return 4; + case GX_TF_C4: return 8; + case GX_TF_C8: return 4; + case GX_TF_C14X2: return 4; + case GX_TF_CMPR: return 8; + case GX_CTF_R4: return 8; + case GX_CTF_RA4: return 4; + case GX_CTF_RA8: return 4; + case GX_CTF_A8: return 4; + case GX_CTF_R8: return 4; + case GX_CTF_G8: return 4; + case GX_CTF_B8: return 4; + case GX_CTF_RG8: return 4; + case GX_CTF_GB8: return 4; + case GX_TF_Z8: return 4; + case GX_TF_Z16: return 4; + case GX_TF_Z24X8: return 4; + case GX_CTF_Z4: return 8; + case GX_CTF_Z8M: return 4; + case GX_CTF_Z8L: return 4; + case GX_CTF_Z16L: return 4; + default: + ERROR_LOG(VIDEO, "Unsupported Texture Format (%08x)! (GetBlockHeightInTexels)", format); + return 4; + } +} + +//returns bytes +int TexDecoder_GetPaletteSize(int format) +{ + switch (format) + { + case GX_TF_C4: return 16 * 2; + case GX_TF_C8: return 256 * 2; + case GX_TF_C14X2: return 16384 * 2; + default: + return 0; + } +} + +static inline u32 decodeIA8(u16 val) +{ + int a = val >> 8; + int i = val & 0xFF; + return (a << 24) | (i << 16) | (i << 8) | i; +} + +static inline u32 decode5A3(u16 val) +{ + int r,g,b,a; + if ((val & 0x8000)) + { + a = 0xFF; + r = Convert5To8((val >> 10) & 0x1F); + g = Convert5To8((val >> 5) & 0x1F); + b = Convert5To8(val & 0x1F); + } + else + { + a = Convert3To8((val >> 12) & 0x7); + r = Convert4To8((val >> 8) & 0xF); + g = Convert4To8((val >> 4) & 0xF); + b = Convert4To8(val & 0xF); + } + return (a << 24) | (r << 16) | (g << 8) | b; +} + +static inline u32 decode5A3RGBA(u16 val) +{ + int r,g,b,a; + if ((val&0x8000)) + { + r=Convert5To8((val>>10) & 0x1f); + g=Convert5To8((val>>5 ) & 0x1f); + b=Convert5To8((val ) & 0x1f); + a=0xFF; + } + else + { + a=Convert3To8((val>>12) & 0x7); + r=Convert4To8((val>>8 ) & 0xf); + g=Convert4To8((val>>4 ) & 0xf); + b=Convert4To8((val ) & 0xf); + } + return r | (g<<8) | (b << 16) | (a << 24); +} + +static inline u32 decode565RGBA(u16 val) +{ + int r,g,b,a; + r=Convert5To8((val>>11) & 0x1f); + g=Convert6To8((val>>5 ) & 0x3f); + b=Convert5To8((val ) & 0x1f); + a=0xFF; + return r | (g<<8) | (b << 16) | (a << 24); +} + +static inline u32 decodeIA8Swapped(u16 val) +{ + int a = val & 0xFF; + int i = val >> 8; + return i | (i<<8) | (i<<16) | (a<<24); +} + + + +struct DXTBlock +{ + u16 color1; + u16 color2; + u8 lines[4]; +}; + +//inline void decodebytesC4(u32 *dst, const u8 *src, int numbytes, int tlutaddr, int tlutfmt) +inline void decodebytesC4_5A3_To_BGRA32(u32 *dst, const u8 *src, int tlutaddr) +{ + u16 *tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 4; x++) + { + u8 val = src[x]; + *dst++ = decode5A3(Common::swap16(tlut[val >> 4])); + *dst++ = decode5A3(Common::swap16(tlut[val & 0xF])); + } +} + +inline void decodebytesC4_5A3_To_rgba32(u32 *dst, const u8 *src, int tlutaddr) +{ + u16 *tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 4; x++) + { + u8 val = src[x]; + *dst++ = decode5A3RGBA(Common::swap16(tlut[val >> 4])); + *dst++ = decode5A3RGBA(Common::swap16(tlut[val & 0xF])); + } +} + +inline void decodebytesC4_To_Raw16(u16* dst, const u8* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem+tlutaddr); + for (int x = 0; x < 4; x++) + { + u8 val = src[x]; + *dst++ = Common::swap16(tlut[val >> 4]); + *dst++ = Common::swap16(tlut[val & 0xF]); + } +} + +inline void decodebytesC4IA8_To_RGBA(u32* dst, const u8* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem+tlutaddr); + for (int x = 0; x < 4; x++) + { + u8 val = src[x]; + *dst++ = decodeIA8Swapped(tlut[val >> 4]); + *dst++ = decodeIA8Swapped(tlut[val & 0xF]); + } +} + +inline void decodebytesC4RGB565_To_RGBA(u32* dst, const u8* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem+tlutaddr); + for (int x = 0; x < 4; x++) + { + u8 val = src[x]; + *dst++ = decode565RGBA(Common::swap16(tlut[val >> 4])); + *dst++ = decode565RGBA(Common::swap16(tlut[val & 0xF])); + } +} + +//inline void decodebytesC8(u32 *dst, const u8 *src, int numbytes, int tlutaddr, int tlutfmt) +inline void decodebytesC8_5A3_To_BGRA32(u32 *dst, const u8 *src, int tlutaddr) +{ + u16 *tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 8; x++) + { + u8 val = src[x]; + *dst++ = decode5A3(Common::swap16(tlut[val])); + } +} + +inline void decodebytesC8_5A3_To_RGBA32(u32 *dst, const u8 *src, int tlutaddr) +{ + u16 *tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 8; x++) + { + u8 val = src[x]; + *dst++ = decode5A3RGBA(Common::swap16(tlut[val])); + } +} + +inline void decodebytesC8_To_Raw16(u16* dst, const u8* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 8; x++) + { + u8 val = src[x]; + *dst++ = Common::swap16(tlut[val]); + } +} + +inline void decodebytesC8IA8_To_RGBA(u32* dst, const u8* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 8; x++) + { + *dst++ = decodeIA8Swapped(tlut[src[x]]); + } +} + +inline void decodebytesC8RGB565_To_RGBA(u32* dst, const u8* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 8; x++) + { + *dst++ = decode565RGBA(Common::swap16(tlut[src[x]])); + } +} + +inline void decodebytesC14X2_5A3_To_BGRA32(u32 *dst, const u16 *src, int tlutaddr) +{ + u16 *tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 4; x++) + { + u16 val = Common::swap16(src[x]); + *dst++ = decode5A3(Common::swap16(tlut[(val & 0x3FFF)])); + } +} + +inline void decodebytesC14X2_5A3_To_RGBA(u32 *dst, const u16 *src, int tlutaddr) +{ + u16 *tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 4; x++) + { + u16 val = Common::swap16(src[x]); + *dst++ = decode5A3RGBA(Common::swap16(tlut[(val & 0x3FFF)])); + } +} + +inline void decodebytesC14X2_To_Raw16(u16* dst, const u16* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 4; x++) + { + u16 val = Common::swap16(src[x]); + *dst++ = Common::swap16(tlut[(val & 0x3FFF)]); + } +} + +inline void decodebytesC14X2IA8_To_RGBA(u32* dst, const u16* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 4; x++) + { + u16 val = Common::swap16(src[x]); + *dst++ = decodeIA8Swapped(tlut[(val & 0x3FFF)]); + } +} + +inline void decodebytesC14X2rgb565_To_RGBA(u32* dst, const u16* src, int tlutaddr) +{ + u16* tlut = (u16*)(texMem + tlutaddr); + for (int x = 0; x < 4; x++) + { + u16 val = Common::swap16(src[x]); + *dst++ = decode565RGBA(Common::swap16(tlut[(val & 0x3FFF)])); + } +} + +// Needs more speed. +inline void decodebytesIA4(u16 *dst, const u8 *src) +{ + for (int x = 0; x < 8; x++) + { + const u8 val = src[x]; + u8 a = Convert4To8(val >> 4); + u8 l = Convert4To8(val & 0xF); + dst[x] = (a << 8) | l; + } +} + +inline void decodebytesIA4RGBA(u32 *dst, const u8 *src) +{ + for (int x = 0; x < 8; x++) + { + const u8 val = src[x]; + u8 a = Convert4To8(val >> 4); + u8 l = Convert4To8(val & 0xF); + dst[x] = (a << 24) | l << 16 | l << 8 | l; + } +} + +inline void decodebytesRGB5A3(u32 *dst, const u16 *src) +{ +#if 0 + for (int x = 0; x < 4; x++) + dst[x] = decode5A3(Common::swap16(src[x])); +#else + dst[0] = decode5A3(Common::swap16(src[0])); + dst[1] = decode5A3(Common::swap16(src[1])); + dst[2] = decode5A3(Common::swap16(src[2])); + dst[3] = decode5A3(Common::swap16(src[3])); +#endif +} + +inline void decodebytesRGB5A3rgba(u32 *dst, const u16 *src) +{ +#if 0 + for (int x = 0; x < 4; x++) + dst[x] = decode5A3RGBA(Common::swap16(src[x])); +#else + dst[0] = decode5A3RGBA(Common::swap16(src[0])); + dst[1] = decode5A3RGBA(Common::swap16(src[1])); + dst[2] = decode5A3RGBA(Common::swap16(src[2])); + dst[3] = decode5A3RGBA(Common::swap16(src[3])); +#endif +} + +// This one is used by many video formats. It'd therefore be good if it was fast. +// Needs more speed. +inline void decodebytesARGB8_4(u32 *dst, const u16 *src, const u16 *src2) +{ +#if 0 + for (int x = 0; x < 4; x++) + dst[x] = Common::swap32((src2[x] << 16) | src[x]); +#else + dst[0] = Common::swap32((src2[0] << 16) | src[0]); + dst[1] = Common::swap32((src2[1] << 16) | src[1]); + dst[2] = Common::swap32((src2[2] << 16) | src[2]); + dst[3] = Common::swap32((src2[3] << 16) | src[3]); +#endif + + // This can probably be done in a few SSE pack/unpack instructions + pshufb + // some unpack instruction x2: + // ABABABABABABABAB 1212121212121212 -> + // AB12AB12AB12AB12 AB12AB12AB12AB12 + // 2x pshufb-> + // 21BA21BA21BA21BA 21BA21BA21BA21BA + // and we are done. +} + +inline void decodebytesARGB8_4ToRgba(u32 *dst, const u16 *src, const u16 * src2) +{ +#if 0 + for (int x = 0; x < 4; x++) { + dst[x] = ((src[x] & 0xFF) << 24) | ((src[x] & 0xFF00)>>8) | (src2[x] << 8); + } +#else + dst[0] = ((src[0] & 0xFF) << 24) | ((src[0] & 0xFF00)>>8) | (src2[0] << 8); + dst[1] = ((src[1] & 0xFF) << 24) | ((src[1] & 0xFF00)>>8) | (src2[1] << 8); + dst[2] = ((src[2] & 0xFF) << 24) | ((src[2] & 0xFF00)>>8) | (src2[2] << 8); + dst[3] = ((src[3] & 0xFF) << 24) | ((src[3] & 0xFF00)>>8) | (src2[3] << 8); +#endif +} + +inline u32 makecol(int r, int g, int b, int a) +{ + return (a << 24)|(r << 16)|(g << 8)|b; +} + +inline u32 makeRGBA(int r, int g, int b, int a) +{ + return (a<<24)|(b<<16)|(g<<8)|r; +} + +void decodeDXTBlock(u32 *dst, const DXTBlock *src, int pitch) +{ + // S3TC Decoder (Note: GCN decodes differently from PC so we can't use native support) + // Needs more speed. + u16 c1 = Common::swap16(src->color1); + u16 c2 = Common::swap16(src->color2); + int blue1 = Convert5To8(c1 & 0x1F); + int blue2 = Convert5To8(c2 & 0x1F); + int green1 = Convert6To8((c1 >> 5) & 0x3F); + int green2 = Convert6To8((c2 >> 5) & 0x3F); + int red1 = Convert5To8((c1 >> 11) & 0x1F); + int red2 = Convert5To8((c2 >> 11) & 0x1F); + int colors[4]; + colors[0] = makecol(red1, green1, blue1, 255); + colors[1] = makecol(red2, green2, blue2, 255); + if (c1 > c2) + { + int blue3 = ((blue2 - blue1) >> 1) - ((blue2 - blue1) >> 3); + int green3 = ((green2 - green1) >> 1) - ((green2 - green1) >> 3); + int red3 = ((red2 - red1) >> 1) - ((red2 - red1) >> 3); + colors[2] = makecol(red1 + red3, green1 + green3, blue1 + blue3, 255); + colors[3] = makecol(red2 - red3, green2 - green3, blue2 - blue3, 255); + } + else + { + colors[2] = makecol((red1 + red2 + 1) / 2, // Average + (green1 + green2 + 1) / 2, + (blue1 + blue2 + 1) / 2, 255); + colors[3] = makecol(red2, green2, blue2, 0); // Color2 but transparent + } + + for (int y = 0; y < 4; y++) + { + int val = src->lines[y]; + for (int x = 0; x < 4; x++) + { + dst[x] = colors[(val >> 6) & 3]; + val <<= 2; + } + dst += pitch; + } +} + +void decodeDXTBlockRGBA(u32 *dst, const DXTBlock *src, int pitch) +{ + // S3TC Decoder (Note: GCN decodes differently from PC so we can't use native support) + // Needs more speed. + u16 c1 = Common::swap16(src->color1); + u16 c2 = Common::swap16(src->color2); + int blue1 = Convert5To8(c1 & 0x1F); + int blue2 = Convert5To8(c2 & 0x1F); + int green1 = Convert6To8((c1 >> 5) & 0x3F); + int green2 = Convert6To8((c2 >> 5) & 0x3F); + int red1 = Convert5To8((c1 >> 11) & 0x1F); + int red2 = Convert5To8((c2 >> 11) & 0x1F); + int colors[4]; + colors[0] = makeRGBA(red1, green1, blue1, 255); + colors[1] = makeRGBA(red2, green2, blue2, 255); + if (c1 > c2) + { + int blue3 = ((blue2 - blue1) >> 1) - ((blue2 - blue1) >> 3); + int green3 = ((green2 - green1) >> 1) - ((green2 - green1) >> 3); + int red3 = ((red2 - red1) >> 1) - ((red2 - red1) >> 3); + colors[2] = makeRGBA(red1 + red3, green1 + green3, blue1 + blue3, 255); + colors[3] = makeRGBA(red2 - red3, green2 - green3, blue2 - blue3, 255); + } + else + { + colors[2] = makeRGBA((red1 + red2 + 1) / 2, // Average + (green1 + green2 + 1) / 2, + (blue1 + blue2 + 1) / 2, 255); + colors[3] = makeRGBA(red2, green2, blue2, 0); // Color2 but transparent + } + + for (int y = 0; y < 4; y++) + { + int val = src->lines[y]; + for (int x = 0; x < 4; x++) + { + dst[x] = colors[(val >> 6) & 3]; + val <<= 2; + } + dst += pitch; + } +} + +#if 0 // TODO - currently does not handle transparency correctly and causes problems when texture dimensions are not multiples of 8 +static void copyDXTBlock(u8* dst, const u8* src) +{ + ((u16*)dst)[0] = Common::swap16(((u16*)src)[0]); + ((u16*)dst)[1] = Common::swap16(((u16*)src)[1]); + u32 pixels = ((u32*)src)[1]; + // A bit of trickiness here: the row are in the same order + // between the two formats, but the ordering within the rows + // is reversed. + pixels = ((pixels >> 4) & 0x0F0F0F0F) | ((pixels << 4) & 0xF0F0F0F0); + pixels = ((pixels >> 2) & 0x33333333) | ((pixels << 2) & 0xCCCCCCCC); + ((u32*)dst)[1] = pixels; +} +#endif + +static PC_TexFormat GetPCFormatFromTLUTFormat(int tlutfmt) +{ + switch (tlutfmt) + { + case 0: return PC_TEX_FMT_IA8; // IA8 + case 1: return PC_TEX_FMT_RGB565; // RGB565 + case 2: return PC_TEX_FMT_BGRA32; // RGB5A3: This TLUT format requires + // extra work to decode. + } + return PC_TEX_FMT_NONE; // Error +} + +PC_TexFormat GetPC_TexFormat(int texformat, int tlutfmt) +{ + switch (texformat) + { + case GX_TF_C4: + return GetPCFormatFromTLUTFormat(tlutfmt); + case GX_TF_I4: + return PC_TEX_FMT_IA8; + case GX_TF_I8: // speed critical + return PC_TEX_FMT_IA8; + case GX_TF_C8: + return GetPCFormatFromTLUTFormat(tlutfmt); + case GX_TF_IA4: + return PC_TEX_FMT_IA4_AS_IA8; + case GX_TF_IA8: + return PC_TEX_FMT_IA8; + case GX_TF_C14X2: + return GetPCFormatFromTLUTFormat(tlutfmt); + case GX_TF_RGB565: + return PC_TEX_FMT_RGB565; + case GX_TF_RGB5A3: + return PC_TEX_FMT_BGRA32; + case GX_TF_RGBA8: // speed critical + return PC_TEX_FMT_BGRA32; + case GX_TF_CMPR: // speed critical + // The metroid games use this format almost exclusively. + { + return PC_TEX_FMT_BGRA32; + } + } + + // The "copy" texture formats, too? + return PC_TEX_FMT_NONE; +} + + +//switch endianness, unswizzle +//TODO: to save memory, don't blindly convert everything to argb8888 +//also ARGB order needs to be swapped later, to accommodate modern hardware better +//need to add DXT support too +PC_TexFormat TexDecoder_Decode_real(u8 *dst, const u8 *src, int width, int height, int texformat, int tlutaddr, int tlutfmt) +{ + const int Wsteps4 = (width + 3) / 4; + const int Wsteps8 = (width + 7) / 8; + + switch (texformat) + { + case GX_TF_C4: + if (tlutfmt == 2) + { + // Special decoding is required for TLUT format 5A3 + for (int y = 0; y < height; y += 8) + for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = yStep * 8; iy < 8; iy++, xStep++) + decodebytesC4_5A3_To_BGRA32((u32*)dst + (y + iy) * width + x, src + 4 * xStep, tlutaddr); + } + else + { + for (int y = 0; y < height; y += 8) + for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = yStep * 8; iy < 8; iy++, xStep++) + decodebytesC4_To_Raw16((u16*)dst + (y + iy) * width + x, src + 4 * xStep, tlutaddr); + } + return GetPCFormatFromTLUTFormat(tlutfmt); + case GX_TF_I4: + { + for (int y = 0; y < height; y += 8) + for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = yStep * 8 ; iy < 8; iy++,xStep++) + for (int ix = 0; ix < 4; ix++) + { + int val = src[4 * xStep + ix]; + dst[(y + iy) * width + x + ix * 2] = Convert4To8(val >> 4); + dst[(y + iy) * width + x + ix * 2 + 1] = Convert4To8(val & 0xF); + } + } + return PC_TEX_FMT_I4_AS_I8; + case GX_TF_I8: // speed critical + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + { + ((u64*)(dst + (y + iy) * width + x))[0] = ((u64*)(src + 8 * xStep))[0]; + } + } + return PC_TEX_FMT_I8; + case GX_TF_C8: + if (tlutfmt == 2) + { + // Special decoding is required for TLUT format 5A3 + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC8_5A3_To_BGRA32((u32*)dst + (y + iy) * width + x, src + 8 * xStep, tlutaddr); + } + else + { + + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC8_To_Raw16((u16*)dst + (y + iy) * width + x, src + 8 * xStep, tlutaddr); + } + } + return GetPCFormatFromTLUTFormat(tlutfmt); + case GX_TF_IA4: + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesIA4((u16*)dst + (y + iy) * width + x, src + 8 * xStep); + } + return PC_TEX_FMT_IA4_AS_IA8; + case GX_TF_IA8: + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = yStep * 4; iy < 4; iy++, xStep++) + { + u16 *ptr = (u16 *)dst + (y + iy) * width + x; + u16 *s = (u16 *)(src + 8 * xStep); + for(int j = 0; j < 4; j++) + *ptr++ = Common::swap16(*s++); + } + + } + return PC_TEX_FMT_IA8; + case GX_TF_C14X2: + if (tlutfmt == 2) + { + // Special decoding is required for TLUT format 5A3 + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC14X2_5A3_To_BGRA32((u32*)dst + (y + iy) * width + x, (u16*)(src + 8 * xStep), tlutaddr); + } + else + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC14X2_To_Raw16((u16*)dst + (y + iy) * width + x,(u16*)(src + 8 * xStep), tlutaddr); + } + return GetPCFormatFromTLUTFormat(tlutfmt); + case GX_TF_RGB565: + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + { + u16 *ptr = (u16 *)dst + (y + iy) * width + x; + u16 *s = (u16 *)(src + 8 * xStep); + for(int j = 0; j < 4; j++) + *ptr++ = Common::swap16(*s++); + } + } + return PC_TEX_FMT_RGB565; + case GX_TF_RGB5A3: + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + //decodebytesRGB5A3((u32*)dst+(y+iy)*width+x, (u16*)src, 4); + decodebytesRGB5A3((u32*)dst+(y+iy)*width+x, (u16*)(src + 8 * xStep)); + } + return PC_TEX_FMT_BGRA32; + case GX_TF_RGBA8: // speed critical + { + + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + { + const u8* src2 = src + 64 * yStep; + for (int iy = 0; iy < 4; iy++) + decodebytesARGB8_4((u32*)dst + (y+iy)*width + x, (u16*)src2 + 4 * iy, (u16*)src2 + 4 * iy + 16); + } + } + } + return PC_TEX_FMT_BGRA32; + case GX_TF_CMPR: // speed critical + // The metroid games use this format almost exclusively. + { +#if 0 // TODO - currently does not handle transparency correctly and causes problems when texture dimensions are not multiples of 8 + // 11111111 22222222 55555555 66666666 + // 33333333 44444444 77777777 88888888 + for (int y = 0; y < height; y += 8) + { + for (int x = 0; x < width; x += 8) + { + copyDXTBlock(dst+(y/2)*width+x*2, src); + src += 8; + copyDXTBlock(dst+(y/2)*width+x*2+8, src); + src += 8; + copyDXTBlock(dst+(y/2+2)*width+x*2, src); + src += 8; + copyDXTBlock(dst+(y/2+2)*width+x*2+8, src); + src += 8; + } + } + return PC_TEX_FMT_DXT1; +#else + for (int y = 0; y < height; y += 8) + { + for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8, yStep++) + { + const u8* src2 = src + 4 * sizeof(DXTBlock) * yStep; + decodeDXTBlock((u32*)dst + y * width + x, (DXTBlock*)src2, width); + src2 += sizeof(DXTBlock); + decodeDXTBlock((u32*)dst + y * width + x + 4, (DXTBlock*)src2, width); + src2 += sizeof(DXTBlock); + decodeDXTBlock((u32*)dst + (y + 4) * width + x, (DXTBlock*)src2, width); + src2 += sizeof(DXTBlock); + decodeDXTBlock((u32*)dst + (y + 4) * width + x + 4, (DXTBlock*)src2, width); + } + } +#endif + return PC_TEX_FMT_BGRA32; + } + } + + // The "copy" texture formats, too? + return PC_TEX_FMT_NONE; +} + + + +// JSD 01/06/11: +// TODO: we really should ensure BOTH the source and destination addresses are aligned to 16-byte boundaries to +// squeeze out a little more performance. _mm_loadu_si128/_mm_storeu_si128 is slower than _mm_load_si128/_mm_store_si128 +// because they work on unaligned addresses. The processor is free to make the assumption that addresses are multiples +// of 16 in the aligned case. +// TODO: complete SSE2 optimization of less often used texture formats. +// TODO: refactor algorithms using _mm_loadl_epi64 unaligned loads to prefer 128-bit aligned loads. + +PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int height, int texformat, int tlutaddr, int tlutfmt) +{ + + const int Wsteps4 = (width + 3) / 4; + const int Wsteps8 = (width + 7) / 8; + + switch (texformat) + { + case GX_TF_C4: + if (tlutfmt == 2) + { + // Special decoding is required for TLUT format 5A3 + for (int y = 0; y < height; y += 8) + for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8,yStep++) + for (int iy = 0, xStep = 8 * yStep; iy < 8; iy++,xStep++) + decodebytesC4_5A3_To_rgba32(dst + (y + iy) * width + x, src + 4 * xStep, tlutaddr); + } + else if(tlutfmt == 0) + { + for (int y = 0; y < height; y += 8) + for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8,yStep++) + for (int iy = 0, xStep = 8 * yStep; iy < 8; iy++,xStep++) + decodebytesC4IA8_To_RGBA(dst + (y + iy) * width + x, src + 4 * xStep, tlutaddr); + + } + else + { + for (int y = 0; y < height; y += 8) + for (int x = 0, yStep = (y / 8) * Wsteps8; x < width; x += 8,yStep++) + for (int iy = 0, xStep = 8 * yStep; iy < 8; iy++,xStep++) + decodebytesC4RGB565_To_RGBA(dst + (y + iy) * width + x, src + 4 * xStep, tlutaddr); + } + break; + case GX_TF_I4: + { + // Reference C implementation: + for (int y = 0; y < height; y += 8) + for (int x = 0; x < width; x += 8) + for (int iy = 0; iy < 8; iy++, src += 4) + for (int ix = 0; ix < 4; ix++) + { + int val = src[ix]; + u8 i1 = Convert4To8(val >> 4); + u8 i2 = Convert4To8(val & 0xF); + memset(dst+(y + iy) * width + x + ix * 2 , i1,4); + memset(dst+(y + iy) * width + x + ix * 2 + 1 , i2,4); + } + } + break; + case GX_TF_I8: // speed critical + { + // Reference C implementation + for (int y = 0; y < height; y += 4) + for (int x = 0; x < width; x += 8) + for (int iy = 0; iy < 4; ++iy, src += 8) + { + u32 * newdst = dst + (y + iy)*width+x; + const u8 * newsrc = src; + u8 srcval; + + srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + srcval = newsrc[0]; newdst[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); + } + } + break; + case GX_TF_C8: + if (tlutfmt == 2) + { + // Special decoding is required for TLUT format 5A3 + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC8_5A3_To_RGBA32((u32*)dst + (y + iy) * width + x, src + 8 * xStep, tlutaddr); + } + else if(tlutfmt == 0) + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC8IA8_To_RGBA(dst + (y + iy) * width + x, src + 8 * xStep, tlutaddr); + + } + else + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC8RGB565_To_RGBA(dst + (y + iy) * width + x, src + 8 * xStep, tlutaddr); + + } + break; + case GX_TF_IA4: + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps8; x < width; x += 8, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesIA4RGBA(dst + (y + iy) * width + x, src + 8 * xStep); + } + break; + case GX_TF_IA8: + { + // Reference C implementation: + for (int y = 0; y < height; y += 4) + for (int x = 0; x < width; x += 4) + for (int iy = 0; iy < 4; iy++, src += 8) + { + u32 *ptr = dst + (y + iy) * width + x; + u16 *s = (u16 *)src; + ptr[0] = decodeIA8Swapped(s[0]); + ptr[1] = decodeIA8Swapped(s[1]); + ptr[2] = decodeIA8Swapped(s[2]); + ptr[3] = decodeIA8Swapped(s[3]); + } + } + break; + case GX_TF_C14X2: + if (tlutfmt == 2) + { + // Special decoding is required for TLUT format 5A3 + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC14X2_5A3_To_BGRA32(dst + (y + iy) * width + x, (u16*)(src + 8 * xStep), tlutaddr); + } + else if (tlutfmt == 0) + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC14X2IA8_To_RGBA(dst + (y + iy) * width + x, (u16*)(src + 8 * xStep), tlutaddr); + } + else + { + for (int y = 0; y < height; y += 4) + for (int x = 0, yStep = (y / 4) * Wsteps4; x < width; x += 4, yStep++) + for (int iy = 0, xStep = 4 * yStep; iy < 4; iy++, xStep++) + decodebytesC14X2rgb565_To_RGBA(dst + (y + iy) * width + x, (u16*)(src + 8 * xStep), tlutaddr); + } + break; + case GX_TF_RGB565: + { + // Reference C implementation. + for (int y = 0; y < height; y += 4) + for (int x = 0; x < width; x += 4) + for (int iy = 0; iy < 4; iy++, src += 8) + { + u32 *ptr = dst + (y + iy) * width + x; + u16 *s = (u16 *)src; + for(int j = 0; j < 4; j++) + *ptr++ = decode565RGBA(Common::swap16(*s++)); + } + } + break; + case GX_TF_RGB5A3: + { + // Reference C implementation: + for (int y = 0; y < height; y += 4) + for (int x = 0; x < width; x += 4) + for (int iy = 0; iy < 4; iy++, src += 8) + decodebytesRGB5A3rgba(dst+(y+iy)*width+x, (u16*)src); + } + break; + case GX_TF_RGBA8: // speed critical + { + // Reference C implementation. + for (int y = 0; y < height; y += 4) + for (int x = 0; x < width; x += 4) + { + for (int iy = 0; iy < 4; iy++) + decodebytesARGB8_4ToRgba(dst + (y+iy)*width + x, (u16*)src + 4 * iy, (u16*)src + 4 * iy + 16); + src += 64; + } + } + break; + case GX_TF_CMPR: // speed critical + // The metroid games use this format almost exclusively. + { + for (int y = 0; y < height; y += 8) + { + for (int x = 0; x < width; x += 8) + { + decodeDXTBlockRGBA((u32*)dst + y * width + x, (DXTBlock*)src, width); + src += sizeof(DXTBlock); + decodeDXTBlockRGBA((u32*)dst + y * width + x + 4, (DXTBlock*)src, width); + src += sizeof(DXTBlock); + decodeDXTBlockRGBA((u32*)dst + (y + 4) * width + x, (DXTBlock*)src, width); + src += sizeof(DXTBlock); + decodeDXTBlockRGBA((u32*)dst + (y + 4) * width + x + 4, (DXTBlock*)src, width); + src += sizeof(DXTBlock); + } + } + break; + } + } + + // The "copy" texture formats, too? + return PC_TEX_FMT_RGBA32; +} + + + + +void TexDecoder_SetTexFmtOverlayOptions(bool enable, bool center) +{ + TexFmt_Overlay_Enable = enable; + TexFmt_Overlay_Center = center; +} + +PC_TexFormat TexDecoder_Decode(u8 *dst, const u8 *src, int width, int height, int texformat, int tlutaddr, int tlutfmt,bool rgbaOnly) +{ + PC_TexFormat retval = TexDecoder_Decode_OpenCL(dst, src, + width, height, texformat, tlutaddr, tlutfmt, rgbaOnly); + if (retval == PC_TEX_FMT_NONE) + retval = rgbaOnly ? TexDecoder_Decode_RGBA((u32*)dst, src, + width, height, texformat, tlutaddr, tlutfmt) + : TexDecoder_Decode_real(dst, src, + width, height, texformat, tlutaddr, tlutfmt); + + if ((!TexFmt_Overlay_Enable)|| (retval == PC_TEX_FMT_NONE)) + return retval; + + int w = min(width, 40); + int h = min(height, 10); + + int xoff = (width - w) >> 1; + int yoff = (height - h) >> 1; + + if (!TexFmt_Overlay_Center) + { + xoff=0; + yoff=0; + } + + const char* fmt = texfmt[texformat&15]; + while (*fmt) + { + int xcnt = 0; + int nchar = sfont_map[(int)*fmt]; + + const unsigned char *ptr = sfont_raw[nchar]; // each char is up to 9x10 + + for (int x = 0; x < 9;x++) + { + if (ptr[x] == 0x78) + break; + xcnt++; + } + + for (int y=0; y < 10; y++) + { + for (int x=0; x < xcnt; x++) + { + switch(retval) + { + case PC_TEX_FMT_I8: + { + // TODO: Is this an acceptable way to draw in I8? + u8 *dtp = (u8*)dst; + dtp[(y + yoff) * width + x + xoff] = ptr[x] ? 0xFF : 0x88; + break; + } + case PC_TEX_FMT_IA8: + case PC_TEX_FMT_IA4_AS_IA8: + { + u16 *dtp = (u16*)dst; + dtp[(y + yoff) * width + x + xoff] = ptr[x] ? 0xFFFF : 0xFF00; + break; + } + case PC_TEX_FMT_RGB565: + { + u16 *dtp = (u16*)dst; + dtp[(y + yoff)*width + x + xoff] = ptr[x] ? 0xFFFF : 0x0000; + break; + } + default: + case PC_TEX_FMT_BGRA32: + { + int *dtp = (int*)dst; + dtp[(y + yoff) * width + x + xoff] = ptr[x] ? 0xFFFFFFFF : 0xFF000000; + break; + } + } + } + ptr += 9; + } + xoff += xcnt; + fmt++; + } + + return retval; +} + + + +void TexDecoder_DecodeTexel(u8 *dst, const u8 *src, int s, int t, int imageWidth, int texformat, int tlutaddr, int tlutfmt) +{ + /* General formula for computing texture offset + // + u16 sBlk = s / blockWidth; + u16 tBlk = t / blockHeight; + u16 widthBlks = (width / blockWidth) + 1; + u32 base = (tBlk * widthBlks + sBlk) * blockWidth * blockHeight; + u16 blkS = s & (blockWidth - 1); + u16 blkT = t & (blockHeight - 1); + u32 blkOff = blkT * blockWidth + blkS; + */ + + switch (texformat) + { + case GX_TF_C4: + { + u16 sBlk = s >> 3; + u16 tBlk = t >> 3; + u16 widthBlks = (imageWidth >> 3) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 5; + u16 blkS = s & 7; + u16 blkT = t & 7; + u32 blkOff = (blkT << 3) + blkS; + + int rs = (blkOff & 1)?0:4; + u32 offset = base + (blkOff >> 1); + + u8 val = (*(src + offset) >> rs) & 0xF; + u16 *tlut = (u16*)(texMem + tlutaddr); + + switch (tlutfmt) + { + case 0: + *((u32*)dst) = decodeIA8Swapped(tlut[val]); + break; + case 1: + *((u32*)dst) = decode565RGBA(Common::swap16(tlut[val])); + break; + case 2: + *((u32*)dst) = decode5A3RGBA(Common::swap16(tlut[val])); + break; + } + } + break; + case GX_TF_I4: + { + u16 sBlk = s >> 3; + u16 tBlk = t >> 3; + u16 widthBlks = (imageWidth >> 3) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 5; + u16 blkS = s & 7; + u16 blkT = t & 7; + u32 blkOff = (blkT << 3) + blkS; + + int rs = (blkOff & 1)?0:4; + u32 offset = base + (blkOff >> 1); + + u8 val = (*(src + offset) >> rs) & 0xF; + val = Convert4To8(val); + dst[0] = val; + dst[1] = val; + dst[2] = val; + dst[3] = val; + } + break; + case GX_TF_I8: + { + u16 sBlk = s >> 3; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 3) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 5; + u16 blkS = s & 7; + u16 blkT = t & 3; + u32 blkOff = (blkT << 3) + blkS; + + u8 val = *(src + base + blkOff); + dst[0] = val; + dst[1] = val; + dst[2] = val; + dst[3] = val; + } + break; + case GX_TF_C8: + { + u16 sBlk = s >> 3; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 3) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 5; + u16 blkS = s & 7; + u16 blkT = t & 3; + u32 blkOff = (blkT << 3) + blkS; + + u8 val = *(src + base + blkOff); + u16 *tlut = (u16*)(texMem + tlutaddr); + + switch (tlutfmt) + { + case 0: + *((u32*)dst) = decodeIA8Swapped(tlut[val]); + break; + case 1: + *((u32*)dst) = decode565RGBA(Common::swap16(tlut[val])); + break; + case 2: + *((u32*)dst) = decode5A3RGBA(Common::swap16(tlut[val])); + break; + } + } + break; + case GX_TF_IA4: + { + u16 sBlk = s >> 3; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 3) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 5; + u16 blkS = s & 7; + u16 blkT = t & 3; + u32 blkOff = (blkT << 3) + blkS; + + u8 val = *(src + base + blkOff); + const u8 a = Convert4To8(val>>4); + const u8 l = Convert4To8(val&0xF); + dst[0] = l; + dst[1] = l; + dst[2] = l; + dst[3] = a; + } + break; + case GX_TF_IA8: + { + u16 sBlk = s >> 2; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 2) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 4; + u16 blkS = s & 3; + u16 blkT = t & 3; + u32 blkOff = (blkT << 2) + blkS; + + u32 offset = (base + blkOff) << 1; + const u16* valAddr = (u16*)(src + offset); + + *((u32*)dst) = decodeIA8Swapped(*valAddr); + } + break; + case GX_TF_C14X2: + { + u16 sBlk = s >> 2; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 2) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 4; + u16 blkS = s & 3; + u16 blkT = t & 3; + u32 blkOff = (blkT << 2) + blkS; + + u32 offset = (base + blkOff) << 1; + const u16* valAddr = (u16*)(src + offset); + + u16 val = Common::swap16(*valAddr) & 0x3FFF; + u16 *tlut = (u16*)(texMem + tlutaddr); + + switch (tlutfmt) + { + case 0: + *((u32*)dst) = decodeIA8Swapped(tlut[val]); + break; + case 1: + *((u32*)dst) = decode565RGBA(Common::swap16(tlut[val])); + break; + case 2: + *((u32*)dst) = decode5A3RGBA(Common::swap16(tlut[val])); + break; + } + } + break; + case GX_TF_RGB565: + { + u16 sBlk = s >> 2; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 2) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 4; + u16 blkS = s & 3; + u16 blkT = t & 3; + u32 blkOff = (blkT << 2) + blkS; + + u32 offset = (base + blkOff) << 1; + const u16* valAddr = (u16*)(src + offset); + + *((u32*)dst) = decode565RGBA(Common::swap16(*valAddr)); + } + break; + case GX_TF_RGB5A3: + { + u16 sBlk = s >> 2; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 2) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 4; + u16 blkS = s & 3; + u16 blkT = t & 3; + u32 blkOff = (blkT << 2) + blkS; + + u32 offset = (base + blkOff) << 1; + const u16* valAddr = (u16*)(src + offset); + + *((u32*)dst) = decode5A3RGBA(Common::swap16(*valAddr)); + } + break; + case GX_TF_RGBA8: + { + u16 sBlk = s >> 2; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 2) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 5; // shift by 5 is correct + u16 blkS = s & 3; + u16 blkT = t & 3; + u32 blkOff = (blkT << 2) + blkS; + + u32 offset = (base + blkOff) << 1 ; + const u8* valAddr = src + offset; + + dst[3] = valAddr[0]; + dst[0] = valAddr[1]; + dst[1] = valAddr[32]; + dst[2] = valAddr[33]; + } + break; + case GX_TF_CMPR: + { + u16 sDxt = s >> 2; + u16 tDxt = t >> 2; + + u16 sBlk = sDxt >> 1; + u16 tBlk = tDxt >> 1; + u16 widthBlks = (imageWidth >> 3) + 1; + u32 base = (tBlk * widthBlks + sBlk) << 2; + u16 blkS = sDxt & 1; + u16 blkT = tDxt & 1; + u32 blkOff = (blkT << 1) + blkS; + + u32 offset = (base + blkOff) << 3; + + const DXTBlock* dxtBlock = (const DXTBlock*)(src + offset); + + u16 c1 = Common::swap16(dxtBlock->color1); + u16 c2 = Common::swap16(dxtBlock->color2); + int blue1 = Convert5To8(c1 & 0x1F); + int blue2 = Convert5To8(c2 & 0x1F); + int green1 = Convert6To8((c1 >> 5) & 0x3F); + int green2 = Convert6To8((c2 >> 5) & 0x3F); + int red1 = Convert5To8((c1 >> 11) & 0x1F); + int red2 = Convert5To8((c2 >> 11) & 0x1F); + + u16 ss = s & 3; + u16 tt = t & 3; + + int colorSel = dxtBlock->lines[tt]; + int rs = 6 - (ss << 1); + colorSel = (colorSel >> rs) & 3; + colorSel |= c1 > c2?0:4; + + u32 color = 0; + + switch (colorSel) + { + case 0: + case 4: + color = makeRGBA(red1, green1, blue1, 255); + break; + case 1: + case 5: + color = makeRGBA(red2, green2, blue2, 255); + break; + case 2: + color = makeRGBA(red1+(red2-red1)/3, green1+(green2-green1)/3, blue1+(blue2-blue1)/3, 255); + break; + case 3: + color = makeRGBA(red2+(red1-red2)/3, green2+(green1-green2)/3, blue2+(blue1-blue2)/3, 255); + break; + case 6: + color = makeRGBA((int)ceil((float)(red1+red2)/2), (int)ceil((float)(green1+green2)/2), (int)ceil((float)(blue1+blue2)/2), 255); + break; + case 7: + color = makeRGBA(red2, green2, blue2, 0); + break; + } + + *((u32*)dst) = color; + } + break; + } +} + + +const char* texfmt[] = { + // pixel + "I4", "I8", "IA4", "IA8", + "RGB565", "RGB5A3", "RGBA8", "0x07", + "C4", "C8", "C14X2", "0x0B", + "0x0C", "0x0D", "CMPR", "0x0F", + // Z-buffer + "0x10", "Z8", "0x12", "Z16", + "0x14", "0x15", "Z24X8", "0x17", + "0x18", "0x19", "0x1A", "0x1B", + "0x1C", "0x1D", "0x1E", "0x1F", + // pixel + copy + "CR4", "0x21", "CRA4", "CRA8", + "0x24", "0x25", "CYUVA8", "CA8", + "CR8", "CG8", "CB8", "CRG8", + "CGB8", "0x2D", "0x2E", "0x2F", + // Z + copy + "CZ4", "0x31", "0x32", "0x33", + "0x34", "0x35", "0x36", "0x37", + "0x38", "CZ8M", "CZ8L", "0x3B", + "CZ16L", "0x3D", "0x3E", "0x3F", +}; + +const unsigned char sfont_map[] = { + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,10,10,10,10,10, + 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25, + 26,27,28,29,30,31,32,33,34,35,36,10,10,10,10,10, + 10,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51, + 52,53,54,55,56,57,58,59,60,61,62,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, +}; + +const unsigned char sfont_raw[][9*10] = { + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0x00, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + },{ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0x00, 0x00, 0x00, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x78, 0x78, 0x78, + }, +}; diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index 5bffab8ee7..526cbe7e49 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -23,7 +23,7 @@ #include "MemoryUtil.h" #include "StringUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "PixelEngine.h" #include "Host.h" @@ -43,8 +43,9 @@ //BBox #include "XFMemory.h" extern float GC_ALIGNED16(g_fProjectionMatrix[16]); - +#ifndef _M_GENERIC #define USE_JIT +#endif #define COMPILED_CODE_SIZE 4096 @@ -82,8 +83,9 @@ static const float fractionTable[32] = { 1.0f / (1U << 24), 1.0f / (1U << 25), 1.0f / (1U << 26), 1.0f / (1U << 27), 1.0f / (1U << 28), 1.0f / (1U << 29), 1.0f / (1U << 30), 1.0f / (1U << 31), }; - +#ifdef USE_JIT using namespace Gen; +#endif void LOADERDECL PosMtx_ReadDirect_UByte() { @@ -182,14 +184,19 @@ VertexLoader::VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr) m_VtxDesc = vtx_desc; SetVAT(vtx_attr.g0.Hex, vtx_attr.g1.Hex, vtx_attr.g2.Hex); + #ifdef USE_JIT AllocCodeSpace(COMPILED_CODE_SIZE); CompileVertexTranslator(); WriteProtect(); + #endif + } VertexLoader::~VertexLoader() { + #ifdef USE_JIT FreeCodeSpace(); + #endif delete m_NativeFmt; } @@ -474,7 +481,8 @@ void VertexLoader::WriteCall(TPipelineFunction func) m_PipelineStages[m_numPipelineStages++] = func; #endif } - +// ARMTODO: This should be done in a better way +#ifndef _M_GENERIC void VertexLoader::WriteGetVariable(int bits, OpArg dest, void *address) { #ifdef USE_JIT @@ -498,7 +506,7 @@ void VertexLoader::WriteSetVariable(int bits, void *address, OpArg value) #endif #endif } - +#endif void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) { m_numLoadedVertices += count; diff --git a/Source/Core/VideoCommon/Src/VertexLoader.h b/Source/Core/VideoCommon/Src/VertexLoader.h index 98a57cb9ff..0f321cd14f 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.h +++ b/Source/Core/VideoCommon/Src/VertexLoader.h @@ -76,7 +76,12 @@ private: } }; +// ARMTODO: This should be done in a better way +#ifndef _M_GENERIC class VertexLoader : public Gen::XCodeBlock, NonCopyable +#else +class VertexLoader +#endif { public: VertexLoader(const TVtxDesc &vtx_desc, const VAT &vtx_attr); @@ -122,8 +127,10 @@ private: void WriteCall(TPipelineFunction); +#ifndef _M_GENERIC void WriteGetVariable(int bits, Gen::OpArg dest, void *address); void WriteSetVariable(int bits, void *address, Gen::OpArg dest); +#endif }; #endif diff --git a/Source/Core/VideoCommon/Src/DLCache.cpp b/Source/Core/VideoCommon/Src/x64DLCache.cpp similarity index 99% rename from Source/Core/VideoCommon/Src/DLCache.cpp rename to Source/Core/VideoCommon/Src/x64DLCache.cpp index c828ea3a03..559593a08c 100644 --- a/Source/Core/VideoCommon/Src/DLCache.cpp +++ b/Source/Core/VideoCommon/Src/x64DLCache.cpp @@ -35,7 +35,7 @@ #include "VertexLoaderManager.h" #include "VertexManagerBase.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "DLCache.h" #include "VideoConfig.h" diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.cpp b/Source/Core/VideoCommon/Src/x64TextureDecoder.cpp similarity index 97% rename from Source/Core/VideoCommon/Src/TextureDecoder.cpp rename to Source/Core/VideoCommon/Src/x64TextureDecoder.cpp index 30df817902..6c474920cd 100644 --- a/Source/Core/VideoCommon/Src/TextureDecoder.cpp +++ b/Source/Core/VideoCommon/Src/x64TextureDecoder.cpp @@ -1119,20 +1119,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he _mm_storeu_si128( (__m128i*)( dst+(y + iy+1) * width + x + 4 ), o4 ); } } -#if 0 - // Reference C implementation: - for (int y = 0; y < height; y += 8) - for (int x = 0; x < width; x += 8) - for (int iy = 0; iy < 8; iy++, src += 4) - for (int ix = 0; ix < 4; ix++) - { - int val = src[ix]; - u8 i1 = Convert4To8(val >> 4); - u8 i2 = Convert4To8(val & 0xF); - memset(dst+(y + iy) * width + x + ix * 2 , i1,4); - memset(dst+(y + iy) * width + x + ix * 2 + 1 , i2,4); - } -#endif } break; case GX_TF_I8: // speed critical @@ -1248,26 +1234,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he } } -#if 0 - // Reference C implementation - for (int y = 0; y < height; y += 4) - for (int x = 0; x < width; x += 8) - for (int iy = 0; iy < 4; ++iy, src += 8) - { - u32 * newdst = dst + (y + iy)*width+x; - const u8 * newsrc = src; - u8 srcval; - - srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - srcval = (newsrc++)[0]; (newdst++)[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - srcval = newsrc[0]; newdst[0] = srcval | (srcval << 8) | (srcval << 16) | (srcval << 24); - } -#endif } break; case GX_TF_C8: @@ -1380,20 +1346,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he _mm_storeu_si128( (__m128i*)(dst + (y + iy) * width + x), r1 ); } } -#if 0 - // Reference C implementation: - for (int y = 0; y < height; y += 4) - for (int x = 0; x < width; x += 4) - for (int iy = 0; iy < 4; iy++, src += 8) - { - u32 *ptr = dst + (y + iy) * width + x; - u16 *s = (u16 *)src; - ptr[0] = decodeIA8Swapped(s[0]); - ptr[1] = decodeIA8Swapped(s[1]); - ptr[2] = decodeIA8Swapped(s[2]); - ptr[3] = decodeIA8Swapped(s[3]); - } -#endif } break; case GX_TF_C14X2: @@ -1493,18 +1445,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he __m128i *ptr = (__m128i *)(dst + (y + iy) * width + x); _mm_storeu_si128(ptr, abgr888x4); } -#if 0 - // Reference C implementation. - for (int y = 0; y < height; y += 4) - for (int x = 0; x < width; x += 4) - for (int iy = 0; iy < 4; iy++, src += 8) - { - u32 *ptr = dst + (y + iy) * width + x; - u16 *s = (u16 *)src; - for(int j = 0; j < 4; j++) - *ptr++ = decode565RGBA(Common::swap16(*s++)); - } -#endif } break; case GX_TF_RGB5A3: @@ -1718,13 +1658,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he } } } -#if 0 - // Reference C implementation: - for (int y = 0; y < height; y += 4) - for (int x = 0; x < width; x += 4) - for (int iy = 0; iy < 4; iy++, src += 8) - decodebytesRGB5A3rgba(dst+(y+iy)*width+x, (u16*)src); -#endif } break; case GX_TF_RGBA8: // speed critical @@ -1860,16 +1793,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he _mm_storeu_si128(dst128, rgba11); } } -#if 0 - // Reference C implementation. - for (int y = 0; y < height; y += 4) - for (int x = 0; x < width; x += 4) - { - for (int iy = 0; iy < 4; iy++) - decodebytesARGB8_4ToRgba(dst + (y+iy)*width + x, (u16*)src + 4 * iy, (u16*)src + 4 * iy + 16); - src += 64; - } -#endif } break; case GX_TF_CMPR: // speed critical @@ -2104,22 +2027,6 @@ PC_TexFormat TexDecoder_Decode_RGBA(u32 * dst, const u8 * src, int width, int he } } } -#if 0 - for (int y = 0; y < height; y += 8) - { - for (int x = 0; x < width; x += 8) - { - decodeDXTBlockRGBA((u32*)dst + y * width + x, (DXTBlock*)src, width); - src += sizeof(DXTBlock); - decodeDXTBlockRGBA((u32*)dst + y * width + x + 4, (DXTBlock*)src, width); - src += sizeof(DXTBlock); - decodeDXTBlockRGBA((u32*)dst + (y + 4) * width + x, (DXTBlock*)src, width); - src += sizeof(DXTBlock); - decodeDXTBlockRGBA((u32*)dst + (y + 4) * width + x + 4, (DXTBlock*)src, width); - src += sizeof(DXTBlock); - } - } -#endif break; } } diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj b/Source/Core/VideoCommon/VideoCommon.vcxproj index bf9122e6b5..0c1b13f301 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj @@ -111,8 +111,8 @@ ..\Common\Src;..\Core\Src;..\..\..\Externals\SOIL;..\..\..\Externals\CLRun\include;%(AdditionalIncludeDirectories) - false - + false + true @@ -143,7 +143,7 @@ ..\Common\Src;..\Core\Src;..\..\..\Externals\SOIL;..\..\..\Externals\CLRun\include;%(AdditionalIncludeDirectories) false - + true true @@ -182,7 +182,6 @@ - @@ -204,7 +203,6 @@ - @@ -216,6 +214,8 @@ + + diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index e7019f17ed..6038d5e9e2 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -5,9 +5,6 @@ - - Vertex Loading - Vertex Loading @@ -92,9 +89,6 @@ Decoding - - Decoding - Base @@ -122,6 +116,12 @@ Util + + Decoding + + + Vertex Loading + diff --git a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp index bfaf21ec7e..d68228273c 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/NativeVertexFormat.cpp @@ -19,7 +19,7 @@ #include "D3DBase.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "MemoryUtil.h" #include "VertexShaderGen.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 29a1b6a662..01ea415263 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -51,7 +51,9 @@ void VideoBackend::UpdateFPSDisplay(const char *text) } void InitInterface() { - #if defined(USE_EGL) && USE_EGL + #ifdef ANDROID + GLInterface = new cInterfaceBase; + #elif defined(USE_EGL) && USE_EGL GLInterface = new cInterfaceEGL; #elif defined(USE_WX) && USE_WX GLInterface = new cInterfaceWX; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp index ae20649433..0528bd1878 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/NativeVertexFormat.cpp @@ -17,7 +17,7 @@ #include "GLUtil.h" #include "x64Emitter.h" -#include "ABI.h" +#include "x64ABI.h" #include "MemoryUtil.h" #include "VertexShaderGen.h" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 05f21beed1..99e01bfb3d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -204,7 +204,9 @@ void VideoBackend::Video_Prepare() GL_REPORT_ERRORD(); VertexLoaderManager::Init(); TextureConverter::Init(); +#ifndef _M_GENERIC DLCache::Init(); +#endif // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); @@ -219,7 +221,9 @@ void VideoBackend::Shutdown() s_efbAccessRequested = false; s_FifoShuttingDown = false; s_swapRequested = false; +#ifndef _M_GENERIC DLCache::Shutdown(); +#endif Fifo_Shutdown(); PostProcessing::Shutdown(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp index 0091e4eaca..032ff9d74a 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp @@ -125,7 +125,9 @@ void DecodeStandard(u32 bufferSize) if (Cmd == GX_NOP) return; - + // Causes a SIGBUS error on Android + // XXX: Investigate +#ifndef ANDROID // check if switching in or out of an object // only used for debuggging if (inObjectStream && (Cmd & 0x87) != lastPrimCmd) @@ -139,7 +141,7 @@ void DecodeStandard(u32 bufferSize) lastPrimCmd = Cmd & 0x87; DebugUtil::OnObjectBegin(); } - +#endif switch(Cmd) { case GX_NOP: diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp index b9afc1abb5..72b26338b5 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp @@ -115,15 +115,15 @@ void RunGpu() if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) { // We are going to do FP math on the main thread so have to save the current state - SaveSSEState(); - LoadDefaultSSEState(); + FPURoundMode::SaveSIMDState(); + FPURoundMode::LoadDefaultSIMDState(); // run the opcode decoder do { RunBuffer(); } while (cpreg.ctrl.GPReadEnable && !AtBreakpoint() && cpreg.readptr != cpreg.writeptr); - LoadSSEState(); + FPURoundMode::LoadSIMDState(); } } From 08fe3c213ad71e903fed83edfada5a79c75f11f9 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Tue, 26 Feb 2013 18:28:56 -0500 Subject: [PATCH 095/167] Abort loading states from incompatible graphics backends. --- Source/Core/Core/Src/State.cpp | 2 +- Source/Core/VideoCommon/Src/MainBase.cpp | 5 +++++ Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 0facf2f387..773d757337 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 14; +static const u32 STATE_VERSION = 15; struct StateHeader { diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index 726ef71b38..a881bebfb2 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -186,6 +186,11 @@ void VideoBackendHardware::InitializeShared() // Run from the CPU thread void VideoBackendHardware::DoState(PointerWrap& p) { + bool software = false; + p.Do(software); + if (p.GetMode() == PointerWrap::MODE_READ && software == true) + // change mode to abort load of incompatible save state. + p.SetMode(PointerWrap::MODE_VERIFY); VideoCommon_DoState(p); p.DoMarker("VideoCommon"); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index d78b8ba13b..6976b18690 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -41,6 +41,7 @@ #include "Core.h" #include "OpcodeDecoder.h" #include "SWVertexLoader.h" +#include "SWStatistics.h" #define VSYNC_ENABLED 0 @@ -97,6 +98,11 @@ bool VideoSoftware::Initialize(void *&window_handle) void VideoSoftware::DoState(PointerWrap& p) { + bool software = true; + p.Do(software); + if (p.GetMode() == PointerWrap::MODE_READ && software == false) + // change mode to abort load of incompatible save state. + p.SetMode(PointerWrap::MODE_VERIFY); // TODO: incomplete SWCommandProcessor::DoState(p); SWPixelEngine::DoState(p); @@ -105,6 +111,7 @@ void VideoSoftware::DoState(PointerWrap& p) Clipper::DoState(p); p.Do(swxfregs); p.Do(bpmem); + p.Do(swstats); // CP Memory p.DoArray(arraybases, 16); From 46f5c19c6d2fbd3318e9a6de3c3c2e313c669cf0 Mon Sep 17 00:00:00 2001 From: Rachel Bryk Date: Tue, 26 Feb 2013 18:43:37 -0500 Subject: [PATCH 096/167] Not sure if this is the right way to handle this, but it makes the save states perfectly stable. That's all that really matters, right? --- Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp | 5 ++--- Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp index 4401916e1f..8e3f0c2925 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/OpcodeDecoder.cpp @@ -55,9 +55,8 @@ void DoState(PointerWrap &p) p.Do(lastPrimCmd); p.Do(streamSize); p.Do(streamAddress); - // not sure how to save this... It seems to be the only thing left that is really important. - // uncommenting this will prevent all error messages, and any crashes/hangs on load, but then obviously it'll segfault once you restart dolphin. - //p.Do(currentFunction); + if (p.GetMode() == PointerWrap::MODE_READ) + ResetDecoding(); } void DecodePrimitiveStream(u32 iBufferSize) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 6976b18690..0e2d6afa72 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -103,7 +103,8 @@ void VideoSoftware::DoState(PointerWrap& p) if (p.GetMode() == PointerWrap::MODE_READ && software == false) // change mode to abort load of incompatible save state. p.SetMode(PointerWrap::MODE_VERIFY); - // TODO: incomplete + + // TODO: incomplete? SWCommandProcessor::DoState(p); SWPixelEngine::DoState(p); EfbInterface::DoState(p); From f1c990069c8d0e54f7aa079e6e2c7b785a0d56db Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 26 Feb 2013 20:47:48 -0500 Subject: [PATCH 097/167] Yell at the user if they change window size while dumping frames, and some other avi dumping stuff. --- Source/Core/VideoCommon/Src/AVIDump.cpp | 18 ++++- Source/Core/VideoCommon/Src/AVIDump.h | 6 +- Source/Core/VideoCommon/Src/RenderBase.cpp | 5 +- Source/Core/VideoCommon/Src/RenderBase.h | 2 +- .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 25 ++++--- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 29 ++++---- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 66 ++++++++----------- 7 files changed, 73 insertions(+), 78 deletions(-) diff --git a/Source/Core/VideoCommon/Src/AVIDump.cpp b/Source/Core/VideoCommon/Src/AVIDump.cpp index c172903b5d..8514e8bd03 100644 --- a/Source/Core/VideoCommon/Src/AVIDump.cpp +++ b/Source/Core/VideoCommon/Src/AVIDump.cpp @@ -157,9 +157,21 @@ void AVIDump::Stop() NOTICE_LOG(VIDEO, "Stop"); } -void AVIDump::AddFrame(char *data) +void AVIDump::AddFrame(const u8* data, int w, int h) { - AVIStreamWrite(m_streamCompressed, ++m_frameCount, 1, (LPVOID) data, m_bitmap.biSizeImage, AVIIF_KEYFRAME, NULL, &m_byteBuffer); + static bool bShownError = false; + if ((w != m_bitmap.biWidth || h != m_bitmap.biHeight) && !bShownError) + { + PanicAlert("You have resized the window while dumping frames.\n" + "Nothing sane can be done to handle this.\n" + "Your video will likely be broken."); + bShownError=true; + + m_bitmap.biWidth = w; + m_bitmap.biHeight = h; + } + + AVIStreamWrite(m_streamCompressed, ++m_frameCount, 1, const_cast(data), m_bitmap.biSizeImage, AVIIF_KEYFRAME, NULL, &m_byteBuffer); m_totalBytes += m_byteBuffer; // Close the recording if the file is more than 2gb // VfW can't properly save files over 2gb in size, but can keep writing to them up to 4gb. @@ -298,7 +310,7 @@ bool AVIDump::CreateFile() return true; } -void AVIDump::AddFrame(uint8_t *data, int width, int height) +void AVIDump::AddFrame(const u8* data, int width, int height) { avpicture_fill((AVPicture *)s_BGRFrame, data, PIX_FMT_BGR24, width, height); diff --git a/Source/Core/VideoCommon/Src/AVIDump.h b/Source/Core/VideoCommon/Src/AVIDump.h index e74df05db4..08ab6be254 100644 --- a/Source/Core/VideoCommon/Src/AVIDump.h +++ b/Source/Core/VideoCommon/Src/AVIDump.h @@ -24,6 +24,8 @@ #include #endif +#include "CommonTypes.h" + class AVIDump { private: @@ -36,11 +38,11 @@ class AVIDump public: #ifdef _WIN32 static bool Start(HWND hWnd, int w, int h); - static void AddFrame(char *data); #else static bool Start(int w, int h); - static void AddFrame(uint8_t *data, int width, int height); #endif + static void AddFrame(const u8* data, int width, int height); + static void Stop(); }; diff --git a/Source/Core/VideoCommon/Src/RenderBase.cpp b/Source/Core/VideoCommon/Src/RenderBase.cpp index 8e1d012fa2..90a09aec43 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.cpp +++ b/Source/Core/VideoCommon/Src/RenderBase.cpp @@ -83,7 +83,9 @@ unsigned int Renderer::efb_scale_denominatorY = 1; unsigned int Renderer::ssaa_multiplier = 1; -Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false) +Renderer::Renderer() + : frame_data() + , bLastFrameDumped(false) { UpdateActiveConfig(); TextureCache::OnConfigChanged(g_ActiveConfig); @@ -110,7 +112,6 @@ Renderer::~Renderer() if (pFrameDump.IsOpen()) pFrameDump.Close(); #endif - delete[] frame_data; } void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h index 5376577cbd..8b5505e082 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.h +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -147,7 +147,7 @@ protected: #else File::IOFile pFrameDump; #endif - char* frame_data; + std::vector frame_data; bool bLastFrameDumped; // The framebuffer size diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index a6cb52c40f..44f4f1b15b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -761,11 +761,11 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle return SUCCEEDED(hr); } -void formatBufferDump(const char *in, char *out, int w, int h, int p) +void formatBufferDump(const u8* in, u8* out, int w, int h, int p) { for (int y = 0; y < h; ++y) { - const u8 *line = (u8*)(in + (h - y - 1) * p); + auto line = (in + (h - y - 1) * p); for (int x = 0; x < w; ++x) { out[0] = line[2]; @@ -782,8 +782,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -794,8 +794,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -934,16 +934,15 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3D11_MAPPED_SUBRESOURCE map; D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map); - if (!frame_data || w != s_recordWidth || h != s_recordHeight) + if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) { - delete[] frame_data; - frame_data = new char[3 * s_recordWidth * s_recordHeight]; + frame_data.resize(3 * s_recordWidth * s_recordHeight); w = s_recordWidth; h = s_recordHeight; } - char* source_ptr = (char*)map.pData + GetTargetRectangle().left*4 + GetTargetRectangle().top*map.RowPitch; - formatBufferDump(source_ptr, frame_data, s_recordWidth, s_recordHeight, map.RowPitch); - AVIDump::AddFrame(frame_data); + auto source_ptr = (const u8*)map.pData + GetTargetRectangle().left*4 + GetTargetRectangle().top*map.RowPitch; + formatBufferDump(source_ptr, &frame_data[0], s_recordWidth, s_recordHeight, map.RowPitch); + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); D3D::context->Unmap(s_screenshot_texture, 0); } bLastFrameDumped = true; @@ -952,7 +951,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (bLastFrameDumped && bAVIDumping) { - SAFE_DELETE_ARRAY(frame_data); + std::vector().swap(frame_data); w = h = 0; AVIDump::Stop(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 0657309801..151d80b16f 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -216,11 +216,11 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) } -void formatBufferDump(const char *in, char *out, int w, int h, int p) +void formatBufferDump(const u8* in, u8* out, int w, int h, int p) { for (int y = 0; y < h; y++) { - const char *line = in + (h - y - 1) * p; + auto line = in + (h - y - 1) * p; for (int x = 0; x < w; x++) { memcpy(out, line, 3); @@ -725,8 +725,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -737,8 +737,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -935,15 +935,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3DLOCKED_RECT rect; if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) { - if (!frame_data || w != s_recordWidth || h != s_recordHeight) + if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) { - delete[] frame_data; - frame_data = new char[3 * s_recordWidth * s_recordHeight]; + frame_data.resize(3 * s_recordWidth * s_recordHeight); w = s_recordWidth; h = s_recordHeight; } - formatBufferDump((const char*)rect.pBits, frame_data, s_recordWidth, s_recordHeight, rect.Pitch); - AVIDump::AddFrame(frame_data); + formatBufferDump((const u8*)rect.pBits, &frame_data[0], s_recordWidth, s_recordHeight, rect.Pitch); + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); ScreenShootMEMSurface->UnlockRect(); } } @@ -953,12 +952,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (bLastFrameDumped && bAVIDumping) { - if (frame_data) - { - delete[] frame_data; - frame_data = 0; - w = h = 0; - } + std::vector().swap(frame_data); + w = h = 0; AVIDump::Stop(); bAVIDumping = false; OSD::AddMessage("Stop dumping frames to AVI", 2000); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 3ff8b834ce..3cb4426513 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -956,20 +956,23 @@ void Renderer::SetBlendMode(bool forceUpdate) s_blendMode = newval; } +void DumpFrame(const std::vector& data, int w, int h) +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (g_ActiveConfig.bDumpFrames && !data.empty()) + { + AVIDump::AddFrame(&data[0], w, h); + } +#endif +} + // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { static int w = 0, h = 0; if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - if (g_ActiveConfig.bDumpFrames && frame_data) - { -#ifdef _WIN32 - AVIDump::AddFrame(frame_data); -#elif defined HAVE_LIBAV - AVIDump::AddFrame((u8*)frame_data, w, h); -#endif - } + DumpFrame(frame_data, w, h); Core::Callback_VideoCopiedToXFB(false); return; } @@ -979,14 +982,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0)) { - if (g_ActiveConfig.bDumpFrames && frame_data) - { -#ifdef _WIN32 - AVIDump::AddFrame(frame_data); -#elif defined HAVE_LIBAV - AVIDump::AddFrame((u8*)frame_data, w, h); -#endif - } + DumpFrame(frame_data, w, h); Core::Callback_VideoCopiedToXFB(false); return; } @@ -1149,16 +1145,15 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (g_ActiveConfig.bDumpFrames) { std::lock_guard lk(s_criticalScreenshot); - if (!frame_data || w != flipped_trc.GetWidth() || + if (frame_data.empty() || w != flipped_trc.GetWidth() || h != flipped_trc.GetHeight()) { - if (frame_data) delete[] frame_data; w = flipped_trc.GetWidth(); h = flipped_trc.GetHeight(); - frame_data = new char[3 * w * h]; + frame_data.resize(3 * w * h); } glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data); + glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, &frame_data[0]); if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0) { if (!bLastFrameDumped) @@ -1179,12 +1174,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } if (bAVIDumping) { - #ifdef _WIN32 - AVIDump::AddFrame(frame_data); - #else - FlipImageData((u8*)frame_data, w, h); - AVIDump::AddFrame((u8*)frame_data, w, h); + #ifndef _WIN32 + FlipImageData(&frame_data[0], w, h); #endif + + AVIDump::AddFrame(&frame_data[0], w, h); } bLastFrameDumped = true; @@ -1196,12 +1190,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (bLastFrameDumped && bAVIDumping) { - if (frame_data) - { - delete[] frame_data; - frame_data = NULL; - w = h = 0; - } + std::vector().swap(frame_data); + w = h = 0; AVIDump::Stop(); bAVIDumping = false; OSD::AddMessage("Stop dumping frames", 2000); @@ -1215,9 +1205,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons std::string movie_file_name; w = GetTargetRectangle().GetWidth(); h = GetTargetRectangle().GetHeight(); - frame_data = new char[3 * w * h]; + frame_data.resize(3 * w * h); glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(GetTargetRectangle().left, GetTargetRectangle().bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data); + glReadPixels(GetTargetRectangle().left, GetTargetRectangle().bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, &frame_data[0]); if (GL_REPORT_ERROR() == GL_NO_ERROR) { if (!bLastFrameDumped) @@ -1228,21 +1218,17 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons OSD::AddMessage("Error opening framedump.raw for writing.", 2000); else { - char msg [255]; - sprintf(msg, "Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h); - OSD::AddMessage(msg, 2000); + OSD::AddMessage(StromFromFormat("Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h), 2000); } } if (pFrameDump) { - FlipImageData((u8*)frame_data, w, h); - pFrameDump.WriteBytes(frame_data, w * 3 * h); + FlipImageData(&frame_data[0], w, h); + pFrameDump.WriteBytes(&frame_data[0], w * 3 * h); pFrameDump.Flush(); } bLastFrameDumped = true; } - - delete[] frame_data; } else { From a680d17eef88646b8cd6018c1c5e8f0e39d056ee Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 26 Feb 2013 19:59:33 -0600 Subject: [PATCH 098/167] Buildfix. --- Source/Core/VideoCommon/Src/AVIDump.cpp | 8 ++++---- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Core/VideoCommon/Src/AVIDump.cpp b/Source/Core/VideoCommon/Src/AVIDump.cpp index 8514e8bd03..fefb09fecb 100644 --- a/Source/Core/VideoCommon/Src/AVIDump.cpp +++ b/Source/Core/VideoCommon/Src/AVIDump.cpp @@ -159,13 +159,13 @@ void AVIDump::Stop() void AVIDump::AddFrame(const u8* data, int w, int h) { - static bool bShownError = false; - if ((w != m_bitmap.biWidth || h != m_bitmap.biHeight) && !bShownError) + static bool shown_error = false; + if ((w != m_bitmap.biWidth || h != m_bitmap.biHeight) && !shown_error) { PanicAlert("You have resized the window while dumping frames.\n" "Nothing sane can be done to handle this.\n" "Your video will likely be broken."); - bShownError=true; + shown_error = true; m_bitmap.biWidth = w; m_bitmap.biHeight = h; @@ -312,7 +312,7 @@ bool AVIDump::CreateFile() void AVIDump::AddFrame(const u8* data, int width, int height) { - avpicture_fill((AVPicture *)s_BGRFrame, data, PIX_FMT_BGR24, width, height); + avpicture_fill((AVPicture *)s_BGRFrame, const_cast(data), PIX_FMT_BGR24, width, height); // Convert image from BGR24 to desired pixel format, and scale to initial // width and height diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 3cb4426513..b5393cdbde 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1218,7 +1218,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons OSD::AddMessage("Error opening framedump.raw for writing.", 2000); else { - OSD::AddMessage(StromFromFormat("Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h), 2000); + OSD::AddMessage(StringFromFormat("Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h).c_str(), 2000); } } if (pFrameDump) From be7643cd2d1a27324070550ad82eca2c3bd59f19 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 27 Feb 2013 02:15:32 +0000 Subject: [PATCH 099/167] Add the missing FPR cache --- .../Core/Src/PowerPC/JitArm32/JitFPRCache.cpp | 168 ++++++++++++++++++ .../Core/Src/PowerPC/JitArm32/JitFPRCache.h | 62 +++++++ 2 files changed, 230 insertions(+) create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp create mode 100644 Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.h diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp new file mode 100644 index 0000000000..08f10df826 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp @@ -0,0 +1,168 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "JitFPRCache.h" + +ArmFPRCache::ArmFPRCache() +{ + emit = 0; +} + +void ArmFPRCache::Init(ARMXEmitter *emitter) +{ + emit = emitter; + ARMReg *PPCRegs = GetPPCAllocationOrder(NUMPPCREG); + ARMReg *Regs = GetAllocationOrder(NUMARMREG); + + for(u8 a = 0; a < NUMPPCREG; ++a) + { + ArmCRegs[a].PPCReg = 33; + ArmCRegs[a].Reg = PPCRegs[a]; + ArmCRegs[a].LastLoad = 0; + ArmCRegs[a].PS1 = false; + } + for(u8 a = 0; a < NUMARMREG; ++a) + { + ArmRegs[a].Reg = Regs[a]; + ArmRegs[a].free = true; + } +} +void ArmFPRCache::Start(PPCAnalyst::BlockRegStats &stats) +{ + for(u8 a = 0; a < NUMPPCREG; ++a) + { + ArmCRegs[a].PPCReg = 33; + ArmCRegs[a].LastLoad = 0; + } +} +ARMReg *ArmFPRCache::GetPPCAllocationOrder(int &count) +{ + // This will return us the allocation order of the registers we can use on + // the ppc side. + static ARMReg allocationOrder[] = + { + D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, + D11, D12, D13, D14, D15, D16, D17, D18, D19, + D20, D21, D22, D23, D24, D25, D26, D27 + }; + count = sizeof(allocationOrder) / sizeof(const int); + return allocationOrder; +} +ARMReg *ArmFPRCache::GetAllocationOrder(int &count) +{ + // This will return us the allocation order of the registers we can use on + // the host side. + static ARMReg allocationOrder[] = + { + D31, D30, D29, D28 + }; + count = sizeof(allocationOrder) / sizeof(const int); + return allocationOrder; +} + +ARMReg ArmFPRCache::GetReg(bool AutoLock) +{ + for(u8 a = 0; a < NUMARMREG; ++a) + if(ArmRegs[a].free) + { + // Alright, this one is free + if (AutoLock) + ArmRegs[a].free = false; + return ArmRegs[a].Reg; + } + // Uh Oh, we have all them locked.... + _assert_msg_(_DYNA_REC_, false, "All available registers are locked dumb dumb"); + return D31; +} +void ArmFPRCache::Unlock(ARMReg V0) +{ + for(u8 RegNum = 0; RegNum < NUMARMREG; ++RegNum) + { + if(ArmRegs[RegNum].Reg == V0) + { + _assert_msg_(_DYNA_REC, !ArmRegs[RegNum].free, "This register is already unlocked"); + ArmRegs[RegNum].free = true; + } + } +} +ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad) +{ + u32 HighestUsed = 0; + u8 Num = 0; + for(u8 a = 0; a < NUMPPCREG; ++a){ + ++ArmCRegs[a].LastLoad; + if (ArmCRegs[a].LastLoad > HighestUsed) + { + HighestUsed = ArmCRegs[a].LastLoad; + Num = a; + } + } + // Check if already Loaded + for(u8 a = 0; a < NUMPPCREG; ++a) + if (ArmCRegs[a].PPCReg == preg && ArmCRegs[a].PS1 == PS1) + { + ArmCRegs[a].LastLoad = 0; + return ArmCRegs[a].Reg; + } + // Check if we have a free register + for (u8 a = 0; a < NUMPPCREG; ++a) + if (ArmCRegs[a].PPCReg == 33) + { + u16 offset = STRUCT_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); + if (preLoad) + emit->VLDR(ArmCRegs[a].Reg, R9, offset); + ArmCRegs[a].PPCReg = preg; + ArmCRegs[a].LastLoad = 0; + ArmCRegs[a].PS1 = PS1; + return ArmCRegs[a].Reg; + } + // Alright, we couldn't get a free space, dump that least used register + u16 offsetOld = STRUCT_OFF(PowerPC::ppcState, ps) + (ArmCRegs[Num].PPCReg * 16) + (ArmCRegs[Num].PS1 ? 8 : 0); + emit->VSTR(ArmCRegs[Num].Reg, R9, offsetOld); + + u16 offsetNew = STRUCT_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); + if (preLoad) + emit->VLDR(ArmCRegs[Num].Reg, R9, offsetNew); + ArmCRegs[Num].PPCReg = preg; + ArmCRegs[Num].LastLoad = 0; + ArmCRegs[Num].PS1 = PS1; + return ArmCRegs[Num].Reg; + +} + +ARMReg ArmFPRCache::R0(u32 preg, bool preLoad) +{ + return GetPPCReg(preg, false, preLoad); +} + +ARMReg ArmFPRCache::R1(u32 preg, bool preLoad) +{ + return GetPPCReg(preg, true, preLoad); +} + +void ArmFPRCache::Flush() +{ + for(u8 a = 0; a < NUMPPCREG; ++a) + if (ArmCRegs[a].PPCReg != 33) + { + u16 offset = STRUCT_OFF(PowerPC::ppcState, ps) + (ArmCRegs[a].PPCReg * 16) + (ArmCRegs[a].PS1 ? 8 : 0); + emit->VSTR(ArmCRegs[a].Reg, R9, offset); + ArmCRegs[a].PPCReg = 33; + ArmCRegs[a].LastLoad = 0; + } +} + diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.h b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.h new file mode 100644 index 0000000000..6b4f056409 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.h @@ -0,0 +1,62 @@ +// Copyright (C) 2003 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _JITARMFPRCACHE_H +#define _JITARMFPRCACHE_H + +#include "ArmEmitter.h" +#include "../Gekko.h" +#include "../PPCAnalyst.h" +#include "JitRegCache.h" + +#define ARMFPUREGS 32 +using namespace ArmGen; + +class ArmFPRCache +{ +private: + PPCCachedReg regs[32]; + JRCPPC ArmCRegs[ARMFPUREGS]; + JRCReg ArmRegs[ARMFPUREGS]; + + int NUMPPCREG; + int NUMARMREG; + + ARMReg *GetAllocationOrder(int &count); + ARMReg *GetPPCAllocationOrder(int &count); + + ARMReg GetPPCReg(u32 preg, bool PS1, bool preLoad); + +protected: + ARMXEmitter *emit; + +public: + ArmFPRCache(); + ~ArmFPRCache() {} + + void Init(ARMXEmitter *emitter); + void Start(PPCAnalyst::BlockRegStats &stats); + + void SetEmitter(ARMXEmitter *emitter) {emit = emitter;} + + ARMReg GetReg(bool AutoLock = true); // Return a ARM register we can use. + void Unlock(ARMReg V0); + void Flush(); + ARMReg R0(u32 preg, bool preLoad = true); // Returns a cached register + ARMReg R1(u32 preg, bool preLoad = true); +}; +#endif From e435851e7a8dd56c94bb9bdc30f4c60c5b561163 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 25 Feb 2013 00:28:25 -0600 Subject: [PATCH 100/167] Add disabled code for authenticating wiimotes on Windows. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 93 ++++++++++++------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 61abeffa2d..2ae34a7ca5 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -35,6 +35,8 @@ #include #include +//#define AUTHENTICATE_WIIMOTES + typedef struct _HIDD_ATTRIBUTES { ULONG Size; @@ -56,6 +58,7 @@ typedef BOOL (__stdcall *PBth_BluetoothFindRadioClose)(HBLUETOOTH_RADIO_FIND); typedef DWORD (__stdcall *PBth_BluetoothGetRadioInfo)(HANDLE, PBLUETOOTH_RADIO_INFO); typedef DWORD (__stdcall *PBth_BluetoothRemoveDevice)(const BLUETOOTH_ADDRESS*); typedef DWORD (__stdcall *PBth_BluetoothSetServiceState)(HANDLE, const BLUETOOTH_DEVICE_INFO*, const GUID*, DWORD); +typedef DWORD (__stdcall *PBth_BluetoothAuthenticateDevice)(HWND, HANDLE, BLUETOOTH_DEVICE_INFO*, PWCHAR, ULONG); PHidD_GetHidGuid HidD_GetHidGuid = NULL; PHidD_GetAttributes HidD_GetAttributes = NULL; @@ -70,6 +73,7 @@ PBth_BluetoothFindRadioClose Bth_BluetoothFindRadioClose = NULL; PBth_BluetoothGetRadioInfo Bth_BluetoothGetRadioInfo = NULL; PBth_BluetoothRemoveDevice Bth_BluetoothRemoveDevice = NULL; PBth_BluetoothSetServiceState Bth_BluetoothSetServiceState = NULL; +PBth_BluetoothAuthenticateDevice Bth_BluetoothAuthenticateDevice = NULL; HINSTANCE hid_lib = NULL; HINSTANCE bthprops_lib = NULL; @@ -114,12 +118,13 @@ inline void init_lib() Bth_BluetoothGetRadioInfo = (PBth_BluetoothGetRadioInfo)GetProcAddress(bthprops_lib, "BluetoothGetRadioInfo"); Bth_BluetoothRemoveDevice = (PBth_BluetoothRemoveDevice)GetProcAddress(bthprops_lib, "BluetoothRemoveDevice"); Bth_BluetoothSetServiceState = (PBth_BluetoothSetServiceState)GetProcAddress(bthprops_lib, "BluetoothSetServiceState"); + Bth_BluetoothAuthenticateDevice = (PBth_BluetoothAuthenticateDevice)GetProcAddress(bthprops_lib, "BluetoothAuthenticateDevice"); if (!Bth_BluetoothFindDeviceClose || !Bth_BluetoothFindFirstDevice || !Bth_BluetoothFindFirstRadio || !Bth_BluetoothFindNextDevice || !Bth_BluetoothFindNextRadio || !Bth_BluetoothFindRadioClose || !Bth_BluetoothGetRadioInfo || !Bth_BluetoothRemoveDevice || - !Bth_BluetoothSetServiceState) + !Bth_BluetoothSetServiceState || !Bth_BluetoothAuthenticateDevice) { PanicAlertT("Failed to load bthprops.cpl"); exit(EXIT_FAILURE); @@ -135,9 +140,9 @@ namespace WiimoteReal template void ProcessWiimotes(bool new_scan, T& callback); -bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); -void RemoveWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); -bool ForgetWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi); +bool AttachWiimote(HANDLE hRadio, const BLUETOOTH_RADIO_INFO&, BLUETOOTH_DEVICE_INFO_STRUCT&); +void RemoveWiimote(BLUETOOTH_DEVICE_INFO_STRUCT&); +bool ForgetWiimote(BLUETOOTH_DEVICE_INFO_STRUCT&); WiimoteScanner::WiimoteScanner() : m_run_thread() @@ -149,16 +154,19 @@ WiimoteScanner::WiimoteScanner() WiimoteScanner::~WiimoteScanner() { // TODO: what do we want here? - ProcessWiimotes(false, RemoveWiimote); + ProcessWiimotes(false, [](HANDLE, BLUETOOTH_RADIO_INFO&, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) + { + RemoveWiimote(btdi); + }); } void WiimoteScanner::Update() { bool forgot_some = false; - ProcessWiimotes(false, [&](HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) + ProcessWiimotes(false, [&](HANDLE, BLUETOOTH_RADIO_INFO&, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { - forgot_some |= ForgetWiimote(hRadio, btdi); + forgot_some |= ForgetWiimote(btdi); }); // Some hacks that allows disconnects to be detected before connections are handled @@ -173,10 +181,10 @@ void WiimoteScanner::Update() // Returns the total number of found and connected wiimotes. std::vector WiimoteScanner::FindWiimotes() { - ProcessWiimotes(true, [](HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) + ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { - ForgetWiimote(hRadio, btdi); - AttachWiimote(hRadio, btdi); + ForgetWiimote(btdi); + AttachWiimote(hRadio, rinfo, btdi); }); // Get the device id @@ -485,31 +493,32 @@ void ProcessWiimotes(bool new_scan, T& callback) BLUETOOTH_RADIO_INFO radioInfo; radioInfo.dwSize = sizeof(radioInfo); - // TODO: check for SUCCEEDED() - Bth_BluetoothGetRadioInfo(hRadio, &radioInfo); - - srch.hRadio = hRadio; - - BLUETOOTH_DEVICE_INFO btdi; - btdi.dwSize = sizeof(btdi); - - // Enumerate BT devices - HBLUETOOTH_DEVICE_FIND hFindDevice = Bth_BluetoothFindFirstDevice(&srch, &btdi); - while (hFindDevice) + auto const rinfo_result = Bth_BluetoothGetRadioInfo(hRadio, &radioInfo); + if (ERROR_SUCCESS == rinfo_result) { - // btdi.szName is sometimes missings it's content - it's a bt feature.. - DEBUG_LOG(WIIMOTE, "authed %i connected %i remembered %i ", - btdi.fAuthenticated, btdi.fConnected, btdi.fRemembered); + srch.hRadio = hRadio; - if (std::regex_match(btdi.szName, wiimote_device_name)) - { - callback(hRadio, btdi); - } + BLUETOOTH_DEVICE_INFO btdi; + btdi.dwSize = sizeof(btdi); - if (false == Bth_BluetoothFindNextDevice(hFindDevice, &btdi)) + // Enumerate BT devices + HBLUETOOTH_DEVICE_FIND hFindDevice = Bth_BluetoothFindFirstDevice(&srch, &btdi); + while (hFindDevice) { - Bth_BluetoothFindDeviceClose(hFindDevice); - hFindDevice = NULL; + // btdi.szName is sometimes missings it's content - it's a bt feature.. + DEBUG_LOG(WIIMOTE, "authed %i connected %i remembered %i ", + btdi.fAuthenticated, btdi.fConnected, btdi.fRemembered); + + if (std::regex_match(btdi.szName, wiimote_device_name)) + { + callback(hRadio, radioInfo, btdi); + } + + if (false == Bth_BluetoothFindNextDevice(hFindDevice, &btdi)) + { + Bth_BluetoothFindDeviceClose(hFindDevice); + hFindDevice = NULL; + } } } @@ -521,7 +530,7 @@ void ProcessWiimotes(bool new_scan, T& callback) } } -void RemoveWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) +void RemoveWiimote(BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { //if (btdi.fConnected) { @@ -532,14 +541,26 @@ void RemoveWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) } } -bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) +bool AttachWiimote(HANDLE hRadio, const BLUETOOTH_RADIO_INFO& radio_info, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { // We don't want "remembered" devices. // SetServiceState will just fail with them.. if (!btdi.fConnected && !btdi.fRemembered) { - NOTICE_LOG(WIIMOTE, "Found wiimote. Enabling HID service."); + auto const& wm_addr = btdi.Address.rgBytes; + NOTICE_LOG(WIIMOTE, "Found wiimote (%02x:%02x:%02x:%02x:%02x:%02x). Enabling HID service.", + wm_addr[0], wm_addr[1], wm_addr[2], wm_addr[3], wm_addr[4], wm_addr[5]); + +#if defined(AUTHENTICATE_WIIMOTES) + // Authenticate + auto const& radio_addr = radio_info.address.rgBytes; + const DWORD auth_result = Bth_BluetoothAuthenticateDevice(NULL, hRadio, &btdi, + std::vector(radio_addr, radio_addr + 6).data(), 6); + + if (ERROR_SUCCESS != auth_result) + ERROR_LOG(WIIMOTE, "AttachWiimote: BluetoothAuthenticateDevice returned %08x", auth_result); +#endif // Activate service const DWORD hr = Bth_BluetoothSetServiceState(hRadio, &btdi, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE); @@ -547,7 +568,7 @@ bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) g_connect_times[btdi.Address.ullLong] = std::time(nullptr); if (FAILED(hr)) - ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr); + ERROR_LOG(WIIMOTE, "AttachWiimote: BluetoothSetServiceState returned %08x", hr); else return true; } @@ -556,7 +577,7 @@ bool AttachWiimote(HANDLE hRadio, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) } // Removes remembered non-connected devices -bool ForgetWiimote(HANDLE, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) +bool ForgetWiimote(BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { if (!btdi.fConnected && btdi.fRemembered) { From 6b80e6f83cf4557eff89402484c1d5b2f5606a5f Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 26 Feb 2013 22:47:50 -0600 Subject: [PATCH 101/167] Tweak Vertex/Index buffer handling a bit. --- Source/Core/VideoCommon/Src/VertexLoader.cpp | 23 ++----- .../VideoCommon/Src/VertexManagerBase.cpp | 66 +++++++++++-------- .../Core/VideoCommon/Src/VertexManagerBase.h | 35 ++++------ .../Plugin_VideoDX11/Src/VertexManager.cpp | 6 +- .../Plugin_VideoDX9/Src/VertexManager.cpp | 12 ++-- .../Plugin_VideoOGL/Src/VertexManager.cpp | 6 +- 6 files changed, 69 insertions(+), 79 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index 7d1b9d99a5..ca128b4f86 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -517,7 +517,7 @@ void VertexLoader::WriteSetVariable(int bits, void *address, OpArg value) #endif } -void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) +void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const count) { m_numLoadedVertices += count; @@ -560,21 +560,11 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int count) for (int i = 0; i < 2; i++) colElements[i] = m_VtxAttr.color[i].Elements; - if (VertexManager::GetRemainingSize() < count * native_stride) - { - VertexManager::Flush(); - - if (VertexManager::GetRemainingSize() < count * native_stride) - ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all vertices! " - "Increase MAXVBUFFERSIZE or we need primitive breaking afterall."); - } - + VertexManager::PrepareForAdditionalData(primitive, count, native_stride); ConvertVertices(count); VertexManager::AddVertices(primitive, count); - //VertexManager::Flush(); } - void VertexLoader::ConvertVertices ( int count ) { #ifdef USE_JIT @@ -598,7 +588,7 @@ void VertexLoader::ConvertVertices ( int count ) -void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int count, u8* Data) +void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int const count, u8* Data) { m_numLoadedVertices += count; @@ -641,16 +631,15 @@ void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int co for (int i = 0; i < 2; i++) colElements[i] = m_VtxAttr.color[i].Elements; - if(VertexManager::GetRemainingSize() < native_stride * count) - VertexManager::Flush(); + VertexManager::PrepareForAdditionalData(primitive, count, native_stride); + memcpy_gc(VertexManager::s_pCurBufferPointer, Data, native_stride * count); VertexManager::s_pCurBufferPointer += native_stride * count; DataSkip(count * m_VertexSize); + VertexManager::AddVertices(primitive, count); } - - void VertexLoader::SetVAT(u32 _group0, u32 _group1, u32 _group2) { VAT vat; diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 131d6de42a..bc1d51b69e 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -23,38 +23,43 @@ u8 *VertexManager::s_pEndBufferPointer; VertexManager::VertexManager() { - LocalVBuffer = new u8[MAXVBUFFERSIZE]; - s_pCurBufferPointer = s_pBaseBufferPointer = LocalVBuffer; - s_pEndBufferPointer = s_pBaseBufferPointer + MAXVBUFFERSIZE; + LocalVBuffer.resize(MAXVBUFFERSIZE); + s_pCurBufferPointer = s_pBaseBufferPointer = &LocalVBuffer[0]; + s_pEndBufferPointer = s_pBaseBufferPointer + LocalVBuffer.size(); - TIBuffer = new u16[MAXIBUFFERSIZE]; - LIBuffer = new u16[MAXIBUFFERSIZE]; - PIBuffer = new u16[MAXIBUFFERSIZE]; + TIBuffer.resize(MAXIBUFFERSIZE); + LIBuffer.resize(MAXIBUFFERSIZE); + PIBuffer.resize(MAXIBUFFERSIZE); ResetBuffer(); } VertexManager::~VertexManager() -{ - delete[] LocalVBuffer; - - delete[] TIBuffer; - delete[] LIBuffer; - delete[] PIBuffer; - - // TODO: necessary?? - ResetBuffer(); -} +{} void VertexManager::ResetBuffer() { s_pCurBufferPointer = s_pBaseBufferPointer; - IndexGenerator::Start(TIBuffer, LIBuffer, PIBuffer); + IndexGenerator::Start(GetTriangleIndexBuffer(), GetLineIndexBuffer(), GetPointIndexBuffer()); } -int VertexManager::GetRemainingSize() +u32 VertexManager::GetRemainingSize() { - return (int)(s_pEndBufferPointer - s_pCurBufferPointer); + return (u32)(s_pEndBufferPointer - s_pCurBufferPointer); +} + +void VertexManager::PrepareForAdditionalData(int primitive, u32 count, u32 stride) +{ + u32 const needed_vertex_bytes = count * stride; + + if (needed_vertex_bytes > GetRemainingSize() || count > GetRemainingIndices(primitive)) + { + Flush(); + + if (needed_vertex_bytes > GetRemainingSize()) + ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all vertices! " + "Increase MAXVBUFFERSIZE or we need primitive breaking afterall."); + } } bool VertexManager::IsFlushed() const @@ -62,10 +67,7 @@ bool VertexManager::IsFlushed() const return s_pBaseBufferPointer == s_pCurBufferPointer; } -// Not used anywhere -// TODO: use this -#if 0 -int VertexManager::GetRemainingVertices(int primitive) +u32 VertexManager::GetRemainingIndices(int primitive) { switch (primitive) { @@ -90,7 +92,6 @@ int VertexManager::GetRemainingVertices(int primitive) break; } } -#endif void VertexManager::AddVertices(int primitive, u32 numVertices) { @@ -252,9 +253,16 @@ void VertexManager::DoState(PointerWrap& p) void VertexManager::DoStateShared(PointerWrap& p) { - p.DoPointer(s_pCurBufferPointer, g_vertex_manager->LocalVBuffer); - p.DoArray(LocalVBuffer, MAXVBUFFERSIZE); - p.DoArray(g_vertex_manager->TIBuffer, MAXIBUFFERSIZE); - p.DoArray(g_vertex_manager->LIBuffer, MAXIBUFFERSIZE); - p.DoArray(g_vertex_manager->PIBuffer, MAXIBUFFERSIZE); + // It seems we half-assume to be flushed here + // We update s_pCurBufferPointer yet don't worry about IndexGenerator's outdated pointers + // and maybe other things are overlooked + + p.Do(LocalVBuffer); + p.Do(TIBuffer); + p.Do(LIBuffer); + p.Do(PIBuffer); + + s_pBaseBufferPointer = &LocalVBuffer[0]; + s_pEndBufferPointer = s_pBaseBufferPointer + LocalVBuffer.size(); + p.DoPointer(s_pCurBufferPointer, s_pBaseBufferPointer); } diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.h b/Source/Core/VideoCommon/Src/VertexManagerBase.h index 4bf5541cbd..2690ffc03e 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.h +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.h @@ -2,6 +2,8 @@ #ifndef _VERTEXMANAGERBASE_H #define _VERTEXMANAGERBASE_H +#include + class NativeVertexFormat; class PointerWrap; @@ -15,16 +17,10 @@ private: static const u32 MAX_PRIMITIVES_PER_COMMAND = (u16)-1; public: - // values from OGL backend - //static const u32 MAXVBUFFERSIZE = 0x1FFFF; - - // values from DX9/11 backend static const u32 MAXVBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * LARGEST_POSSIBLE_VERTEX; // We may convert triangle-fans to triangle-lists, almost 3x as many indices. - // Watching for a full index buffer would probably be smarter than this calculation. - static const u32 MAXIBUFFERSIZE = MAXVBUFFERSIZE * 3 / SMALLEST_POSSIBLE_VERTEX; - //static const u32 MAXIBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * 3; + static const u32 MAXIBUFFERSIZE = MAX_PRIMITIVES_PER_COMMAND * 3; VertexManager(); // needs to be virtual for DX11's dtor @@ -36,29 +32,23 @@ public: static u8 *s_pBaseBufferPointer; static u8 *s_pEndBufferPointer; - static int GetRemainingSize(); - - //int GetRemainingVertices(int primitive); + static u32 GetRemainingSize(); + static void PrepareForAdditionalData(int primitive, u32 count, u32 stride); + static u32 GetRemainingIndices(int primitive); static void Flush(); virtual ::NativeVertexFormat* CreateNativeVertexFormat() = 0; - // TODO: use these instead of TIBuffer, etc - -// u16* GetTriangleIndexBuffer() { return TIBuffer; } -// u16* GetLineIndexBuffer() { return LIBuffer; } -// u16* GetPointIndexBuffer() { return PIBuffer; } -// u8* GetVertexBuffer() { return s_pBaseBufferPointer; } - static void DoState(PointerWrap& p); virtual void CreateDeviceObjects(){}; virtual void DestroyDeviceObjects(){}; protected: - u16* TIBuffer; - u16* LIBuffer; - u16* PIBuffer; + u16* GetTriangleIndexBuffer() { return &TIBuffer[0]; } + u16* GetLineIndexBuffer() { return &LIBuffer[0]; } + u16* GetPointIndexBuffer() { return &PIBuffer[0]; } + u8* GetVertexBuffer() { return &s_pBaseBufferPointer[0]; } virtual void vDoState(PointerWrap& p) { DoStateShared(p); } void DoStateShared(PointerWrap& p); @@ -72,7 +62,10 @@ private: // temp virtual void vFlush() = 0; - u8* LocalVBuffer; + std::vector LocalVBuffer; + std::vector TIBuffer; + std::vector LIBuffer; + std::vector PIBuffer; }; extern VertexManager *g_vertex_manager; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 573180e0b7..b7c8392b42 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -136,9 +136,9 @@ void VertexManager::LoadBuffers() m_triangleDrawIndex = m_indexBufferCursor; m_lineDrawIndex = m_triangleDrawIndex + IndexGenerator::GetTriangleindexLen(); m_pointDrawIndex = m_lineDrawIndex + IndexGenerator::GetLineindexLen(); - memcpy((u16*)map.pData + m_triangleDrawIndex, TIBuffer, sizeof(u16) * IndexGenerator::GetTriangleindexLen()); - memcpy((u16*)map.pData + m_lineDrawIndex, LIBuffer, sizeof(u16) * IndexGenerator::GetLineindexLen()); - memcpy((u16*)map.pData + m_pointDrawIndex, PIBuffer, sizeof(u16) * IndexGenerator::GetPointindexLen()); + memcpy((u16*)map.pData + m_triangleDrawIndex, GetTriangleIndexBuffer(), sizeof(u16) * IndexGenerator::GetTriangleindexLen()); + memcpy((u16*)map.pData + m_lineDrawIndex, GetLineIndexBuffer(), sizeof(u16) * IndexGenerator::GetLineindexLen()); + memcpy((u16*)map.pData + m_pointDrawIndex, GetPointIndexBuffer(), sizeof(u16) * IndexGenerator::GetPointindexLen()); D3D::context->Unmap(m_indexBuffers[m_activeIndexBuffer], 0); m_indexBufferCursor += iCount; } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 7ef3052a96..7e1f4dfae2 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -192,17 +192,17 @@ void VertexManager::PrepareVBuffers(int stride) } if(TdataSize) { - memcpy(pIndices, TIBuffer, TdataSize * sizeof(u16)); + memcpy(pIndices, GetTriangleIndexBuffer(), TdataSize * sizeof(u16)); pIndices += TdataSize; } if(LDataSize) { - memcpy(pIndices, LIBuffer, LDataSize * sizeof(u16)); + memcpy(pIndices, GetLineIndexBuffer(), LDataSize * sizeof(u16)); pIndices += LDataSize; } if(PDataSize) { - memcpy(pIndices, PIBuffer, PDataSize * sizeof(u16)); + memcpy(pIndices, GetPointIndexBuffer(), PDataSize * sizeof(u16)); } IBuffers[CurrentIBuffer]->Unlock(); D3D::dev->SetStreamSource( 0, VBuffers[CurrentVBuffer], CurrentVBufferIndex, stride); @@ -266,7 +266,7 @@ void VertexManager::DrawVA(int stride) if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumTriangles(), - TIBuffer, + GetTriangleIndexBuffer(), D3DFMT_INDEX16, s_pBaseBufferPointer, stride))) @@ -280,7 +280,7 @@ void VertexManager::DrawVA(int stride) if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_LINELIST, 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumLines(), - LIBuffer, + GetLineIndexBuffer(), D3DFMT_INDEX16, s_pBaseBufferPointer, stride))) @@ -294,7 +294,7 @@ void VertexManager::DrawVA(int stride) if (FAILED(D3D::dev->DrawIndexedPrimitiveUP( D3DPT_POINTLIST, 0, IndexGenerator::GetNumVerts(), IndexGenerator::GetNumPoints(), - PIBuffer, + GetPointIndexBuffer(), D3DFMT_INDEX16, s_pBaseBufferPointer, stride))) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 5777f225cd..bbd48f90d9 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -83,17 +83,17 @@ void VertexManager::Draw() { if (IndexGenerator::GetNumTriangles() > 0) { - glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, TIBuffer); + glDrawElements(GL_TRIANGLES, IndexGenerator::GetTriangleindexLen(), GL_UNSIGNED_SHORT, GetTriangleIndexBuffer()); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (IndexGenerator::GetNumLines() > 0) { - glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, LIBuffer); + glDrawElements(GL_LINES, IndexGenerator::GetLineindexLen(), GL_UNSIGNED_SHORT, GetLineIndexBuffer()); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } if (IndexGenerator::GetNumPoints() > 0) { - glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, PIBuffer); + glDrawElements(GL_POINTS, IndexGenerator::GetPointindexLen(), GL_UNSIGNED_SHORT, GetPointIndexBuffer()); INCSTAT(stats.thisFrame.numIndexedDrawCalls); } } From 8c779bb2426a5eae7fbf0e5048ae18bdf3d34a3c Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 27 Feb 2013 10:26:32 -0600 Subject: [PATCH 102/167] Ah. I blame vim on this typo entirely. --- Source/Core/Common/Src/ArmEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp index 6463dbe2ef..f24ffbb07f 100644 --- a/Source/Core/Common/Src/ArmEmitter.cpp +++ b/Source/Core/Common/Src/ArmEmitter.cpp @@ -791,7 +791,7 @@ void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm) if (single_reg) { - Write32(NO_COND | (0xEB << 20) | ((Vd & 0x1) << 6) | ((Vd & 0x1E) << 11) \ + Write32(NO_COND | (0xEB << 20) | ((Vd & 0x1) << 22) | ((Vd & 0x1E) << 11) \ | (0xAC << 4) | ((Vm & 0x1) << 5) | (Vm >> 1)); } else From f1d727cf1376efebf434abcaa31c63abd2894dad Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 27 Feb 2013 11:53:24 -0600 Subject: [PATCH 103/167] Merge latest ArmEmitter changes from ppsspp while we're at it. --- Source/Core/Common/Src/ArmEmitter.cpp | 137 +++++++++++++++++++++----- Source/Core/Common/Src/ArmEmitter.h | 16 +-- 2 files changed, 123 insertions(+), 30 deletions(-) diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp index f24ffbb07f..3b3bf7c550 100644 --- a/Source/Core/Common/Src/ArmEmitter.cpp +++ b/Source/Core/Common/Src/ArmEmitter.cpp @@ -22,11 +22,16 @@ #include #include -// For cache flushing on Symbian/Blackberry +// For cache flushing on Symbian/iOS/Blackberry #ifdef __SYMBIAN32__ #include #endif +#ifdef IOS +#include +#include +#endif + #ifdef BLACKBERRY #include #endif @@ -185,18 +190,16 @@ void ARMXEmitter::FlushIcache() void ARMXEmitter::FlushIcacheSection(u8 *start, u8 *end) { #ifdef __SYMBIAN32__ - User::IMB_Range( start, end); + User::IMB_Range(start, end); #elif defined(BLACKBERRY) msync(start, end - start, MS_SYNC | MS_INVALIDATE_ICACHE); -#else -#ifndef _WIN32 -#ifdef ANDROID - __builtin___clear_cache (start, end); -#else - // If on Linux, we HAVE to clear from start addr or else everything gets /really/ unstable - __builtin___clear_cache (startcode, end); -#endif +#elif defined(IOS) + sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start); +#elif !defined(_WIN32) +#ifndef ANDROID + start = startcode; #endif + __builtin___clear_cache(start, end); #endif } @@ -493,6 +496,7 @@ void ARMXEmitter::SMULL(ARMReg destLo, ARMReg destHi, ARMReg rm, ARMReg rn) { Write4OpMultiply(0xC, destLo, destHi, rn, rm); } + void ARMXEmitter::SXTB (ARMReg dest, ARMReg op2) { Write32(condition | (0x6AF << 16) | (dest << 12) | (7 << 4) | op2); @@ -528,9 +532,10 @@ void ARMXEmitter::MRS (ARMReg dest) { Write32(condition | (16 << 20) | (15 << 16) | (dest << 12)); } + void ARMXEmitter::WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2) { - if (op2.GetData() == 0) // Don't index + if (op2.GetData() == 0) // set the preindex bit, but not the W bit! Write32(condition | 0x01800000 | (op << 20) | (dest << 16) | (src << 12) | op2.Imm12()); else Write32(condition | (op << 20) | (3 << 23) | (dest << 16) | (src << 12) | op2.Imm12()); @@ -620,6 +625,7 @@ ARMReg ARMXEmitter::SubBase(ARMReg Reg) } return Reg; } + // NEON Specific void ARMXEmitter::VADD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) { @@ -627,7 +633,7 @@ void ARMXEmitter::VADD(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) _assert_msg_(DYNA_REC, cpu_info.bNEON, "Can't use VADD(integer) when CPU doesn't support it"); bool register_quad = Vd >= Q0; - + // Gets encoded as a double register Vd = SubBase(Vd); Vn = SubBase(Vn); @@ -651,16 +657,20 @@ void ARMXEmitter::VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) Write32((0xF3 << 24) | ((Vd & 0x10) << 18) | (Size << 20) | ((Vn & 0xF) << 16) \ | ((Vd & 0xF) << 12) | (0x8 << 8) | ((Vn & 0x10) << 3) | (1 << 6) \ | ((Vm & 0x10) << 2) | (Vm & 0xF)); - } // VFP Specific -void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 op) +void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 offset) { _assert_msg_(DYNA_REC, Dest >= S0 && Dest <= D31, "Passed Invalid dest register to VLDR"); _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid Base register to VLDR"); - _assert_msg_(DYNA_REC, !(op & 3), "Offset needs to be word aligned"); + _assert_msg_(DYNA_REC, (offset & 0xC03) == 0, "VLDR: Offset needs to be word aligned and small enough"); + + if (offset & 0xC03) { + ERROR_LOG(DYNA_REC, "VLDR: Bad offset %08x", offset); + } + bool single_reg = Dest < D0; Dest = SubBase(Dest); @@ -668,20 +678,25 @@ void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 op) if (single_reg) { Write32(NO_COND | (0x1B << 23) | ((Dest & 0x1) << 22) | (1 << 20) | (Base << 16) \ - | ((Dest & 0x1E) << 11) | (10 << 8) | (op >> 2)); + | ((Dest & 0x1E) << 11) | (10 << 8) | (offset >> 2)); } else { Write32(NO_COND | (0x1B << 23) | ((Dest & 0x10) << 18) | (1 << 20) | (Base << 16) \ - | ((Dest & 0xF) << 12) | (11 << 8) | (op >> 2)); + | ((Dest & 0xF) << 12) | (11 << 8) | (offset >> 2)); } } -void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 op) +void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 offset) { _assert_msg_(DYNA_REC, Src >= S0 && Src <= D31, "Passed invalid src register to VSTR"); _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid base register to VSTR"); - _assert_msg_(DYNA_REC, !(op & 3), "Offset needs to be word aligned"); + _assert_msg_(DYNA_REC, (offset & 0xC03) == 0, "VSTR: Offset needs to be word aligned"); + + if (offset & 0xC03) { + ERROR_LOG(DYNA_REC, "VSTR: Bad offset %08x", offset); + } + bool single_reg = Src < D0; Src = SubBase(Src); @@ -689,13 +704,13 @@ void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 op) if (single_reg) { Write32(NO_COND | (0x1B << 23) | ((Src & 0x1) << 22) | (Base << 16) \ - | ((Src & 0x1E) << 11) | (10 << 8) | (op >> 2)); + | ((Src & 0x1E) << 11) | (10 << 8) | (offset >> 2)); } else { Write32(NO_COND | (0x1B << 23) | ((Src & 0x10) << 18) | (Base << 16) \ - | ((Src & 0xF) << 12) | (11 << 8) | (op >> 2)); + | ((Src & 0xF) << 12) | (11 << 8) | (offset >> 2)); } } void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm) @@ -779,12 +794,14 @@ void ARMXEmitter::VSQRT(ARMReg Vd, ARMReg Vm) | ((Vd & 0xF) << 12) | (0x2F << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); } } + // VFP and ASIMD void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm) { _assert_msg_(DYNA_REC, Vd < Q0, "VABS doesn't currently support Quad reg"); _assert_msg_(DYNA_REC, Vd >= S0, "VABS doesn't support ARM Regs"); bool single_reg = Vd < D0; + bool double_reg = Vd < Q0; Vd = SubBase(Vd); Vm = SubBase(Vm); @@ -796,10 +813,19 @@ void ARMXEmitter::VABS(ARMReg Vd, ARMReg Vm) } else { - Write32(NO_COND | (0xEB << 20) | ((Vd & 0x10) << 18) | ((Vd & 0xF) << 12) \ - | (0xBC << 4) | ((Vm & 0x10) << 1) | (Vm & 0xF)); + if (double_reg) + { + Write32(NO_COND | (0xEB << 20) | ((Vd & 0x10) << 18) | ((Vd & 0xF) << 12) \ + | (0xBC << 4) | ((Vm & 0x10) << 1) | (Vm & 0xF)); + } + else + { + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VADD with Quad Reg without support!"); + // XXX: TODO + } } } + void ARMXEmitter::VADD(ARMReg Vd, ARMReg Vn, ARMReg Vm) { _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VADD"); @@ -870,6 +896,70 @@ void ARMXEmitter::VSUB(ARMReg Vd, ARMReg Vn, ARMReg Vm) } } } +void ARMXEmitter::VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd >= S0, "Passed invalid dest register to VADD"); + _assert_msg_(DYNA_REC, Vn >= S0, "Passed invalid Vn to VADD"); + _assert_msg_(DYNA_REC, Vm >= S0, "Passed invalid Vm to VADD"); + bool single_reg = Vd < D0; + bool double_reg = Vd < Q0; + + Vd = SubBase(Vd); + Vn = SubBase(Vn); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1C << 23) | ((Vd & 0x1) << 22) | (0x2 << 20) \ + | ((Vn & 0x1E) << 15) | ((Vd & 0x1E) << 11) | (0x5 << 9) \ + | ((Vn & 0x1) << 7) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + if (double_reg) + { + Write32(NO_COND | (0x1C << 23) | ((Vd & 0x10) << 18) | (0x2 << 20) \ + | ((Vn & 0xF) << 16) | ((Vd & 0xF) << 12) | (0xB << 8) \ + | ((Vn & 0x10) << 3) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } + else + { + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VMUL with Quad Reg without support!"); + // XXX: TODO + } + } +} + +void ARMXEmitter::VNEG(ARMReg Vd, ARMReg Vm) +{ + _assert_msg_(DYNA_REC, Vd < Q0, "VNEG doesn't currently support Quad reg"); + _assert_msg_(DYNA_REC, Vd >= S0, "VNEG doesn't support ARM Regs"); + bool single_reg = Vd < D0; + bool double_reg = Vd < Q0; + + Vd = SubBase(Vd); + Vm = SubBase(Vm); + + if (single_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x1) << 22) | (0x31 << 16) \ + | ((Vd & 0x1E) << 11) | (0x29 << 6) | ((Vm & 0x1) << 5) | (Vm >> 1)); + } + else + { + if (double_reg) + { + Write32(NO_COND | (0x1D << 23) | ((Vd & 0x10) << 18) | (0x31 << 16) \ + | ((Vd & 0xF) << 12) | (0x2D << 6) | ((Vm & 0x10) << 2) | (Vm & 0xF)); + } + else + { + _assert_msg_(DYNA_REC, cpu_info.bNEON, "Trying to use VNEG with Quad Reg without support!"); + // XXX: TODO + + } + } +} void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src, bool high) { @@ -881,6 +971,7 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src, bool high) Write32(NO_COND | (0xE << 24) | (high << 21) | ((Dest & 0xF) << 16) | (Src << 12) \ | (11 << 8) | ((Dest & 0x10) << 3) | (1 << 4)); } + void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src) { if (Dest > R15) diff --git a/Source/Core/Common/Src/ArmEmitter.h b/Source/Core/Common/Src/ArmEmitter.h index 13635867a9..a3ff7d25ae 100644 --- a/Source/Core/Common/Src/ArmEmitter.h +++ b/Source/Core/Common/Src/ArmEmitter.h @@ -227,7 +227,7 @@ public: } const u32 IMMSR() // IMM shifted register { - _assert_msg_(DYNA_REC, Type = TYPE_IMMSREG, "IMMSR must be imm shifted register"); + _assert_msg_(DYNA_REC, Type == TYPE_IMMSREG, "IMMSR must be imm shifted register"); return ((IndexOrShift & 0x1f) << 7 | (Shift << 5) | Value); } const u32 RSR() // Register shifted register @@ -343,8 +343,9 @@ private: void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2); void WriteSignedMultiply(u32 Op, u32 Op2, u32 Op3, ARMReg dest, ARMReg r1, ARMReg r2); + void Write4OpMultiply(u32 op, ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); - + // New Ops void WriteInstruction(u32 op, ARMReg Rd, ARMReg Rn, Operand2 Rm, bool SetFlags = false); @@ -452,7 +453,7 @@ public: void MUL (ARMReg dest, ARMReg src, ARMReg op2); void MULS(ARMReg dest, ARMReg src, ARMReg op2); - + void UMULL(ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); void SMULL(ARMReg destLo, ARMReg destHi, ARMReg rn, ARMReg rm); @@ -498,8 +499,8 @@ public: void VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); // VFP Only - void VLDR(ARMReg Dest, ARMReg Base, u16 op); - void VSTR(ARMReg Src, ARMReg Base, u16 op); + void VLDR(ARMReg Dest, ARMReg Base, u16 offset); + void VSTR(ARMReg Src, ARMReg Base, u16 offset); void VCMP(ARMReg Vd, ARMReg Vm); // Compares against zero void VCMP(ARMReg Vd); @@ -507,10 +508,11 @@ public: void VSQRT(ARMReg Vd, ARMReg Vm); // NEON and VFP - void VABS(ARMReg Vd, ARMReg Vm); void VADD(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VSUB(ARMReg Vd, ARMReg Vn, ARMReg Vm); - + void VABS(ARMReg Vd, ARMReg Vm); + void VNEG(ARMReg Vd, ARMReg Vm); + void VMUL(ARMReg Vd, ARMReg Vn, ARMReg Vm); void VMOV(ARMReg Dest, ARMReg Src, bool high); void VMOV(ARMReg Dest, ARMReg Src); From 9ff704f202cf4d31e00476c08d27327f12478b8a Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 27 Feb 2013 15:17:23 -0600 Subject: [PATCH 104/167] Small improvement to cmpli/cmpi in ARMJit. --- .../Src/PowerPC/JitArm32/JitArm_Integer.cpp | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp index 63c96b21fd..753568c9d3 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -193,11 +193,18 @@ void JitArm::cmpi(UGeckoInstruction inst) JITDISABLE(Integer) ARMReg RA = gpr.R(inst.RA); - ARMReg rA = gpr.GetReg(); int crf = inst.CRFD; - MOVI2R(rA, inst.SIMM_16); - CMP(RA, rA); - gpr.Unlock(rA); + if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256) + { + CMP(RA, inst.SIMM_16); + } + else + { + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, inst.SIMM_16); + CMP(RA, rA); + gpr.Unlock(rA); + } ComputeRC(crf); } void JitArm::cmpli(UGeckoInstruction inst) @@ -208,9 +215,16 @@ void JitArm::cmpli(UGeckoInstruction inst) ARMReg RA = gpr.R(inst.RA); ARMReg rA = gpr.GetReg(); int crf = inst.CRFD; - MOVI2R(rA, (u32)inst.UIMM); - CMP(RA, rA); - + u32 uimm = (u32)inst.UIMM; + if (uimm < 256) + { + CMP(RA, uimm); + } + else + { + MOVI2R(rA, (u32)inst.UIMM); + CMP(RA, rA); + } // Unsigned GenerateRC() MOV(rA, 0x2); // Result == 0 From 0ea458b4dc9241a59fd18456c846be44694fdb7d Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 18:00:42 -0600 Subject: [PATCH 105/167] Add functions for converting between UTF-8/16. --- Source/Core/Common/Src/StringUtil.cpp | 34 +++++++++++++++++++++++++++ Source/Core/Common/Src/StringUtil.h | 7 ++++++ 2 files changed, 41 insertions(+) diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 6ef3d91a73..503c2810c3 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -22,6 +22,10 @@ #include "CommonPaths.h" #include "StringUtil.h" +#ifdef _WIN32 +#include +#endif + // faster than sscanf bool AsciiToHex(const char* _szValue, u32& result) { @@ -375,3 +379,33 @@ std::string UriEncode(const std::string & sSrc) delete [] pStart; return sResult; } + +#ifdef _WIN32 + +std::string UTF16ToUTF8(const std::wstring& input) +{ + auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), nullptr, 0, nullptr, nullptr); + + std::string output; + output.resize(size); + + if (size != WideCharToMultiByte(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size(), nullptr, nullptr)) + output.clear(); + + return output; +} + +std::wstring UTF8ToUTF16(const std::string& input) +{ + auto const size = MultiByteToWideChar(CP_UTF8, 0, input.data(), input.size(), nullptr, 0); + + std::wstring output; + output.resize(size); + + if (size != MultiByteToWideChar(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size())) + output.clear(); + + return output; +} + +#endif diff --git a/Source/Core/Common/Src/StringUtil.h b/Source/Core/Common/Src/StringUtil.h index 102ae2d5fb..4e02ce4506 100644 --- a/Source/Core/Common/Src/StringUtil.h +++ b/Source/Core/Common/Src/StringUtil.h @@ -97,4 +97,11 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st std::string UriDecode(const std::string & sSrc); std::string UriEncode(const std::string & sSrc); +#ifdef _WIN32 + +std::string UTF16ToUTF8(const std::wstring& str); +std::wstring UTF8ToUTF16(const std::string& str); + +#endif + #endif // _STRINGUTIL_H_ From ea75577278d818e4d3cb3b6db329017df69df00f Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 18:01:48 -0600 Subject: [PATCH 106/167] Use the new UTF-16 conversion function in two places. --- .../Src/ControllerInterface/DInput/DInput.cpp | 16 +++++----------- Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 6 ++---- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInput.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInput.cpp index c23e9df17e..01baf9cf1a 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInput.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInput.cpp @@ -4,7 +4,7 @@ #include "DInput.h" -#include +#include "StringUtil.h" #ifdef CIFACE_USE_DINPUT_JOYSTICK #include "DInputJoystick.h" @@ -41,24 +41,18 @@ BOOL CALLBACK DIEnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) std::string GetDeviceName(const LPDIRECTINPUTDEVICE8 device) { - std::string out; - - DIPROPSTRING str; - ZeroMemory(&str, sizeof(str)); + DIPROPSTRING str = {}; str.diph.dwSize = sizeof(str); str.diph.dwHeaderSize = sizeof(str.diph); str.diph.dwHow = DIPH_DEVICE; + std::string result; if (SUCCEEDED(device->GetProperty(DIPROP_PRODUCTNAME, &str.diph))) { - const int size = WideCharToMultiByte(CP_UTF8, 0, str.wsz, -1, NULL, 0, NULL, NULL); - char* const data = new char[size]; - if (size == WideCharToMultiByte(CP_UTF8, 0, str.wsz, -1, data, size, NULL, NULL)) - out.assign(data); - delete[] data; + result = StripSpaces(UTF16ToUTF8(str.wsz)); } - return StripSpaces(out); + return result; } void Init(std::vector& devices, HWND hwnd) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index b7dd9101d3..512f70eaa7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -102,15 +102,13 @@ void InitBackendInfo() if (FAILED(hr)) PanicAlert("Failed to create IDXGIFactory object"); - char tmpstr[512] = {}; - DXGI_ADAPTER_DESC desc; // adapters g_Config.backend_info.Adapters.clear(); g_Config.backend_info.AAModes.clear(); while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND) { + DXGI_ADAPTER_DESC desc; ad->GetDesc(&desc); - WideCharToMultiByte(/*CP_UTF8*/CP_ACP, 0, desc.Description, -1, tmpstr, 512, 0, false); // TODO: These don't get updated on adapter change, yet if (g_Config.backend_info.Adapters.size() == g_Config.iAdapter) @@ -127,7 +125,7 @@ void InitBackendInfo() } } - g_Config.backend_info.Adapters.push_back(tmpstr); + g_Config.backend_info.Adapters.push_back(UTF16ToUTF8(desc.Description)); ad->Release(); } From 69f7671ee8184b109d801243707116eb1a5cba56 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 18:51:02 -0600 Subject: [PATCH 107/167] Fix "Common" to build with "Unicode" project setting. --- Source/Core/Common/Common.vcxproj | 4 +- Source/Core/Common/Src/CDUtils.cpp | 11 ++--- Source/Core/Common/Src/ConsoleListener.cpp | 4 +- Source/Core/Common/Src/ExtendedTrace.cpp | 52 +++++++++------------- Source/Core/Common/Src/ExtendedTrace.h | 9 ++-- Source/Core/Common/Src/FileSearch.cpp | 5 +-- Source/Core/Common/Src/FileUtil.cpp | 19 ++++---- Source/Core/Common/Src/Misc.cpp | 2 +- Source/Core/Common/Src/MsgHandler.cpp | 2 +- Source/Core/Common/Src/StringUtil.h | 14 ++++++ 10 files changed, 63 insertions(+), 59 deletions(-) diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 626a4df909..822fafe74b 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -44,7 +44,7 @@ false StaticLibrary - MultiByte + Unicode StaticLibrary @@ -54,7 +54,7 @@ false StaticLibrary - MultiByte + Unicode StaticLibrary diff --git a/Source/Core/Common/Src/CDUtils.cpp b/Source/Core/Common/Src/CDUtils.cpp index 42aa9bfe34..9a302b9189 100644 --- a/Source/Core/Common/Src/CDUtils.cpp +++ b/Source/Core/Common/Src/CDUtils.cpp @@ -6,6 +6,7 @@ #include // for std::unique_ptr #ifdef _WIN32 #include +#include "StringUtil.h" #elif __APPLE__ #include #include @@ -25,7 +26,7 @@ #ifdef _WIN32 // takes a root drive path, returns true if it is a cdrom drive -bool is_cdrom(const char drive[]) +bool is_cdrom(const TCHAR* drive) { return (DRIVE_CDROM == GetDriveType(drive)); } @@ -36,15 +37,15 @@ std::vector cdio_get_devices() std::vector drives; const DWORD buffsize = GetLogicalDriveStrings(0, NULL); - std::unique_ptr buff(new char[buffsize]); - if (GetLogicalDriveStrings(buffsize, buff.get()) == buffsize - 1) + std::vector buff(buffsize); + if (GetLogicalDriveStrings(buffsize, buff.data()) == buffsize - 1) { - const char* drive = buff.get(); + auto drive = buff.data(); while (*drive) { if (is_cdrom(drive)) { - std::string str(drive); + std::string str(TStrToUTF8(drive)); str.pop_back(); // we don't want the final backslash drives.push_back(std::move(str)); } diff --git a/Source/Core/Common/Src/ConsoleListener.cpp b/Source/Core/Common/Src/ConsoleListener.cpp index cf03581431..5a4ff126bf 100644 --- a/Source/Core/Common/Src/ConsoleListener.cpp +++ b/Source/Core/Common/Src/ConsoleListener.cpp @@ -61,7 +61,7 @@ void ConsoleListener::Open(bool Hidden, int Width, int Height, const char *Title // Save the window handle that AllocConsole() created hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // Set the console window title - SetConsoleTitle(Title); + SetConsoleTitle(UTF8ToTStr(Title).c_str()); // Set letter space LetterSpace(80, 4000); //MoveWindow(GetConsoleWindow(), 200,200, 800,800, true); @@ -195,7 +195,7 @@ void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool static const int MAX_BYTES = 1024 * 16; - std::vector> Str; + std::vector> Str; std::vector> Attr; // ReadConsoleOutputAttribute seems to have a limit at this level diff --git a/Source/Core/Common/Src/ExtendedTrace.cpp b/Source/Core/Common/Src/ExtendedTrace.cpp index 3fe661f2e4..85057639a5 100644 --- a/Source/Core/Common/Src/ExtendedTrace.cpp +++ b/Source/Core/Common/Src/ExtendedTrace.cpp @@ -17,6 +17,7 @@ #include #include #include "ExtendedTrace.h" +#include "StringUtil.h" using namespace std; #include @@ -274,13 +275,21 @@ static BOOL GetSourceInfoFromAddress( UINT address, LPTSTR lpszSourceInfo ) return ret; } -void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file ) +void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack) +{ + TCHAR symInfo[BUFFERSIZE] = _T("?"); + TCHAR srcInfo[BUFFERSIZE] = _T("?"); + + GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo); + GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo); + etfprint(file, " " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n"); +} + +void StackTrace( HANDLE hThread, const char* lpszMessage, FILE *file ) { STACKFRAME callStack; BOOL bResult; CONTEXT context; - TCHAR symInfo[BUFFERSIZE] = _T("?"); - TCHAR srcInfo[BUFFERSIZE] = _T("?"); HANDLE hProcess = GetCurrentProcess(); // If it's not this thread, let's suspend it, and resume it at the end @@ -318,9 +327,7 @@ void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file ) etfprint(file, "Call stack info: \n"); etfprint(file, lpszMessage); - GetFunctionInfoFromAddresses( (ULONG)callStack.AddrPC.Offset, (ULONG)callStack.AddrFrame.Offset, symInfo ); - GetSourceInfoFromAddress( (ULONG)callStack.AddrPC.Offset, srcInfo ); - etfprint(file, string(" ") + srcInfo + string(" : ") + symInfo + string("\n")); + PrintFunctionAndSourceInfo(file, callStack); for( ULONG index = 0; ; index++ ) { @@ -341,9 +348,7 @@ void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file ) if( !bResult || callStack.AddrFrame.Offset == 0 ) break; - GetFunctionInfoFromAddresses( (ULONG)callStack.AddrPC.Offset, (ULONG)callStack.AddrFrame.Offset, symInfo ); - GetSourceInfoFromAddress( (UINT)callStack.AddrPC.Offset, srcInfo ); - etfprint(file, string(" ") + srcInfo + string(" : ") + symInfo + string("\n")); + PrintFunctionAndSourceInfo(file, callStack); } @@ -351,19 +356,7 @@ void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file ) ResumeThread( hThread ); } -void StackTrace( HANDLE hThread, wchar_t const*lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) -{ - // TODO: remove when Common builds as unicode - size_t origsize = wcslen(lpszMessage) + 1; - const size_t newsize = 100; - size_t convertedChars = 0; - char nstring[newsize]; - wcstombs_s(&convertedChars, nstring, origsize, lpszMessage, _TRUNCATE); - - StackTrace(hThread, nstring, file, eip, esp, ebp ); -} - -void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) +void StackTrace(HANDLE hThread, const char* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp ) { STACKFRAME callStack; BOOL bResult; @@ -391,9 +384,7 @@ void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file, DWORD eip, DWO etfprint(file, "Call stack info: \n"); etfprint(file, lpszMessage); - GetFunctionInfoFromAddresses( (ULONG)callStack.AddrPC.Offset, (ULONG)callStack.AddrFrame.Offset, symInfo ); - GetSourceInfoFromAddress( (UINT)callStack.AddrPC.Offset, srcInfo ); - etfprint(file, string(" ") + srcInfo + string(" : ") + symInfo + string("\n")); + PrintFunctionAndSourceInfo(file, callStack); for( ULONG index = 0; ; index++ ) { @@ -414,10 +405,7 @@ void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file, DWORD eip, DWO if( !bResult || callStack.AddrFrame.Offset == 0 ) break; - GetFunctionInfoFromAddresses( (ULONG)callStack.AddrPC.Offset, (ULONG)callStack.AddrFrame.Offset, symInfo ); - GetSourceInfoFromAddress( (UINT)callStack.AddrPC.Offset, srcInfo ); - etfprint(file, string(" ") + srcInfo + string(" : ") + symInfo + string("\n")); - + PrintFunctionAndSourceInfo(file, callStack); } if ( hThread != GetCurrentThread() ) @@ -426,7 +414,8 @@ void StackTrace( HANDLE hThread, LPCTSTR lpszMessage, FILE *file, DWORD eip, DWO char g_uefbuf[2048]; -void etfprintf(FILE *file, const char *format, ...) { +void etfprintf(FILE *file, const char *format, ...) +{ va_list ap; va_start(ap, format); int len = vsprintf(g_uefbuf, format, ap); @@ -434,7 +423,8 @@ void etfprintf(FILE *file, const char *format, ...) { va_end(ap); } -void etfprint(FILE *file, const std::string &text) { +void etfprint(FILE *file, const std::string &text) +{ size_t len = text.length(); fwrite(text.data(), 1, len, file); } diff --git a/Source/Core/Common/Src/ExtendedTrace.h b/Source/Core/Common/Src/ExtendedTrace.h index 12e7ed41fa..003c8a68e3 100644 --- a/Source/Core/Common/Src/ExtendedTrace.h +++ b/Source/Core/Common/Src/ExtendedTrace.h @@ -26,15 +26,14 @@ #define EXTENDEDTRACEINITIALIZE( IniSymbolPath ) InitSymInfo( IniSymbolPath ) #define EXTENDEDTRACEUNINITIALIZE() UninitSymInfo() -#define STACKTRACE(file) StackTrace( GetCurrentThread(), _T(""), file) -#define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), _T(""), file, eip, esp, ebp) +#define STACKTRACE(file) StackTrace( GetCurrentThread(), "", file) +#define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), "", file, eip, esp, ebp) // class File; BOOL InitSymInfo( PCSTR ); BOOL UninitSymInfo(); -void StackTrace( HANDLE, LPCTSTR, FILE *file); -void StackTrace( HANDLE, LPCTSTR, FILE *file, DWORD eip, DWORD esp, DWORD ebp); -void StackTrace( HANDLE hThread, wchar_t const* lpszMessage, FILE *file, DWORD eip, DWORD esp, DWORD ebp); +void StackTrace(HANDLE, char const* msg, FILE *file); +void StackTrace(HANDLE, char const* msg, FILE *file, DWORD eip, DWORD esp, DWORD ebp); // functions by Masken void etfprintf(FILE *file, const char *format, ...); diff --git a/Source/Core/Common/Src/FileSearch.cpp b/Source/Core/Common/Src/FileSearch.cpp index 595dfe7000..674cf0e1d5 100644 --- a/Source/Core/Common/Src/FileSearch.cpp +++ b/Source/Core/Common/Src/FileSearch.cpp @@ -51,7 +51,7 @@ void CFileSearch::FindFiles(const std::string& _searchString, const std::string& BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); #ifdef _WIN32 WIN32_FIND_DATA findData; - HANDLE FindFirst = FindFirstFile(GCMSearchPath.c_str(), &findData); + HANDLE FindFirst = FindFirstFile(UTF8ToTStr(GCMSearchPath).c_str(), &findData); if (FindFirst != INVALID_HANDLE_VALUE) { @@ -62,7 +62,7 @@ void CFileSearch::FindFiles(const std::string& _searchString, const std::string& if (findData.cFileName[0] != '.') { std::string strFilename; - BuildCompleteFilename(strFilename, _strPath, findData.cFileName); + BuildCompleteFilename(strFilename, _strPath, TStrToUTF8(findData.cFileName)); m_FileNames.push_back(strFilename); } @@ -112,7 +112,6 @@ void CFileSearch::FindFiles(const std::string& _searchString, const std::string& #endif } - const CFileSearch::XStringVector& CFileSearch::GetFileNames() const { return m_FileNames; diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp index f42c204396..b3c2d7c161 100644 --- a/Source/Core/Common/Src/FileUtil.cpp +++ b/Source/Core/Common/Src/FileUtil.cpp @@ -41,10 +41,11 @@ #include #endif -#include #include #include +#include "StringUtil.h" + #ifndef S_ISDIR #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) #endif @@ -127,7 +128,7 @@ bool Delete(const std::string &filename) } #ifdef _WIN32 - if (!DeleteFile(filename.c_str())) + if (!DeleteFile(UTF8ToTStr(filename).c_str())) { WARN_LOG(COMMON, "Delete: DeleteFile failed on %s: %s", filename.c_str(), GetLastErrorMsg()); @@ -149,7 +150,7 @@ bool CreateDir(const std::string &path) { INFO_LOG(COMMON, "CreateDir: directory %s", path.c_str()); #ifdef _WIN32 - if (::CreateDirectory(path.c_str(), NULL)) + if (::CreateDirectory(UTF8ToTStr(path).c_str(), NULL)) return true; DWORD error = GetLastError(); if (error == ERROR_ALREADY_EXISTS) @@ -228,7 +229,7 @@ bool DeleteDir(const std::string &filename) } #ifdef _WIN32 - if (::RemoveDirectory(filename.c_str())) + if (::RemoveDirectory(UTF8ToTStr(filename).c_str())) return true; #else if (rmdir(filename.c_str()) == 0) @@ -257,7 +258,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename) INFO_LOG(COMMON, "Copy: %s --> %s", srcFilename.c_str(), destFilename.c_str()); #ifdef _WIN32 - if (CopyFile(srcFilename.c_str(), destFilename.c_str(), FALSE)) + if (CopyFile(UTF8ToTStr(srcFilename).c_str(), UTF8ToTStr(destFilename).c_str(), FALSE)) return true; ERROR_LOG(COMMON, "Copy: failed %s --> %s: %s", @@ -413,7 +414,7 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) // Find the first file in the directory. WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile((directory + "\\*").c_str(), &ffd); + HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { FindClose(hFind); @@ -423,7 +424,7 @@ u32 ScanDirectoryTree(const std::string &directory, FSTEntry& parentEntry) do { FSTEntry entry; - const std::string virtualName(ffd.cFileName); + const std::string virtualName(TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = NULL; @@ -480,7 +481,7 @@ bool DeleteDirRecursively(const std::string &directory) #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFile((directory + "\\*").c_str(), &ffd); + HANDLE hFind = FindFirstFile(UTF8ToTStr(directory + "\\*").c_str(), &ffd); if (hFind == INVALID_HANDLE_VALUE) { @@ -491,7 +492,7 @@ bool DeleteDirRecursively(const std::string &directory) // windows loop do { - const std::string virtualName = ffd.cFileName; + const std::string virtualName(TStrToUTF8(ffd.cFileName)); #else struct dirent dirent, *result = NULL; DIR *dirp = opendir(directory.c_str()); diff --git a/Source/Core/Common/Src/Misc.cpp b/Source/Core/Common/Src/Misc.cpp index aafe37886f..8364bda48d 100644 --- a/Source/Core/Common/Src/Misc.cpp +++ b/Source/Core/Common/Src/Misc.cpp @@ -31,7 +31,7 @@ const char* GetLastErrorMsg() #ifdef _WIN32 static __declspec(thread) char err_str[buff_size] = {}; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_str, buff_size, NULL); #else diff --git a/Source/Core/Common/Src/MsgHandler.cpp b/Source/Core/Common/Src/MsgHandler.cpp index 7c666227aa..283dc72ef1 100644 --- a/Source/Core/Common/Src/MsgHandler.cpp +++ b/Source/Core/Common/Src/MsgHandler.cpp @@ -106,7 +106,7 @@ bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int S if (Style == QUESTION) STYLE = MB_ICONQUESTION; if (Style == WARNING) STYLE = MB_ICONWARNING; - return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK)); + return IDYES == MessageBox(0, UTF8ToTStr(text).c_str(), UTF8ToTStr(caption).c_str(), STYLE | (yes_no ? MB_YESNO : MB_OK)); #else printf("%s\n", text); diff --git a/Source/Core/Common/Src/StringUtil.h b/Source/Core/Common/Src/StringUtil.h index 4e02ce4506..5177bc8ed8 100644 --- a/Source/Core/Common/Src/StringUtil.h +++ b/Source/Core/Common/Src/StringUtil.h @@ -102,6 +102,20 @@ std::string UriEncode(const std::string & sSrc); std::string UTF16ToUTF8(const std::wstring& str); std::wstring UTF8ToUTF16(const std::string& str); +#ifdef _UNICODE +inline std::string TStrToUTF8(const std::wstring& str) +{ return UTF16ToUTF8(str); } + +inline std::wstring UTF8ToTStr(const std::string& str) +{ return UTF8ToUTF16(str); } +#else +inline std::string TStrToUTF8(const std::string& str) +{ return str; } + +inline std::string UTF8ToTStr(const std::string& str) +{ return str; } +#endif + #endif #endif // _STRINGUTIL_H_ From 65683ebc6494623a7bf0e297522b6912319e3e8c Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 19:43:29 -0600 Subject: [PATCH 108/167] Hopefully fix all filename handling to support Unicode. --- Source/Core/Common/Src/FileUtil.cpp | 48 ++++++++++----------------- Source/Core/Common/Src/SDCardUtil.cpp | 7 ++-- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp index b3c2d7c161..78685bbe70 100644 --- a/Source/Core/Common/Src/FileUtil.cpp +++ b/Source/Core/Common/Src/FileUtil.cpp @@ -82,7 +82,7 @@ bool Exists(const std::string &filename) std::string copy(filename); StripTailDirSlashes(copy); - int result = stat64(copy.c_str(), &file_info); + int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); return (result == 0); } @@ -95,7 +95,7 @@ bool IsDirectory(const std::string &filename) std::string copy(filename); StripTailDirSlashes(copy); - int result = stat64(copy.c_str(), &file_info); + int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); if (result < 0) { WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", @@ -344,7 +344,7 @@ u64 GetSize(const std::string &filename) return 0; } struct stat64 buf; - if (stat64(filename.c_str(), &buf) == 0) + if (_tstat64(UTF8ToTStr(filename).c_str(), &buf) == 0) { DEBUG_LOG(COMMON, "GetSize: %s: %lld", filename.c_str(), (long long)buf.st_size); @@ -392,13 +392,13 @@ bool CreateEmptyFile(const std::string &filename) { INFO_LOG(COMMON, "CreateEmptyFile: %s", filename.c_str()); - FILE *pFile = fopen(filename.c_str(), "wb"); - if (!pFile) { + if (!File::IOFile(filename, "wb")) + { ERROR_LOG(COMMON, "CreateEmptyFile: failed %s: %s", filename.c_str(), GetLastErrorMsg()); return false; } - fclose(pFile); + return true; } @@ -623,14 +623,14 @@ std::string GetBundleDirectory() #endif #ifdef _WIN32 -std::string &GetExeDirectory() +std::string& GetExeDirectory() { static std::string DolphinPath; if (DolphinPath.empty()) { - char Dolphin_exe_Path[2048]; - GetModuleFileNameA(NULL, Dolphin_exe_Path, 2048); - DolphinPath = Dolphin_exe_Path; + TCHAR Dolphin_exe_Path[2048]; + GetModuleFileName(NULL, Dolphin_exe_Path, 2048); + DolphinPath = TStrToUTF8(Dolphin_exe_Path); DolphinPath = DolphinPath.substr(0, DolphinPath.find_last_of('\\')); } return DolphinPath; @@ -731,31 +731,19 @@ std::string &GetUserPath(const unsigned int DirIDX, const std::string &newPath) bool WriteStringToFile(bool text_file, const std::string &str, const char *filename) { - FILE *f = fopen(filename, text_file ? "w" : "wb"); - if (!f) - return false; - size_t len = str.size(); - if (len != fwrite(str.data(), 1, str.size(), f)) // TODO: string::data() may not be contiguous - { - fclose(f); - return false; - } - fclose(f); - return true; + return File::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); } bool ReadFileToString(bool text_file, const char *filename, std::string &str) { - FILE *f = fopen(filename, text_file ? "r" : "rb"); + File::IOFile file(filename, text_file ? "r" : "rb"); + auto const f = file.GetHandle(); + if (!f) return false; - size_t len = (size_t)GetSize(f); - char *buf = new char[len + 1]; - buf[fread(buf, 1, len, f)] = 0; - str = std::string(buf, len); - fclose(f); - delete [] buf; - return true; + + str.resize(GetSize(f)); + return file.ReadArray(&str[0], str.size()); } IOFile::IOFile() @@ -799,7 +787,7 @@ bool IOFile::Open(const std::string& filename, const char openmode[]) { Close(); #ifdef _WIN32 - fopen_s(&m_file, filename.c_str(), openmode); + _tfopen_s(&m_file, UTF8ToTStr(filename).c_str(), UTF8ToTStr(openmode).c_str()); #else m_file = fopen(filename.c_str(), openmode); #endif diff --git a/Source/Core/Common/Src/SDCardUtil.cpp b/Source/Core/Common/Src/SDCardUtil.cpp index 0f2ad08607..cf37ffff3e 100644 --- a/Source/Core/Common/Src/SDCardUtil.cpp +++ b/Source/Core/Common/Src/SDCardUtil.cpp @@ -29,6 +29,7 @@ // Modified for Dolphin. #include "SDCardUtil.h" +#include "FileUtil.h" #include #include @@ -190,7 +191,6 @@ bool SDCardCreate(u64 disk_size /*in MB*/, const char* filename) { u32 sectors_per_fat; u32 sectors_per_disk; - FILE* f; // Convert MB to bytes disk_size *= 1024 * 1024; @@ -207,7 +207,8 @@ bool SDCardCreate(u64 disk_size /*in MB*/, const char* filename) boot_sector_init(s_boot_sector, s_fsinfo_sector, disk_size, nullptr); fat_init(s_fat_head); - f = fopen(filename, "wb"); + File::IOFile file(filename, "wb"); + FILE* const f = file.GetHandle(); if (!f) { ERROR_LOG(COMMON, "Could not create file '%s', aborting...\n", filename); @@ -247,13 +248,11 @@ bool SDCardCreate(u64 disk_size /*in MB*/, const char* filename) if (write_empty(f, sectors_per_disk - RESERVED_SECTORS - 2*sectors_per_fat)) goto FailWrite; - fclose(f); return true; FailWrite: ERROR_LOG(COMMON, "Could not write to '%s', aborting...\n", filename); if (unlink(filename) < 0) ERROR_LOG(COMMON, "unlink(%s) failed\n%s", filename, GetLastErrorMsg()); - fclose(f); return false; } From 536c110b31339eab5437c5f023494a9ec5c9364b Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 20:04:07 -0600 Subject: [PATCH 109/167] Fix "DiscIO" to build with "Unicode". --- Source/Core/DiscIO/DiscIO.vcxproj | 4 ++-- Source/Core/DiscIO/Src/DriveBlob.cpp | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj index 6dd24ddd44..722aae2040 100644 --- a/Source/Core/DiscIO/DiscIO.vcxproj +++ b/Source/Core/DiscIO/DiscIO.vcxproj @@ -44,7 +44,7 @@ false StaticLibrary - MultiByte + Unicode StaticLibrary @@ -54,7 +54,7 @@ false StaticLibrary - MultiByte + Unicode StaticLibrary diff --git a/Source/Core/DiscIO/Src/DriveBlob.cpp b/Source/Core/DiscIO/Src/DriveBlob.cpp index e69f8ff34c..2638f3fac4 100644 --- a/Source/Core/DiscIO/Src/DriveBlob.cpp +++ b/Source/Core/DiscIO/Src/DriveBlob.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "DriveBlob.h" +#include "StringUtil.h" namespace DiscIO { @@ -23,12 +24,9 @@ namespace DiscIO DriveReader::DriveReader(const char *drive) { #ifdef _WIN32 - char path[MAX_PATH]; - strncpy(path, drive, 3); - path[2] = 0; - sprintf(path, "\\\\.\\%s", drive); SectorReader::SetSectorSize(2048); - hDisc = CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + auto const path = UTF8ToTStr(std::string("\\\\.\\") + drive); + hDisc = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); if (hDisc != INVALID_HANDLE_VALUE) { From 6f87611767ea9072a2680154b26dd8d3f2dd0222 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 20:27:22 -0600 Subject: [PATCH 110/167] Fix "Core" to build with "Unicode". --- Source/Core/Core/Core.vcxproj | 6 +-- Source/Core/Core/Src/ConfigManager.cpp | 6 +-- Source/Core/Core/Src/Console.cpp | 4 +- Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp | 46 +++++++++---------- Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.h | 14 +++--- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 6 +-- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 2 +- .../Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 5 +- 8 files changed, 41 insertions(+), 48 deletions(-) diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 1dd547b2ea..17495de740 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -44,7 +44,7 @@ false StaticLibrary - MultiByte + Unicode StaticLibrary @@ -54,7 +54,7 @@ false StaticLibrary - MultiByte + Unicode StaticLibrary @@ -602,4 +602,4 @@ - + \ No newline at end of file diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 85ecc7143f..8c7872119e 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -137,7 +137,7 @@ void SConfig::SaveSettings() ini.Get("General", "GCMPathes", &oldPaths, 0); for (int i = numPaths; i < oldPaths; i++) { - TCHAR tmp[16]; + char tmp[16]; sprintf(tmp, "GCMPath%i", i); ini.DeleteKey("General", tmp); } @@ -146,7 +146,7 @@ void SConfig::SaveSettings() for (int i = 0; i < numPaths; i++) { - TCHAR tmp[16]; + char tmp[16]; sprintf(tmp, "GCMPath%i", i); ini.Set("General", tmp, m_ISOFolder[i]); } @@ -284,7 +284,7 @@ void SConfig::LoadSettings() { for (int i = 0; i < numGCMPaths; i++) { - TCHAR tmp[16]; + char tmp[16]; sprintf(tmp, "GCMPath%i", i); std::string tmpPath; ini.Get("General", tmp, &tmpPath, ""); diff --git a/Source/Core/Core/Src/Console.cpp b/Source/Core/Core/Src/Console.cpp index 759dc46bc5..b0ef416a84 100644 --- a/Source/Core/Core/Src/Console.cpp +++ b/Source/Core/Core/Src/Console.cpp @@ -98,8 +98,8 @@ void Console_Submit(const char *cmd) } CASE("dump") { - TCHAR temp[256]; - TCHAR filename[256]; + char temp[256]; + char filename[256]; u32 start; u32 end; sscanf(cmd, "%s %08x %08x %s", temp, &start, &end, filename); diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp index 87ebd90344..03332d3012 100644 --- a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.cpp @@ -25,7 +25,7 @@ namespace Win32TAPHelper { -bool IsTAPDevice(const char *guid) +bool IsTAPDevice(const TCHAR *guid) { HKEY netcard_key; LONG status; @@ -39,13 +39,13 @@ bool IsTAPDevice(const char *guid) for (;;) { - char enum_name[256]; - char unit_string[256]; + TCHAR enum_name[256]; + TCHAR unit_string[256]; HKEY unit_key; - char component_id_string[] = "ComponentId"; - char component_id[256]; - char net_cfg_instance_id_string[] = "NetCfgInstanceId"; - char net_cfg_instance_id[256]; + TCHAR component_id_string[] = _T("ComponentId"); + TCHAR component_id[256]; + TCHAR net_cfg_instance_id_string[] = _T("NetCfgInstanceId"); + TCHAR net_cfg_instance_id[256]; DWORD data_type; len = sizeof(enum_name); @@ -56,7 +56,7 @@ bool IsTAPDevice(const char *guid) else if (status != ERROR_SUCCESS) return false; - snprintf(unit_string, sizeof(unit_string), "%s\\%s", ADAPTER_KEY, enum_name); + _sntprintf(unit_string, sizeof(unit_string), _T("%s\\%s"), ADAPTER_KEY, enum_name); status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key); @@ -78,8 +78,8 @@ bool IsTAPDevice(const char *guid) if (status == ERROR_SUCCESS && data_type == REG_SZ) { - if (!strcmp(component_id, TAP_COMPONENT_ID) && - !strcmp(net_cfg_instance_id, guid)) + if (!_tcscmp(component_id, TAP_COMPONENT_ID) && + !_tcscmp(net_cfg_instance_id, guid)) { RegCloseKey(unit_key); RegCloseKey(netcard_key); @@ -96,7 +96,7 @@ bool IsTAPDevice(const char *guid) return false; } -bool GetGUIDs(std::vector& guids) +bool GetGUIDs(std::vector>& guids) { LONG status; HKEY control_net_key; @@ -111,12 +111,12 @@ bool GetGUIDs(std::vector& guids) while (!found_all) { - char enum_name[256]; - char connection_string[256]; + TCHAR enum_name[256]; + TCHAR connection_string[256]; HKEY connection_key; - char name_data[256]; + TCHAR name_data[256]; DWORD name_type; - const char name_string[] = "Name"; + const TCHAR name_string[] = _T("Name"); len = sizeof(enum_name); status = RegEnumKeyEx(control_net_key, i, enum_name, @@ -127,8 +127,8 @@ bool GetGUIDs(std::vector& guids) else if (status != ERROR_SUCCESS) return false; - snprintf(connection_string, sizeof(connection_string), - "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, enum_name); + _sntprintf(connection_string, sizeof(connection_string), + _T("%s\\%s\\Connection"), NETWORK_CONNECTIONS_KEY, enum_name); status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key); @@ -165,15 +165,11 @@ bool GetGUIDs(std::vector& guids) return true; } -bool OpenTAP(HANDLE& adapter, const std::string device_guid) +bool OpenTAP(HANDLE& adapter, const std::basic_string& device_guid) { - char device_path[256]; + auto const device_path = USERMODEDEVICEDIR + device_guid + TAPSUFFIX; - /* Open Windows TAP-Win32 adapter */ - snprintf(device_path, sizeof(device_path), "%s%s%s", - USERMODEDEVICEDIR, device_guid.c_str(), TAPSUFFIX); - - adapter = CreateFile(device_path, GENERIC_READ | GENERIC_WRITE, 0, 0, + adapter = CreateFile(device_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); if (adapter == INVALID_HANDLE_VALUE) @@ -192,7 +188,7 @@ bool CEXIETHERNET::Activate() return true; DWORD len; - std::vector device_guids; + std::vector> device_guids; if (!Win32TAPHelper::GetGUIDs(device_guids)) { diff --git a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.h b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.h index 2676a3fc7e..2a5bc52ffa 100644 --- a/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.h +++ b/Source/Core/Core/Src/HW/BBA-TAP/TAP_Win32.h @@ -65,18 +65,18 @@ // Registry keys //================= -#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define ADAPTER_KEY _T("SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}") -#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define NETWORK_CONNECTIONS_KEY _T("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}") //====================== // Filesystem prefixes //====================== -#define USERMODEDEVICEDIR "\\\\.\\Global\\" -#define SYSDEVICEDIR "\\Device\\" -#define USERDEVICEDIR "\\DosDevices\\Global\\" -#define TAPSUFFIX ".tap" +#define USERMODEDEVICEDIR _T("\\\\.\\Global\\") +#define SYSDEVICEDIR _T("\\Device\\") +#define USERDEVICEDIR _T("\\DosDevices\\Global\\") +#define TAPSUFFIX _T(".tap") //========================================================= // TAP_COMPONENT_ID -- This string defines the TAP driver @@ -84,4 +84,4 @@ // simultaneously. //========================================================= -#define TAP_COMPONENT_ID "tap0901" +#define TAP_COMPONENT_ID _T("tap0901") diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 2ae34a7ca5..2407d697a4 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -464,9 +463,6 @@ int Wiimote::IOWrite(const u8* buf, int len) template void ProcessWiimotes(bool new_scan, T& callback) { - // match strings like "Nintendo RVL-WBC-01", "Nintendo RVL-CNT-01", "Nintendo RVL-CNT-01-TR" - const std::wregex wiimote_device_name(L"Nintendo RVL-.*"); - BLUETOOTH_DEVICE_SEARCH_PARAMS srch; srch.dwSize = sizeof(srch); srch.fReturnAuthenticated = true; @@ -509,7 +505,7 @@ void ProcessWiimotes(bool new_scan, T& callback) DEBUG_LOG(WIIMOTE, "authed %i connected %i remembered %i ", btdi.fAuthenticated, btdi.fConnected, btdi.fRemembered); - if (std::regex_match(btdi.szName, wiimote_device_name)) + if (IsValidBluetoothName(UTF16ToUTF8(btdi.szName))) { callback(hRadio, radioInfo, btdi); } diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 793a13ceb0..cfc66106b4 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -91,7 +91,7 @@ public: int int_sock; // Interrupt socket #elif defined(_WIN32) - std::string devicepath; // Unique wiimote reference + std::basic_string devicepath; // Unique wiimote reference //ULONGLONG btaddr; // Bluetooth address HANDLE dev_handle; // HID handle OVERLAPPED hid_overlap_read, hid_overlap_write; // Overlap handle diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp index 3eb0096929..363176e18a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -58,6 +58,7 @@ #include "CommonPaths.h" #include "IPC_HLE/WII_IPC_HLE_Device_usb.h" #include "../Movie.h" +#include "StringUtil.h" #ifdef _WIN32 #include @@ -926,7 +927,7 @@ u32 CWII_IPC_HLE_Device_es::ES_DIVerify(u8* _pTMD, u32 _sz) else { #ifdef _WIN32 - MoveFile(savePath.c_str(), (savePath + "../backup/").c_str()); + MoveFile(UTF8ToTStr(savePath).c_str(), UTF8ToTStr(savePath + "../backup/").c_str()); #else File::CopyDir(savePath.c_str(),(savePath + "../backup/").c_str()); File::DeleteDirRecursively(savePath.c_str()); @@ -940,7 +941,7 @@ u32 CWII_IPC_HLE_Device_es::ES_DIVerify(u8* _pTMD, u32 _sz) if (File::Exists((savePath + "banner.bin").c_str())) File::DeleteDirRecursively(savePath); #ifdef _WIN32 - MoveFile((savePath + "../backup/").c_str(), savePath.c_str()); + MoveFile(UTF8ToTStr(savePath + "../backup/").c_str(), UTF8ToTStr(savePath).c_str()); #else File::CopyDir((savePath + "../backup/").c_str(), savePath.c_str()); File::DeleteDirRecursively((savePath + "../backup/").c_str()); From e82d976d2f2e2f026ecdcdbe978ce7eaeb0da804 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 20:55:19 -0600 Subject: [PATCH 111/167] Buildfix for non-legacy OSes. --- Source/Core/Common/Src/FileUtil.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Source/Core/Common/Src/FileUtil.cpp b/Source/Core/Common/Src/FileUtil.cpp index 78685bbe70..7b9ab2e464 100644 --- a/Source/Core/Common/Src/FileUtil.cpp +++ b/Source/Core/Common/Src/FileUtil.cpp @@ -82,7 +82,11 @@ bool Exists(const std::string &filename) std::string copy(filename); StripTailDirSlashes(copy); +#ifdef _WIN32 int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); +#else + int result = stat64(copy.c_str(), &file_info); +#endif return (result == 0); } @@ -95,7 +99,11 @@ bool IsDirectory(const std::string &filename) std::string copy(filename); StripTailDirSlashes(copy); +#ifdef _WIN32 int result = _tstat64(UTF8ToTStr(copy).c_str(), &file_info); +#else + int result = stat64(copy.c_str(), &file_info); +#endif if (result < 0) { WARN_LOG(COMMON, "IsDirectory: stat failed on %s: %s", @@ -343,8 +351,13 @@ u64 GetSize(const std::string &filename) WARN_LOG(COMMON, "GetSize: failed %s: is a directory", filename.c_str()); return 0; } + struct stat64 buf; +#ifdef _WIN32 if (_tstat64(UTF8ToTStr(filename).c_str(), &buf) == 0) +#else + if (stat64(filename.c_str(), &buf) == 0) +#endif { DEBUG_LOG(COMMON, "GetSize: %s: %lld", filename.c_str(), (long long)buf.st_size); From 56f09d3b91479deb0f3ae3c7ce623c7a4724e087 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 27 Feb 2013 22:37:38 -0600 Subject: [PATCH 112/167] Attempt to be consistent with conversions between std::string and wxString. --- Source/Core/DolphinWX/Src/ARCodeAddEdit.cpp | 11 +-- Source/Core/DolphinWX/Src/AboutDolphin.cpp | 3 +- Source/Core/DolphinWX/Src/CheatsWindow.cpp | 13 ++-- Source/Core/DolphinWX/Src/ConfigMain.cpp | 42 +++++------ .../DolphinWX/Src/Debugger/BreakpointDlg.cpp | 5 +- .../DolphinWX/Src/Debugger/BreakpointView.cpp | 19 ++--- .../Core/DolphinWX/Src/Debugger/CodeView.cpp | 39 +++++----- .../DolphinWX/Src/Debugger/CodeWindow.cpp | 21 +++--- .../Src/Debugger/CodeWindowFunctions.cpp | 20 ++--- .../DolphinWX/Src/Debugger/DSPDebugWindow.cpp | 6 +- .../Src/Debugger/DSPRegisterView.cpp | 4 +- .../Core/DolphinWX/Src/Debugger/JitWindow.cpp | 1 + .../DolphinWX/Src/Debugger/MemoryCheckDlg.cpp | 5 +- .../DolphinWX/Src/Debugger/MemoryView.cpp | 26 ++++--- .../DolphinWX/Src/Debugger/MemoryWindow.cpp | 17 ++--- .../DolphinWX/Src/Debugger/RegisterView.cpp | 9 ++- Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp | 7 +- Source/Core/DolphinWX/Src/FrameAui.cpp | 11 +-- Source/Core/DolphinWX/Src/FrameTools.cpp | 27 ++++--- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 34 ++++----- Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp | 9 ++- Source/Core/DolphinWX/Src/ISOFile.cpp | 3 +- Source/Core/DolphinWX/Src/ISOProperties.cpp | 36 ++++----- Source/Core/DolphinWX/Src/InputConfigDiag.cpp | 75 +++++++++---------- .../DolphinWX/Src/InputConfigDiagBitmaps.cpp | 11 +-- Source/Core/DolphinWX/Src/LogConfigWindow.cpp | 3 +- Source/Core/DolphinWX/Src/Main.cpp | 24 +++--- Source/Core/DolphinWX/Src/MemcardManager.cpp | 28 +++---- Source/Core/DolphinWX/Src/NetWindow.cpp | 45 +++++------ Source/Core/DolphinWX/Src/PHackSettings.cpp | 13 ++-- Source/Core/DolphinWX/Src/PatchAddEdit.cpp | 9 ++- Source/Core/DolphinWX/Src/UDPConfigDiag.cpp | 8 +- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 18 ++--- Source/Core/DolphinWX/Src/VideoConfigDiag.h | 5 +- Source/Core/DolphinWX/Src/WxUtils.cpp | 16 +++- Source/Core/DolphinWX/Src/WxUtils.h | 9 ++- Source/Core/DolphinWX/Src/X11Utils.cpp | 3 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 3 +- .../Src/VideoConfigDialog.cpp | 6 +- 39 files changed, 344 insertions(+), 300 deletions(-) diff --git a/Source/Core/DolphinWX/Src/ARCodeAddEdit.cpp b/Source/Core/DolphinWX/Src/ARCodeAddEdit.cpp index c3ed12bbea..e08753f40f 100644 --- a/Source/Core/DolphinWX/Src/ARCodeAddEdit.cpp +++ b/Source/Core/DolphinWX/Src/ARCodeAddEdit.cpp @@ -17,6 +17,7 @@ #include "ARCodeAddEdit.h" #include "ARDecrypt.h" +#include "WxUtils.h" extern std::vector arCodes; @@ -38,7 +39,7 @@ CARCodeAddEdit::CARCodeAddEdit(int _selection, wxWindow* parent, wxWindowID id, } else { - currentName = wxString(arCodes.at(selection).name.c_str(), *wxConvCurrent); + currentName = StrToWxStr(arCodes.at(selection).name); tempEntries = arCodes.at(selection); } @@ -73,7 +74,7 @@ CARCodeAddEdit::CARCodeAddEdit(int _selection, wxWindow* parent, wxWindowID id, void CARCodeAddEdit::ChangeEntry(wxSpinEvent& event) { ActionReplay::ARCode currentCode = arCodes.at((int)arCodes.size() - event.GetPosition()); - EditCheatName->SetValue(wxString(currentCode.name.c_str(), *wxConvCurrent)); + EditCheatName->SetValue(StrToWxStr(currentCode.name)); UpdateTextCtrl(currentCode); } @@ -84,7 +85,7 @@ void CARCodeAddEdit::SaveCheatData(wxCommandEvent& WXUNUSED (event)) // Split the entered cheat into lines. std::vector userInputLines; - SplitString(std::string(EditCheatCode->GetValue().mb_str()), '\n', userInputLines); + SplitString(WxStrToStr(EditCheatCode->GetValue()), '\n', userInputLines); for (size_t i = 0; i < userInputLines.size(); i++) { @@ -148,7 +149,7 @@ void CARCodeAddEdit::SaveCheatData(wxCommandEvent& WXUNUSED (event)) // Add a new AR cheat code. ActionReplay::ARCode newCheat; - newCheat.name = std::string(EditCheatName->GetValue().mb_str()); + newCheat.name = WxStrToStr(EditCheatName->GetValue()); newCheat.ops = decryptedLines; newCheat.active = true; @@ -157,7 +158,7 @@ void CARCodeAddEdit::SaveCheatData(wxCommandEvent& WXUNUSED (event)) else { // Update the currently-selected AR cheat code. - arCodes.at(selection).name = std::string(EditCheatName->GetValue().mb_str()); + arCodes.at(selection).name = WxStrToStr(EditCheatName->GetValue()); arCodes.at(selection).ops = decryptedLines; } diff --git a/Source/Core/DolphinWX/Src/AboutDolphin.cpp b/Source/Core/DolphinWX/Src/AboutDolphin.cpp index 5e1825b6ae..eeecf18d48 100644 --- a/Source/Core/DolphinWX/Src/AboutDolphin.cpp +++ b/Source/Core/DolphinWX/Src/AboutDolphin.cpp @@ -17,6 +17,7 @@ #include "Common.h" #include "AboutDolphin.h" +#include "WxUtils.h" #include "../resources/dolphin_logo.cpp" #include "scmrev.h" @@ -62,7 +63,7 @@ AboutDolphin::AboutDolphin(wxWindow *parent, wxWindowID id, "and should not be used to play games you do\n" "not legally own."; wxStaticText* const Message = new wxStaticText(this, wxID_ANY, - wxString::FromAscii(Text.c_str())); + StrToWxStr(Text.c_str())); Message->Wrap(GetSize().GetWidth()); wxBoxSizer* const sInfo = new wxBoxSizer(wxVERTICAL); diff --git a/Source/Core/DolphinWX/Src/CheatsWindow.cpp b/Source/Core/DolphinWX/Src/CheatsWindow.cpp index 63ddced86b..1e0f714467 100644 --- a/Source/Core/DolphinWX/Src/CheatsWindow.cpp +++ b/Source/Core/DolphinWX/Src/CheatsWindow.cpp @@ -24,6 +24,7 @@ #include "ISOProperties.h" #include "HW/Memmap.h" #include "Frame.h" +#include "WxUtils.h" #define MAX_CHEAT_SEARCH_RESULTS_DISPLAY 256 @@ -273,7 +274,7 @@ void wxCheatsWindow::Load_ARCodes() { ARCode code = GetARCode(i); ARCodeIndex ind; - u32 index = m_CheckListBox_CheatsList->Append(wxString(code.name.c_str(), *wxConvCurrent)); + u32 index = m_CheckListBox_CheatsList->Append(StrToWxStr(code.name)); m_CheckListBox_CheatsList->Check(index, code.active); ind.index = i; ind.uiIndex = index; @@ -291,18 +292,18 @@ void wxCheatsWindow::OnEvent_CheatsList_ItemSelected(wxCommandEvent& WXUNUSED (e if ((int)indexList[i].uiIndex == index) { ARCode code = GetARCode(i); - m_Label_Codename->SetLabel(_("Name: ") + wxString(code.name.c_str(), *wxConvCurrent)); + m_Label_Codename->SetLabel(_("Name: ") + StrToWxStr(code.name)); char text[CHAR_MAX]; char* numcodes = text; sprintf(numcodes, "Number of Codes: %lu", (unsigned long)code.ops.size()); - m_Label_NumCodes->SetLabel(wxString::FromAscii(numcodes)); + m_Label_NumCodes->SetLabel(StrToWxStr(numcodes)); m_ListBox_CodesList->Clear(); for (size_t j = 0; j < code.ops.size(); j++) { char text2[CHAR_MAX]; char* ops = text2; sprintf(ops, "%08x %08x", code.ops[j].cmd_addr, code.ops[j].value); - m_ListBox_CodesList->Append(wxString::FromAscii(ops)); + m_ListBox_CodesList->Append(StrToWxStr(ops)); } } } @@ -347,7 +348,7 @@ void wxCheatsWindow::OnEvent_ButtonUpdateLog_Press(wxCommandEvent& WXUNUSED (eve const std::vector &arLog = ActionReplay::GetSelfLog(); for (u32 i = 0; i < arLog.size(); i++) { - m_TextCtrl_Log->AppendText(wxString::FromAscii(arLog[i].c_str())); + m_TextCtrl_Log->AppendText(StrToWxStr(arLog[i].c_str())); } } @@ -619,7 +620,7 @@ void CreateCodeDialog::PressOK(wxCommandEvent& ev) // create the new code ActionReplay::ARCode new_cheat; new_cheat.active = false; - new_cheat.name = std::string(code_name.ToAscii()); + new_cheat.name = WxStrToStr(code_name); const ActionReplay::AREntry new_entry(code_address, code_value); new_cheat.ops.push_back(new_entry); diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index dc044afe09..bdb4cdc7fe 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -33,6 +33,7 @@ #include "IPC_HLE/WII_IPC_HLE.h" #include "NANDContentLoader.h" +#include "WxUtils.h" #include "Globals.h" // Local #include "ConfigMain.h" #include "ConfigManager.h" @@ -100,7 +101,6 @@ static const wxLanguage langIds[] = #define EXIDEV_AM_BB_STR _trans("AM-Baseboard") #define EXIDEV_GECKO_STR "USBGecko" -#define CSTR_TRANS(a) wxString(wxGetTranslation(wxT(a))).mb_str() #define WXSTR_TRANS(a) wxString(wxGetTranslation(wxT(a))) #ifdef WIN32 //only used with xgettext to be picked up as translatable string. @@ -188,7 +188,7 @@ CConfigMain::CConfigMain(wxWindow* parent, wxWindowID id, const wxString& title, // Update selected ISO paths for(u32 i = 0; i < SConfig::GetInstance().m_ISOFolder.size(); i++) { - ISOPaths->Append(wxString(SConfig::GetInstance().m_ISOFolder[i].c_str(), *wxConvCurrent)); + ISOPaths->Append(StrToWxStr(SConfig::GetInstance().m_ISOFolder[i])); } } @@ -477,10 +477,10 @@ void CConfigMain::InitializeGUIValues() // Paths RecursiveISOPath->SetValue(SConfig::GetInstance().m_RecursiveISOFolder); - DefaultISO->SetPath(wxString(startup_params.m_strDefaultGCM.c_str(), *wxConvCurrent)); - DVDRoot->SetPath(wxString(startup_params.m_strDVDRoot.c_str(), *wxConvCurrent)); - ApploaderPath->SetPath(wxString(startup_params.m_strApploader.c_str(), *wxConvCurrent)); - NANDRoot->SetPath(wxString(SConfig::GetInstance().m_NANDPath.c_str(), *wxConvCurrent)); + DefaultISO->SetPath(StrToWxStr(startup_params.m_strDefaultGCM)); + DVDRoot->SetPath(StrToWxStr(startup_params.m_strDVDRoot)); + ApploaderPath->SetPath(StrToWxStr(startup_params.m_strApploader)); + NANDRoot->SetPath(StrToWxStr(SConfig::GetInstance().m_NANDPath)); } void CConfigMain::InitializeGUITooltips() @@ -958,10 +958,10 @@ void CConfigMain::AudioSettingsChanged(wxCommandEvent& event) break; case ID_BACKEND: - VolumeSlider->Enable(SupportsVolumeChanges(std::string(BackendSelection->GetStringSelection().mb_str()))); - Latency->Enable(std::string(BackendSelection->GetStringSelection().mb_str()) == BACKEND_OPENAL); - DPL2Decoder->Enable(std::string(BackendSelection->GetStringSelection().mb_str()) == BACKEND_OPENAL); - SConfig::GetInstance().sBackend = BackendSelection->GetStringSelection().mb_str(); + VolumeSlider->Enable(SupportsVolumeChanges(WxStrToStr(BackendSelection->GetStringSelection()))); + Latency->Enable(WxStrToStr(BackendSelection->GetStringSelection()) == BACKEND_OPENAL); + DPL2Decoder->Enable(WxStrToStr(BackendSelection->GetStringSelection()) == BACKEND_OPENAL); + SConfig::GetInstance().sBackend = WxStrToStr(BackendSelection->GetStringSelection()); AudioCommon::UpdateSoundStream(); break; @@ -982,9 +982,9 @@ void CConfigMain::AddAudioBackends() for (std::vector::const_iterator iter = backends.begin(); iter != backends.end(); ++iter) { - BackendSelection->Append(wxString::FromAscii((*iter).c_str())); + BackendSelection->Append(StrToWxStr((*iter).c_str())); int num = BackendSelection->\ - FindString(wxString::FromAscii(SConfig::GetInstance().sBackend.c_str())); + FindString(StrToWxStr(SConfig::GetInstance().sBackend.c_str())); BackendSelection->SetSelection(num); } } @@ -1046,12 +1046,12 @@ void CConfigMain::GCSettingsChanged(wxCommandEvent& event) void CConfigMain::ChooseMemcardPath(std::string& strMemcard, bool isSlotA) { - std::string filename = std::string(wxFileSelector( + std::string filename = WxStrToStr(wxFileSelector( _("Choose a file to open"), - wxString::FromUTF8(File::GetUserPath(D_GCUSER_IDX).c_str()), + StrToWxStr(File::GetUserPath(D_GCUSER_IDX)), isSlotA ? wxT(GC_MEMCARDA) : wxT(GC_MEMCARDB), wxEmptyString, - _("Gamecube Memory Cards (*.raw,*.gcp)") + wxString(wxT("|*.raw;*.gcp"))).mb_str()); + _("Gamecube Memory Cards (*.raw,*.gcp)") + wxString(wxT("|*.raw;*.gcp")))); if (!filename.empty()) { @@ -1242,7 +1242,7 @@ void CConfigMain::AddRemoveISOPaths(wxCommandEvent& event) SConfig::GetInstance().m_ISOFolder.clear(); for (unsigned int i = 0; i < ISOPaths->GetCount(); i++) - SConfig::GetInstance().m_ISOFolder.push_back(std::string(ISOPaths->GetStrings()[i].mb_str())); + SConfig::GetInstance().m_ISOFolder.push_back(WxStrToStr(ISOPaths->GetStrings()[i])); } void CConfigMain::RecursiveDirectoryChanged(wxCommandEvent& WXUNUSED (event)) @@ -1253,24 +1253,24 @@ void CConfigMain::RecursiveDirectoryChanged(wxCommandEvent& WXUNUSED (event)) void CConfigMain::DefaultISOChanged(wxFileDirPickerEvent& WXUNUSED (event)) { - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM = DefaultISO->GetPath().mb_str(); + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM = WxStrToStr(DefaultISO->GetPath()); } void CConfigMain::DVDRootChanged(wxFileDirPickerEvent& WXUNUSED (event)) { - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDVDRoot = DVDRoot->GetPath().mb_str(); + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDVDRoot = WxStrToStr(DVDRoot->GetPath()); } void CConfigMain::ApploaderPathChanged(wxFileDirPickerEvent& WXUNUSED (event)) { - SConfig::GetInstance().m_LocalCoreStartupParameter.m_strApploader = ApploaderPath->GetPath().mb_str(); + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strApploader = WxStrToStr(ApploaderPath->GetPath()); } void CConfigMain::NANDRootChanged(wxFileDirPickerEvent& WXUNUSED (event)) { std::string NANDPath = - SConfig::GetInstance().m_NANDPath = File::GetUserPath(D_WIIROOT_IDX, std::string(NANDRoot->GetPath().mb_str())); - NANDRoot->SetPath(wxString(NANDPath.c_str(), *wxConvCurrent)); + SConfig::GetInstance().m_NANDPath = File::GetUserPath(D_WIIROOT_IDX, WxStrToStr(NANDRoot->GetPath())); + NANDRoot->SetPath(wxString(NANDPath)); SConfig::GetInstance().m_SYSCONF->UpdateLocation(); DiscIO::cUIDsys::AccessInstance().UpdateLocation(); DiscIO::CSharedContent::AccessInstance().UpdateLocation(); diff --git a/Source/Core/DolphinWX/Src/Debugger/BreakpointDlg.cpp b/Source/Core/DolphinWX/Src/Debugger/BreakpointDlg.cpp index 58e73b167e..96dbac8ff8 100644 --- a/Source/Core/DolphinWX/Src/Debugger/BreakpointDlg.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/BreakpointDlg.cpp @@ -19,6 +19,7 @@ #include "StringUtil.h" #include "PowerPC/PowerPC.h" #include "BreakpointWindow.h" +#include "../WxUtils.h" BEGIN_EVENT_TABLE(BreakPointDlg, wxDialog) EVT_BUTTON(wxID_OK, BreakPointDlg::OnOK) @@ -42,14 +43,14 @@ void BreakPointDlg::OnOK(wxCommandEvent& event) { wxString AddressString = m_pEditAddress->GetLineText(0); u32 Address = 0; - if (AsciiToHex(AddressString.mb_str(), Address)) + if (AsciiToHex(WxStrToStr(AddressString).c_str(), Address)) { PowerPC::breakpoints.Add(Address); Parent->NotifyUpdate(); Close(); } else - PanicAlert("The address %s is invalid.", (const char *)AddressString.ToUTF8()); + PanicAlert("The address %s is invalid.", WxStrToStr(AddressString).c_str()); event.Skip(); } diff --git a/Source/Core/DolphinWX/Src/Debugger/BreakpointView.cpp b/Source/Core/DolphinWX/Src/Debugger/BreakpointView.cpp index 496cb8fe5d..a23e9194fd 100644 --- a/Source/Core/DolphinWX/Src/Debugger/BreakpointView.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/BreakpointView.cpp @@ -23,6 +23,7 @@ #include "PowerPC/PPCSymbolDB.h" #include "PowerPC/PowerPC.h" #include "HW/Memmap.h" +#include "../WxUtils.h" CBreakPointView::CBreakPointView(wxWindow* parent, const wxWindowID id) : wxListCtrl(parent, id, wxDefaultPosition, wxDefaultSize, @@ -50,20 +51,20 @@ void CBreakPointView::Update() if (!rBP.bTemporary) { wxString temp; - temp = wxString::FromAscii(rBP.bOn ? "on" : " "); + temp = StrToWxStr(rBP.bOn ? "on" : " "); int Item = InsertItem(0, temp); - temp = wxString::FromAscii("BP"); + temp = StrToWxStr("BP"); SetItem(Item, 1, temp); Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rBP.iAddress); if (symbol) { - temp = wxString::FromAscii(g_symbolDB.GetDescription(rBP.iAddress)); + temp = StrToWxStr(g_symbolDB.GetDescription(rBP.iAddress)); SetItem(Item, 2, temp); } sprintf(szBuffer, "%08x", rBP.iAddress); - temp = wxString::FromAscii(szBuffer); + temp = StrToWxStr(szBuffer); SetItem(Item, 3, temp); SetItemData(Item, rBP.iAddress); @@ -76,27 +77,27 @@ void CBreakPointView::Update() const TMemCheck& rMemCheck = rMemChecks[i]; wxString temp; - temp = wxString::FromAscii((rMemCheck.Break || rMemCheck.Log) ? "on" : " "); + temp = StrToWxStr((rMemCheck.Break || rMemCheck.Log) ? "on" : " "); int Item = InsertItem(0, temp); - temp = wxString::FromAscii("MC"); + temp = StrToWxStr("MC"); SetItem(Item, 1, temp); Symbol *symbol = g_symbolDB.GetSymbolFromAddr(rMemCheck.StartAddress); if (symbol) { - temp = wxString::FromAscii(g_symbolDB.GetDescription(rMemCheck.StartAddress)); + temp = StrToWxStr(g_symbolDB.GetDescription(rMemCheck.StartAddress)); SetItem(Item, 2, temp); } sprintf(szBuffer, "%08x to %08x", rMemCheck.StartAddress, rMemCheck.EndAddress); - temp = wxString::FromAscii(szBuffer); + temp = StrToWxStr(szBuffer); SetItem(Item, 3, temp); size_t c = 0; if (rMemCheck.OnRead) szBuffer[c++] = 'r'; if (rMemCheck.OnWrite) szBuffer[c++] = 'w'; szBuffer[c] = 0x00; - temp = wxString::FromAscii(szBuffer); + temp = StrToWxStr(szBuffer); SetItem(Item, 4, temp); SetItemData(Item, rMemCheck.StartAddress); diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp index f696aaab64..3b22ca339d 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp @@ -23,6 +23,7 @@ #include "Host.h" #include "CodeView.h" #include "SymbolDB.h" +#include "../WxUtils.h" #include #include @@ -223,7 +224,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) { char disasm[256]; debugger->disasm(selection, disasm, 256); - wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(disasm))); + wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(disasm))); } break; @@ -231,7 +232,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) { char temp[24]; sprintf(temp, "%08x", debugger->readInstruction(selection)); - wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(temp))); + wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp))); } break; @@ -252,7 +253,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) debugger->disasm(addr, disasm, 256); text = text + StringFromFormat("%08x: ", addr) + disasm + "\r\n"; } - wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(text.c_str()))); + wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(text.c_str()))); } } break; @@ -297,12 +298,12 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) Symbol *symbol = symbol_db->GetSymbolFromAddr(selection); if (symbol) { - wxTextEntryDialog input_symbol(this, wxString::FromAscii("Rename symbol:"), + wxTextEntryDialog input_symbol(this, StrToWxStr("Rename symbol:"), wxGetTextFromUserPromptStr, - wxString::FromAscii(symbol->name.c_str())); + StrToWxStr(symbol->name.c_str())); if (input_symbol.ShowModal() == wxID_OK) { - symbol->name = input_symbol.GetValue().mb_str(); + symbol->name = WxStrToStr(input_symbol.GetValue()); Refresh(); // Redraw to show the renamed symbol } Host_NotifyMapLoaded(); @@ -327,23 +328,23 @@ void CCodeView::OnMouseUpR(wxMouseEvent& event) wxMenu* menu = new wxMenu; //menu->Append(IDM_GOTOINMEMVIEW, "&Goto in mem view"); menu->Append(IDM_FOLLOWBRANCH, - wxString::FromAscii("&Follow branch"))->Enable(AddrToBranch(selection) ? true : false); + StrToWxStr("&Follow branch"))->Enable(AddrToBranch(selection) ? true : false); menu->AppendSeparator(); #if wxUSE_CLIPBOARD - menu->Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address")); - menu->Append(IDM_COPYFUNCTION, wxString::FromAscii("Copy &function"))->Enable(isSymbol); - menu->Append(IDM_COPYCODE, wxString::FromAscii("Copy &code line")); - menu->Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex")); + menu->Append(IDM_COPYADDRESS, StrToWxStr("Copy &address")); + menu->Append(IDM_COPYFUNCTION, StrToWxStr("Copy &function"))->Enable(isSymbol); + menu->Append(IDM_COPYCODE, StrToWxStr("Copy &code line")); + menu->Append(IDM_COPYHEX, StrToWxStr("Copy &hex")); menu->AppendSeparator(); #endif - menu->Append(IDM_RENAMESYMBOL, wxString::FromAscii("Rename &symbol"))->Enable(isSymbol); + menu->Append(IDM_RENAMESYMBOL, StrToWxStr("Rename &symbol"))->Enable(isSymbol); menu->AppendSeparator(); menu->Append(IDM_RUNTOHERE, _("&Run To Here")); menu->Append(IDM_ADDFUNCTION, _("&Add function")); - menu->Append(IDM_JITRESULTS, wxString::FromAscii("PPC vs X86")); - menu->Append(IDM_INSERTBLR, wxString::FromAscii("Insert &blr")); - menu->Append(IDM_INSERTNOP, wxString::FromAscii("Insert &nop")); - menu->Append(IDM_PATCHALERT, wxString::FromAscii("Patch alert")); + menu->Append(IDM_JITRESULTS, StrToWxStr("PPC vs X86")); + menu->Append(IDM_INSERTBLR, StrToWxStr("Insert &blr")); + menu->Append(IDM_INSERTNOP, StrToWxStr("Insert &nop")); + menu->Append(IDM_PATCHALERT, StrToWxStr("Patch alert")); PopupMenu(menu); event.Skip(true); } @@ -489,7 +490,7 @@ void CCodeView::OnPaint(wxPaintEvent& event) dc.SetTextForeground(_T("#000000")); } - dc.DrawText(wxString::FromAscii(dis2), 17 + 17*charWidth, rowY1); + dc.DrawText(StrToWxStr(dis2), 17 + 17*charWidth, rowY1); // ------------ } @@ -499,7 +500,7 @@ void CCodeView::OnPaint(wxPaintEvent& event) else dc.SetTextForeground(_T("#8000FF")); // purple - dc.DrawText(wxString::FromAscii(dis), 17 + (plain ? 1*charWidth : 9*charWidth), rowY1); + dc.DrawText(StrToWxStr(dis), 17 + (plain ? 1*charWidth : 9*charWidth), rowY1); if (desc[0] == 0) { @@ -513,7 +514,7 @@ void CCodeView::OnPaint(wxPaintEvent& event) //UnDecorateSymbolName(desc,temp,255,UNDNAME_COMPLETE); if (strlen(desc)) { - dc.DrawText(wxString::FromAscii(desc), 17 + 35 * charWidth, rowY1); + dc.DrawText(StrToWxStr(desc), 17 + 35 * charWidth, rowY1); } } diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp index 601faeaec6..1cff07c0f4 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp @@ -30,6 +30,7 @@ #include "CodeWindow.h" #include "CodeView.h" +#include "../WxUtils.h" #include "FileUtil.h" #include "Core.h" #include "HW/Memmap.h" @@ -210,7 +211,7 @@ void CCodeWindow::OnAddrBoxChange(wxCommandEvent& event) wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(IDM_ADDRBOX); wxString txt = pAddrCtrl->GetValue(); - std::string text(txt.mb_str()); + std::string text(WxStrToStr(txt)); text = StripSpaces(text); if (text.size() == 8) { @@ -312,7 +313,7 @@ void CCodeWindow::UpdateLists() Symbol *caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr); if (caller_symbol) { - int idx = callers->Append(wxString::FromAscii(StringFromFormat + int idx = callers->Append(StrToWxStr(StringFromFormat ("< %s (%08x)", caller_symbol->name.c_str(), caller_addr).c_str())); callers->SetClientData(idx, (void*)(u64)caller_addr); } @@ -325,7 +326,7 @@ void CCodeWindow::UpdateLists() Symbol *call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr); if (call_symbol) { - int idx = calls->Append(wxString::FromAscii(StringFromFormat + int idx = calls->Append(StrToWxStr(StringFromFormat ("> %s (%08x)", call_symbol->name.c_str(), call_addr).c_str())); calls->SetClientData(idx, (void*)(u64)call_addr); } @@ -344,12 +345,12 @@ void CCodeWindow::UpdateCallstack() for (size_t i = 0; i < stack.size(); i++) { - int idx = callstack->Append(wxString::FromAscii(stack[i].Name.c_str())); + int idx = callstack->Append(StrToWxStr(stack[i].Name.c_str())); callstack->SetClientData(idx, (void*)(u64)stack[i].vAddress); } if (!ret) - callstack->Append(wxString::FromAscii("invalid callstack")); + callstack->Append(StrToWxStr("invalid callstack")); } // Create CPU Mode menus @@ -360,7 +361,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam wxMenu* pCoreMenu = new wxMenu; wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _("&Interpreter core"), - wxString::FromAscii("This is necessary to get break points" + StrToWxStr("This is necessary to get break points" " and stepping to work as explained in the Developer Documentation. But it can be very" " slow, perhaps slower than 1 fps."), wxITEM_CHECK); @@ -428,7 +429,7 @@ void CCodeWindow::CreateMenuOptions(wxMenu* pMenu) boottopause->Check(bBootToPause); wxMenuItem* automaticstart = pMenu->Append(IDM_AUTOMATICSTART, _("&Automatic start"), - wxString::FromAscii( + StrToWxStr( "Automatically load the Default ISO when Dolphin starts, or the last game you loaded," " if you have not given it an elf file with the --elf command line. [This can be" " convenient if you are bug-testing with a certain game and want to rebuild" @@ -515,10 +516,10 @@ void CCodeWindow::OnJitMenu(wxCommandEvent& event) for (u32 addr = 0x80000000; addr < 0x80100000; addr += 4) { const char *name = PPCTables::GetInstructionName(Memory::ReadUnchecked_U32(addr)); - if (name && !strcmp((const char *)str.mb_str(), name)) + auto const wx_name = WxStrToStr(str); + if (name && (wx_name == name)) { - std::string mb_str(str.mb_str()); - NOTICE_LOG(POWERPC, "Found %s at %08x", mb_str.c_str(), addr); + NOTICE_LOG(POWERPC, "Found %s at %08x", wx_name.c_str(), addr); } } break; diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp index 706b398dce..a11783c010 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp @@ -25,6 +25,7 @@ #include "DebuggerUIUtil.h" +#include "../WxUtils.h" #include "RegisterWindow.h" #include "BreakpointWindow.h" #include "MemoryWindow.h" @@ -65,7 +66,7 @@ void CCodeWindow::Load() std::string fontDesc; ini.Get("General", "DebuggerFont", &fontDesc); if (!fontDesc.empty()) - DebuggerFont.SetNativeFontInfoUserDesc(wxString::FromAscii(fontDesc.c_str())); + DebuggerFont.SetNativeFontInfoUserDesc(StrToWxStr(fontDesc.c_str())); // Boot to pause or not ini.Get("General", "AutomaticStart", &bAutomaticStart, false); @@ -107,7 +108,7 @@ void CCodeWindow::Save() ini.Load(File::GetUserPath(F_DEBUGGERCONFIG_IDX)); ini.Set("General", "DebuggerFont", - std::string(DebuggerFont.GetNativeFontInfoUserDesc().mb_str())); + WxStrToStr(DebuggerFont.GetNativeFontInfoUserDesc())); // Boot to pause or not ini.Set("General", "AutomaticStart", GetMenuBar()->IsChecked(IDM_AUTOMATICSTART)); @@ -154,7 +155,7 @@ void CCodeWindow::CreateMenuSymbols(wxMenuBar *pMenuBar) pSymbolsMenu->Append(IDM_SAVEMAPFILE, _("&Save symbol map")); pSymbolsMenu->AppendSeparator(); pSymbolsMenu->Append(IDM_SAVEMAPFILEWITHCODES, _("Save code"), - wxString::FromAscii("Save the entire disassembled code. This may take a several seconds" + StrToWxStr("Save the entire disassembled code. This may take a several seconds" " and may require between 50 and 100 MB of hard drive space. It will only save code" " that are in the first 4 MB of memory, if you are debugging a game that load .rel" " files with code to memory you may want to increase that to perhaps 8 MB, you can do" @@ -284,7 +285,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) if (!path.IsEmpty()) { - std::ifstream f(path.mb_str()); + std::ifstream f(WxStrToStr(path)); std::string line; while (std::getline(f, line)) @@ -312,13 +313,13 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) { wxTextEntryDialog input_prefix( this, - wxString::FromAscii("Only export symbols with prefix:\n(Blank for all symbols)"), + StrToWxStr("Only export symbols with prefix:\n(Blank for all symbols)"), wxGetTextFromUserPromptStr, wxEmptyString); if (input_prefix.ShowModal() == wxID_OK) { - std::string prefix(input_prefix.GetValue().mb_str()); + std::string prefix(WxStrToStr(input_prefix.GetValue())); wxString path = wxFileSelector( _T("Save signature as"), wxEmptyString, wxEmptyString, wxEmptyString, @@ -328,8 +329,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) { SignatureDB db; db.Initialize(&g_symbolDB, prefix.c_str()); - std::string filename(path.mb_str()); - db.Save(path.mb_str()); + db.Save(WxStrToStr(path).c_str()); } } } @@ -343,7 +343,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) if (!path.IsEmpty()) { SignatureDB db; - db.Load(path.mb_str()); + db.Load(WxStrToStr(path).c_str()); db.Apply(&g_symbolDB); } } @@ -366,7 +366,7 @@ void CCodeWindow::NotifyMapLoaded() symbols->Clear(); for (PPCSymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); ++iter) { - int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str())); + int idx = symbols->Append(StrToWxStr(iter->second.name.c_str())); symbols->SetClientData(idx, (void*)&iter->second); } symbols->Thaw(); diff --git a/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp index a4591d3994..27da055990 100644 --- a/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp @@ -22,6 +22,7 @@ #include +#include "../WxUtils.h" #include "StringUtil.h" #include "DSPDebugWindow.h" #include "DSPRegisterView.h" @@ -220,7 +221,7 @@ void DSPDebuggerLLE::UpdateSymbolMap() for (SymbolDB::XFuncMap::iterator iter = DSPSymbols::g_dsp_symbol_db.GetIterator(); iter != DSPSymbols::g_dsp_symbol_db.End(); ++iter) { - int idx = m_SymbolList->Append(wxString::FromAscii(iter->second.name.c_str())); + int idx = m_SymbolList->Append(StrToWxStr(iter->second.name.c_str())); m_SymbolList->SetClientData(idx, (void*)&iter->second); } m_SymbolList->Thaw(); @@ -250,8 +251,7 @@ void DSPDebuggerLLE::OnAddrBoxChange(wxCommandEvent& event) wxTextCtrl* pAddrCtrl = (wxTextCtrl*)m_Toolbar->FindControl(ID_ADDRBOX); wxString txt = pAddrCtrl->GetValue(); - std::string text(txt.mb_str()); - text = StripSpaces(text); + auto text = StripSpaces(WxStrToStr(txt)); if (text.size()) { u32 addr; diff --git a/Source/Core/DolphinWX/Src/Debugger/DSPRegisterView.cpp b/Source/Core/DolphinWX/Src/Debugger/DSPRegisterView.cpp index ca275ba66a..b8634e14dc 100644 --- a/Source/Core/DolphinWX/Src/Debugger/DSPRegisterView.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/DSPRegisterView.cpp @@ -17,7 +17,7 @@ #include "DSPDebugWindow.h" #include "DSPRegisterView.h" - +#include "../WxUtils.h" wxString CDSPRegTable::GetValue(int row, int col) { @@ -25,7 +25,7 @@ wxString CDSPRegTable::GetValue(int row, int col) { switch (col) { - case 0: return wxString::FromAscii(pdregname(row)); + case 0: return StrToWxStr(pdregname(row)); case 1: return wxString::Format(wxT("0x%04x"), DSPCore_ReadRegister(row)); default: return wxEmptyString; } diff --git a/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp index 69cee04db5..e80d206112 100644 --- a/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp @@ -37,6 +37,7 @@ #include "Core.h" #include "StringUtil.h" #include "LogManager.h" +#include "../WxUtils.h" #include "../Globals.h" diff --git a/Source/Core/DolphinWX/Src/Debugger/MemoryCheckDlg.cpp b/Source/Core/DolphinWX/Src/Debugger/MemoryCheckDlg.cpp index f66e781ca3..41e09a7451 100644 --- a/Source/Core/DolphinWX/Src/Debugger/MemoryCheckDlg.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/MemoryCheckDlg.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "../WxUtils.h" #include "MemoryCheckDlg.h" #include "Common.h" #include "StringUtil.h" @@ -79,9 +80,9 @@ void MemoryCheckDlg::OnOK(wxCommandEvent& event) u32 StartAddress, EndAddress; bool EndAddressOK = EndAddressString.Len() && - AsciiToHex(EndAddressString.mb_str(), EndAddress); + AsciiToHex(WxStrToStr(EndAddressString).c_str(), EndAddress); - if (AsciiToHex(StartAddressString.mb_str(), StartAddress) && + if (AsciiToHex(WxStrToStr(StartAddressString).c_str(), StartAddress) && (OnRead || OnWrite) && (Log || Break)) { TMemCheck MemCheck; diff --git a/Source/Core/DolphinWX/Src/Debugger/MemoryView.cpp b/Source/Core/DolphinWX/Src/Debugger/MemoryView.cpp index c6244fb7de..14d1aed8c0 100644 --- a/Source/Core/DolphinWX/Src/Debugger/MemoryView.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/MemoryView.cpp @@ -22,6 +22,8 @@ #include "HW/Memmap.h" #include "MemoryView.h" +#include "../WxUtils.h" + #include #include @@ -149,7 +151,7 @@ void CMemoryView::OnPopupMenu(wxCommandEvent& event) { char temp[24]; sprintf(temp, "%08x", debugger->readExtraMemory(memory, selection)); - wxTheClipboard->SetData(new wxTextDataObject(wxString::FromAscii(temp))); + wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(temp))); } break; #endif @@ -186,16 +188,16 @@ void CMemoryView::OnMouseDownR(wxMouseEvent& event) wxMenu* menu = new wxMenu; //menu.Append(IDM_GOTOINMEMVIEW, "&Goto in mem view"); #if wxUSE_CLIPBOARD - menu->Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address")); - menu->Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex")); + menu->Append(IDM_COPYADDRESS, StrToWxStr("Copy &address")); + menu->Append(IDM_COPYHEX, StrToWxStr("Copy &hex")); #endif - menu->Append(IDM_TOGGLEMEMORY, wxString::FromAscii("Toggle &memory")); + menu->Append(IDM_TOGGLEMEMORY, StrToWxStr("Toggle &memory")); wxMenu* viewAsSubMenu = new wxMenu; - viewAsSubMenu->Append(IDM_VIEWASFP, wxString::FromAscii("FP value")); - viewAsSubMenu->Append(IDM_VIEWASASCII, wxString::FromAscii("ASCII")); - viewAsSubMenu->Append(IDM_VIEWASHEX, wxString::FromAscii("Hex")); - menu->AppendSubMenu(viewAsSubMenu, wxString::FromAscii("View As:")); + viewAsSubMenu->Append(IDM_VIEWASFP, StrToWxStr("FP value")); + viewAsSubMenu->Append(IDM_VIEWASASCII, StrToWxStr("ASCII")); + viewAsSubMenu->Append(IDM_VIEWASHEX, StrToWxStr("Hex")); + menu->AppendSubMenu(viewAsSubMenu, StrToWxStr("View As:")); PopupMenu(menu); } @@ -285,7 +287,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event) char mem[256]; debugger->getRawMemoryString(memory, address, mem, 256); dc.SetTextForeground(_T("#000080")); - dc.DrawText(wxString::FromAscii(mem), 17+fontSize*(8), rowY1); + dc.DrawText(StrToWxStr(mem), 17+fontSize*(8), rowY1); dc.SetTextForeground(_T("#000000")); } @@ -361,9 +363,9 @@ void CMemoryView::OnPaint(wxPaintEvent& event) char desc[256] = ""; if (viewAsType != VIEWAS_HEX) - dc.DrawText(wxString::FromAscii(dis), textPlacement + fontSize*(8 + 8), rowY1); + dc.DrawText(StrToWxStr(dis), textPlacement + fontSize*(8 + 8), rowY1); else - dc.DrawText(wxString::FromAscii(dis), textPlacement, rowY1); + dc.DrawText(StrToWxStr(dis), textPlacement, rowY1); if (desc[0] == 0) strcpy(desc, debugger->getDescription(address).c_str()); @@ -371,7 +373,7 @@ void CMemoryView::OnPaint(wxPaintEvent& event) dc.SetTextForeground(_T("#0000FF")); if (strlen(desc)) - dc.DrawText(wxString::FromAscii(desc), 17+fontSize*((8+8+8+30)*2), rowY1); + dc.DrawText(StrToWxStr(desc), 17+fontSize*((8+8+8+30)*2), rowY1); // Show blue memory check dot if (debugger->isMemCheck(address)) diff --git a/Source/Core/DolphinWX/Src/Debugger/MemoryWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/MemoryWindow.cpp index 5673d7b7c1..4b87cfa154 100644 --- a/Source/Core/DolphinWX/Src/Debugger/MemoryWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/MemoryWindow.cpp @@ -20,6 +20,8 @@ #include #include #include + +#include "../WxUtils.h" #include "MemoryWindow.h" #include "HW/CPU.h" #include "PowerPC/PowerPC.h" @@ -152,8 +154,8 @@ void CMemoryWindow::JumpToAddress(u32 _Address) void CMemoryWindow::SetMemoryValue(wxCommandEvent& event) { - std::string str_addr = std::string(addrbox->GetValue().mb_str()); - std::string str_val = std::string(valbox->GetValue().mb_str()); + std::string str_addr = WxStrToStr(addrbox->GetValue()); + std::string str_val = WxStrToStr(valbox->GetValue()); u32 addr; u32 val; @@ -179,7 +181,7 @@ void CMemoryWindow::OnAddrBoxChange(wxCommandEvent& event) if (txt.size()) { u32 addr; - sscanf(txt.mb_str(), "%08x", &addr); + sscanf(WxStrToStr(txt).c_str(), "%08x", &addr); memview->Center(addr & ~3); } @@ -349,10 +351,7 @@ void CMemoryWindow::onSearch(wxCommandEvent& event) tmpstr = new char[newsize + 1]; memset(tmpstr, 0, newsize + 1); } - //sprintf(tmpstr, "%s%s", tmpstr, rawData.c_str()); - //strcpy(&tmpstr[1], rawData.ToAscii()); - //memcpy(&tmpstr[1], &rawData.c_str()[0], rawData.size()); - sprintf(tmpstr, "%s%s", tmpstr, (const char *)rawData.mb_str()); + sprintf(tmpstr, "%s%s", tmpstr, WxStrToStr(rawData).c_str()); tmp2 = &Dest.front(); count = 0; for(i = 0; i < strlen(tmpstr); i++) @@ -376,7 +375,7 @@ void CMemoryWindow::onSearch(wxCommandEvent& event) tmpstr = new char[size+1]; tmp2 = &Dest.front(); - sprintf(tmpstr, "%s", (const char *)rawData.mb_str()); + sprintf(tmpstr, "%s", WxStrToStr(rawData).c_str()); for(i = 0; i < size; i++) tmp2[i] = tmpstr[i]; @@ -393,7 +392,7 @@ void CMemoryWindow::onSearch(wxCommandEvent& event) u32 addr = 0; if (txt.size()) { - sscanf(txt.mb_str(), "%08x", &addr); + sscanf(WxStrToStr(txt).c_str(), "%08x", &addr); } i = addr+4; for( ; i < szRAM; i++) diff --git a/Source/Core/DolphinWX/Src/Debugger/RegisterView.cpp b/Source/Core/DolphinWX/Src/Debugger/RegisterView.cpp index c4a30fd522..0c414cb522 100644 --- a/Source/Core/DolphinWX/Src/Debugger/RegisterView.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/RegisterView.cpp @@ -20,6 +20,7 @@ #include "PowerPC/PowerPC.h" #include "HW/ProcessorInterface.h" #include "IniFile.h" +#include "../WxUtils.h" // F-zero 80005e60 wtf?? @@ -51,9 +52,9 @@ wxString CRegTable::GetValue(int row, int col) { if (row < 32) { switch (col) { - case 0: return wxString::FromAscii(GetGPRName(row)); + case 0: return StrToWxStr(GetGPRName(row)); case 1: return wxString::Format(wxT("%08x"), GPR(row)); - case 2: return wxString::FromAscii(GetFPRName(row)); + case 2: return StrToWxStr(GetFPRName(row)); case 3: return wxString::Format(wxT("%016llx"), riPS0(row)); case 4: return wxString::Format(wxT("%016llx"), riPS1(row)); default: return wxEmptyString; @@ -61,7 +62,7 @@ wxString CRegTable::GetValue(int row, int col) } else { if (row - 32 < NUM_SPECIALS) { switch (col) { - case 0: return wxString::FromAscii(special_reg_names[row - 32]); + case 0: return StrToWxStr(special_reg_names[row - 32]); case 1: return wxString::Format(wxT("%08x"), GetSpecialRegValue(row - 32)); default: return wxEmptyString; } @@ -91,7 +92,7 @@ static void SetSpecialRegValue(int reg, u32 value) { void CRegTable::SetValue(int row, int col, const wxString& strNewVal) { u32 newVal = 0; - if (TryParse(std::string(strNewVal.mb_str()), &newVal)) + if (TryParse(WxStrToStr(strNewVal), &newVal)) { if (row < 32) { if (col == 1) diff --git a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp index 81268e3467..6e18c192eb 100644 --- a/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp +++ b/Source/Core/DolphinWX/Src/FifoPlayerDlg.cpp @@ -22,6 +22,7 @@ #include "FifoPlayer/FifoPlayer.h" #include "FifoPlayer/FifoRecorder.h" #include "OpcodeDecoding.h" +#include "WxUtils.h" #include #include @@ -395,7 +396,7 @@ void FifoPlayerDlg::OnSaveFile(wxCommandEvent& WXUNUSED(event)) if (!path.empty()) { wxBeginBusyCursor(); - bool result = file->Save(path.mb_str()); + bool result = file->Save(WxStrToStr(path).c_str()); wxEndBusyCursor(); if (!result) @@ -752,10 +753,10 @@ void FifoPlayerDlg::OnObjectCmdListSelectionChanged(wxCommandEvent& event) char name[64]="\0", desc[512]="\0"; GetBPRegInfo(cmddata+1, name, sizeof(name), desc, sizeof(desc)); newLabel = _("BP register "); - newLabel += (name[0] != '\0') ? wxString(name, *wxConvCurrent) : wxString::Format(_("UNKNOWN_%02X"), *(cmddata+1)); + newLabel += (name[0] != '\0') ? StrToWxStr(name) : wxString::Format(_("UNKNOWN_%02X"), *(cmddata+1)); newLabel += wxT(":\n"); if (desc[0] != '\0') - newLabel += wxString(desc, *wxConvCurrent); + newLabel += StrToWxStr(desc); else newLabel += _("No description available"); } diff --git a/Source/Core/DolphinWX/Src/FrameAui.cpp b/Source/Core/DolphinWX/Src/FrameAui.cpp index 0550c5cd39..fd3cbb662b 100644 --- a/Source/Core/DolphinWX/Src/FrameAui.cpp +++ b/Source/Core/DolphinWX/Src/FrameAui.cpp @@ -21,6 +21,7 @@ #include "Globals.h" // Local #include "Frame.h" #include "LogWindow.h" +#include "WxUtils.h" #include "ConfigManager.h" // Core @@ -548,7 +549,7 @@ void CFrame::OnDropDownToolbarItem(wxAuiToolBarEvent& event) for (u32 i = 0; i < Perspectives.size(); i++) { wxMenuItem* mItem = new wxMenuItem(menuPopup, IDM_PERSPECTIVES_0 + i, - wxString::FromAscii(Perspectives[i].Name.c_str()), + StrToWxStr(Perspectives[i].Name.c_str()), wxT(""), wxITEM_CHECK); menuPopup->Append(mItem); if (i == ActivePerspective) mItem->Check(true); @@ -580,7 +581,7 @@ void CFrame::OnToolBar(wxCommandEvent& event) return; } SaveIniPerspectives(); - GetStatusBar()->SetStatusText(wxString::FromAscii(std::string + GetStatusBar()->SetStatusText(StrToWxStr(std::string ("Saved " + Perspectives[ActivePerspective].Name).c_str()), 0); break; case IDM_PERSPECTIVES_ADD_PANE: @@ -633,7 +634,7 @@ void CFrame::OnDropDownToolbarSelect(wxCommandEvent& event) } SPerspectives Tmp; - Tmp.Name = dlg.GetValue().mb_str(); + Tmp.Name = WxStrToStr(dlg.GetValue()); Tmp.Perspective = m_Mgr->SavePerspective(); ActivePerspective = (u32)Perspectives.size(); @@ -870,7 +871,7 @@ void CFrame::LoadIniPerspectives() ini.Get(_Section.c_str(), "Width", &_Width, "70,25"); ini.Get(_Section.c_str(), "Height", &_Height, "80,80"); - Tmp.Perspective = wxString::FromAscii(_Perspective.c_str()); + Tmp.Perspective = StrToWxStr(_Perspective.c_str()); SplitString(_Width, ',', _SWidth); SplitString(_Height, ',', _SHeight); @@ -940,7 +941,7 @@ void CFrame::SaveIniPerspectives() for (u32 i = 0; i < Perspectives.size(); i++) { std::string _Section = "P - " + Perspectives[i].Name; - ini.Set(_Section.c_str(), "Perspective", Perspectives[i].Perspective.mb_str()); + ini.Set(_Section.c_str(), "Perspective", WxStrToStr(Perspectives[i].Perspective)); std::string SWidth = "", SHeight = ""; for (u32 j = 0; j < Perspectives[i].Width.size(); j++) diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index cb2750ade4..a1dcd959fe 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -101,7 +101,7 @@ void CFrame::CreateMenu() drives = cdio_get_devices(); // Windows Limitation of 24 character drives for (unsigned int i = 0; i < drives.size() && i < 24; i++) { - externalDrive->Append(IDM_DRIVE1 + i, wxString::FromAscii(drives[i].c_str())); + externalDrive->Append(IDM_DRIVE1 + i, StrToWxStr(drives[i].c_str())); } fileMenu->AppendSeparator(); @@ -601,12 +601,10 @@ void CFrame::DoOpen(bool Boot) // Should we boot a new game or just change the disc? if (Boot && !path.IsEmpty()) - BootGame(std::string(path.mb_str())); + BootGame(WxStrToStr(path)); else { - char newDiscpath[2048]; - strncpy(newDiscpath, path.mb_str(), strlen(path.mb_str())+1); - DVDInterface::ChangeDisc(newDiscpath); + DVDInterface::ChangeDisc(WxStrToStr(path).c_str()); } } @@ -693,7 +691,7 @@ void CFrame::OnPlayRecording(wxCommandEvent& WXUNUSED (event)) GetMenuBar()->FindItem(IDM_RECORDREADONLY)->Check(true); } - if(Movie::PlayInput(path.mb_str())) + if (Movie::PlayInput(WxStrToStr(path).c_str())) BootGame(std::string("")); } @@ -1015,7 +1013,7 @@ void CFrame::DoStop() X11Utils::InhibitScreensaver(X11Utils::XDisplayFromHandle(GetHandle()), X11Utils::XWindowFromHandle(GetHandle()), false); #endif - m_RenderFrame->SetTitle(wxString::FromAscii(scm_rev_str)); + m_RenderFrame->SetTitle(StrToWxStr(scm_rev_str)); // Destroy the renderer frame when not rendering to main m_RenderParent->Unbind(wxEVT_SIZE, &CFrame::OnRenderParentResize, this); @@ -1081,7 +1079,7 @@ void CFrame::DoRecordingSave() if(path.IsEmpty()) return; - Movie::SaveRecording(path.mb_str()); + Movie::SaveRecording(WxStrToStr(path).c_str()); if (!paused) DoPause(); @@ -1212,7 +1210,7 @@ void CFrame::StatusBarMessage(const char * Text, ...) vsnprintf(Str, MAX_BYTES, Text, ArgPtr); va_end(ArgPtr); - if (this->GetStatusBar()->IsEnabled()) this->GetStatusBar()->SetStatusText(wxString::FromAscii(Str),0); + if (this->GetStatusBar()->IsEnabled()) this->GetStatusBar()->SetStatusText(StrToWxStr(Str),0); } @@ -1248,7 +1246,8 @@ void CFrame::OnImportSave(wxCommandEvent& WXUNUSED (event)) if (!path.IsEmpty()) { - CWiiSaveCrypted* saveFile = new CWiiSaveCrypted(path.mb_str()); + // TODO: Does this actually need to be dynamically allocated for some reason? + CWiiSaveCrypted* saveFile = new CWiiSaveCrypted(WxStrToStr(path).c_str()); delete saveFile; } } @@ -1288,7 +1287,7 @@ void CFrame::OnInstallWAD(wxCommandEvent& event) _T("Wii WAD file (*.wad)|*.wad"), wxFD_OPEN | wxFD_PREVIEW | wxFD_FILE_MUST_EXIST, this); - fileName = path.mb_str(); + fileName = WxStrToStr(path); break; } default: @@ -1354,7 +1353,7 @@ void CFrame::ConnectWiimote(int wm_idx, bool connect) GetUsbPointer()->AccessWiiMote(wm_idx | 0x100)->Activate(connect); wxString msg(wxString::Format(wxT("Wiimote %i %s"), wm_idx + 1, connect ? wxT("Connected") : wxT("Disconnected"))); - Core::DisplayMessage(msg.ToAscii(), 3000); + Core::DisplayMessage(WxStrToStr(msg), 3000); Host_UpdateMainFrame(); } } @@ -1394,7 +1393,7 @@ void CFrame::OnLoadStateFromFile(wxCommandEvent& WXUNUSED (event)) this); if (!path.IsEmpty()) - State::LoadAs((const char*)path.mb_str()); + State::LoadAs(WxStrToStr(path)); } void CFrame::OnSaveStateToFile(wxCommandEvent& WXUNUSED (event)) @@ -1408,7 +1407,7 @@ void CFrame::OnSaveStateToFile(wxCommandEvent& WXUNUSED (event)) this); if (!path.IsEmpty()) - State::SaveAs((const char*)path.mb_str()); + State::SaveAs(WxStrToStr(path)); } void CFrame::OnLoadLastState(wxCommandEvent& WXUNUSED (event)) diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index 6fd298ad81..d385b947e5 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -257,7 +257,7 @@ void CGameListCtrl::BrowseForDirectory() if (dialog.ShowModal() == wxID_OK) { - std::string sPath(dialog.GetPath().mb_str()); + std::string sPath(WxStrToStr(dialog.GetPath())); std::vector::iterator itResult = std::find( SConfig::GetInstance().m_ISOFolder.begin(), SConfig::GetInstance().m_ISOFolder.end(), sPath); @@ -402,7 +402,7 @@ wxString NiceSizeFormat(s64 _size) wxString NiceString; char tempstr[32]; sprintf(tempstr,"%3.1f %s", f, sizes[s]); - NiceString = wxString::FromAscii(tempstr); + NiceString = StrToWxStr(tempstr); return(NiceString); } @@ -614,7 +614,7 @@ void CGameListCtrl::ScanForISOs() // Update with the progress (i) and the message dialog.Update(i, wxString::Format(_("Scanning %s"), - wxString(FileName.c_str(), *wxConvCurrent).c_str())); + StrToWxStr(FileName).c_str())); if (dialog.WasCancelled()) break; @@ -858,7 +858,7 @@ void CGameListCtrl::OnMouseMotion(wxMouseEvent& event) char temp[2048]; sprintf(temp, "^ %s%s%s", emuState[emu_state - 1], issues.size() > 0 ? " :\n" : "", issues.c_str()); - toolTip = new wxEmuStateTip(this, wxString(temp, *wxConvCurrent), &toolTip); + toolTip = new wxEmuStateTip(this, StrToWxStr(temp), &toolTip); } else toolTip = new wxEmuStateTip(this, _("Not Set"), &toolTip); @@ -1115,9 +1115,9 @@ void CGameListCtrl::OnWiki(wxCommandEvent& WXUNUSED (event)) void CGameListCtrl::MultiCompressCB(const char* text, float percent, void* arg) { percent = (((float)m_currentItem) + percent) / (float)m_numberItem; - wxString textString(StringFromFormat("%s (%i/%i) - %s", + wxString textString(StrToWxStr(StringFromFormat("%s (%i/%i) - %s", m_currentFilename.c_str(), (int)m_currentItem+1, - (int)m_numberItem, text).c_str(), *wxConvCurrent); + (int)m_numberItem, text))); ((wxProgressDialog*)arg)->Update((int)(percent*1000), textString); } @@ -1170,13 +1170,13 @@ void CGameListCtrl::CompressSelection(bool _compress) std::string OutputFileName; BuildCompleteFilename(OutputFileName, - (const char *)browseDialog.GetPath().mb_str(wxConvUTF8), + WxStrToStr(browseDialog.GetPath()), FileName); - if (wxFileExists(wxString::FromAscii(OutputFileName.c_str())) && + if (wxFileExists(StrToWxStr(OutputFileName.c_str())) && wxMessageBox( wxString::Format(_("The file %s already exists.\nDo you wish to replace it?"), - wxString(OutputFileName.c_str(), *wxConvCurrent).c_str()), + StrToWxStr(OutputFileName).c_str()), _("Confirm File Overwrite"), wxYES_NO) == wxNO) continue; @@ -1198,13 +1198,13 @@ void CGameListCtrl::CompressSelection(bool _compress) std::string OutputFileName; BuildCompleteFilename(OutputFileName, - (const char *)browseDialog.GetPath().mb_str(wxConvUTF8), + WxStrToStr(browseDialog.GetPath()), FileName); - if (wxFileExists(wxString::FromAscii(OutputFileName.c_str())) && + if (wxFileExists(StrToWxStr(OutputFileName.c_str())) && wxMessageBox( wxString::Format(_("The file %s already exists.\nDo you wish to replace it?"), - wxString(OutputFileName.c_str(), *wxConvCurrent).c_str()), + StrToWxStr(OutputFileName).c_str()), _("Confirm File Overwrite"), wxYES_NO) == wxNO) continue; @@ -1225,7 +1225,7 @@ void CGameListCtrl::CompressSelection(bool _compress) void CGameListCtrl::CompressCB(const char* text, float percent, void* arg) { ((wxProgressDialog*)arg)-> - Update((int)(percent*1000), wxString(text, *wxConvCurrent)); + Update((int)(percent*1000), StrToWxStr(text)); } void CGameListCtrl::OnCompressGCM(wxCommandEvent& WXUNUSED (event)) @@ -1251,8 +1251,8 @@ void CGameListCtrl::OnCompressGCM(wxCommandEvent& WXUNUSED (event)) path = wxFileSelector( _("Save decompressed GCM/ISO"), - wxString(FilePath.c_str(), *wxConvCurrent), - wxString(FileName.c_str(), *wxConvCurrent) + FileType.After('*'), + StrToWxStr(FilePath), + StrToWxStr(FileName) + FileType.After('*'), wxEmptyString, FileType + wxT("|") + wxGetTranslation(wxALL_FILES), wxFD_SAVE, @@ -1262,8 +1262,8 @@ void CGameListCtrl::OnCompressGCM(wxCommandEvent& WXUNUSED (event)) { path = wxFileSelector( _("Save compressed GCM/ISO"), - wxString(FilePath.c_str(), *wxConvCurrent), - wxString(FileName.c_str(), *wxConvCurrent) + _T(".gcz"), + StrToWxStr(FilePath), + StrToWxStr(FileName) + _T(".gcz"), wxEmptyString, _("All compressed GC/Wii ISO files (gcz)") + wxString::Format(wxT("|*.gcz|%s"), wxGetTranslation(wxALL_FILES)), diff --git a/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp b/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp index e015c55ae8..76d4833c0b 100644 --- a/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp +++ b/Source/Core/DolphinWX/Src/GeckoCodeDiag.cpp @@ -13,6 +13,7 @@ // If not, see http://www.gnu.org/licenses/ #include "GeckoCodeDiag.h" +#include "WxUtils.h" #include @@ -76,7 +77,7 @@ void CodeConfigPanel::UpdateCodeList() gcodes_end = m_gcodes.end(); for (; gcodes_iter!=gcodes_end; ++gcodes_iter) { - m_listbox_gcodes->Append(wxString(gcodes_iter->name.c_str(), *wxConvCurrent)); + m_listbox_gcodes->Append(StrToWxStr(gcodes_iter->name)); if (gcodes_iter->enabled) m_listbox_gcodes->Check(m_listbox_gcodes->GetCount()-1, true); } @@ -109,7 +110,7 @@ void CodeConfigPanel::UpdateInfoBox(wxCommandEvent&) if (sel > -1) { - m_infobox.label_name->SetLabel(wxGetTranslation(wxstr_name) + wxString(m_gcodes[sel].name.c_str(), *wxConvCurrent)); + m_infobox.label_name->SetLabel(wxGetTranslation(wxstr_name) + StrToWxStr(m_gcodes[sel].name)); // notes textctrl m_infobox.textctrl_notes->Clear(); @@ -117,10 +118,10 @@ void CodeConfigPanel::UpdateInfoBox(wxCommandEvent&) notes_iter = m_gcodes[sel].notes.begin(), notes_end = m_gcodes[sel].notes.end(); for (; notes_iter!=notes_end; ++notes_iter) - m_infobox.textctrl_notes->AppendText(wxString(notes_iter->c_str(), *wxConvCurrent)); + m_infobox.textctrl_notes->AppendText(StrToWxStr(*notes_iter)); m_infobox.textctrl_notes->ScrollLines(-99); // silly - m_infobox.label_creator->SetLabel(wxGetTranslation(wxstr_creator) + wxString(m_gcodes[sel].creator.c_str(), *wxConvCurrent)); + m_infobox.label_creator->SetLabel(wxGetTranslation(wxstr_creator) + StrToWxStr(m_gcodes[sel].creator)); // add codes to info listbox std::vector::const_iterator diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index 833268ad63..639190fa0e 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -28,6 +28,7 @@ #include "StringUtil.h" #include "Hash.h" #include "IniFile.h" +#include "WxUtils.h" #include "Filesystem.h" #include "BannerLoader.h" @@ -331,7 +332,7 @@ const std::string GameListItem::GetWiiFSPath() const File::CreateFullPath(Path); if (Path[0] == '.') - ret = std::string(wxGetCwd().mb_str()) + std::string(Path).substr(strlen(ROOT_DIR)); + ret = WxStrToStr(wxGetCwd()) + std::string(Path).substr(strlen(ROOT_DIR)); else ret = std::string(Path); } diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index c44aad5d5b..e739ff043b 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -23,6 +23,7 @@ #include "CommonPaths.h" #include "Globals.h" +#include "WxUtils.h" #include "VolumeCreator.h" #include "Filesystem.h" #include "ISOProperties.h" @@ -663,10 +664,10 @@ void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event)) { int partitionNum = wxAtoi(File.SubString(10, 11)); File.Remove(0, 12); // Remove "Partition x/" - WiiDisc.at(partitionNum).FileSystem->ExportFile(File.mb_str(), Path.mb_str()); + WiiDisc.at(partitionNum).FileSystem->ExportFile(WxStrToStr(File).c_str(), WxStrToStr(Path).c_str()); } else - pFileSystem->ExportFile(File.mb_str(), Path.mb_str()); + pFileSystem->ExportFile(WxStrToStr(File).c_str(), WxStrToStr(Path).c_str()); } void CISOProperties::ExportDir(const char* _rFullPath, const char* _rExportFolder, const int partitionNum) @@ -727,7 +728,7 @@ void CISOProperties::ExportDir(const char* _rFullPath, const char* _rExportFolde (u32)(((float)(i - index[0]) / (float)(index[1] - index[0])) * 100))); dialog.Update(i, wxString::Format(_("Extracting %s"), - wxString(fst[i]->m_FullPath, *wxConvCurrent).c_str())); + StrToWxStr(fst[i]->m_FullPath).c_str())); if (dialog.WasCancelled()) break; @@ -778,9 +779,9 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event) { if (DiscIO::IsVolumeWiiDisc(OpenISO)) for (u32 i = 0; i < WiiDisc.size(); i++) - ExportDir(NULL, Path.mb_str(), i); + ExportDir(NULL, WxStrToStr(Path).c_str(), i); else - ExportDir(NULL, Path.mb_str()); + ExportDir(NULL, WxStrToStr(Path).c_str()); return; } @@ -798,10 +799,10 @@ void CISOProperties::OnExtractDir(wxCommandEvent& event) { int partitionNum = wxAtoi(Directory.SubString(10, 11)); Directory.Remove(0, 12); // Remove "Partition x/" - ExportDir(Directory.mb_str(), Path.mb_str(), partitionNum); + ExportDir(WxStrToStr(Directory).c_str(), WxStrToStr(Path).c_str(), partitionNum); } else - ExportDir(Directory.mb_str(), Path.mb_str()); + ExportDir(WxStrToStr(Directory).c_str(), WxStrToStr(Path).c_str()); } void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event) @@ -821,15 +822,15 @@ void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event) bool ret = false; if (event.GetId() == IDM_EXTRACTAPPLOADER) { - ret = FS->ExportApploader(Path.mb_str()); + ret = FS->ExportApploader(WxStrToStr(Path).c_str()); } else if (event.GetId() == IDM_EXTRACTDOL) { - ret = FS->ExportDOL(Path.mb_str()); + ret = FS->ExportDOL(WxStrToStr(Path).c_str()); } if (!ret) - PanicAlertT("Failed to extract to %s!", (const char *)Path.mb_str()); + PanicAlertT("Failed to extract to %s!", WxStrToStr(Path).c_str()); } class IntegrityCheckThread : public wxThread @@ -989,7 +990,7 @@ void CISOProperties::LoadGameConfig() GameIni.Get("EmuState", "EmulationIssues", &sTemp); if (!sTemp.empty()) { - EmuIssues->SetValue(wxString(sTemp.c_str(), *wxConvCurrent)); + EmuIssues->SetValue(StrToWxStr(sTemp.c_str())); } EmuIssues->Enable(EmuState->GetSelection() != 0); @@ -1075,7 +1076,7 @@ bool CISOProperties::SaveGameConfig() GameIni.Get("EmuState","EmulationIssues", &sTemp); if (EmuIssues->GetValue() != sTemp) bRefreshList = true; - GameIni.Set("EmuState", "EmulationIssues", (const char*)EmuIssues->GetValue().mb_str(*wxConvCurrent)); + GameIni.Set("EmuState", "EmulationIssues", WxStrToStr(EmuIssues->GetValue())); PatchList_Save(); ActionReplayList_Save(); @@ -1156,7 +1157,7 @@ void CISOProperties::PatchList_Load() for (std::vector::const_iterator it = onFrame.begin(); it != onFrame.end(); ++it) { PatchEngine::Patch p = *it; - Patches->Append(wxString(p.name.c_str(), *wxConvCurrent)); + Patches->Append(StrToWxStr(p.name.c_str())); Patches->Check(index, p.active); ++index; } @@ -1209,7 +1210,7 @@ void CISOProperties::PatchButtonClicked(wxCommandEvent& event) CPatchAddEdit dlg(-1, this, 1, _("Add Patch")); if (dlg.ShowModal() == wxID_OK) { - Patches->Append(wxString(onFrame.back().name.c_str(), *wxConvCurrent)); + Patches->Append(StrToWxStr(onFrame.back().name)); Patches->Check((unsigned int)(onFrame.size() - 1), onFrame.back().active); } } @@ -1238,7 +1239,7 @@ void CISOProperties::ActionReplayList_Load() for (std::vector::const_iterator it = arCodes.begin(); it != arCodes.end(); ++it) { ActionReplay::ARCode arCode = *it; - Cheats->Append(wxString(arCode.name.c_str(), *wxConvCurrent)); + Cheats->Append(StrToWxStr(arCode.name)); Cheats->Check(index, arCode.active); ++index; } @@ -1256,7 +1257,7 @@ void CISOProperties::ActionReplayList_Save() for (std::vector::const_iterator iter2 = code.ops.begin(); iter2 != code.ops.end(); ++iter2) { - lines.push_back(std::string(wxString::Format(wxT("%08X %08X"), iter2->cmd_addr, iter2->value).mb_str())); + lines.push_back(WxStrToStr(wxString::Format(wxT("%08X %08X"), iter2->cmd_addr, iter2->value))); } ++index; } @@ -1364,5 +1365,6 @@ void CISOProperties::ChangeBannerDetails(int lang) std::string filename, extension; SplitPath(OpenGameListItem->GetFileName(), 0, &filename, &extension); // Also sets the window's title - SetTitle(wxString(StringFromFormat("%s%s: %s - ", filename.c_str(), extension.c_str(), OpenGameListItem->GetUniqueID().c_str()).c_str(), *wxConvCurrent)+shortName); + SetTitle(StrToWxStr(StringFromFormat("%s%s: %s - ", filename.c_str(), + extension.c_str(), OpenGameListItem->GetUniqueID().c_str()).c_str()) + shortName); } diff --git a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp index 1efcf98af6..d8a755aca6 100644 --- a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp @@ -17,10 +17,7 @@ #include "InputConfigDiag.h" #include "UDPConfigDiag.h" - -#define WXSTR_FROM_STR(s) (wxString::FromUTF8((s).c_str())) -#define WXTSTR_FROM_CSTR(s) (wxGetTranslation(wxString::FromUTF8(s))) -#define STR_FROM_WXSTR(w) (std::string((w).ToUTF8())) +#include "WxUtils.h" void GamepadPage::ConfigUDPWii(wxCommandEvent &event) { @@ -37,7 +34,7 @@ void GamepadPage::ConfigExtension(wxCommandEvent& event) if (ex->switch_extension) { wxDialog dlg(this, -1, - WXTSTR_FROM_CSTR(ex->attachments[ex->switch_extension]->GetName().c_str()), + StrToWxStr(ex->attachments[ex->switch_extension]->GetName().c_str()), wxDefaultPosition, wxDefaultSize); wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); @@ -67,7 +64,7 @@ PadSettingExtension::PadSettingExtension(wxWindow* const parent, ControllerEmu:: e = extension->attachments.end(); for (; i!=e; ++i) - ((wxChoice*)wxcontrol)->Append(WXTSTR_FROM_CSTR((*i)->GetName().c_str())); + ((wxChoice*)wxcontrol)->Append(StrToWxStr((*i)->GetName().c_str())); UpdateGUI(); } @@ -83,7 +80,7 @@ void PadSettingExtension::UpdateValue() } PadSettingCheckBox::PadSettingCheckBox(wxWindow* const parent, ControlState& _value, const char* const label) - : PadSetting(new wxCheckBox(parent, -1, WXTSTR_FROM_CSTR(label), wxDefaultPosition)) + : PadSetting(new wxCheckBox(parent, -1, StrToWxStr(label), wxDefaultPosition)) , value(_value) { UpdateGUI(); @@ -119,8 +116,8 @@ ControlDialog::ControlDialog(GamepadPage* const parent, InputPlugin& plugin, Con m_devq = m_parent->controller->default_device; // GetStrings() sounds slow :/ - //device_cbox = new wxComboBox(this, -1, WXSTR_FROM_STR(ref->device_qualifier.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER); - device_cbox = new wxComboBox(this, -1, WXSTR_FROM_STR(m_devq.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER); + //device_cbox = new wxComboBox(this, -1, StrToWxStr(ref->device_qualifier.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER); + device_cbox = new wxComboBox(this, -1, StrToWxStr(m_devq.ToString()), wxDefaultPosition, wxSize(256,-1), parent->device_cbox->GetStrings(), wxTE_PROCESS_ENTER); device_cbox->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &ControlDialog::SetDevice, this); device_cbox->Bind(wxEVT_COMMAND_TEXT_ENTER, &ControlDialog::SetDevice, this); @@ -145,9 +142,9 @@ ControlButton::ControlButton(wxWindow* const parent, ControllerInterface::Contro , control_reference(_ref) { if (label.empty()) - SetLabel(WXSTR_FROM_STR(_ref->expression)); + SetLabel(StrToWxStr(_ref->expression)); else - SetLabel(WXSTR_FROM_STR(label)); + SetLabel(StrToWxStr(label)); } void InputConfigDialog::UpdateProfileComboBox() @@ -169,7 +166,7 @@ void InputConfigDialog::UpdateProfileComboBox() for (; si!=se; ++si) { std::string str(si->begin() + si->find_last_of('/') + 1 , si->end() - 4) ; - strs.push_back(WXSTR_FROM_STR(str)); + strs.push_back(StrToWxStr(str)); } std::vector< GamepadPage* >::iterator i = m_padpages.begin(), @@ -209,7 +206,7 @@ void ControlDialog::UpdateListContents() i = dev->Inputs().begin(), e = dev->Inputs().end(); for (; i!=e; ++i) - control_lbox->Append(WXSTR_FROM_STR((*i)->GetName())); + control_lbox->Append(StrToWxStr((*i)->GetName())); } else { @@ -218,7 +215,7 @@ void ControlDialog::UpdateListContents() i = dev->Outputs().begin(), e = dev->Outputs().end(); for (; i!=e; ++i) - control_lbox->Append(WXSTR_FROM_STR((*i)->GetName())); + control_lbox->Append(StrToWxStr((*i)->GetName())); } } } @@ -227,7 +224,7 @@ void ControlDialog::SelectControl(const std::string& name) { //UpdateGUI(); - const int f = control_lbox->FindString(WXSTR_FROM_STR(name)); + const int f = control_lbox->FindString(StrToWxStr(name)); if (f >= 0) control_lbox->Select(f); } @@ -235,7 +232,7 @@ void ControlDialog::SelectControl(const std::string& name) void ControlDialog::UpdateGUI() { // update textbox - textctrl->SetValue(WXSTR_FROM_STR(control_reference->expression)); + textctrl->SetValue(StrToWxStr(control_reference->expression)); // updates the "bound controls:" label m_bound_label->SetLabel(wxString::Format(_("Bound Controls: %lu"), @@ -244,7 +241,7 @@ void ControlDialog::UpdateGUI() void GamepadPage::UpdateGUI() { - device_cbox->SetValue(WXSTR_FROM_STR(controller->default_device.ToString())); + device_cbox->SetValue(StrToWxStr(controller->default_device.ToString())); std::vector< ControlGroupBox* >::const_iterator g = control_groups.begin(), ge = control_groups.end(); @@ -255,7 +252,7 @@ void GamepadPage::UpdateGUI() , e = (*g)->control_buttons.end(); for (; i!=e; ++i) //if (std::string::npos == (*i)->control_reference->expression.find_first_of("`|&!#")) - (*i)->SetLabel(WXSTR_FROM_STR((*i)->control_reference->expression)); + (*i)->SetLabel(StrToWxStr((*i)->control_reference->expression)); //else //(*i)->SetLabel(wxT("...")); @@ -294,7 +291,7 @@ void GamepadPage::LoadDefaults(wxCommandEvent&) void ControlDialog::SetControl(wxCommandEvent&) { - control_reference->expression = STR_FROM_WXSTR(textctrl->GetValue()); + control_reference->expression = WxStrToStr(textctrl->GetValue()); std::lock_guard lk(m_plugin.controls_lock); g_controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); @@ -304,10 +301,10 @@ void ControlDialog::SetControl(wxCommandEvent&) void GamepadPage::SetDevice(wxCommandEvent&) { - controller->default_device.FromString(STR_FROM_WXSTR(device_cbox->GetValue())); + controller->default_device.FromString(WxStrToStr(device_cbox->GetValue())); // show user what it was validated as - device_cbox->SetValue(WXSTR_FROM_STR(controller->default_device.ToString())); + device_cbox->SetValue(StrToWxStr(controller->default_device.ToString())); // this will set all the controls to this default device controller->UpdateDefaultDevice(); @@ -319,10 +316,10 @@ void GamepadPage::SetDevice(wxCommandEvent&) void ControlDialog::SetDevice(wxCommandEvent&) { - m_devq.FromString(STR_FROM_WXSTR(device_cbox->GetValue())); + m_devq.FromString(WxStrToStr(device_cbox->GetValue())); // show user what it was validated as - device_cbox->SetValue(WXSTR_FROM_STR(m_devq.ToString())); + device_cbox->SetValue(StrToWxStr(m_devq.ToString())); // update gui UpdateListContents(); @@ -349,12 +346,12 @@ void ControlDialog::SetSelectedControl(wxCommandEvent&) // non-default device if (false == (m_devq == m_parent->controller->default_device)) - expr.append(wxT('`')).append(WXSTR_FROM_STR(m_devq.ToString())).append(wxT('`')); + expr.append(wxT('`')).append(StrToWxStr(m_devq.ToString())).append(wxT('`')); // append the control name expr += control_lbox->GetString(num); - control_reference->expression = STR_FROM_WXSTR(expr); + control_reference->expression = WxStrToStr(expr); std::lock_guard lk(m_plugin.controls_lock); g_controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); @@ -380,12 +377,12 @@ void ControlDialog::AppendControl(wxCommandEvent& event) // non-default device if (false == (m_devq == m_parent->controller->default_device)) - expr.append(wxT('`')).append(WXSTR_FROM_STR(m_devq.ToString())).append(wxT('`')); + expr.append(wxT('`')).append(StrToWxStr(m_devq.ToString())).append(wxT('`')); // append the control name expr += control_lbox->GetString(num); - control_reference->expression = STR_FROM_WXSTR(expr); + control_reference->expression = WxStrToStr(expr); std::lock_guard lk(m_plugin.controls_lock); g_controller_interface.UpdateReference(control_reference, m_parent->controller->default_device); @@ -475,7 +472,7 @@ void GamepadPage::DetectControl(wxCommandEvent& event) g_controller_interface.UpdateReference(btn->control_reference, controller->default_device); } - btn->SetLabel(WXSTR_FROM_STR(btn->control_reference->expression)); + btn->SetLabel(StrToWxStr(btn->control_reference->expression)); } } @@ -565,7 +562,7 @@ void GamepadPage::GetProfilePath(std::string& path) path += PROFILES_PATH; path += m_plugin.profile_name; path += '/'; - path += STR_FROM_WXSTR(profile_cbox->GetValue()); + path += WxStrToStr(profile_cbox->GetValue()); path += ".ini"; } } @@ -615,7 +612,7 @@ void GamepadPage::DeleteProfile(wxCommandEvent&) if (File::Exists(fnamecstr) && AskYesNoT("Are you sure you want to delete \"%s\"?", - STR_FROM_WXSTR(profile_cbox->GetValue()).c_str())) + WxStrToStr(profile_cbox->GetValue()).c_str())) { File::Delete(fnamecstr); @@ -637,9 +634,9 @@ void InputConfigDialog::UpdateDeviceComboBox() for (; di!=de; ++di) { dq.FromDevice(*di); - (*i)->device_cbox->Append(WXSTR_FROM_STR(dq.ToString())); + (*i)->device_cbox->Append(StrToWxStr(dq.ToString())); } - (*i)->device_cbox->SetValue(WXSTR_FROM_STR((*i)->controller->default_device.ToString())); + (*i)->device_cbox->SetValue(StrToWxStr((*i)->controller->default_device.ToString())); } } @@ -680,7 +677,7 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin for (; ci != ce; ++ci) { - wxStaticText* const label = new wxStaticText(parent, -1, WXTSTR_FROM_CSTR((*ci)->name)); + wxStaticText* const label = new wxStaticText(parent, -1, StrToWxStr((*ci)->name)); ControlButton* const control_button = new ControlButton(parent, (*ci)->control_ref, 80); control_button->SetFont(m_SmallFont); @@ -734,7 +731,7 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin PadSettingSpin* setting = new PadSettingSpin(parent, *i); setting->wxcontrol->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &GamepadPage::AdjustSetting, eventsink); options.push_back(setting); - szr->Add(new wxStaticText(parent, -1, WXTSTR_FROM_CSTR((*i)->name))); + szr->Add(new wxStaticText(parent, -1, StrToWxStr((*i)->name))); szr->Add(setting->wxcontrol, 0, wxLEFT, 0); } @@ -760,7 +757,7 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin options.push_back(threshold_cbox); wxBoxSizer* const szr = new wxBoxSizer(wxHORIZONTAL); - szr->Add(new wxStaticText(parent, -1, WXTSTR_FROM_CSTR(group->settings[0]->name)), + szr->Add(new wxStaticText(parent, -1, StrToWxStr(group->settings[0]->name)), 0, wxCENTER|wxRIGHT, 3); szr->Add(threshold_cbox->wxcontrol, 0, wxRIGHT, 3); @@ -795,7 +792,7 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin setting->wxcontrol->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &GamepadPage::AdjustSetting, eventsink); options.push_back(setting); wxBoxSizer* const szr = new wxBoxSizer(wxHORIZONTAL); - szr->Add(new wxStaticText(parent, -1, WXTSTR_FROM_CSTR((*i)->name)), 0, wxCENTER|wxRIGHT, 3); + szr->Add(new wxStaticText(parent, -1, StrToWxStr((*i)->name)), 0, wxCENTER|wxRIGHT, 3); szr->Add(setting->wxcontrol, 0, wxRIGHT, 3); Add(szr, 0, wxALL|wxCENTER, 3); } @@ -859,7 +856,7 @@ ControlGroupsSizer::ControlGroupsSizer(ControllerEmu* const controller, wxWindow { ControlGroupBox* control_group_box = new ControlGroupBox(controller->groups[i], parent, eventsink); wxStaticBoxSizer *control_group = - new wxStaticBoxSizer(wxVERTICAL, parent, WXTSTR_FROM_CSTR(controller->groups[i]->name)); + new wxStaticBoxSizer(wxVERTICAL, parent, StrToWxStr(controller->groups[i]->name)); control_group->Add(control_group_box); const size_t grp_size = controller->groups[i]->controls.size() + controller->groups[i]->settings.size(); @@ -955,7 +952,7 @@ GamepadPage::GamepadPage(wxWindow* parent, InputPlugin& plugin, const unsigned i InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin, const std::string& name, const int tab_num) - : wxDialog(parent, wxID_ANY, WXTSTR_FROM_CSTR(name.c_str()), wxPoint(128,-1), wxDefaultSize) + : wxDialog(parent, wxID_ANY, StrToWxStr(name.c_str()), wxPoint(128,-1), wxDefaultSize) , m_plugin(plugin) { m_pad_notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT); @@ -963,7 +960,7 @@ InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin { GamepadPage* gp = new GamepadPage(m_pad_notebook, m_plugin, i, this); m_padpages.push_back(gp); - m_pad_notebook->AddPage(gp, wxString::Format(wxT("%s %u"), WXTSTR_FROM_CSTR(m_plugin.gui_name), 1+i)); + m_pad_notebook->AddPage(gp, wxString::Format(wxT("%s %u"), StrToWxStr(m_plugin.gui_name), 1+i)); } m_pad_notebook->SetSelection(tab_num); diff --git a/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp b/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp index ff5ed3b9cd..4e07ed990d 100644 --- a/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp +++ b/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "InputConfigDiag.h" +#include "WxUtils.h" void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event)) { @@ -48,7 +49,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event)) // label for sticks and stuff if (64 == bitmap.GetHeight()) - dc.DrawText(wxString::FromAscii((*g)->control_group->name).Upper(), 4, 2); + dc.DrawText(StrToWxStr((*g)->control_group->name).Upper(), 4, 2); switch ( (*g)->control_group->type ) { @@ -227,7 +228,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event)) // text const char* const name = (*g)->control_group->controls[n]->name; // bit of hax so ZL, ZR show up as L, R - dc.DrawText(wxString::FromAscii((name[1] && name[1] < 'a') ? name[1] : name[0]), n*12 + 2, 1); + dc.DrawText(StrToWxStr((name[1] && name[1] < 'a') ? name[1] : name[0]), n*12 + 2, 1); } delete[] bitmasks; @@ -263,7 +264,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event)) dc.DrawRectangle(0, n*12, trigs[n], 14); // text - dc.DrawText(wxString::FromAscii((*g)->control_group->controls[n]->name), 3, n*12 + 1); + dc.DrawText(StrToWxStr((*g)->control_group->controls[n]->name), 3, n*12 + 1); } delete[] trigs; @@ -298,8 +299,8 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event)) dc.DrawRectangle(64, n*12, 32, 14); // text - dc.DrawText(wxString::FromAscii((*g)->control_group->controls[n+trigger_count]->name), 3, n*12 + 1); - dc.DrawText(wxString::FromAscii((*g)->control_group->controls[n]->name[0]), 64 + 3, n*12 + 1); + dc.DrawText(StrToWxStr((*g)->control_group->controls[n+trigger_count]->name), 3, n*12 + 1); + dc.DrawText(StrToWxStr((*g)->control_group->controls[n]->name[0]), 64 + 3, n*12 + 1); } // threshold box diff --git a/Source/Core/DolphinWX/Src/LogConfigWindow.cpp b/Source/Core/DolphinWX/Src/LogConfigWindow.cpp index 162647c64d..a4a5fa647a 100644 --- a/Source/Core/DolphinWX/Src/LogConfigWindow.cpp +++ b/Source/Core/DolphinWX/Src/LogConfigWindow.cpp @@ -20,6 +20,7 @@ #include "ConsoleListener.h" #include "LogWindow.h" #include "FileUtil.h" +#include "WxUtils.h" LogConfigWindow::LogConfigWindow(wxWindow* parent, CLogWindow *log_window, wxWindowID id) : wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("Log Configuration")) @@ -74,7 +75,7 @@ void LogConfigWindow::CreateGUIControls() m_checks = new wxCheckListBox(this, wxID_ANY); m_checks->Bind(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, &LogConfigWindow::OnLogCheck, this); for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) - m_checks->Append(wxString::FromAscii(m_LogManager->GetFullName((LogTypes::LOG_TYPE)i))); + m_checks->Append(StrToWxStr(m_LogManager->GetFullName((LogTypes::LOG_TYPE)i))); // Sizers wxStaticBoxSizer* sbOutputs = new wxStaticBoxSizer(wxVERTICAL, this, _("Logger Outputs")); diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index d9d1908de3..60a8157c28 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -32,6 +32,7 @@ #include "Host.h" // Core #include "HW/Wiimote.h" +#include "WxUtils.h" #include "Globals.h" // Local #include "Main.h" #include "ConfigManager.h" @@ -211,7 +212,7 @@ bool DolphinApp::OnInit() } #ifdef _WIN32 - if (!wxSetWorkingDirectory(wxString(File::GetExeDirectory().c_str(), *wxConvCurrent))) + if (!wxSetWorkingDirectory(StrToWxStr(File::GetExeDirectory()))) { INFO_LOG(CONSOLE, "set working directory failed"); } @@ -246,7 +247,7 @@ bool DolphinApp::OnInit() if (selectVideoBackend && videoBackendName != wxEmptyString) SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoBackend = - std::string(videoBackendName.mb_str()); + WxStrToStr(videoBackendName); if (selectAudioEmulation) { @@ -296,7 +297,7 @@ bool DolphinApp::OnInit() #endif main_frame = new CFrame((wxFrame*)NULL, wxID_ANY, - wxString::FromAscii(scm_rev_str), + StrToWxStr(scm_rev_str), wxPoint(x, y), wxSize(w, h), UseDebugger, BatchMode, UseLogger); SetTopWindow(main_frame); @@ -317,7 +318,7 @@ void DolphinApp::MacOpenFile(const wxString &fileName) LoadFile = true; if (m_afterinit == NULL) - main_frame->BootGame(std::string(FileToLoad.mb_str())); + main_frame->BootGame(WxStrToStr(FileToLoad)); } void DolphinApp::AfterInit(wxTimerEvent& WXUNUSED(event)) @@ -331,7 +332,7 @@ void DolphinApp::AfterInit(wxTimerEvent& WXUNUSED(event)) // First check if we have an exec command line. if (LoadFile && FileToLoad != wxEmptyString) { - main_frame->BootGame(std::string(FileToLoad.mb_str())); + main_frame->BootGame(WxStrToStr(FileToLoad)); } // If we have selected Automatic Start, start the default ISO, // or if no default ISO exists, start the last loaded ISO @@ -418,7 +419,7 @@ void Host_SysMessage(const char *fmt, ...) va_end(list); if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; - //wxMessageBox(wxString::FromAscii(msg)); + //wxMessageBox(StrToWxStr(msg)); PanicAlert("%s", msg); } @@ -427,14 +428,13 @@ bool wxMsgAlert(const char* caption, const char* text, bool yes_no, int /*Style* #ifdef __WXGTK__ if (wxIsMainThread()) #endif - return wxYES == wxMessageBox(wxString::FromUTF8(text), - wxString::FromUTF8(caption), + return wxYES == wxMessageBox(StrToWxStr(text), StrToWxStr(caption), (yes_no) ? wxYES_NO : wxOK, wxGetActiveWindow()); #ifdef __WXGTK__ else { wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_PANIC); - event.SetString(wxString::FromUTF8(caption) + wxT(":") + wxString::FromUTF8(text)); + event.SetString(StrToWxStr(caption) + wxT(":") + StrToWxStr(text)); event.SetInt(yes_no); main_frame->GetEventHandler()->AddPendingEvent(event); main_frame->panic_event.Wait(); @@ -445,7 +445,7 @@ bool wxMsgAlert(const char* caption, const char* text, bool yes_no, int /*Style* std::string wxStringTranslator(const char *text) { - return (const char *)wxString(wxGetTranslation(wxString::From8BitData(text))).ToUTF8(); + return WxStrToStr(wxGetTranslation(wxString::From8BitData(text))); } // Accessor for the main window class @@ -536,7 +536,7 @@ void Host_UpdateMainFrame() void Host_UpdateTitle(const char* title) { wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATETITLE); - event.SetString(wxString::FromAscii(title)); + event.SetString(StrToWxStr(title)); main_frame->GetEventHandler()->AddPendingEvent(event); } @@ -603,7 +603,7 @@ void Host_UpdateStatusBar(const char* _pText, int Field) { wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATESTATUSBAR); // Set the event string - event.SetString(wxString::FromAscii(_pText)); + event.SetString(StrToWxStr(_pText)); // Update statusbar field event.SetInt(Field); // Post message diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp index b3a7ab22b8..d9fd4d3ae6 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.cpp +++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp @@ -17,6 +17,8 @@ #include "MemcardManager.h" #include "Common.h" + +#include "WxUtils.h" #include "wx/mstream.h" #define ARROWS slot ? _T("") : ARROW[slot], slot ? ARROW[slot] : _T("") @@ -290,7 +292,7 @@ void CMemcardManager::ChangePath(int slot) } else { - if (m_MemcardPath[slot]->GetPath().length() && ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot)) + if (m_MemcardPath[slot]->GetPath().length() && ReloadMemcard(WxStrToStr(m_MemcardPath[slot]->GetPath()).c_str(), slot)) { if (memoryCard[slot2]) { @@ -345,7 +347,7 @@ void CMemcardManager::OnPageChange(wxCommandEvent& event) m_NextPage[slot]->Disable(); m_MemcardList[slot]->nextPage = false; } - ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot); + ReloadMemcard(WxStrToStr(m_MemcardPath[slot]->GetPath()).c_str(), slot); break; case ID_PREVPAGE_A: slot = SLOT_A; @@ -361,7 +363,7 @@ void CMemcardManager::OnPageChange(wxCommandEvent& event) m_PrevPage[slot]->Disable(); m_MemcardList[slot]->prevPage = false; } - ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot); + ReloadMemcard(WxStrToStr(m_MemcardPath[slot]->GetPath()).c_str(), slot); break; } } @@ -373,7 +375,7 @@ void CMemcardManager::OnMenuChange(wxCommandEvent& event) { case ID_MEMCARDPATH_A: case ID_MEMCARDPATH_B: - DefaultMemcard[_id - ID_MEMCARDPATH_A] = m_MemcardPath[_id - ID_MEMCARDPATH_A]->GetPath().mb_str(); + DefaultMemcard[_id - ID_MEMCARDPATH_A] = WxStrToStr(m_MemcardPath[_id - ID_MEMCARDPATH_A]->GetPath()); return; case ID_USEPAGES: mcmSettings.usePages = !mcmSettings.usePages; @@ -400,8 +402,8 @@ void CMemcardManager::OnMenuChange(wxCommandEvent& event) break; } - if (memoryCard[SLOT_A]) ReloadMemcard(m_MemcardPath[SLOT_A]->GetPath().mb_str(), SLOT_A); - if (memoryCard[SLOT_B]) ReloadMemcard(m_MemcardPath[SLOT_B]->GetPath().mb_str(), SLOT_B); + if (memoryCard[SLOT_A]) ReloadMemcard(WxStrToStr(m_MemcardPath[SLOT_A]->GetPath()).c_str(), SLOT_A); + if (memoryCard[SLOT_B]) ReloadMemcard(WxStrToStr(m_MemcardPath[SLOT_B]->GetPath()).c_str(), SLOT_B); } bool CMemcardManager::CopyDeleteSwitch(u32 error, int slot) { @@ -416,7 +418,7 @@ bool CMemcardManager::CopyDeleteSwitch(u32 error, int slot) memoryCard[slot]->FixChecksums(); if (!memoryCard[slot]->Save()) PanicAlert(E_SAVEFAILED); page[slot] = FIRSTPAGE; - ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot); + ReloadMemcard(WxStrToStr(m_MemcardPath[slot]->GetPath()).c_str(), slot); } break; case NOMEMCARD: @@ -517,7 +519,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) wxString fileName = wxFileSelector( _("Select a save file to import"), (strcmp(DefaultIOPath.c_str(), "/Users/GC") == 0) - ? wxString::FromAscii("") + ? StrToWxStr("") : wxString::From8BitData(DefaultIOPath.c_str()), wxEmptyString, wxEmptyString, _("GameCube Savegame files(*.gci;*.gcs;*.sav)") + wxString(wxT("|*.gci;*.gcs;*.sav|")) + @@ -532,11 +534,11 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) _("GCI File(*.gci)") + wxString(_T("|*.gci")), wxFD_OVERWRITE_PROMPT|wxFD_SAVE, this); if (temp2.empty()) break; - fileName2 = temp2.mb_str(); + fileName2 = WxStrToStr(temp2); } if (fileName.length() > 0) { - CopyDeleteSwitch(memoryCard[slot]->ImportGci(fileName.mb_str(), fileName2), slot); + CopyDeleteSwitch(memoryCard[slot]->ImportGci(WxStrToStr(fileName).c_str(), fileName2), slot); } } break; @@ -564,9 +566,9 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) if (fileName.length() > 0) { - if (!CopyDeleteSwitch(memoryCard[slot]->ExportGci(index, fileName.mb_str(), ""), -1)) + if (!CopyDeleteSwitch(memoryCard[slot]->ExportGci(index, WxStrToStr(fileName).c_str(), ""), -1)) { - File::Delete(std::string(fileName.mb_str())); + File::Delete(WxStrToStr(fileName)); } } } @@ -576,7 +578,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) case ID_EXPORTALL_B: { std::string path1, path2, mpath; - mpath = m_MemcardPath[slot]->GetPath().mb_str(); + mpath = WxStrToStr(m_MemcardPath[slot]->GetPath()); SplitPath(mpath, &path1, &path2, NULL); path1 += path2; File::CreateDir(path1); diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 142a7ea00c..d9fd5e6ca0 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -18,6 +18,7 @@ #include #include +#include "WxUtils.h" #include "NetPlay.h" #include "NetWindow.h" #include "Frame.h" @@ -72,7 +73,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* std::string address; netplay_section.Get("Address", &address, "localhost"); - m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, wxString::FromAscii(address.c_str())); + m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(address.c_str())); wxStaticText* const port_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Port :"), wxDefaultPosition, wxDefaultSize); @@ -80,7 +81,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* // string? w/e std::string port; netplay_section.Get("ConnectPort", &port, "2626"); - m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, wxString::FromAscii(port.c_str())); + m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(port.c_str())); wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, _("Connect")); connect_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlaySetupDiag::OnJoin, this); @@ -113,7 +114,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* // string? w/e std::string port; netplay_section.Get("HostPort", &port, "2626"); - m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, wxString::FromAscii(port.c_str())); + m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, StrToWxStr(port.c_str())); wxButton* const host_btn = new wxButton(host_tab, wxID_ANY, _("Host")); host_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlaySetupDiag::OnHost, this); @@ -124,7 +125,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* std::istringstream ss(game_list->GetGameNames()); std::string game; while (std::getline(ss,game)) - m_game_lbox->Append(wxString(game.c_str(), *wxConvCurrent)); + m_game_lbox->Append(StrToWxStr(game)); wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL); top_szr->Add(port_lbl, 0, wxCENTER | wxRIGHT, 5); @@ -167,10 +168,10 @@ NetPlaySetupDiag::~NetPlaySetupDiag() inifile.Load(dolphin_ini); IniFile::Section& netplay_section = *inifile.GetOrCreateSection("NetPlay"); - netplay_section.Set("Nickname", m_nickname_text->GetValue().mb_str()); - netplay_section.Set("Address", m_connect_ip_text->GetValue().mb_str()); - netplay_section.Set("ConnectPort", m_connect_port_text->GetValue().mb_str()); - netplay_section.Set("HostPort", m_host_port_text->GetValue().mb_str()); + netplay_section.Set("Nickname", WxStrToStr(m_nickname_text->GetValue())); + netplay_section.Set("Address", WxStrToStr(m_connect_ip_text->GetValue())); + netplay_section.Set("ConnectPort", WxStrToStr(m_connect_port_text->GetValue())); + netplay_section.Set("HostPort", WxStrToStr(m_host_port_text->GetValue())); inifile.Save(dolphin_ini); main_frame->g_NetPlaySetupDiag = NULL; @@ -191,13 +192,13 @@ void NetPlaySetupDiag::OnHost(wxCommandEvent&) return; } - std::string game(m_game_lbox->GetStringSelection().mb_str()); + std::string game(WxStrToStr(m_game_lbox->GetStringSelection())); npd = new NetPlayDiag(m_parent, m_game_list, game, true); unsigned long port = 0; m_host_port_text->GetValue().ToULong(&port); netplay_ptr = new NetPlayServer(u16(port) - , std::string(m_nickname_text->GetValue().mb_str()), npd, game); + , WxStrToStr(m_nickname_text->GetValue()), npd, game); if (netplay_ptr->is_connected) { npd->Show(); @@ -222,8 +223,8 @@ void NetPlaySetupDiag::OnJoin(wxCommandEvent&) npd = new NetPlayDiag(m_parent, m_game_list, ""); unsigned long port = 0; m_connect_port_text->GetValue().ToULong(&port); - netplay_ptr = new NetPlayClient(std::string(m_connect_ip_text->GetValue().mb_str()) - , (u16)port, npd, std::string(m_nickname_text->GetValue().mb_str())); + netplay_ptr = new NetPlayClient(WxStrToStr(m_connect_ip_text->GetValue()) + , (u16)port, npd, WxStrToStr(m_nickname_text->GetValue())); if (netplay_ptr->is_connected) { npd->Show(); @@ -250,7 +251,7 @@ NetPlayDiag::NetPlayDiag(wxWindow* const parent, const CGameListCtrl* const game // top crap m_game_btn = new wxButton(panel, wxID_ANY, - wxString(m_selected_game.c_str(), *wxConvCurrent).Prepend(_(" Game : ")), + StrToWxStr(m_selected_game).Prepend(_(" Game : ")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT); if (is_hosting) @@ -351,7 +352,7 @@ void NetPlayDiag::OnChat(wxCommandEvent&) if (s.Length()) { - netplay_ptr->SendChatMessage(std::string(s.mb_str())); + netplay_ptr->SendChatMessage(WxStrToStr(s)); m_chat_text->AppendText(s.Prepend(wxT(" >> ")).Append(wxT('\n'))); m_chat_msg_text->Clear(); } @@ -412,7 +413,7 @@ void NetPlayDiag::OnMsgChangeGame(const std::string& filename) { wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_CHANGE_GAME); // TODO: using a wxString in AddPendingEvent from another thread is unsafe i guess? - evt.SetString(wxString(filename.c_str(), *wxConvCurrent)); + evt.SetString(StrToWxStr(filename)); GetEventHandler()->AddPendingEvent(evt); } @@ -436,7 +437,7 @@ void NetPlayDiag::OnPadBuffHelp(wxCommandEvent&) << time * (60.0f/1000) << "(60fps) / " << time * (50.0f/1000) << "(50fps) >\n"; - m_chat_text->AppendText(wxString(ss.str().c_str(), *wxConvCurrent)); + m_chat_text->AppendText(StrToWxStr(ss.str())); } void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event) @@ -447,7 +448,7 @@ void NetPlayDiag::OnAdjustBuffer(wxCommandEvent& event) std::ostringstream ss; ss << "< Pad Buffer: " << val << " >"; netplay_ptr->SendChatMessage(ss.str()); - m_chat_text->AppendText(wxString(ss.str().c_str(), *wxConvCurrent).Append(wxT('\n'))); + m_chat_text->AppendText(StrToWxStr(ss.str()).Append(wxT('\n'))); } void NetPlayDiag::OnQuit(wxCommandEvent&) @@ -468,7 +469,7 @@ void NetPlayDiag::OnThread(wxCommandEvent& event) m_player_lbox->Clear(); std::istringstream ss(tmps); while (std::getline(ss, tmps)) - m_player_lbox->Append(wxString(tmps.c_str(), *wxConvCurrent)); + m_player_lbox->Append(StrToWxStr(tmps)); m_player_lbox->SetSelection(selection); @@ -477,7 +478,7 @@ void NetPlayDiag::OnThread(wxCommandEvent& event) case NP_GUI_EVT_CHANGE_GAME : // update selected game :/ { - m_selected_game.assign(event.GetString().mb_str()); + m_selected_game.assign(WxStrToStr(event.GetString())); m_game_btn->SetLabel(event.GetString().Prepend(_(" Game : "))); } break; @@ -503,7 +504,7 @@ void NetPlayDiag::OnThread(wxCommandEvent& event) std::string s; chat_msgs.Pop(s); //PanicAlert("message: %s", s.c_str()); - m_chat_text->AppendText(wxString(s.c_str(), *wxConvCurrent).Append(wxT('\n'))); + m_chat_text->AppendText(StrToWxStr(s).Append(wxT('\n'))); } } @@ -515,7 +516,7 @@ void NetPlayDiag::OnChangeGame(wxCommandEvent&) if (game_name.length()) { - m_selected_game = std::string(game_name.mb_str()); + m_selected_game = WxStrToStr(game_name); netplay_ptr->ChangeGame(m_selected_game); m_game_btn->SetLabel(game_name.Prepend(_(" Game : "))); } @@ -553,7 +554,7 @@ ChangeGameDiag::ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* cons std::istringstream ss(game_list->GetGameNames()); std::string game; while (std::getline(ss,game)) - m_game_lbox->Append(wxString(game.c_str(), *wxConvCurrent)); + m_game_lbox->Append(StrToWxStr(game)); wxButton* const ok_btn = new wxButton(this, wxID_OK, _("Change")); ok_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ChangeGameDiag::OnPick, this); diff --git a/Source/Core/DolphinWX/Src/PHackSettings.cpp b/Source/Core/DolphinWX/Src/PHackSettings.cpp index 83f08d9cb7..dcfa1a8501 100644 --- a/Source/Core/DolphinWX/Src/PHackSettings.cpp +++ b/Source/Core/DolphinWX/Src/PHackSettings.cpp @@ -17,6 +17,7 @@ #include "PHackSettings.h" #include "ConfigManager.h" +#include "WxUtils.h" extern PHackData PHack_Data; @@ -97,8 +98,8 @@ void CPHackSettings::LoadPHackData() if (sTemp.empty()) sTemp = wxString(_("(UNKNOWN)")).char_str(); if (i == 0) - PHackChoice->Append(wxString("-------------", *wxConvCurrent)); - PHackChoice->Append(wxString(sTemp.c_str(), *wxConvCurrent)); + PHackChoice->Append(StrToWxStr("-------------")); + PHackChoice->Append(StrToWxStr(sTemp)); } PHackChoice->Select(0); @@ -106,8 +107,8 @@ void CPHackSettings::LoadPHackData() PHackSZFar->Set3StateValue((wxCheckBoxState)PHack_Data.PHackSZFar); PHackExP->Set3StateValue((wxCheckBoxState)PHack_Data.PHackExP); - PHackZNear->SetValue(wxString(PHack_Data.PHZNear.c_str(), *wxConvCurrent)); - PHackZFar->SetValue(wxString(PHack_Data.PHZFar.c_str(), *wxConvCurrent)); + PHackZNear->SetValue(StrToWxStr(PHack_Data.PHZNear)); + PHackZFar->SetValue(StrToWxStr(PHack_Data.PHZFar)); } void CPHackSettings::SetRefresh(wxCommandEvent& event) @@ -128,9 +129,9 @@ void CPHackSettings::SetRefresh(wxCommandEvent& event) PHPresetsIni.Get(sIndex, "PH_ExtraParam", &bTemp); PHackExP->Set3StateValue((wxCheckBoxState)bTemp); PHPresetsIni.Get(sIndex, "PH_ZNear", &sTemp); - PHackZNear->SetValue(wxString(sTemp.c_str(), *wxConvCurrent)); + PHackZNear->SetValue(StrToWxStr(sTemp)); PHPresetsIni.Get(sIndex, "PH_ZFar", &sTemp); - PHackZFar->SetValue(wxString(sTemp.c_str(), *wxConvCurrent)); + PHackZFar->SetValue(StrToWxStr(sTemp)); } } diff --git a/Source/Core/DolphinWX/Src/PatchAddEdit.cpp b/Source/Core/DolphinWX/Src/PatchAddEdit.cpp index 7d521006d3..3199240d74 100644 --- a/Source/Core/DolphinWX/Src/PatchAddEdit.cpp +++ b/Source/Core/DolphinWX/Src/PatchAddEdit.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "PatchAddEdit.h" +#include "WxUtils.h" extern std::vector onFrame; @@ -48,7 +49,7 @@ void CPatchAddEdit::CreateGUIControls(int _selection) } else { - currentName = wxString(onFrame.at(_selection).name.c_str(), *wxConvCurrent); + currentName = StrToWxStr(onFrame.at(_selection).name.c_str()); tempEntries = onFrame.at(_selection).entries; } @@ -66,7 +67,7 @@ void CPatchAddEdit::CreateGUIControls(int _selection) EntrySelection->SetValue((int)tempEntries.size()-1); wxArrayString wxArrayStringFor_EditPatchType; for (int i = 0; i < 3; ++i) - wxArrayStringFor_EditPatchType.Add(wxString::FromAscii(PatchEngine::PatchTypeStrings[i])); + wxArrayStringFor_EditPatchType.Add(StrToWxStr(PatchEngine::PatchTypeStrings[i])); EditPatchType = new wxRadioBox(this, ID_EDITPATCH_TYPE, _("Type"), wxDefaultPosition, wxDefaultSize, wxArrayStringFor_EditPatchType, 3, wxRA_SPECIFY_COLS); EditPatchType->SetSelection((int)tempEntries.at(0).type); wxStaticText* EditPatchValueText = new wxStaticText(this, ID_EDITPATCH_VALUE_TEXT, _("Value:")); @@ -121,7 +122,7 @@ void CPatchAddEdit::SavePatchData(wxCommandEvent& event) if (selection == -1) { PatchEngine::Patch newPatch; - newPatch.name = std::string(EditPatchName->GetValue().mb_str()); + newPatch.name = WxStrToStr(EditPatchName->GetValue()); newPatch.entries = tempEntries; newPatch.active = true; @@ -129,7 +130,7 @@ void CPatchAddEdit::SavePatchData(wxCommandEvent& event) } else { - onFrame.at(selection).name = std::string(EditPatchName->GetValue().mb_str()); + onFrame.at(selection).name = WxStrToStr(EditPatchName->GetValue()); onFrame.at(selection).entries = tempEntries; } diff --git a/Source/Core/DolphinWX/Src/UDPConfigDiag.cpp b/Source/Core/DolphinWX/Src/UDPConfigDiag.cpp index 2f31311495..9619f38dee 100644 --- a/Source/Core/DolphinWX/Src/UDPConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/UDPConfigDiag.cpp @@ -4,6 +4,8 @@ #include "Common.h" #include "ControllerEmu.h" #include "IniFile.h" +#include "WxUtils.h" + #include UDPConfigDiag::UDPConfigDiag(wxWindow * const parent, UDPWrapper * _wrp) : @@ -26,7 +28,7 @@ UDPConfigDiag::UDPConfigDiag(wxWindow * const parent, UDPWrapper * _wrp) : wxBoxSizer *const port_sizer = new wxBoxSizer(wxHORIZONTAL); port_sizer->Add(new wxStaticText(this, wxID_ANY, _("UDP Port:")), 0, wxALIGN_CENTER); - port_tbox = new wxTextCtrl(this, wxID_ANY, wxString::FromUTF8(wrp->port.c_str())); + port_tbox = new wxTextCtrl(this, wxID_ANY, StrToWxStr(wrp->port)); port_sizer->Add(port_tbox, 1, wxLEFT | wxEXPAND, 5); enable->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &UDPConfigDiag::ChangeState, this); @@ -71,7 +73,7 @@ void UDPConfigDiag::ChangeUpdateFlags(wxCommandEvent & WXUNUSED(event)) void UDPConfigDiag::ChangeState(wxCommandEvent & WXUNUSED(event)) { - wrp->udpEn=enable->GetValue(); - wrp->port=port_tbox->GetValue().mb_str(wxConvUTF8); + wrp->udpEn = enable->GetValue(); + wrp->port = WxStrToStr(port_tbox->GetValue()); wrp->Refresh(); } diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 0ca4715c3d..7c8a3b7e04 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -141,7 +141,7 @@ wxArrayString GetListOfResolutions() if (std::find(resos.begin(), resos.end(), strRes) == resos.end()) { resos.push_back(strRes); - retlist.Add(wxString::FromAscii(res)); + retlist.Add(StrToWxStr(res)); } ZeroMemory(&dmi, sizeof(dmi)); } @@ -212,9 +212,9 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = g_available_video_backends.begin(), itend = g_available_video_backends.end(); for (; it != itend; ++it) - choice_backend->AppendString(wxGetTranslation(wxString::FromAscii((*it)->GetName().c_str()))); + choice_backend->AppendString(wxGetTranslation(StrToWxStr((*it)->GetName().c_str()))); - choice_backend->SetStringSelection(wxGetTranslation(wxString::FromAscii(g_video_backend->GetName().c_str()))); + choice_backend->SetStringSelection(wxGetTranslation(StrToWxStr(g_video_backend->GetName().c_str()))); choice_backend->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &VideoConfigDiag::Event_Backend, this); szr_basic->Add(label_backend, 1, wxALIGN_CENTER_VERTICAL, 5); @@ -236,7 +236,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = vconfig.backend_info.Adapters.begin(), itend = vconfig.backend_info.Adapters.end(); for (; it != itend; ++it) - choice_adapter->AppendString(wxString::FromAscii(it->c_str())); + choice_adapter->AppendString(StrToWxStr(it->c_str())); choice_adapter->Select(vconfig.iAdapter); @@ -259,7 +259,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con RegisterControl(choice_display_resolution, wxGetTranslation(display_res_desc)); choice_display_resolution->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &VideoConfigDiag::Event_DisplayResolution, this); - choice_display_resolution->SetStringSelection(wxString::FromAscii(SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution.c_str())); + choice_display_resolution->SetStringSelection(StrToWxStr(SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution.c_str())); szr_display->Add(label_display_resolution, 1, wxALIGN_CENTER_VERTICAL, 0); szr_display->Add(choice_display_resolution); @@ -355,7 +355,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = vconfig.backend_info.AAModes.begin(), itend = vconfig.backend_info.AAModes.end(); for (; it != itend; ++it) - choice_aamode->AppendString(wxGetTranslation(wxString::FromAscii(it->c_str()))); + choice_aamode->AppendString(wxGetTranslation(StrToWxStr(it->c_str()))); choice_aamode->Select(vconfig.iMultisampleMode); szr_enh->Add(text_aamode, 1, wxALIGN_CENTER_VERTICAL, 0); @@ -380,12 +380,12 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = vconfig.backend_info.PPShaders.begin(), itend = vconfig.backend_info.PPShaders.end(); for (; it != itend; ++it) - choice_ppshader->AppendString(wxString::FromAscii(it->c_str())); + choice_ppshader->AppendString(StrToWxStr(it->c_str())); if (vconfig.sPostProcessingShader.empty()) choice_ppshader->Select(0); else - choice_ppshader->SetStringSelection(wxString::FromAscii(vconfig.sPostProcessingShader.c_str())); + choice_ppshader->SetStringSelection(StrToWxStr(vconfig.sPostProcessingShader.c_str())); choice_ppshader->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &VideoConfigDiag::Event_PPShader, this); @@ -595,7 +595,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con void VideoConfigDiag::Event_DisplayResolution(wxCommandEvent &ev) { SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution = - choice_display_resolution->GetStringSelection().mb_str(); + WxStrToStr(choice_display_resolution->GetStringSelection()); #if defined(HAVE_XRANDR) && HAVE_XRANDR main_frame->m_XRRConfig->Update(); #endif diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.h b/Source/Core/DolphinWX/Src/VideoConfigDiag.h index c7a19c6cb8..8507fffdc1 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.h +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.h @@ -20,6 +20,7 @@ #include #include "MsgHandler.h" +#include "WxUtils.h" template class BoolSetting : public W @@ -99,7 +100,7 @@ protected: else { // Select current backend again - choice_backend->SetStringSelection(wxString::FromAscii(g_video_backend->GetName().c_str())); + choice_backend->SetStringSelection(StrToWxStr(g_video_backend->GetName().c_str())); } } @@ -129,7 +130,7 @@ protected: { const int sel = ev.GetInt(); if (sel) - vconfig.sPostProcessingShader = ev.GetString().mb_str(); + vconfig.sPostProcessingShader = WxStrToStr(ev.GetString()); else vconfig.sPostProcessingShader.clear(); diff --git a/Source/Core/DolphinWX/Src/WxUtils.cpp b/Source/Core/DolphinWX/Src/WxUtils.cpp index 22fa10b84d..ee6f815648 100644 --- a/Source/Core/DolphinWX/Src/WxUtils.cpp +++ b/Source/Core/DolphinWX/Src/WxUtils.cpp @@ -20,12 +20,14 @@ #include #include +#include "WxUtils.h" + namespace WxUtils { // Launch a file according to its mime type void Launch(const char *filename) { - if (! ::wxLaunchDefaultBrowser(wxString(filename, *wxConvCurrent))) + if (! ::wxLaunchDefaultBrowser(StrToWxStr(filename))) { // WARN_LOG } @@ -34,7 +36,7 @@ void Launch(const char *filename) // Launch an file explorer window on a certain path void Explore(const char *path) { - wxString wxPath = wxString(path, *wxConvCurrent); + wxString wxPath = StrToWxStr(path); // Default to file if (! wxPath.Contains(wxT("://"))) { @@ -52,3 +54,13 @@ void Explore(const char *path) } } // namespace + +std::string WxStrToStr(const wxString& str) +{ + return str.ToUTF8(); +} + +wxString StrToWxStr(const std::string& str) +{ + return wxString::FromUTF8(str.c_str()); +} diff --git a/Source/Core/DolphinWX/Src/WxUtils.h b/Source/Core/DolphinWX/Src/WxUtils.h index 8e837e9e96..61a16b298e 100644 --- a/Source/Core/DolphinWX/Src/WxUtils.h +++ b/Source/Core/DolphinWX/Src/WxUtils.h @@ -18,7 +18,11 @@ #ifndef WXUTILS_H #define WXUTILS_H -namespace WxUtils { +#include +#include + +namespace WxUtils +{ // Launch a file according to its mime type void Launch(const char *filename); @@ -28,4 +32,7 @@ void Explore(const char *path); } // namespace +std::string WxStrToStr(const wxString& str); +wxString StrToWxStr(const std::string& str); + #endif // WXUTILS diff --git a/Source/Core/DolphinWX/Src/X11Utils.cpp b/Source/Core/DolphinWX/Src/X11Utils.cpp index f032f81e96..3582b9b576 100644 --- a/Source/Core/DolphinWX/Src/X11Utils.cpp +++ b/Source/Core/DolphinWX/Src/X11Utils.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "X11Utils.h" +#include "WxUtils.h" #include #include @@ -350,7 +351,7 @@ void XRRConfiguration::AddResolutions(wxArrayString& arrayStringFor_FullscreenRe if (std::find(resos.begin(), resos.end(), strRes) == resos.end()) { resos.push_back(strRes); - arrayStringFor_FullscreenResolution.Add(wxString::FromUTF8(strRes.c_str())); + arrayStringFor_FullscreenResolution.Add(StrToWxStr(strRes)); } } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index b5393cdbde..d0bb94a39a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -24,6 +24,7 @@ #include #include "GLUtil.h" +#include "WxUtils.h" #include "FileUtil.h" @@ -1538,7 +1539,7 @@ void TakeScreenshot(ScrStrct* threadStruct) // Save the screenshot and finally kill the wxImage object // This is really expensive when saving to PNG, but not at all when using BMP - threadStruct->img->SaveFile(wxString::FromAscii(threadStruct->filename.c_str()), + threadStruct->img->SaveFile(StrToWxStr(threadStruct->filename.c_str()), wxBITMAP_TYPE_PNG); threadStruct->img->Destroy(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp index bd085a3edf..670c3f9c6d 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp @@ -34,7 +34,7 @@ IntegerSetting::IntegerSetting(wxWindow* parent, const wxString& label, T& se VideoConfigDialog::VideoConfigDialog(wxWindow* parent, const std::string& title, const std::string& _ininame) : wxDialog(parent, -1, - wxString(wxT("Dolphin ")).append(wxString::FromAscii(title.c_str())).append(wxT(" Graphics Configuration")), + wxString(wxT("Dolphin ")).append(StrToWxStr(title.c_str())).append(wxT(" Graphics Configuration")), wxDefaultPosition, wxDefaultSize), vconfig(g_SWVideoConfig), ininame(_ininame) @@ -64,10 +64,10 @@ VideoConfigDialog::VideoConfigDialog(wxWindow* parent, const std::string& title, it = g_available_video_backends.begin(), itend = g_available_video_backends.end(); for (; it != itend; ++it) - choice_backend->AppendString(wxString::FromAscii((*it)->GetName().c_str())); + choice_backend->AppendString(StrToWxStr((*it)->GetName())); // TODO: How to get the translated plugin name? - choice_backend->SetStringSelection(wxString::FromAscii(g_video_backend->GetName().c_str())); + choice_backend->SetStringSelection(StrToWxStr(g_video_backend->GetName())); choice_backend->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &VideoConfigDialog::Event_Backend, this); szr_rendering->Add(label_backend, 1, wxALIGN_CENTER_VERTICAL, 5); From 03ec9a2e088b0818bf02a5bc2ffda4a512cba2b7 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 28 Feb 2013 02:39:06 -0600 Subject: [PATCH 113/167] Kill some unnecessary c_str and use StrToWxStr in a few places that I missed. --- Source/Core/DolphinWX/Src/AboutDolphin.cpp | 2 +- Source/Core/DolphinWX/Src/CheatsWindow.cpp | 2 +- Source/Core/DolphinWX/Src/ConfigMain.cpp | 9 +++++---- Source/Core/DolphinWX/Src/Debugger/CodeView.cpp | 4 ++-- .../Core/DolphinWX/Src/Debugger/CodeWindow.cpp | 2 +- .../Src/Debugger/CodeWindowFunctions.cpp | 4 ++-- .../DolphinWX/Src/Debugger/DSPDebugWindow.cpp | 2 +- Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp | 16 ++++++++-------- Source/Core/DolphinWX/Src/FrameAui.cpp | 4 ++-- Source/Core/DolphinWX/Src/FrameTools.cpp | 2 +- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 10 +++++----- Source/Core/DolphinWX/Src/ISOProperties.cpp | 8 ++++---- Source/Core/DolphinWX/Src/InputConfigDiag.cpp | 8 ++++---- .../DolphinWX/Src/InputConfigDiagBitmaps.cpp | 4 ++-- Source/Core/DolphinWX/Src/NetWindow.cpp | 6 +++--- Source/Core/DolphinWX/Src/PatchAddEdit.cpp | 2 +- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 14 +++++++------- Source/Core/DolphinWX/Src/VideoConfigDiag.h | 2 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 2 +- .../Src/VideoConfigDialog.cpp | 2 +- 20 files changed, 53 insertions(+), 52 deletions(-) diff --git a/Source/Core/DolphinWX/Src/AboutDolphin.cpp b/Source/Core/DolphinWX/Src/AboutDolphin.cpp index eeecf18d48..5126274601 100644 --- a/Source/Core/DolphinWX/Src/AboutDolphin.cpp +++ b/Source/Core/DolphinWX/Src/AboutDolphin.cpp @@ -63,7 +63,7 @@ AboutDolphin::AboutDolphin(wxWindow *parent, wxWindowID id, "and should not be used to play games you do\n" "not legally own."; wxStaticText* const Message = new wxStaticText(this, wxID_ANY, - StrToWxStr(Text.c_str())); + StrToWxStr(Text)); Message->Wrap(GetSize().GetWidth()); wxBoxSizer* const sInfo = new wxBoxSizer(wxVERTICAL); diff --git a/Source/Core/DolphinWX/Src/CheatsWindow.cpp b/Source/Core/DolphinWX/Src/CheatsWindow.cpp index 1e0f714467..fb3c3cbb23 100644 --- a/Source/Core/DolphinWX/Src/CheatsWindow.cpp +++ b/Source/Core/DolphinWX/Src/CheatsWindow.cpp @@ -348,7 +348,7 @@ void wxCheatsWindow::OnEvent_ButtonUpdateLog_Press(wxCommandEvent& WXUNUSED (eve const std::vector &arLog = ActionReplay::GetSelfLog(); for (u32 i = 0; i < arLog.size(); i++) { - m_TextCtrl_Log->AppendText(StrToWxStr(arLog[i].c_str())); + m_TextCtrl_Log->AppendText(StrToWxStr(arLog[i])); } } diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index bdb4cdc7fe..068501c432 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -982,9 +982,9 @@ void CConfigMain::AddAudioBackends() for (std::vector::const_iterator iter = backends.begin(); iter != backends.end(); ++iter) { - BackendSelection->Append(StrToWxStr((*iter).c_str())); + BackendSelection->Append(StrToWxStr(*iter)); int num = BackendSelection->\ - FindString(StrToWxStr(SConfig::GetInstance().sBackend.c_str())); + FindString(StrToWxStr(SConfig::GetInstance().sBackend)); BackendSelection->SetSelection(num); } } @@ -1269,8 +1269,9 @@ void CConfigMain::ApploaderPathChanged(wxFileDirPickerEvent& WXUNUSED (event)) void CConfigMain::NANDRootChanged(wxFileDirPickerEvent& WXUNUSED (event)) { std::string NANDPath = - SConfig::GetInstance().m_NANDPath = File::GetUserPath(D_WIIROOT_IDX, WxStrToStr(NANDRoot->GetPath())); - NANDRoot->SetPath(wxString(NANDPath)); + SConfig::GetInstance().m_NANDPath = + File::GetUserPath(D_WIIROOT_IDX, WxStrToStr(NANDRoot->GetPath())); + NANDRoot->SetPath(StrToWxStr(NANDPath)); SConfig::GetInstance().m_SYSCONF->UpdateLocation(); DiscIO::cUIDsys::AccessInstance().UpdateLocation(); DiscIO::CSharedContent::AccessInstance().UpdateLocation(); diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp index 3b22ca339d..31ad19d6da 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeView.cpp @@ -253,7 +253,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) debugger->disasm(addr, disasm, 256); text = text + StringFromFormat("%08x: ", addr) + disasm + "\r\n"; } - wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(text.c_str()))); + wxTheClipboard->SetData(new wxTextDataObject(StrToWxStr(text))); } } break; @@ -300,7 +300,7 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) { wxTextEntryDialog input_symbol(this, StrToWxStr("Rename symbol:"), wxGetTextFromUserPromptStr, - StrToWxStr(symbol->name.c_str())); + StrToWxStr(symbol->name)); if (input_symbol.ShowModal() == wxID_OK) { symbol->name = WxStrToStr(input_symbol.GetValue()); diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp index 1cff07c0f4..9172a3af9a 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindow.cpp @@ -345,7 +345,7 @@ void CCodeWindow::UpdateCallstack() for (size_t i = 0; i < stack.size(); i++) { - int idx = callstack->Append(StrToWxStr(stack[i].Name.c_str())); + int idx = callstack->Append(StrToWxStr(stack[i].Name)); callstack->SetClientData(idx, (void*)(u64)stack[i].vAddress); } diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp index a11783c010..7ec36131ff 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp @@ -66,7 +66,7 @@ void CCodeWindow::Load() std::string fontDesc; ini.Get("General", "DebuggerFont", &fontDesc); if (!fontDesc.empty()) - DebuggerFont.SetNativeFontInfoUserDesc(StrToWxStr(fontDesc.c_str())); + DebuggerFont.SetNativeFontInfoUserDesc(StrToWxStr(fontDesc)); // Boot to pause or not ini.Get("General", "AutomaticStart", &bAutomaticStart, false); @@ -366,7 +366,7 @@ void CCodeWindow::NotifyMapLoaded() symbols->Clear(); for (PPCSymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); ++iter) { - int idx = symbols->Append(StrToWxStr(iter->second.name.c_str())); + int idx = symbols->Append(StrToWxStr(iter->second.name)); symbols->SetClientData(idx, (void*)&iter->second); } symbols->Thaw(); diff --git a/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp index 27da055990..e77b57399e 100644 --- a/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/DSPDebugWindow.cpp @@ -221,7 +221,7 @@ void DSPDebuggerLLE::UpdateSymbolMap() for (SymbolDB::XFuncMap::iterator iter = DSPSymbols::g_dsp_symbol_db.GetIterator(); iter != DSPSymbols::g_dsp_symbol_db.End(); ++iter) { - int idx = m_SymbolList->Append(StrToWxStr(iter->second.name.c_str())); + int idx = m_SymbolList->Append(StrToWxStr(iter->second.name)); m_SymbolList->SetClientData(idx, (void*)&iter->second); } m_SymbolList->Thaw(); diff --git a/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp b/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp index e80d206112..7f98af6c57 100644 --- a/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/JitWindow.cpp @@ -120,9 +120,9 @@ void CJitWindow::Compare(u32 em_address) } // Do not merge this "if" with the above - block_num changes inside it. if (block_num < 0) { - ppc_box->SetValue(wxString::FromAscii(StringFromFormat("(non-code address: %08x)", - em_address).c_str())); - x86_box->SetValue(wxString::FromAscii(StringFromFormat("(no translation)").c_str())); + ppc_box->SetValue(StrToWxStr(StringFromFormat("(non-code address: %08x)", + em_address))); + x86_box->SetValue(StrToWxStr(StringFromFormat("(no translation)"))); delete[] xDis; return; } @@ -151,7 +151,7 @@ void CJitWindow::Compare(u32 em_address) *sptr++ = 10; num_x86_instructions++; } - x86_box->SetValue(wxString::FromAscii((char*)xDis)); + x86_box->SetValue(StrToWxStr((char*)xDis)); // == Fill in ppc box u32 ppc_addr = block->originalAddress; @@ -190,11 +190,11 @@ void CJitWindow::Compare(u32 em_address) sptr += sprintf(sptr, "Num bytes: PPC: %i x86: %i (blowup: %i%%)\n", size * 4, block->codeSize, 100 * (block->codeSize / (4 * size) - 1)); - ppc_box->SetValue(wxString::FromAscii((char*)xDis)); + ppc_box->SetValue(StrToWxStr((char*)xDis)); } else { - ppc_box->SetValue(wxString::FromAscii(StringFromFormat( - "(non-code address: %08x)", em_address).c_str())); - x86_box->SetValue(wxString::FromAscii("---")); + ppc_box->SetValue(StrToWxStr(StringFromFormat( + "(non-code address: %08x)", em_address))); + x86_box->SetValue("---"); } delete[] xDis; diff --git a/Source/Core/DolphinWX/Src/FrameAui.cpp b/Source/Core/DolphinWX/Src/FrameAui.cpp index fd3cbb662b..6f10d46722 100644 --- a/Source/Core/DolphinWX/Src/FrameAui.cpp +++ b/Source/Core/DolphinWX/Src/FrameAui.cpp @@ -549,7 +549,7 @@ void CFrame::OnDropDownToolbarItem(wxAuiToolBarEvent& event) for (u32 i = 0; i < Perspectives.size(); i++) { wxMenuItem* mItem = new wxMenuItem(menuPopup, IDM_PERSPECTIVES_0 + i, - StrToWxStr(Perspectives[i].Name.c_str()), + StrToWxStr(Perspectives[i].Name), wxT(""), wxITEM_CHECK); menuPopup->Append(mItem); if (i == ActivePerspective) mItem->Check(true); @@ -871,7 +871,7 @@ void CFrame::LoadIniPerspectives() ini.Get(_Section.c_str(), "Width", &_Width, "70,25"); ini.Get(_Section.c_str(), "Height", &_Height, "80,80"); - Tmp.Perspective = StrToWxStr(_Perspective.c_str()); + Tmp.Perspective = StrToWxStr(_Perspective); SplitString(_Width, ',', _SWidth); SplitString(_Height, ',', _SHeight); diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index a1dcd959fe..4b1fc820a9 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -101,7 +101,7 @@ void CFrame::CreateMenu() drives = cdio_get_devices(); // Windows Limitation of 24 character drives for (unsigned int i = 0; i < drives.size() && i < 24; i++) { - externalDrive->Append(IDM_DRIVE1 + i, StrToWxStr(drives[i].c_str())); + externalDrive->Append(IDM_DRIVE1 + i, StrToWxStr(drives[i])); } fileMenu->AppendSeparator(); diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index d385b947e5..cab4c8125b 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -614,7 +614,7 @@ void CGameListCtrl::ScanForISOs() // Update with the progress (i) and the message dialog.Update(i, wxString::Format(_("Scanning %s"), - StrToWxStr(FileName).c_str())); + StrToWxStr(FileName))); if (dialog.WasCancelled()) break; @@ -1173,10 +1173,10 @@ void CGameListCtrl::CompressSelection(bool _compress) WxStrToStr(browseDialog.GetPath()), FileName); - if (wxFileExists(StrToWxStr(OutputFileName.c_str())) && + if (wxFileExists(StrToWxStr(OutputFileName)) && wxMessageBox( wxString::Format(_("The file %s already exists.\nDo you wish to replace it?"), - StrToWxStr(OutputFileName).c_str()), + StrToWxStr(OutputFileName)), _("Confirm File Overwrite"), wxYES_NO) == wxNO) continue; @@ -1201,10 +1201,10 @@ void CGameListCtrl::CompressSelection(bool _compress) WxStrToStr(browseDialog.GetPath()), FileName); - if (wxFileExists(StrToWxStr(OutputFileName.c_str())) && + if (wxFileExists(StrToWxStr(OutputFileName)) && wxMessageBox( wxString::Format(_("The file %s already exists.\nDo you wish to replace it?"), - StrToWxStr(OutputFileName).c_str()), + StrToWxStr(OutputFileName)), _("Confirm File Overwrite"), wxYES_NO) == wxNO) continue; diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index e739ff043b..6434c8cd54 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -728,7 +728,7 @@ void CISOProperties::ExportDir(const char* _rFullPath, const char* _rExportFolde (u32)(((float)(i - index[0]) / (float)(index[1] - index[0])) * 100))); dialog.Update(i, wxString::Format(_("Extracting %s"), - StrToWxStr(fst[i]->m_FullPath).c_str())); + StrToWxStr(fst[i]->m_FullPath))); if (dialog.WasCancelled()) break; @@ -990,7 +990,7 @@ void CISOProperties::LoadGameConfig() GameIni.Get("EmuState", "EmulationIssues", &sTemp); if (!sTemp.empty()) { - EmuIssues->SetValue(StrToWxStr(sTemp.c_str())); + EmuIssues->SetValue(StrToWxStr(sTemp)); } EmuIssues->Enable(EmuState->GetSelection() != 0); @@ -1157,7 +1157,7 @@ void CISOProperties::PatchList_Load() for (std::vector::const_iterator it = onFrame.begin(); it != onFrame.end(); ++it) { PatchEngine::Patch p = *it; - Patches->Append(StrToWxStr(p.name.c_str())); + Patches->Append(StrToWxStr(p.name)); Patches->Check(index, p.active); ++index; } @@ -1366,5 +1366,5 @@ void CISOProperties::ChangeBannerDetails(int lang) SplitPath(OpenGameListItem->GetFileName(), 0, &filename, &extension); // Also sets the window's title SetTitle(StrToWxStr(StringFromFormat("%s%s: %s - ", filename.c_str(), - extension.c_str(), OpenGameListItem->GetUniqueID().c_str()).c_str()) + shortName); + extension.c_str(), OpenGameListItem->GetUniqueID().c_str())) + shortName); } diff --git a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp index d8a755aca6..1df215fb1e 100644 --- a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp @@ -34,7 +34,7 @@ void GamepadPage::ConfigExtension(wxCommandEvent& event) if (ex->switch_extension) { wxDialog dlg(this, -1, - StrToWxStr(ex->attachments[ex->switch_extension]->GetName().c_str()), + StrToWxStr(ex->attachments[ex->switch_extension]->GetName()), wxDefaultPosition, wxDefaultSize); wxBoxSizer* const main_szr = new wxBoxSizer(wxVERTICAL); @@ -64,7 +64,7 @@ PadSettingExtension::PadSettingExtension(wxWindow* const parent, ControllerEmu:: e = extension->attachments.end(); for (; i!=e; ++i) - ((wxChoice*)wxcontrol)->Append(StrToWxStr((*i)->GetName().c_str())); + ((wxChoice*)wxcontrol)->Append(StrToWxStr((*i)->GetName())); UpdateGUI(); } @@ -612,7 +612,7 @@ void GamepadPage::DeleteProfile(wxCommandEvent&) if (File::Exists(fnamecstr) && AskYesNoT("Are you sure you want to delete \"%s\"?", - WxStrToStr(profile_cbox->GetValue()).c_str())) + WxStrToStr(profile_cbox->GetValue()))) { File::Delete(fnamecstr); @@ -952,7 +952,7 @@ GamepadPage::GamepadPage(wxWindow* parent, InputPlugin& plugin, const unsigned i InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin, const std::string& name, const int tab_num) - : wxDialog(parent, wxID_ANY, StrToWxStr(name.c_str()), wxPoint(128,-1), wxDefaultSize) + : wxDialog(parent, wxID_ANY, StrToWxStr(name), wxPoint(128,-1), wxDefaultSize) , m_plugin(plugin) { m_pad_notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT); diff --git a/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp b/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp index 4e07ed990d..efb7db59af 100644 --- a/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp +++ b/Source/Core/DolphinWX/Src/InputConfigDiagBitmaps.cpp @@ -228,7 +228,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event)) // text const char* const name = (*g)->control_group->controls[n]->name; // bit of hax so ZL, ZR show up as L, R - dc.DrawText(StrToWxStr((name[1] && name[1] < 'a') ? name[1] : name[0]), n*12 + 2, 1); + dc.DrawText(StrToWxStr(std::string(1, (name[1] && name[1] < 'a') ? name[1] : name[0])), n*12 + 2, 1); } delete[] bitmasks; @@ -300,7 +300,7 @@ void InputConfigDialog::UpdateBitmaps(wxTimerEvent& WXUNUSED(event)) // text dc.DrawText(StrToWxStr((*g)->control_group->controls[n+trigger_count]->name), 3, n*12 + 1); - dc.DrawText(StrToWxStr((*g)->control_group->controls[n]->name[0]), 64 + 3, n*12 + 1); + dc.DrawText(StrToWxStr(std::string(1, (*g)->control_group->controls[n]->name[0])), 64 + 3, n*12 + 1); } // threshold box diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index d9fd5e6ca0..988ccae83e 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -73,7 +73,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* std::string address; netplay_section.Get("Address", &address, "localhost"); - m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(address.c_str())); + m_connect_ip_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(address)); wxStaticText* const port_lbl = new wxStaticText(connect_tab, wxID_ANY, _("Port :"), wxDefaultPosition, wxDefaultSize); @@ -81,7 +81,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* // string? w/e std::string port; netplay_section.Get("ConnectPort", &port, "2626"); - m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(port.c_str())); + m_connect_port_text = new wxTextCtrl(connect_tab, wxID_ANY, StrToWxStr(port)); wxButton* const connect_btn = new wxButton(connect_tab, wxID_ANY, _("Connect")); connect_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlaySetupDiag::OnJoin, this); @@ -114,7 +114,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* // string? w/e std::string port; netplay_section.Get("HostPort", &port, "2626"); - m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, StrToWxStr(port.c_str())); + m_host_port_text = new wxTextCtrl(host_tab, wxID_ANY, StrToWxStr(port)); wxButton* const host_btn = new wxButton(host_tab, wxID_ANY, _("Host")); host_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &NetPlaySetupDiag::OnHost, this); diff --git a/Source/Core/DolphinWX/Src/PatchAddEdit.cpp b/Source/Core/DolphinWX/Src/PatchAddEdit.cpp index 3199240d74..ead7918d34 100644 --- a/Source/Core/DolphinWX/Src/PatchAddEdit.cpp +++ b/Source/Core/DolphinWX/Src/PatchAddEdit.cpp @@ -49,7 +49,7 @@ void CPatchAddEdit::CreateGUIControls(int _selection) } else { - currentName = StrToWxStr(onFrame.at(_selection).name.c_str()); + currentName = StrToWxStr(onFrame.at(_selection).name); tempEntries = onFrame.at(_selection).entries; } diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 7c8a3b7e04..154a5bc602 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -212,9 +212,9 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = g_available_video_backends.begin(), itend = g_available_video_backends.end(); for (; it != itend; ++it) - choice_backend->AppendString(wxGetTranslation(StrToWxStr((*it)->GetName().c_str()))); + choice_backend->AppendString(wxGetTranslation(StrToWxStr((*it)->GetName()))); - choice_backend->SetStringSelection(wxGetTranslation(StrToWxStr(g_video_backend->GetName().c_str()))); + choice_backend->SetStringSelection(wxGetTranslation(StrToWxStr(g_video_backend->GetName()))); choice_backend->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &VideoConfigDiag::Event_Backend, this); szr_basic->Add(label_backend, 1, wxALIGN_CENTER_VERTICAL, 5); @@ -236,7 +236,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = vconfig.backend_info.Adapters.begin(), itend = vconfig.backend_info.Adapters.end(); for (; it != itend; ++it) - choice_adapter->AppendString(StrToWxStr(it->c_str())); + choice_adapter->AppendString(StrToWxStr(*it)); choice_adapter->Select(vconfig.iAdapter); @@ -259,7 +259,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con RegisterControl(choice_display_resolution, wxGetTranslation(display_res_desc)); choice_display_resolution->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &VideoConfigDiag::Event_DisplayResolution, this); - choice_display_resolution->SetStringSelection(StrToWxStr(SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution.c_str())); + choice_display_resolution->SetStringSelection(StrToWxStr(SConfig::GetInstance().m_LocalCoreStartupParameter.strFullscreenResolution)); szr_display->Add(label_display_resolution, 1, wxALIGN_CENTER_VERTICAL, 0); szr_display->Add(choice_display_resolution); @@ -355,7 +355,7 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = vconfig.backend_info.AAModes.begin(), itend = vconfig.backend_info.AAModes.end(); for (; it != itend; ++it) - choice_aamode->AppendString(wxGetTranslation(StrToWxStr(it->c_str()))); + choice_aamode->AppendString(wxGetTranslation(StrToWxStr(*it))); choice_aamode->Select(vconfig.iMultisampleMode); szr_enh->Add(text_aamode, 1, wxALIGN_CENTER_VERTICAL, 0); @@ -380,12 +380,12 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con it = vconfig.backend_info.PPShaders.begin(), itend = vconfig.backend_info.PPShaders.end(); for (; it != itend; ++it) - choice_ppshader->AppendString(StrToWxStr(it->c_str())); + choice_ppshader->AppendString(StrToWxStr(*it)); if (vconfig.sPostProcessingShader.empty()) choice_ppshader->Select(0); else - choice_ppshader->SetStringSelection(StrToWxStr(vconfig.sPostProcessingShader.c_str())); + choice_ppshader->SetStringSelection(StrToWxStr(vconfig.sPostProcessingShader)); choice_ppshader->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &VideoConfigDiag::Event_PPShader, this); diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.h b/Source/Core/DolphinWX/Src/VideoConfigDiag.h index 8507fffdc1..90a42c34a1 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.h +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.h @@ -100,7 +100,7 @@ protected: else { // Select current backend again - choice_backend->SetStringSelection(StrToWxStr(g_video_backend->GetName().c_str())); + choice_backend->SetStringSelection(StrToWxStr(g_video_backend->GetName())); } } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index d0bb94a39a..f0213578c5 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1539,7 +1539,7 @@ void TakeScreenshot(ScrStrct* threadStruct) // Save the screenshot and finally kill the wxImage object // This is really expensive when saving to PNG, but not at all when using BMP - threadStruct->img->SaveFile(StrToWxStr(threadStruct->filename.c_str()), + threadStruct->img->SaveFile(StrToWxStr(threadStruct->filename), wxBITMAP_TYPE_PNG); threadStruct->img->Destroy(); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp index 670c3f9c6d..e7122d2f71 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoConfigDialog.cpp @@ -34,7 +34,7 @@ IntegerSetting::IntegerSetting(wxWindow* parent, const wxString& label, T& se VideoConfigDialog::VideoConfigDialog(wxWindow* parent, const std::string& title, const std::string& _ininame) : wxDialog(parent, -1, - wxString(wxT("Dolphin ")).append(StrToWxStr(title.c_str())).append(wxT(" Graphics Configuration")), + wxString(wxT("Dolphin ")).append(StrToWxStr(title)).append(wxT(" Graphics Configuration")), wxDefaultPosition, wxDefaultSize), vconfig(g_SWVideoConfig), ininame(_ininame) From 95558cdc6911e6122fec94616e4d6975d2c355fb Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 28 Feb 2013 03:11:10 -0600 Subject: [PATCH 114/167] Buildfix. --- Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp | 2 +- Source/Core/DolphinWX/Src/InputConfigDiag.cpp | 2 +- Source/Core/DolphinWX/Src/WxUtils.cpp | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp index 7ec36131ff..362e617696 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp @@ -285,7 +285,7 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) if (!path.IsEmpty()) { - std::ifstream f(WxStrToStr(path)); + std::ifstream f(WxStrToStr(path).c_str()); std::string line; while (std::getline(f, line)) diff --git a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp index 1df215fb1e..14772d8676 100644 --- a/Source/Core/DolphinWX/Src/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/InputConfigDiag.cpp @@ -612,7 +612,7 @@ void GamepadPage::DeleteProfile(wxCommandEvent&) if (File::Exists(fnamecstr) && AskYesNoT("Are you sure you want to delete \"%s\"?", - WxStrToStr(profile_cbox->GetValue()))) + WxStrToStr(profile_cbox->GetValue()).c_str())) { File::Delete(fnamecstr); diff --git a/Source/Core/DolphinWX/Src/WxUtils.cpp b/Source/Core/DolphinWX/Src/WxUtils.cpp index ee6f815648..6856c96481 100644 --- a/Source/Core/DolphinWX/Src/WxUtils.cpp +++ b/Source/Core/DolphinWX/Src/WxUtils.cpp @@ -57,10 +57,11 @@ void Explore(const char *path) std::string WxStrToStr(const wxString& str) { - return str.ToUTF8(); + return str.ToUTF8().data(); } wxString StrToWxStr(const std::string& str) { + //return wxString::FromUTF8Unchecked(str.c_str()); return wxString::FromUTF8(str.c_str()); } From 07539b9a3ff1bc55bd829d0098ac025dbfd4ad44 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Thu, 28 Feb 2013 13:12:35 +0100 Subject: [PATCH 115/167] Fix a StringUtil regression from the arm-noglsl merge Fixes issue 6048. Thanks to Starscream for locating the regression. --- Source/Core/Common/Src/StringUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 6ef3d91a73..cd08863877 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -245,7 +245,7 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st while(1) { const int pos = result.find(src); - if (pos == 16) break; + if (pos == -1) break; result.replace(pos, src.size(), dest); } return result; From bc15919e2ebefe327ce6330f7abdaccaa2fd2004 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 28 Feb 2013 16:15:32 -0600 Subject: [PATCH 116/167] Make ARMJit core default CPU core on ARM architecture --- Source/Core/Core/Src/ConfigManager.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 85ecc7143f..377aa16a27 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -362,7 +362,11 @@ void SConfig::LoadSettings() // Core ini.Get("Core", "HLE_BS2", &m_LocalCoreStartupParameter.bHLE_BS2, false); +#ifdef _M_ARM + ini.Get("Core", "CPUCore", &m_LocalCoreStartupParameter.iCPUCore, 3); +#else ini.Get("Core", "CPUCore", &m_LocalCoreStartupParameter.iCPUCore, 1); +#endif ini.Get("Core", "DSPThread", &m_LocalCoreStartupParameter.bDSPThread, false); ini.Get("Core", "DSPHLE", &m_LocalCoreStartupParameter.bDSPHLE, true); ini.Get("Core", "CPUThread", &m_LocalCoreStartupParameter.bCPUThread, true); From 5c4a130688b22459662d15f11324b93fa9382eb9 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 1 Mar 2013 10:28:42 +1100 Subject: [PATCH 117/167] Added a BluetoothEnumerateInstalledServices call so that the wiimote remembers the pairing. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 2ae34a7ca5..1119ae3f1d 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -59,6 +59,7 @@ typedef DWORD (__stdcall *PBth_BluetoothGetRadioInfo)(HANDLE, PBLUETOOTH_RADIO_I typedef DWORD (__stdcall *PBth_BluetoothRemoveDevice)(const BLUETOOTH_ADDRESS*); typedef DWORD (__stdcall *PBth_BluetoothSetServiceState)(HANDLE, const BLUETOOTH_DEVICE_INFO*, const GUID*, DWORD); typedef DWORD (__stdcall *PBth_BluetoothAuthenticateDevice)(HWND, HANDLE, BLUETOOTH_DEVICE_INFO*, PWCHAR, ULONG); +typedef DWORD (__stdcall *PBth_BluetoothEnumerateInstalledServices)(HANDLE, BLUETOOTH_DEVICE_INFO*, DWORD*, GUID*); PHidD_GetHidGuid HidD_GetHidGuid = NULL; PHidD_GetAttributes HidD_GetAttributes = NULL; @@ -74,6 +75,7 @@ PBth_BluetoothGetRadioInfo Bth_BluetoothGetRadioInfo = NULL; PBth_BluetoothRemoveDevice Bth_BluetoothRemoveDevice = NULL; PBth_BluetoothSetServiceState Bth_BluetoothSetServiceState = NULL; PBth_BluetoothAuthenticateDevice Bth_BluetoothAuthenticateDevice = NULL; +PBth_BluetoothEnumerateInstalledServices Bth_BluetoothEnumerateInstalledServices = NULL; HINSTANCE hid_lib = NULL; HINSTANCE bthprops_lib = NULL; @@ -119,12 +121,14 @@ inline void init_lib() Bth_BluetoothRemoveDevice = (PBth_BluetoothRemoveDevice)GetProcAddress(bthprops_lib, "BluetoothRemoveDevice"); Bth_BluetoothSetServiceState = (PBth_BluetoothSetServiceState)GetProcAddress(bthprops_lib, "BluetoothSetServiceState"); Bth_BluetoothAuthenticateDevice = (PBth_BluetoothAuthenticateDevice)GetProcAddress(bthprops_lib, "BluetoothAuthenticateDevice"); + Bth_BluetoothEnumerateInstalledServices = (PBth_BluetoothEnumerateInstalledServices)GetProcAddress(bthprops_lib, "BluetoothEnumerateInstalledServices"); if (!Bth_BluetoothFindDeviceClose || !Bth_BluetoothFindFirstDevice || !Bth_BluetoothFindFirstRadio || !Bth_BluetoothFindNextDevice || !Bth_BluetoothFindNextRadio || !Bth_BluetoothFindRadioClose || !Bth_BluetoothGetRadioInfo || !Bth_BluetoothRemoveDevice || - !Bth_BluetoothSetServiceState || !Bth_BluetoothAuthenticateDevice) + !Bth_BluetoothSetServiceState || !Bth_BluetoothAuthenticateDevice || + !Bth_BluetoothEnumerateInstalledServices) { PanicAlertT("Failed to load bthprops.cpl"); exit(EXIT_FAILURE); @@ -560,6 +564,14 @@ bool AttachWiimote(HANDLE hRadio, const BLUETOOTH_RADIO_INFO& radio_info, BLUETO if (ERROR_SUCCESS != auth_result) ERROR_LOG(WIIMOTE, "AttachWiimote: BluetoothAuthenticateDevice returned %08x", auth_result); + + DWORD pcServices = 16; + GUID guids[16]; + // If this is not done, the Wii device will not remember the pairing + const DWORD srv_result = Bth_BluetoothEnumerateInstalledServices(hRadio, &btdi, &pcServices, guids); + + if (ERROR_SUCCESS != srv_result) + ERROR_LOG(WIIMOTE, "AttachWiimote: BluetoothEnumerateInstalledServices returned %08x", srv_result); #endif // Activate service const DWORD hr = Bth_BluetoothSetServiceState(hRadio, &btdi, From d0dbcc6369b1482237521308982baf84cd5989d5 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 00:52:15 +0100 Subject: [PATCH 118/167] VideoSoftware: Cleanup PE perf metrics; returning the proper value now. --- .../Plugin_VideoSoftware/Src/BPMemLoader.cpp | 2 +- .../Plugin_VideoSoftware/Src/Rasterizer.cpp | 9 ++-- .../Src/SWPixelEngine.cpp | 11 ----- .../Plugin_VideoSoftware/Src/SWPixelEngine.h | 48 +++++++++++++++++++ .../Plugins/Plugin_VideoSoftware/Src/Tev.cpp | 14 ++---- 5 files changed, 57 insertions(+), 27 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp index dde31ab7d3..0d7c77c767 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/BPMemLoader.cpp @@ -91,7 +91,7 @@ void SWBPWritten(int address, int newvalue) SWPixelEngine::pereg.boxTop = newvalue & 0x3ff; break; case BPMEM_CLEAR_PIXEL_PERF: - // TODO: Parameter? + // TODO: I didn't test if the value written to this register affects the amount of cleared registers SWPixelEngine::pereg.perfZcompInputZcomplocLo = 0; SWPixelEngine::pereg.perfZcompInputZcomplocHi = 0; SWPixelEngine::pereg.perfZcompOutputZcomplocLo = 0; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp index d30c3d7033..badb123fa0 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Rasterizer.cpp @@ -150,18 +150,15 @@ inline void Draw(s32 x, s32 y, s32 xi, s32 yi) if (bpmem.zcontrol.early_ztest && bpmem.zmode.testenable && g_SWVideoConfig.bZComploc) { - // TODO: Verify that perf regs are being incremented even if test is disabled - if (++SWPixelEngine::pereg.perfZcompInputZcomplocLo == 0) - SWPixelEngine::pereg.perfZcompInputZcomplocHi++; - + // TODO: Test if perf regs are incremented even if test is disabled + SWPixelEngine::pereg.IncZInputQuadCount(true); if (bpmem.zmode.testenable) { // early z if (!EfbInterface::ZCompare(x, y, z)) return; } - if (++SWPixelEngine::pereg.perfZcompOutputZcomplocLo == 0) - SWPixelEngine::pereg.perfZcompOutputZcomplocHi++; + SWPixelEngine::pereg.IncZOutputQuadCount(true); } RasterBlockPixel& pixel = rasterBlock.Pixel[xi][yi]; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp index a621542ea0..118e59629e 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.cpp @@ -81,17 +81,6 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) if (address <= 0x2e) _uReturnValue = ((u16*)&pereg)[address >> 1]; - - if (address > 0x16) - { - ERROR_LOG(PIXELENGINE, "addr %#08x, ret %#04x; %#04x%04x, %#04x%04x, %#04x%04x, %#04x%04x, %#04x%04x, %#04x%04x\n", address, _uReturnValue, - pereg.perfZcompInputZcomplocHi, pereg.perfZcompInputZcomplocLo, - pereg.perfZcompOutputZcomplocHi, pereg.perfZcompOutputZcomplocLo, - pereg.perfZcompInputHi, pereg.perfZcompInputLo, - pereg.perfZcompOutputHi, pereg.perfZcompOutputLo, - pereg.perfBlendInputHi, pereg.perfBlendInputLo, - pereg.perfEfbCopyClocksHi, pereg.perfEfbCopyClocksLo); - } } void Write32(const u32 _iValue, const u32 _iAddress) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h index 7deb69a164..351e53456d 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWPixelEngine.h @@ -158,6 +158,54 @@ namespace SWPixelEngine u16 perfBlendInputHi; u16 perfEfbCopyClocksLo; u16 perfEfbCopyClocksHi; + + // NOTE: hardware doesn't process individual pixels but quads instead. Current software renderer architecture works on pixels though, so we have this "quad" hack here to only increment the registers on every fourth rendered pixel + void IncZInputQuadCount(bool early_ztest) + { + static int quad = 0; + if (++quad != 3) + return; + quad = 0; + + if (early_ztest) + { + if (++perfZcompInputZcomplocLo == 0) + perfZcompInputZcomplocHi++; + } + else + { + if (++perfZcompInputLo == 0) + perfZcompInputHi++; + } + } + void IncZOutputQuadCount(bool early_ztest) + { + static int quad = 0; + if (++quad != 3) + return; + quad = 0; + + if (early_ztest) + { + if (++perfZcompOutputZcomplocLo == 0) + perfZcompOutputZcomplocHi++; + } + else + { + if (++perfZcompOutputLo == 0) + perfZcompOutputHi++; + } + } + void IncBlendInputQuadCount() + { + static int quad = 0; + if (++quad != 3) + return; + quad = 0; + + if (++perfBlendInputLo == 0) + perfBlendInputHi++; + } }; extern PEReg pereg; diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp index c9c408a623..3d5c0d7724 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp @@ -789,14 +789,12 @@ void Tev::Draw() if (late_ztest && bpmem.zmode.testenable) { // TODO: Check against hw if these values get incremented even if depth testing is disabled - if (++SWPixelEngine::pereg.perfZcompInputLo == 0) - SWPixelEngine::pereg.perfZcompInputHi++; + SWPixelEngine::pereg.IncZInputQuadCount(false); - if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2])) - return; + if (!EfbInterface::ZCompare(Position[0], Position[1], Position[2])) + return; - if (++SWPixelEngine::pereg.perfZcompOutputLo == 0) - SWPixelEngine::pereg.perfZcompOutputHi++; + SWPixelEngine::pereg.IncZOutputQuadCount(false); } #if ALLOW_TEV_DUMPS @@ -820,9 +818,7 @@ void Tev::Draw() #endif INCSTAT(swstats.thisFrame.tevPixelsOut); - - if (++SWPixelEngine::pereg.perfBlendInputLo == 0) - SWPixelEngine::pereg.perfBlendInputHi++; + SWPixelEngine::pereg.IncBlendInputQuadCount(); EfbInterface::BlendTev(Position[0], Position[1], output); } From 1c9860246c1773ede5c35ba15d774cdb566fae18 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 01:14:10 +0100 Subject: [PATCH 119/167] Build fixes for everyone! --- Source/Core/Common/Src/VideoBackendBase.h | 2 +- Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/Common/Src/VideoBackendBase.h b/Source/Core/Common/Src/VideoBackendBase.h index f502bf42b6..f1c8b0a131 100644 --- a/Source/Core/Common/Src/VideoBackendBase.h +++ b/Source/Core/Common/Src/VideoBackendBase.h @@ -22,7 +22,7 @@ #include #include "ChunkFile.h" -#include "PerfQueryBase.h" +#include "../../VideoCommon/Src/PerfQueryBase.h" typedef void (*writeFn16)(const u16,const u32); typedef void (*writeFn32)(const u32,const u32); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 87d79fdb38..87257f15da 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -218,10 +218,10 @@ void VertexManager::vFlush() if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here. if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid); - g_perf_query->EnableQuery(bpmem.zcontrol.zcomploc ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); Draw(); - g_perf_query->DisableQuery(bpmem.zcontrol.zcomploc ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - //ERROR_LOG(VIDEO, "PerfQuery result: %d", g_perf_query->GetQueryResult(bpmem.zcontrol.zcomploc ? PQ_ZCOMP_OUTPUT_ZCOMPLOC : PQ_ZCOMP_OUTPUT)); + g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); + //ERROR_LOG(VIDEO, "PerfQuery result: %d", g_perf_query->GetQueryResult(bpmem.zcontrol.early_ztest ? PQ_ZCOMP_OUTPUT_ZCOMPLOC : PQ_ZCOMP_OUTPUT)); // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) From cbf5efe19108a677987242f5ba6a71b38e129c05 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 01:31:57 +0100 Subject: [PATCH 120/167] Some cleanups. PE perf metrics officially declared unsupported for the D3D9 project (out of pure laziness, anyone who cares can implement them :P). --- Source/Core/VideoCommon/Src/OnScreenDisplay.h | 2 +- Source/Core/VideoCommon/Src/VideoConfig.cpp | 1 - Source/Core/VideoCommon/Src/VideoConfig.h | 1 - Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 1 - Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 9 ++++++--- Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 1 - 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Source/Core/VideoCommon/Src/OnScreenDisplay.h b/Source/Core/VideoCommon/Src/OnScreenDisplay.h index 3777e2b5d3..80187b8ac3 100644 --- a/Source/Core/VideoCommon/Src/OnScreenDisplay.h +++ b/Source/Core/VideoCommon/Src/OnScreenDisplay.h @@ -22,7 +22,7 @@ namespace OSD { // On-screen message display -void AddMessage(const char* str, u32 ms); +void AddMessage(const char* str, u32 ms = 2000); void DrawMessages(); // draw the current messages on the screen. Only call once per frame. void ClearMessages(); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index 74484efb01..bd5c6a7acb 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -174,7 +174,6 @@ void VideoConfig::VerifyValidity() if (!backend_info.bSupports3DVision) b3DVision = false; if (!backend_info.bSupportsFormatReinterpretation) bEFBEmulateFormatChanges = false; if (!backend_info.bSupportsPixelLighting) bEnablePixelLighting = false; - if (!backend_info.bSupportsPixelPerfQuery) bDisablePixelPerf = true; } void VideoConfig::Save(const char *ini_file) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index 29ad6ec721..c9d2eef217 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -163,7 +163,6 @@ struct VideoConfig bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL bool bSupportsFormatReinterpretation; bool bSupportsPixelLighting; - bool bSupportsPixelPerfQuery; } backend_info; // Utility diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index f858021e77..b7dd9101d3 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -95,7 +95,6 @@ void InitBackendInfo() g_Config.backend_info.bSupportsDualSourceBlend = true; g_Config.backend_info.bSupportsFormatReinterpretation = true; g_Config.backend_info.bSupportsPixelLighting = true; - g_Config.backend_info.bSupportsPixelPerfQuery = true; IDXGIFactory* factory; IDXGIAdapter* ad; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 8085ae4991..bf7bf16989 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -97,9 +97,6 @@ void InitBackendInfo() g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupportsDualSourceBlend = false; g_Config.backend_info.bSupportsFormatReinterpretation = true; - g_Config.backend_info.bSupportsPixelPerfQuery = false; - - g_Config.backend_info.bSupportsPixelLighting = C_PLIGHTS + 40 <= maxConstants && C_PMATERIALS + 4 <= maxConstants; // adapters @@ -159,6 +156,12 @@ bool VideoBackend::Initialize(void *&window_handle) s_BackendInitialized = true; + if (!g_Config.bDisablePixelPerf) + { + OSD::AddMessage("PE perf metrics enabled although the D3D9 backend doesn't support them!"); + OSD::AddMessage("Try a different backend when issues arise."); + } + return true; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 266ac2a8ae..854554d968 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -136,7 +136,6 @@ void InitBackendInfo() g_Config.backend_info.bSupportsDualSourceBlend = false; // supported, but broken g_Config.backend_info.bSupportsFormatReinterpretation = false; g_Config.backend_info.bSupportsPixelLighting = true; - g_Config.backend_info.bSupportsPixelPerfQuery = false; // aamodes const char* caamodes[] = {"None", "2x", "4x", "8x", "8x CSAA", "8xQ CSAA", "16x CSAA", "16xQ CSAA"}; From b94f65b66608148450c22615ea896d90bbc27ed4 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 01:37:47 +0100 Subject: [PATCH 121/167] Remove two incorrect lines. How did those even get there?! --- Source/Core/VideoCommon/Src/BPStructs.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index a8d081666f..a79af48370 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -269,8 +269,6 @@ void BPWritten(const BPCmd& bp) UPE_Copy PE_copy = bpmem.triggerEFBCopy; - g_renderer->ResumePixelPerf(true); - // Check if we are to copy from the EFB or draw to the XFB if (PE_copy.copy_to_xfb == 0) { @@ -309,8 +307,6 @@ void BPWritten(const BPCmd& bp) s_gammaLUT[PE_copy.gamma]); } - g_renderer->PausePixelPerf(true); - // Clear the rectangular region after copying it. if (PE_copy.clear) { From dea1e2827d6ce6eb5f6bfe2c64c59a36b3606b02 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 28 Feb 2013 19:33:39 -0600 Subject: [PATCH 122/167] Open std::fstream in a unicode-safe manner. --- Source/Core/Common/Src/FileUtil.h | 12 ++++++++++++ Source/Core/Common/Src/IniFile.cpp | 5 +++-- Source/Core/Common/Src/LinearDiskCache.h | 2 +- Source/Core/Common/Src/LogManager.cpp | 2 +- Source/Core/Common/Src/NandPaths.cpp | 6 ++++-- Source/Core/Core/Src/DSP/assemble.cpp | 3 ++- .../Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp | 2 +- Source/Core/Core/Src/HW/WiimoteEmu/Speaker.cpp | 2 +- .../DolphinWX/Src/Debugger/CodeWindowFunctions.cpp | 3 ++- Source/Core/DolphinWX/Src/ISOProperties.cpp | 3 ++- Source/Core/VideoCommon/Src/ImageWrite.cpp | 3 ++- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 3 ++- Source/Core/VideoCommon/Src/VertexManagerBase.cpp | 6 ++++-- Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 3 ++- Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp | 9 ++++++--- Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp | 6 ++++-- .../Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp | 3 ++- Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp | 6 ++++-- .../Plugin_VideoOGL/Src/VertexShaderCache.cpp | 3 ++- 19 files changed, 57 insertions(+), 25 deletions(-) diff --git a/Source/Core/Common/Src/FileUtil.h b/Source/Core/Common/Src/FileUtil.h index b8e8d9c17c..dd1abe6ae9 100644 --- a/Source/Core/Common/Src/FileUtil.h +++ b/Source/Core/Common/Src/FileUtil.h @@ -25,6 +25,7 @@ #include #include "Common.h" +#include "StringUtil.h" // User directory indices for GetUserPath enum { @@ -226,4 +227,15 @@ private: } // namespace +// To deal with Windows being dumb at unicode: +template +void OpenFStream(T& fstream, const std::string& filename, std::ios_base::openmode openmode) +{ +#ifdef _WIN32 + fstream.open(UTF8ToTStr(filename).c_str(), openmode); +#else + fstream.open(filename, openmode); +#endif +} + #endif diff --git a/Source/Core/Common/Src/IniFile.cpp b/Source/Core/Common/Src/IniFile.cpp index acad498106..da44855941 100644 --- a/Source/Core/Common/Src/IniFile.cpp +++ b/Source/Core/Common/Src/IniFile.cpp @@ -25,6 +25,7 @@ #include #include +#include "FileUtil.h" #include "StringUtil.h" #include "IniFile.h" @@ -400,7 +401,7 @@ bool IniFile::Load(const char* filename) // Open file std::ifstream in; - in.open(filename, std::ios::in); + OpenFStream(in, filename, std::ios::in); if (in.fail()) return false; @@ -452,7 +453,7 @@ bool IniFile::Load(const char* filename) bool IniFile::Save(const char* filename) { std::ofstream out; - out.open(filename, std::ios::out); + OpenFStream(out, filename, std::ios::out); if (out.fail()) { diff --git a/Source/Core/Common/Src/LinearDiskCache.h b/Source/Core/Common/Src/LinearDiskCache.h index 9755c996bd..42b3d9ff15 100644 --- a/Source/Core/Common/Src/LinearDiskCache.h +++ b/Source/Core/Common/Src/LinearDiskCache.h @@ -74,7 +74,7 @@ public: m_num_entries = 0; // try opening for reading/writing - m_file.open(filename, ios_base::in | ios_base::out | ios_base::binary); + OpenFStream(m_file, filename, ios_base::in | ios_base::out | ios_base::binary); m_file.seekg(0, std::ios::end); std::fstream::pos_type end_pos = m_file.tellg(); diff --git a/Source/Core/Common/Src/LogManager.cpp b/Source/Core/Common/Src/LogManager.cpp index 3beae08c15..9b0ed43333 100644 --- a/Source/Core/Common/Src/LogManager.cpp +++ b/Source/Core/Common/Src/LogManager.cpp @@ -186,7 +186,7 @@ void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg) FileLogListener::FileLogListener(const char *filename) { - m_logfile.open(filename, std::ios::app); + OpenFStream(m_logfile, filename, std::ios::app); SetEnable(true); } diff --git a/Source/Core/Common/Src/NandPaths.cpp b/Source/Core/Common/Src/NandPaths.cpp index cec79414a7..eb0673afe0 100644 --- a/Source/Core/Common/Src/NandPaths.cpp +++ b/Source/Core/Common/Src/NandPaths.cpp @@ -86,7 +86,8 @@ bool CheckTitleTIK(u64 _titleID) static void CreateReplacementFile(std::string &filename) { - std::ofstream replace(filename.c_str()); + std::ofstream replace; + OpenFStream(replace, filename, std::ios_base::out); replace <<"\" __22__\n"; replace << "* __2a__\n"; //replace << "/ __2f__\n"; @@ -108,7 +109,8 @@ void ReadReplacements(replace_v& replacements) if (!File::Exists(filename)) CreateReplacementFile(filename); - std::ifstream f(filename.c_str()); + std::ifstream f; + OpenFStream(f, filename, std::ios_base::in); char letter; std::string replacement; diff --git a/Source/Core/Core/Src/DSP/assemble.cpp b/Source/Core/Core/Src/DSP/assemble.cpp index dd394ab82c..248b0d8ba8 100644 --- a/Source/Core/Core/Src/DSP/assemble.cpp +++ b/Source/Core/Core/Src/DSP/assemble.cpp @@ -754,7 +754,8 @@ bool DSPAssembler::AssembleFile(const char *fname, int pass) { int disable_text = 0; // modified by Hermes - std::ifstream fsrc(fname); + std::ifstream fsrc; + OpenFStream(fsrc, fname, std::ios_base::in); if (fsrc.fail()) { diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp index 5c2a28b57a..5710fd4f25 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Core/Core/Src/HW/WiimoteEmu/EmuSubroutines.cpp @@ -297,7 +297,7 @@ void Wiimote::WriteData(const wm_write_data* const wd) { // writing the whole mii block each write :/ std::ofstream file; - file.open((File::GetUserPath(D_WIIUSER_IDX) + "mii.bin").c_str(), std::ios::binary | std::ios::out); + OpenFStream(file, File::GetUserPath(D_WIIUSER_IDX) + "mii.bin", std::ios::binary | std::ios::out); file.write((char*)m_eeprom + 0x0FCA, 0x02f0); file.close(); } diff --git a/Source/Core/Core/Src/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/Src/HW/WiimoteEmu/Speaker.cpp index ba01239bf2..c743c80294 100644 --- a/Source/Core/Core/Src/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/Src/HW/WiimoteEmu/Speaker.cpp @@ -106,7 +106,7 @@ void Wiimote::SpeakerData(wm_speaker_data* sd) File::Delete("rmtdump.wav"); File::Delete("rmtdump.bin"); atexit(stopdamnwav); - ofile.open("rmtdump.bin", ofile.binary | ofile.out); + OpenFStream(ofile, "rmtdump.bin", ofile.binary | ofile.out); wav.Start("rmtdump.wav", 6000/*Common::swap16(m_reg_speaker.sample_rate)*/); } wav.AddMonoSamples(samples, sd->length*2); diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp index 362e617696..fad0380eca 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp @@ -285,7 +285,8 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) if (!path.IsEmpty()) { - std::ifstream f(WxStrToStr(path).c_str()); + std::ifstream f; + OpenFStream(f, WxStrToStr(path), std::ios_base::in); std::string line; while (std::getline(f, line)) diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 6434c8cd54..a194345585 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -137,7 +137,8 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW else { // Will fail out if GameConfig folder doesn't exist - std::ofstream f(GameIniFile.c_str()); + std::ofstream f; + OpenFStream(f, GameIniFile, std::ios_base::out); if (f) { f << "# " << OpenISO->GetUniqueID() << " - " << OpenISO->GetName() << '\n' diff --git a/Source/Core/VideoCommon/Src/ImageWrite.cpp b/Source/Core/VideoCommon/Src/ImageWrite.cpp index 23b0e73427..482b4dad25 100644 --- a/Source/Core/VideoCommon/Src/ImageWrite.cpp +++ b/Source/Core/VideoCommon/Src/ImageWrite.cpp @@ -69,7 +69,8 @@ bool SaveTGA(const char* filename, int width, int height, void* pdata) bool SaveData(const char* filename, const char* data) { - std::ofstream f(filename, std::ios::binary); + std::ofstream f; + OpenFStream(f, filename, std::ios::binary); f << data; return true; diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 448501aad0..6793862ef9 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -252,7 +252,8 @@ void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std:: static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%spsuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << msg; file << "\n\nOld shader code:\n" << old_code; file << "\n\nNew shader code:\n" << new_code; diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index cd5a01c6b3..6d5d122704 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -277,10 +277,12 @@ void VertexManager::Flush() // save the shaders char strfile[255]; sprintf(strfile, "%sps%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); - std::ofstream fps(strfile); + std::ofstream fps; + OpenFStream(fps, strfile, std::ios_base::out); fps << ps->strprog.c_str(); sprintf(strfile, "%svs%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); - std::ofstream fvs(strfile); + std::ofstream fvs; + OpenFStream(fvs, strfile, std::ios_base::out); fvs << vs->strprog.c_str(); } diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index cad117c2c8..2ca6f67077 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -114,7 +114,8 @@ void ValidateVertexShaderIDs(API_TYPE api, VERTEXSHADERUIDSAFE old_id, const std static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%svsuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << msg; file << "\n\nOld shader code:\n" << old_code; file << "\n\nNew shader code:\n" << new_code; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp index 41e5423990..c688228945 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/D3DShader.cpp @@ -64,7 +64,8 @@ bool CompileVertexShader(const char* code, unsigned int len, D3DBlob** blob) static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_vs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << code; file.close(); @@ -121,7 +122,8 @@ bool CompileGeometryShader(const char* code, unsigned int len, D3DBlob** blob, static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_gs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << code; file.close(); @@ -180,7 +182,8 @@ bool CompilePixelShader(const char* code, unsigned int len, D3DBlob** blob, static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_ps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << code; file.close(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp index 9c17c3df8c..c7c4cf266a 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DShader.cpp @@ -50,7 +50,8 @@ bool CompileVertexShader(const char *code, int len, u8 **bytecode, int *bytecode static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_vs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << code; file.close(); @@ -105,7 +106,8 @@ bool CompilePixelShader(const char *code, int len, u8 **bytecode, int *bytecodel static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_ps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << code; file.close(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 61e41008b3..572c7f19c7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -264,7 +264,8 @@ bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrpr static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_ps_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << pstrprogram; file.close(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 6ea10fc077..a6da4d6fa4 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -249,10 +249,12 @@ void VertexManager::vFlush() // save the shaders char strfile[255]; sprintf(strfile, "%sps%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); - std::ofstream fps(strfile); + std::ofstream fps; + OpenFStream(fps, strfile, std::ios_base::out); fps << ps->strprog.c_str(); sprintf(strfile, "%svs%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); - std::ofstream fvs(strfile); + std::ofstream fvs; + OpenFStream(fvs, strfile, std::ios_base::out); fvs << vs->strprog.c_str(); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index dbbb7ee29b..7d003b8363 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -144,7 +144,8 @@ bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrpr static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%sbad_vs_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << pstrprogram; file.close(); From b0630790c1c195ba7654c140d6c6baa4dcddd346 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 28 Feb 2013 19:42:29 -0600 Subject: [PATCH 123/167] It's 2013! Why can't I use C++11 yet!? --- Source/Core/Common/Src/FileUtil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/Src/FileUtil.h b/Source/Core/Common/Src/FileUtil.h index dd1abe6ae9..2747c50cf4 100644 --- a/Source/Core/Common/Src/FileUtil.h +++ b/Source/Core/Common/Src/FileUtil.h @@ -234,7 +234,7 @@ void OpenFStream(T& fstream, const std::string& filename, std::ios_base::openmod #ifdef _WIN32 fstream.open(UTF8ToTStr(filename).c_str(), openmode); #else - fstream.open(filename, openmode); + fstream.open(filename.c_str(), openmode); #endif } From 99cf57eb393e61bc0a9072a6e4f4f21c57daea9d Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Fri, 1 Mar 2013 19:21:34 +1300 Subject: [PATCH 124/167] Fixes two memory leaks, one is pretty bad for OSX. Yell at pauldachz if this doesn't work. Or... say thanks. --- Source/Core/DiscIO/Src/WiiWad.cpp | 3 ++- .../InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Core/DiscIO/Src/WiiWad.cpp b/Source/Core/DiscIO/Src/WiiWad.cpp index 24e091f9f4..fa44108586 100644 --- a/Source/Core/DiscIO/Src/WiiWad.cpp +++ b/Source/Core/DiscIO/Src/WiiWad.cpp @@ -49,7 +49,8 @@ WiiWAD::WiiWAD(const std::string& _rName) if (pReader == NULL || File::IsDirectory(_rName)) { m_Valid = false; - return; + if(pReader) delete pReader; + return; } m_Valid = ParseWAD(*pReader); diff --git a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm index 56e360019a..c22e267044 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm +++ b/Source/Core/InputCommon/Src/ControllerInterface/OSX/OSXKeyboard.mm @@ -69,6 +69,7 @@ bool Keyboard::UpdateInput() CGRectMakeWithDictionaryRepresentation(boundsDictionary, &bounds); } + CFRelease(windowDescriptions); CFRelease(windowArray); CGEventRef event = CGEventCreate(nil); From a2d08d674079720037910a2b3bb82940648875f5 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Fri, 1 Mar 2013 10:11:08 +0100 Subject: [PATCH 125/167] Fix Dolphin starting only once then crashing at startup --- Source/Core/DolphinWX/Src/LogWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/DolphinWX/Src/LogWindow.cpp b/Source/Core/DolphinWX/Src/LogWindow.cpp index 4c9c495713..7af1de1aaa 100644 --- a/Source/Core/DolphinWX/Src/LogWindow.cpp +++ b/Source/Core/DolphinWX/Src/LogWindow.cpp @@ -247,7 +247,7 @@ wxTextCtrl* CLogWindow::CreateTextCtrl(wxPanel* parent, wxWindowID id, long Styl #else TC->SetBackgroundColour(*wxBLACK); #endif - if (m_FontChoice && m_FontChoice->GetSelection() < (int)LogFont.size()) + if (m_FontChoice && m_FontChoice->GetSelection() < (int)LogFont.size() && m_FontChoice->GetSelection() >= 0) TC->SetDefaultStyle(wxTextAttr(wxNullColour, wxNullColour, LogFont[m_FontChoice->GetSelection()])); return TC; From ef7083d78cdeb9eb8881a0d1593164ad1dd04225 Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 1 Mar 2013 11:31:52 +0100 Subject: [PATCH 126/167] also don't cleanup efb copys on efb2ram these may be upscaled and this high res textures would be lost --- Source/Core/VideoCommon/Src/TextureCacheBase.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp index 6871c411fa..dcd3fbdd90 100644 --- a/Source/Core/VideoCommon/Src/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/Src/TextureCacheBase.cpp @@ -132,8 +132,7 @@ void TextureCache::Cleanup() if ( frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount // EFB copies living on the host GPU are unrecoverable and thus shouldn't be deleted - // TODO: encoding the texture back to RAM here might be a good idea - && ! (g_ActiveConfig.bCopyEFBToTexture && iter->second->IsEfbCopy()) ) + && ! iter->second->IsEfbCopy() ) { delete iter->second; textures.erase(iter++); From 5a7bb2abfae1d37d01bef16d3113a0b54813b81f Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 19:30:37 +0100 Subject: [PATCH 127/167] D3D11: Port perf queries code to the PerfQueryBase interface. Remove deprecated PerfQuery methods from RenderBase. Windows build fix. --- Source/Core/VideoCommon/Src/RenderBase.h | 5 - .../VideoCommon/VideoCommon.vcxproj.filters | 10 +- .../Plugin_VideoDX11/Plugin_VideoDX11.vcxproj | 2 + .../Plugin_VideoDX11.vcxproj.filters | 6 + .../Plugin_VideoDX11/Src/PerfQuery.cpp | 148 ++++++++++++++++++ .../Plugins/Plugin_VideoDX11/Src/PerfQuery.h | 46 ++++++ .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 132 ---------------- Source/Plugins/Plugin_VideoDX11/Src/Render.h | 6 - .../Plugin_VideoDX11/Src/VertexManager.cpp | 4 +- Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 3 + .../Plugins/Plugin_VideoOGL/Src/PerfQuery.h | 10 +- 11 files changed, 218 insertions(+), 154 deletions(-) create mode 100644 Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp create mode 100644 Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.h diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h index 7f2853bcc3..55678f3f5a 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.h +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -128,11 +128,6 @@ public: static unsigned int GetPrevPixelFormat() { return prev_efb_format; } static void StorePixelFormat(unsigned int new_format) { prev_efb_format = new_format; } - virtual void ResetPixelPerf() {}; - virtual void ResumePixelPerf(bool efb_copies) {}; - virtual void PausePixelPerf(bool efb_copies) {}; - virtual u32 GetPixelPerfResult(PixelPerfQuery type) { return 0; }; - // TODO: doesn't belong here virtual void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4) = 0; virtual void SetPSConstant4fv(unsigned int const_number, const float *f) = 0; diff --git a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters index 86b2e03221..330b23d370 100644 --- a/Source/Core/VideoCommon/VideoCommon.vcxproj.filters +++ b/Source/Core/VideoCommon/VideoCommon.vcxproj.filters @@ -101,6 +101,9 @@ Base + + Base + Base @@ -113,8 +116,6 @@ Shader Generators - - Base Util @@ -239,6 +240,9 @@ Base + + Base + Base @@ -251,8 +255,6 @@ Shader Generators - - Base Util diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj index 52d1c37aed..aab9345ef7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj @@ -199,6 +199,7 @@ + @@ -228,6 +229,7 @@ + diff --git a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters index 6492e887ca..4b8efac92b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters +++ b/Source/Plugins/Plugin_VideoDX11/Plugin_VideoDX11.vcxproj.filters @@ -57,6 +57,9 @@ Render + + Render + @@ -117,6 +120,9 @@ Render + + Render + diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp new file mode 100644 index 0000000000..6ab91fed27 --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp @@ -0,0 +1,148 @@ +#include "RenderBase.h" + +#include "D3DBase.h" +#include "PerfQuery.h" + +namespace DX11 { + +PerfQuery::PerfQuery() + : m_query_read_pos() + , m_query_count() +{ + for (int i = 0; i != ARRAYSIZE(m_query_buffer); ++i) + { + D3D11_QUERY_DESC qdesc = CD3D11_QUERY_DESC(D3D11_QUERY_OCCLUSION, 0); + D3D::device->CreateQuery(&qdesc, &m_query_buffer[i].query); + } + ResetQuery(); +} + +PerfQuery::~PerfQuery() +{ + for (int i = 0; i != ARRAYSIZE(m_query_buffer); ++i) + { + // TODO: EndQuery? + m_query_buffer[i].query->Release(); + } +} + +void PerfQuery::EnableQuery(PerfQueryGroup type) +{ + // Is this sane? + if (m_query_count > ARRAYSIZE(m_query_buffer) / 2) + WeakFlush(); + + if (ARRAYSIZE(m_query_buffer) == m_query_count) + { + // TODO + FlushOne(); + ERROR_LOG(VIDEO, "flushed query buffer early!"); + } + + // start query + if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) + { + auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % ARRAYSIZE(m_query_buffer)]; + + D3D::context->Begin(entry.query); + entry.query_type = type; + + ++m_query_count; + } +} + +void PerfQuery::DisableQuery(PerfQueryGroup type) +{ + // stop query + if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP) + { + auto& entry = m_query_buffer[(m_query_read_pos + m_query_count + ARRAYSIZE(m_query_buffer)-1) % ARRAYSIZE(m_query_buffer)]; + D3D::context->End(entry.query); + } +} + +void PerfQuery::ResetQuery() +{ + m_query_count = 0; + std::fill_n(m_results, ARRAYSIZE(m_results), 0); +} + +u32 PerfQuery::GetQueryResult(PerfQueryType type) +{ + u32 result = 0; + + if (type == PQ_ZCOMP_INPUT_ZCOMPLOC || type == PQ_ZCOMP_OUTPUT_ZCOMPLOC) + { + result = m_results[PQG_ZCOMP_ZCOMPLOC]; + } + else if (type == PQ_ZCOMP_INPUT || type == PQ_ZCOMP_OUTPUT) + { + result = m_results[PQG_ZCOMP]; + } + else if (type == PQ_BLEND_INPUT) + { + result = m_results[PQG_ZCOMP] + m_results[PQG_ZCOMP_ZCOMPLOC]; + } + else if (type == PQ_EFB_COPY_CLOCKS) + { + result = m_results[PQG_EFB_COPY_CLOCKS]; + } + + return result / 4; +} + +void PerfQuery::FlushOne() +{ + auto& entry = m_query_buffer[m_query_read_pos]; + + UINT64 result = 0; + HRESULT hr = S_FALSE; + while (hr != S_OK) + { + // TODO: Might cause us to be stuck in an infinite loop! + hr = D3D::context->GetData(entry.query, &result, sizeof(result), 0); + } + + m_results[entry.query_type] += result * EFB_WIDTH * EFB_HEIGHT / g_renderer->GetTargetWidth() / g_renderer->GetTargetHeight(); + + m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); + --m_query_count; +} + +// TODO: could selectively flush things, but I don't think that will do much +void PerfQuery::FlushResults() +{ + while (!IsFlushed()) + FlushOne(); +} + +void PerfQuery::WeakFlush() +{ + while (!IsFlushed()) + { + auto& entry = m_query_buffer[m_query_read_pos]; + + UINT64 result = 0; + HRESULT hr = D3D::context->GetData(entry.query, &result, sizeof(result), D3D11_ASYNC_GETDATA_DONOTFLUSH); + + if (hr == S_OK) + { + m_results[entry.query_type] += result * EFB_WIDTH * EFB_HEIGHT / g_renderer->GetTargetWidth() / g_renderer->GetTargetHeight(); + + m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); + --m_query_count; + } + else + { + break; + } + } +} + +bool PerfQuery::IsFlushed() const +{ + return 0 == m_query_count; +} + + +} // namespace diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.h b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.h new file mode 100644 index 0000000000..b3709d1013 --- /dev/null +++ b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.h @@ -0,0 +1,46 @@ +#ifndef _PERFQUERY_H_ +#define _PERFQUERY_H_ + +#include "PerfQueryBase.h" + +namespace DX11 { + +class PerfQuery : public PerfQueryBase +{ +public: + PerfQuery(); + ~PerfQuery(); + + void EnableQuery(PerfQueryGroup type); + void DisableQuery(PerfQueryGroup type); + void ResetQuery(); + u32 GetQueryResult(PerfQueryType type); + void FlushResults(); + bool IsFlushed() const; + +private: + struct ActiveQuery + { + ID3D11Query* query; + PerfQueryGroup query_type; + }; + + void WeakFlush(); + + // Only use when non-empty + void FlushOne(); + + // when testing in SMS: 64 was too small, 128 was ok + static const int PERF_QUERY_BUFFER_SIZE = 512; + + ActiveQuery m_query_buffer[PERF_QUERY_BUFFER_SIZE]; + int m_query_read_pos; + + // TODO: sloppy + volatile int m_query_count; + volatile u32 m_results[PQG_NUM_MEMBERS]; +}; + +} // namespace + +#endif // _PERFQUERY_H_ diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 882d20f8e6..2dcfcd041c 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -65,18 +65,6 @@ ID3D11RasterizerState* resetraststate = NULL; static ID3D11Texture2D* s_screenshot_texture = NULL; -// Using a vector of query objects to avoid flushing the gpu pipeline all the time -// TODO: Could probably optimized further by using a ring buffer or something -#define MAX_PIXEL_PERF_QUERIES 20 // 20 is an arbitrary guess -std::vector pixel_perf_queries; -static int pixel_perf_query_index = 0; - -static u64 pixel_perf = 0; -static bool pixel_perf_active = false; -static bool pixel_perf_dirty = false; - -ID3D11Query* gpu_finished_query = NULL; - // GX pipeline state struct @@ -170,9 +158,6 @@ void SetupDeviceObjects() D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState"); s_screenshot_texture = NULL; - - D3D11_QUERY_DESC qdesc = CD3D11_QUERY_DESC(D3D11_QUERY_EVENT, 0); - D3D::device->CreateQuery(&qdesc, &gpu_finished_query); } // Kill off all device objects @@ -180,12 +165,6 @@ void TeardownDeviceObjects() { delete g_framebuffer_manager; - while (!pixel_perf_queries.empty()) - { - SAFE_RELEASE(pixel_perf_queries.back()); - pixel_perf_queries.pop_back(); - } - SAFE_RELEASE(gpu_finished_query); SAFE_RELEASE(access_efb_cbuf); SAFE_RELEASE(clearblendstates[0]); SAFE_RELEASE(clearblendstates[1]); @@ -232,11 +211,6 @@ Renderer::Renderer() s_LastEFBScale = g_ActiveConfig.iEFBScale; CalculateTargetSize(s_backbuffer_width, s_backbuffer_height); - pixel_perf_query_index = 0; - pixel_perf = 0; - pixel_perf_active = false; - pixel_perf_dirty = false; - SetupDeviceObjects(); @@ -660,112 +634,6 @@ void Renderer::ReinterpretPixelData(unsigned int convtype) D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), FramebufferManager::GetEFBDepthTexture()->GetDSV()); } -void Renderer::ResetPixelPerf() -{ - if (g_ActiveConfig.bDisablePixelPerf) - return; - - if (pixel_perf_active) - PausePixelPerf(false); - - pixel_perf_query_index = 0; - pixel_perf = 0; -} - -void Renderer::ResumePixelPerf(bool efb_copies) -{ - if (g_ActiveConfig.bDisablePixelPerf) - return; - - if (efb_copies) - return; - - if(pixel_perf_active) - return; - - if (pixel_perf_queries.size() < pixel_perf_query_index+1 && pixel_perf_query_index < MAX_PIXEL_PERF_QUERIES) - { - D3D11_QUERY_DESC qdesc = CD3D11_QUERY_DESC(D3D11_QUERY_OCCLUSION, 0); - ID3D11Query* tmpquery = NULL; - D3D::device->CreateQuery(&qdesc, &tmpquery); - pixel_perf_queries.push_back(tmpquery); - pixel_perf_query_index = pixel_perf_queries.size() - 1; - } - else if (pixel_perf_queries.size() < pixel_perf_query_index+1) - { - StorePixelPerfResult(PP_ZCOMP_OUTPUT); - pixel_perf_query_index = 0; - } - // This will spam the D3D11 debug runtime output with QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS warnings which safely can be ignored. Mute them in the DX control panel if you need to read the debug runtime output. - D3D::context->Begin(pixel_perf_queries[pixel_perf_query_index]); - pixel_perf_active = true; - pixel_perf_dirty = true; -} - -void Renderer::PausePixelPerf(bool efb_copies) -{ - if (g_ActiveConfig.bDisablePixelPerf) - return; - - if(!pixel_perf_active) - return; - - D3D::context->End(pixel_perf_queries[pixel_perf_query_index]); - pixel_perf_query_index++; - pixel_perf_active = false; -} - -void Renderer::StorePixelPerfResult(PixelPerfQuery type) -{ - // First, make sure the GPU has finished rendering so that query results are valid - D3D::context->End(gpu_finished_query); - BOOL gpu_finished = FALSE; - while (!gpu_finished) - { - // If nothing goes horribly wrong here, this should complete in finite time... - D3D::context->GetData(gpu_finished_query, &gpu_finished, sizeof(gpu_finished), 0); - } - - for(int i = 0; i < pixel_perf_query_index; ++i) - { - UINT64 buf = 0; - D3D::context->GetData(pixel_perf_queries[i], &buf, sizeof(buf), 0); - - // Reported pixel metrics should be referenced to native resolution: - pixel_perf += buf * EFB_WIDTH * EFB_HEIGHT / GetTargetWidth() / GetTargetHeight(); - } - pixel_perf_dirty = false; -} - -u32 Renderer::GetPixelPerfResult(PixelPerfQuery type) -{ - if (g_ActiveConfig.bDisablePixelPerf) - return 0; - - if (type == PP_EFB_COPY_CLOCKS) - { - // not implemented - return 0; - } - - if (type == PE_PERF_ZCOMP_INPUT_ZCOMPLOC_L || - type == PE_PERF_ZCOMP_INPUT_ZCOMPLOC_H || - type == PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_L || - type == PE_PERF_ZCOMP_OUTPUT_ZCOMPLOC_H) - { - // return zero for now because ZCOMP_OUTPUT_ZCOMPLOC + ZCOMP_OUTPUT should equal BLEND_INPUT - // TODO: Instead, should keep separate counters for zcomploc and non-zcomploc registers. - return 0; - } - - // Basically we only implement PP_ZCOMP_OUTPUT, but we're returning the same value for PP_ZCOMP_INPUT and PP_BLEND_INPUT anyway - if (pixel_perf_dirty) - StorePixelPerfResult(PP_ZCOMP_OUTPUT); - - // Dividing by 4 because we're expected to return the number of 2x2 quads instead of pixels - return std::min(pixel_perf / 4, (u64)0xFFFFFFFF); -} - void SetSrcBlend(D3D11_BLEND val) { // Colors should blend against SRC_ALPHA diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h index 6db829c205..8f6c78fae1 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.h @@ -46,12 +46,6 @@ public: void ReinterpretPixelData(unsigned int convtype); - void ResetPixelPerf(); - void ResumePixelPerf(bool efb_copies); - void PausePixelPerf(bool efb_copies); - u32 GetPixelPerfResult(PixelPerfQuery type); - void StorePixelPerfResult(PixelPerfQuery type); // internal - void UpdateViewport(Matrix44& vpCorrection); bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 8137e1a39f..6991b11690 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -274,9 +274,9 @@ void VertexManager::vFlush() g_nativeVertexFmt->SetupVertexPointers(); g_renderer->ApplyState(useDstAlpha); - g_renderer->ResumePixelPerf(false); + g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); Draw(stride); - g_renderer->PausePixelPerf(false); + g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index b7dd9101d3..af4d57dbf9 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -42,6 +42,7 @@ #include "D3DUtil.h" #include "D3DBase.h" +#include "PerfQuery.h" #include "PixelShaderCache.h" #include "TextureCache.h" #include "VertexManager.h" @@ -185,6 +186,7 @@ void VideoBackend::Video_Prepare() g_renderer = new Renderer; g_texture_cache = new TextureCache; g_vertex_manager = new VertexManager; + g_perf_query = new PerfQuery; VertexShaderCache::Init(); PixelShaderCache::Init(); D3D::InitUtils(); @@ -227,6 +229,7 @@ void VideoBackend::Shutdown() D3D::ShutdownUtils(); PixelShaderCache::Shutdown(); VertexShaderCache::Shutdown(); + delete g_perf_query; delete g_vertex_manager; delete g_texture_cache; delete g_renderer; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h index 76040272e3..34c64e43a1 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h @@ -17,25 +17,25 @@ public: u32 GetQueryResult(PerfQueryType type); void FlushResults(); bool IsFlushed() const; - + private: struct ActiveQuery { GLuint query_id; PerfQueryGroup query_type; }; - + // when testing in SMS: 64 was too small, 128 was ok static const int PERF_QUERY_BUFFER_SIZE = 512; - + void WeakFlush(); // Only use when non-empty void FlushOne(); - + // This contains gl query objects with unretrieved results. ActiveQuery m_query_buffer[PERF_QUERY_BUFFER_SIZE]; int m_query_read_pos; - + // TODO: sloppy volatile int m_query_count; volatile u32 m_results[PQG_NUM_MEMBERS]; From 4058b4c38a1d591253e1b1f84a44c95161607249 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 23:02:11 +0100 Subject: [PATCH 128/167] Add documentation to PerfQueryBase interface. Remove the config field for perf queries (wasn't used for the new interface anyway). Few other cleanups. --- Source/Core/VideoCommon/Src/BPStructs.cpp | 2 +- Source/Core/VideoCommon/Src/MainBase.cpp | 4 ++-- Source/Core/VideoCommon/Src/PerfQueryBase.h | 13 +++++++++++++ Source/Core/VideoCommon/Src/PixelEngine.cpp | 1 - Source/Core/VideoCommon/Src/VideoConfig.cpp | 4 ---- Source/Core/VideoCommon/Src/VideoConfig.h | 3 +-- Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 9 +++------ 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index a79af48370..fa6bc08966 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -485,7 +485,7 @@ void BPWritten(const BPCmd& bp) case BPMEM_IND_IMASK: // Index Mask ? case BPMEM_REVBITS: // Always set to 0x0F when GX_InitRevBits() is called. break; - + case BPMEM_CLEAR_PIXEL_PERF: // GXClearPixMetric writes 0xAAA here, Sunshine alternates this register between values 0x000 and 0xAAA g_perf_query->ResetQuery(); diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index 0d357a4f80..1472367f21 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -195,7 +195,7 @@ void VideoFifo_CheckPerfQueryRequest() u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type) { - // Is this check sane? + // TODO: Is this check sane? if (!g_perf_query->IsFlushed()) { if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) @@ -207,7 +207,7 @@ u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type) else g_perf_query->FlushResults(); } - + return g_perf_query->GetQueryResult(type); } diff --git a/Source/Core/VideoCommon/Src/PerfQueryBase.h b/Source/Core/VideoCommon/Src/PerfQueryBase.h index 2643482379..b979449edb 100644 --- a/Source/Core/VideoCommon/Src/PerfQueryBase.h +++ b/Source/Core/VideoCommon/Src/PerfQueryBase.h @@ -28,11 +28,24 @@ public: PerfQueryBase() {}; virtual ~PerfQueryBase() {} + // Begin querying the specified value for the following host GPU commands virtual void EnableQuery(PerfQueryGroup type) {} + + // Stop querying the specified value for the following host GPU commands virtual void DisableQuery(PerfQueryGroup type) {} + + // Reset query counters to zero and drop any pending queries virtual void ResetQuery() {} + + // Return the measured value for the specified query type + // NOTE: Called from CPU thread virtual u32 GetQueryResult(PerfQueryType type) { return 0; } + + // Request the value of any pending queries - causes a pipeline flush and thus should be used carefully! virtual void FlushResults() {} + + // True if there are no further pending query results + // NOTE: Called from CPU thread virtual bool IsFlushed() const { return true; } }; diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index 2d6275096c..e5ba554678 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -299,7 +299,6 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) // Later builds returned 1 for the high register. That caused the timer to actually count down, but made the challenge unbeatable because the game always thought you didn't clear any goop at all. // Note that currently this functionality is only implemented in the D3D11 backend. _uReturnValue = g_video_backend->Video_GetQueryResult(PQ_BLEND_INPUT) & 0xFFFF; - //ERROR_LOG(VIDEO, "PQ_BLEND_INPUT: %d", g_video_backend->Video_GetQueryResult(PQ_BLEND_INPUT)); break; case PE_PERF_BLEND_INPUT_H: diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index bd5c6a7acb..a76514a10c 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -105,7 +105,6 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true); iniFile.Get("Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable, false); iniFile.Get("Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, false); - iniFile.Get("Hacks", "DisablePixelPerf", &bDisablePixelPerf, true); iniFile.Get("Hardware", "Adapter", &iAdapter, 0); @@ -154,7 +153,6 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video_Hacks", "EFBScaledCopy", &bCopyEFBScaled); iniFile.GetIfExists("Video_Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable); iniFile.GetIfExists("Video_Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges); - iniFile.GetIfExists("Video_Hacks", "DisablePixelPerf", &bDisablePixelPerf); iniFile.GetIfExists("Video", "ProjectionHack", &iPhackvalue[0]); iniFile.GetIfExists("Video", "PH_SZNear", &iPhackvalue[1]); @@ -233,7 +231,6 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled); iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); - iniFile.Set("Hacks", "DisablePixelPerf", bDisablePixelPerf); iniFile.Set("Hardware", "Adapter", iAdapter); @@ -289,7 +286,6 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini) SET_IF_DIFFERS("Video_Hacks", "EFBScaledCopy", bCopyEFBScaled); SET_IF_DIFFERS("Video_Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable); SET_IF_DIFFERS("Video_Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges); - SET_IF_DIFFERS("Video_Hacks", "DisablePixelPerf", bDisablePixelPerf); iniFile.Save(game_ini); } diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index c9d2eef217..0531918183 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -115,7 +115,7 @@ struct VideoConfig int iAnaglyphStereoSeparation; int iAnaglyphFocalAngle; bool b3DVision; - + // Hacks bool bEFBAccessEnable; bool bDlistCachingEnable; @@ -133,7 +133,6 @@ struct VideoConfig bool bZTPSpeedHack; // The Legend of Zelda: Twilight Princess bool bUseBBox; bool bEnablePixelLighting; - bool bDisablePixelPerf; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index bf7bf16989..970d4c7085 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -57,6 +57,7 @@ #include "ConfigManager.h" #include "VideoBackend.h" +#include "PerfQueryBase.h" namespace DX9 { @@ -156,12 +157,6 @@ bool VideoBackend::Initialize(void *&window_handle) s_BackendInitialized = true; - if (!g_Config.bDisablePixelPerf) - { - OSD::AddMessage("PE perf metrics enabled although the D3D9 backend doesn't support them!"); - OSD::AddMessage("Try a different backend when issues arise."); - } - return true; } @@ -176,6 +171,7 @@ void VideoBackend::Video_Prepare() g_vertex_manager = new VertexManager; g_renderer = new Renderer; g_texture_cache = new TextureCache; + g_perf_query = new PerfQueryBase; // VideoCommon BPInit(); Fifo_Init(); @@ -213,6 +209,7 @@ void VideoBackend::Shutdown() // internal interfaces PixelShaderCache::Shutdown(); VertexShaderCache::Shutdown(); + delete g_perf_query; delete g_texture_cache; delete g_renderer; delete g_vertex_manager; From d1acb0a937d842abaf55844d63298971e73ecee7 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 23:12:41 +0100 Subject: [PATCH 129/167] OGL: Fix perf metrics being overcounted when using a non-native internal resolution. --- Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp | 1 + Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp index 6ab91fed27..d2a76d7d4b 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp @@ -103,6 +103,7 @@ void PerfQuery::FlushOne() hr = D3D::context->GetData(entry.query, &result, sizeof(result), 0); } + // NOTE: Reported pixel metrics should be referenced to native resolution m_results[entry.query_type] += result * EFB_WIDTH * EFB_HEIGHT / g_renderer->GetTargetWidth() / g_renderer->GetTargetHeight(); m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp index 8cee426e98..42ff918942 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp @@ -1,3 +1,4 @@ +#include "RenderBase.h" #include "GLUtil.h" #include "PerfQuery.h" @@ -61,12 +62,13 @@ bool PerfQuery::IsFlushed() const void PerfQuery::FlushOne() { auto& entry = m_query_buffer[m_query_read_pos]; - + GLuint result = 0; glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result); - - m_results[entry.query_type] += result; - + + // NOTE: Reported pixel metrics should be referenced to native resolution + m_results[entry.query_type] += result * EFB_WIDTH * EFB_HEIGHT / g_renderer->GetTargetWidth() / g_renderer->GetTargetHeight(); + m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); --m_query_count; } From cb1d21c032b92412d5d795705642189657db37e3 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 1 Mar 2013 23:57:56 +0100 Subject: [PATCH 130/167] PerfQueries: Fix an integer overflow. --- Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp | 5 +++-- Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp index d2a76d7d4b..b859d50ec6 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PerfQuery.cpp @@ -104,7 +104,7 @@ void PerfQuery::FlushOne() } // NOTE: Reported pixel metrics should be referenced to native resolution - m_results[entry.query_type] += result * EFB_WIDTH * EFB_HEIGHT / g_renderer->GetTargetWidth() / g_renderer->GetTargetHeight(); + m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight(); m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); --m_query_count; @@ -128,7 +128,8 @@ void PerfQuery::WeakFlush() if (hr == S_OK) { - m_results[entry.query_type] += result * EFB_WIDTH * EFB_HEIGHT / g_renderer->GetTargetWidth() / g_renderer->GetTargetHeight(); + // NOTE: Reported pixel metrics should be referenced to native resolution + m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight(); m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); --m_query_count; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp index 42ff918942..95311eb98d 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp @@ -67,7 +67,7 @@ void PerfQuery::FlushOne() glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result); // NOTE: Reported pixel metrics should be referenced to native resolution - m_results[entry.query_type] += result * EFB_WIDTH * EFB_HEIGHT / g_renderer->GetTargetWidth() / g_renderer->GetTargetHeight(); + m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight(); m_query_read_pos = (m_query_read_pos + 1) % ARRAYSIZE(m_query_buffer); --m_query_count; From e079d2491282f334f0d87dd16801550efcf8d4d1 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Fri, 1 Mar 2013 19:33:17 -0600 Subject: [PATCH 131/167] Kill wstring version of game description. --- Source/Core/DiscIO/Src/BannerLoader.cpp | 126 -------------------- Source/Core/DiscIO/Src/BannerLoader.h | 5 +- Source/Core/DiscIO/Src/BannerLoaderWii.cpp | 120 ++++++++++++++++--- Source/Core/DiscIO/Src/BannerLoaderWii.h | 4 +- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 22 ++-- Source/Core/DolphinWX/Src/ISOFile.cpp | 9 +- Source/Core/DolphinWX/Src/ISOFile.h | 4 +- Source/Core/DolphinWX/Src/ISOProperties.cpp | 6 +- 8 files changed, 120 insertions(+), 176 deletions(-) diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp index 2350896c9c..2c28401c93 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.cpp +++ b/Source/Core/DiscIO/Src/BannerLoader.cpp @@ -22,25 +22,6 @@ #include "VolumeCreator.h" #include "FileUtil.h" -// HyperIris: dunno if this suitable, may be need move. -#ifdef _WIN32 -#include -#else -#include -#ifndef ANDROID -#include -#endif -#include -#endif - -#ifndef ICONV_CONST -#if defined __FreeBSD__ || __NetBSD__ -#define ICONV_CONST const -#else -#define ICONV_CONST -#endif -#endif - namespace DiscIO { void IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _src) @@ -96,113 +77,6 @@ void IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _rDestination = destBuffer; } -bool IBannerLoader::CopyBeUnicodeToString( std::string& _rDestination, const u16* _src, int length ) -{ - bool returnCode = false; -#ifdef WIN32 - if (_src) - { - u16* buffer = new u16[length]; - if (buffer) - { - memcpy(buffer, _src, sizeof(u16)*length); - for (int i = 0; i < length; i++) - { - buffer[i] = swap16(buffer[i]); - } - - u32 ansiNameSize = WideCharToMultiByte(932, 0, - (LPCWSTR)buffer, (int)wcslen((LPCWSTR)buffer), - NULL, NULL, NULL, NULL); - if (ansiNameSize > 0) - { - char* pAnsiStrBuffer = new char[ansiNameSize + 1]; - if (pAnsiStrBuffer) - { - memset(pAnsiStrBuffer, 0, (ansiNameSize + 1) * sizeof(char)); - if (WideCharToMultiByte(932, 0, - (LPCWSTR)buffer, (int)wcslen((LPCWSTR)buffer), - pAnsiStrBuffer, ansiNameSize, NULL, NULL)) - { - _rDestination = pAnsiStrBuffer; - returnCode = true; - } - delete[] pAnsiStrBuffer; - } - } - delete[] buffer; - } - } -#else -#ifdef ANDROID - return false; -#else - if (_src) - { - iconv_t conv_desc = iconv_open("UTF-8", "CP932"); - if (conv_desc == (iconv_t) -1) - { - // Initialization failure. - if (errno == EINVAL) - { - ERROR_LOG(DISCIO, "Conversion from CP932 to UTF-8 is not supported."); - } - else - { - ERROR_LOG(DISCIO, "Iconv initialization failure: %s\n", strerror (errno)); - } - return false; - } - - char* src_buffer = new char[length]; - for (int i = 0; i < length; i++) - src_buffer[i] = swap16(_src[i]); - - size_t inbytes = sizeof(char) * length; - size_t outbytes = 2 * inbytes; - char* utf8_buffer = new char[outbytes + 1]; - memset(utf8_buffer, 0, (outbytes + 1) * sizeof(char)); - - // Save the buffer locations because iconv increments them - char* utf8_buffer_start = utf8_buffer; - char* src_buffer_start = src_buffer; - - size_t iconv_size = iconv(conv_desc, - (ICONV_CONST char**)&src_buffer, &inbytes, - &utf8_buffer, &outbytes); - - // Handle failures - if (iconv_size == (size_t) -1) - { - ERROR_LOG(DISCIO, "iconv failed."); - switch (errno) { - case EILSEQ: - ERROR_LOG(DISCIO, "Invalid multibyte sequence."); - break; - case EINVAL: - ERROR_LOG(DISCIO, "Incomplete multibyte sequence."); - break; - case E2BIG: - ERROR_LOG(DISCIO, "Insufficient space allocated for output buffer."); - break; - default: - ERROR_LOG(DISCIO, "Error: %s.", strerror(errno)); - } - } - else - { - _rDestination = utf8_buffer_start; - returnCode = true; - } - delete[] utf8_buffer_start; - delete[] src_buffer_start; - iconv_close(conv_desc); - } -#endif -#endif - return returnCode; -} - IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume) { if (IsVolumeWiiDisc(pVolume) || IsVolumeWadFile(pVolume)) diff --git a/Source/Core/DiscIO/Src/BannerLoader.h b/Source/Core/DiscIO/Src/BannerLoader.h index 1fe48dd364..ef2e0e64b9 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.h +++ b/Source/Core/DiscIO/Src/BannerLoader.h @@ -43,14 +43,11 @@ class IBannerLoader virtual bool GetCompany(std::string& _rCompany) = 0; virtual bool GetDescription(std::string* _rDescription) = 0; - virtual bool GetDescription(std::wstring& _rDescription) {return false;}; - protected: void CopyToStringAndCheck(std::string& _rDestination, const char* _src); - - bool CopyBeUnicodeToString(std::string& _rDestination, const u16* _src, int length); + private: u16 swap16(u16 data) { diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp index b23dc4d91a..d8d8076721 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include +#include #include "Common.h" #include "ColorUtil.h" @@ -24,6 +25,25 @@ #include "FileUtil.h" #include "FileHandlerARC.h" +// HyperIris: dunno if this suitable, may be need move. +#ifdef _WIN32 +#include +#else +#include +#ifndef ANDROID +#include +#endif +#include +#endif + +#ifndef ICONV_CONST +#if defined __FreeBSD__ || __NetBSD__ +#define ICONV_CONST const +#else +#define ICONV_CONST +#endif +#endif + namespace DiscIO { @@ -152,16 +172,8 @@ bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::stri { // find Banner type SWiiBanner *pBanner = (SWiiBanner*)m_pBannerFile; - - // Ensure the string is null-terminating, since the banner format - // doesn't require it - u16 *src = new u16[COMMENT_SIZE + 1]; - memcpy(src, &pBanner->m_Comment[index], COMMENT_SIZE * sizeof(u16)); - src[COMMENT_SIZE] = 0; - - ret = CopyBeUnicodeToString(s, src, COMMENT_SIZE + 1); - - delete [] src; + // TODO: trim NULLs + ret = CopyBeUnicodeToString(s, pBanner->m_Comment[index], COMMENT_SIZE); } return ret; @@ -208,11 +220,6 @@ bool CBannerLoaderWii::GetDescription(std::string* _rDescription) return GetStringFromComments(DESC_IDX, *_rDescription); } -bool CBannerLoaderWii::GetDescription(std::wstring& _rDescription) -{ - return GetStringFromComments(DESC_IDX, _rDescription); -} - void CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height) { for (int y = 0; y < height; y += 4) @@ -231,4 +238,87 @@ void CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height) } } +bool CBannerLoaderWii::CopyBeUnicodeToString( std::string& _rDestination, const u16* _src, int length ) +{ + bool returnCode = false; +#ifdef _WIN32 + if (_src) + { + std::wstring src; + src.resize(length); + std::transform(_src, _src + length, &src[0], (u16(&)(u16))Common::swap16); + + _rDestination = UTF16ToUTF8(src); + returnCode = true; + } +#else +#ifdef ANDROID + return false; +#else + if (_src) + { + iconv_t conv_desc = iconv_open("UTF-8", "CP932"); + if (conv_desc == (iconv_t) -1) + { + // Initialization failure. + if (errno == EINVAL) + { + ERROR_LOG(DISCIO, "Conversion from CP932 to UTF-8 is not supported."); + } + else + { + ERROR_LOG(DISCIO, "Iconv initialization failure: %s\n", strerror (errno)); + } + return false; + } + + char* src_buffer = new char[length]; + for (int i = 0; i < length; i++) + src_buffer[i] = swap16(_src[i]); + + size_t inbytes = sizeof(char) * length; + size_t outbytes = 2 * inbytes; + char* utf8_buffer = new char[outbytes + 1]; + memset(utf8_buffer, 0, (outbytes + 1) * sizeof(char)); + + // Save the buffer locations because iconv increments them + char* utf8_buffer_start = utf8_buffer; + char* src_buffer_start = src_buffer; + + size_t iconv_size = iconv(conv_desc, + (ICONV_CONST char**)&src_buffer, &inbytes, + &utf8_buffer, &outbytes); + + // Handle failures + if (iconv_size == (size_t) -1) + { + ERROR_LOG(DISCIO, "iconv failed."); + switch (errno) { + case EILSEQ: + ERROR_LOG(DISCIO, "Invalid multibyte sequence."); + break; + case EINVAL: + ERROR_LOG(DISCIO, "Incomplete multibyte sequence."); + break; + case E2BIG: + ERROR_LOG(DISCIO, "Insufficient space allocated for output buffer."); + break; + default: + ERROR_LOG(DISCIO, "Error: %s.", strerror(errno)); + } + } + else + { + _rDestination = utf8_buffer_start; + returnCode = true; + } + delete[] utf8_buffer_start; + delete[] src_buffer_start; + iconv_close(conv_desc); + } +#endif +#endif + return returnCode; +} + } // namespace diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.h b/Source/Core/DiscIO/Src/BannerLoaderWii.h index 83733cf5ed..d7150d7009 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.h +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.h @@ -43,8 +43,6 @@ class CBannerLoaderWii virtual bool GetDescription(std::string* _rDescription); - bool GetDescription(std::wstring& _rDescription); - private: enum @@ -82,6 +80,8 @@ class CBannerLoaderWii bool GetStringFromComments(const CommentIndex index, std::string& s); bool GetStringFromComments(const CommentIndex index, std::wstring& s); + + bool CopyBeUnicodeToString(std::string& _rDestination, const u16* _src, int length); }; } // namespace diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index cab4c8125b..c24f0509ba 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -456,16 +456,9 @@ void CGameListCtrl::InsertItemInReportView(long _Index) SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex); std::wstring wstring_name; - const std::wstring& wstring_description = rISOFile.GetDescription(); - std::string company; wxString name; - wxString description; - // We show the company string on Gamecube only - // On Wii we show the description instead as the company string is empty - if (rISOFile.GetPlatform() == GameListItem::GAMECUBE_DISC) - company = rISOFile.GetCompany().c_str(); int SelectedLanguage = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage; switch (rISOFile.GetCountry()) { @@ -475,11 +468,10 @@ void CGameListCtrl::InsertItemInReportView(long _Index) rISOFile.GetName(wstring_name, -1); name = wxString(rISOFile.GetName(0).c_str(), SJISConv); m_gameList.append(StringFromFormat("%s (J)\n", (const char *)name.c_str())); - description = wxString(company.size() ? company.c_str() : - rISOFile.GetDescription(0).c_str(), SJISConv); } break; case DiscIO::IVolume::COUNTRY_USA: + // Is this sane? SelectedLanguage = 0; default: { @@ -490,19 +482,21 @@ void CGameListCtrl::InsertItemInReportView(long _Index) m_gameList.append(StringFromFormat("%s (%c)\n", rISOFile.GetName(SelectedLanguage).c_str(), (rISOFile.GetCountry() == DiscIO::IVolume::COUNTRY_USA) ? 'U' : 'E')); - description = wxString(company.size() ? company.c_str() : - rISOFile.GetDescription(SelectedLanguage).c_str(), WindowsCP1252); + } break; } if (wstring_name.length()) name = wstring_name.c_str(); - if (wstring_description.length()) - description = wstring_description.c_str(); SetItem(_Index, COLUMN_TITLE, name, -1); - SetItem(_Index, COLUMN_NOTES, description, -1); + + // We show the company string on Gamecube only + // On Wii we show the description instead as the company string is empty + std::string const notes = (rISOFile.GetPlatform() == GameListItem::GAMECUBE_DISC) ? + rISOFile.GetCompany() : rISOFile.GetDescription(SelectedLanguage); + SetItem(_Index, COLUMN_NOTES, StrToWxStr(notes), -1); // Emulation state SetItemColumnImage(_Index, COLUMN_EMULATION_STATE, m_EmuStateImageIndex[rISOFile.GetEmuState()]); diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index 639190fa0e..918a72b0bf 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -37,7 +37,7 @@ #include "ChunkFile.h" #include "ConfigManager.h" -#define CACHE_REVISION 0x10F +#define CACHE_REVISION 0x110 #define DVD_BANNER_WIDTH 96 #define DVD_BANNER_HEIGHT 32 @@ -109,7 +109,6 @@ GameListItem::GameListItem(const std::string& _rFileName) pBannerLoader->GetName(m_wNames); pBannerLoader->GetName(m_Name); pBannerLoader->GetCompany(m_Company); - pBannerLoader->GetDescription(m_wDescription); pBannerLoader->GetDescription(m_Description); if (pBannerLoader->GetBanner(g_ImageTemp)) @@ -235,7 +234,6 @@ void GameListItem::DoState(PointerWrap &p) p.Do(m_Company); p.Do(m_Description[0]); p.Do(m_Description[1]); p.Do(m_Description[2]); p.Do(m_Description[3]); p.Do(m_Description[4]); p.Do(m_Description[5]); - p.Do(m_wDescription); p.Do(m_UniqueID); p.Do(m_FileSize); p.Do(m_VolumeSize); @@ -273,11 +271,6 @@ const std::string& GameListItem::GetDescription(int index) const return m_Description[0]; } -const std::wstring& GameListItem::GetDescription() const -{ - return m_wDescription; -} - const std::string& GameListItem::GetName(int index) const { if ((index >=0) && (index < 6)) diff --git a/Source/Core/DolphinWX/Src/ISOFile.h b/Source/Core/DolphinWX/Src/ISOFile.h index e58dcf7713..1f3ecaa261 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.h +++ b/Source/Core/DolphinWX/Src/ISOFile.h @@ -37,8 +37,7 @@ public: const std::string& GetName(int index) const; bool GetName(std::wstring& wName, int index=0) const; const std::string& GetCompany() const {return m_Company;} - const std::string& GetDescription(int index) const; - const std::wstring& GetDescription() const; + const std::string& GetDescription(int index = 0) const; const std::string& GetUniqueID() const {return m_UniqueID;} const std::string GetWiiFSPath() const; DiscIO::IVolume::ECountry GetCountry() const {return m_Country;} @@ -69,7 +68,6 @@ private: std::vector m_wNames; std::string m_Company; std::string m_Description[6]; - std::wstring m_wDescription; std::string m_UniqueID; std::string m_issues; diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index a194345585..21d451a1ac 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -1339,8 +1339,7 @@ void CISOProperties::ChangeBannerDetails(int lang) else shortName = wxString(OpenGameListItem->GetName(0).c_str(), SJISConv); - if ((comment = OpenGameListItem->GetDescription().c_str()).size() == 0) - comment = wxString(OpenGameListItem->GetDescription(0).c_str(), SJISConv); + comment = StrToWxStr(OpenGameListItem->GetDescription()); maker = wxString(OpenGameListItem->GetCompany().c_str(), SJISConv); break; case DiscIO::IVolume::COUNTRY_USA: @@ -1352,8 +1351,7 @@ void CISOProperties::ChangeBannerDetails(int lang) shortName = wname.c_str(); else shortName = wxString(OpenGameListItem->GetName(lang).c_str(), WindowsCP1252); - if ((comment = OpenGameListItem->GetDescription().c_str()).size() == 0) - comment = wxString(OpenGameListItem->GetDescription(lang).c_str(), WindowsCP1252); + comment = StrToWxStr(OpenGameListItem->GetDescription(lang)); maker = wxString(OpenGameListItem->GetCompany().c_str(), WindowsCP1252); } break; From 2356e5c0e7dab9c0f541e48f8df5fd663d3b671f Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 2 Mar 2013 03:28:44 -0600 Subject: [PATCH 132/167] Eliminate some baseless restrictions in PointerWrap, mainly vector not working. --- Source/Core/Common/Src/ChunkFile.h | 230 +++++++++++++------------- Source/Core/Core/Src/HW/Wiimote.cpp | 2 +- Source/Core/Core/Src/HW/Wiimote.h | 3 +- Source/Core/Core/Src/State.cpp | 2 +- Source/Core/DolphinWX/Src/ISOFile.cpp | 2 +- 5 files changed, 123 insertions(+), 116 deletions(-) diff --git a/Source/Core/Common/Src/ChunkFile.h b/Source/Core/Common/Src/ChunkFile.h index 38e1b2176c..3c0a58f678 100644 --- a/Source/Core/Common/Src/ChunkFile.h +++ b/Source/Core/Common/Src/ChunkFile.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -45,7 +46,8 @@ struct LinkedListItem : public T class PointerWrap { public: - enum Mode { + enum Mode + { MODE_READ = 1, // load MODE_WRITE, // save MODE_MEASURE, // calculate size @@ -57,124 +59,95 @@ public: public: PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_) {} - PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_) {} - void SetMode(Mode mode_) {mode = mode_;} - Mode GetMode() const {return mode;} - u8 **GetPPtr() {return ptr;} + void SetMode(Mode mode_) { mode = mode_; } + Mode GetMode() const { return mode; } + u8** GetPPtr() { return ptr; } - void DoVoid(void *data, int size) + template + void Do(std::map& x) { - switch (mode) { - case MODE_READ: memcpy(data, *ptr, size); break; - case MODE_WRITE: memcpy(*ptr, data, size); break; - case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything - case MODE_VERIFY: for(int i = 0; i < size; i++) _dbg_assert_msg_(COMMON, ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], &(*ptr)[i]); break; - default: break; // throw an error? - } - (*ptr) += size; - } - - template - void Do(std::map &x) - { - unsigned int number = (unsigned int)x.size(); - Do(number); - switch (mode) { + u32 count = (u32)x.size(); + Do(count); + + switch (mode) + { case MODE_READ: + for (x.clear(); count != 0; --count) { - x.clear(); - while (number > 0) - { - unsigned int first = 0; - Do(first); - T second; - Do(second); - x[first] = second; - --number; - } + std::pair pair; + Do(pair.first); + Do(pair.second); + x.insert(pair); } break; + case MODE_WRITE: case MODE_MEASURE: case MODE_VERIFY: + for (auto itr = x.begin(); itr != x.end(); ++itr) { - typename std::map::iterator itr = x.begin(); - while (number > 0) - { - Do(itr->first); - Do(itr->second); - --number; - ++itr; - } + Do(itr->first); + Do(itr->second); } break; } } - - // Store vectors. - template - void Do(std::vector &x) - { - u32 vec_size = (u32)x.size(); - Do(vec_size); - x.resize(vec_size); - DoArray(&x[0], vec_size); - } - // Store deques. - template - void Do(std::deque &x) + template + void DoContainer(T& x) { - u32 deq_size = (u32)x.size(); - Do(deq_size); - x.resize(deq_size); - u32 i; - for(i = 0; i < deq_size; i++) - DoVoid(&x[i],sizeof(T)); - } - - // Store strings. - void Do(std::string &x) - { - int stringLen = (int)x.length() + 1; - Do(stringLen); + u32 size = (u32)x.size(); + Do(size); + x.resize(size); - switch (mode) { - case MODE_READ: x = (char*)*ptr; break; - case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; - case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(COMMON, !strcmp(x.c_str(), (char*)*ptr), "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", x.c_str(), (char*)*ptr, ptr); break; - } - (*ptr) += stringLen; + for (auto itr = x.begin(); itr != x.end(); ++itr) + Do(*itr); } - void Do(std::wstring &x) + template + void Do(std::vector& x) { - int stringLen = sizeof(wchar_t)*((int)x.length() + 1); - Do(stringLen); - - switch (mode) { - case MODE_READ: x.assign((wchar_t*)*ptr, (stringLen / sizeof(wchar_t)) - 1); break; - case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; - case MODE_MEASURE: break; - case MODE_VERIFY: _dbg_assert_msg_(COMMON, x == (wchar_t*)*ptr, "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", x.c_str(), (wchar_t*)*ptr, ptr); break; - } - (*ptr) += stringLen; + DoContainer(x); + } + + template + void Do(std::list& x) + { + DoContainer(x); + } + + template + void Do(std::deque& x) + { + DoContainer(x); + } + + template + void Do(std::basic_string& x) + { + DoContainer(x); } - template - void DoArray(T *x, int count) { - DoVoid((void *)x, sizeof(T) * count); + template + void DoArray(T* x, u32 count) + { + for (u32 i = 0; i != count; ++i) + Do(x[i]); } - template - void Do(T &x) { - DoVoid((void *)&x, sizeof(x)); + template + void Do(T& x) + { + // TODO: Bad, Do(some_non_POD) will compile and fail at runtime + // type_traits are not fully supported everywhere yet + + DoVoid((void*)&x, sizeof(x)); } - template - void DoPointer(T* &x, T*const base) { + template + void DoPointer(T*& x, T* const base) + { // pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range s32 offset = x - base; Do(offset); @@ -182,7 +155,8 @@ public: x = base + offset; } - template* (*TNew)(), void (*TFree)(LinkedListItem*), void (*TDo)(PointerWrap&, T*)> + // Let's pretend std::list doesn't exist! + template * (*TNew)(), void (*TFree)(LinkedListItem*), void (*TDo)(PointerWrap&, T*)> void DoLinkedList(LinkedListItem*& list_start, LinkedListItem** list_end=0) { LinkedListItem* list_cur = list_start; @@ -242,25 +216,61 @@ public: } } - void DoMarker(const char* prevName, u32 arbitraryNumber=0x42) + void DoMarker(const char* prevName, u32 arbitraryNumber = 0x42) { u32 cookie = arbitraryNumber; Do(cookie); - if(mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) + + if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) { - PanicAlertT("Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); + PanicAlertT("Error: After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", + prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); mode = PointerWrap::MODE_MEASURE; } } + +private: + __forceinline void DoByte(u8& x) + { + switch (mode) + { + case MODE_READ: + x = **ptr; + break; + + case MODE_WRITE: + **ptr = x; + break; + + case MODE_MEASURE: + break; + + case MODE_VERIFY: + _dbg_assert_msg_(COMMON, (x == *ptr), + "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", + x, x, &x, *ptr, *ptr, &*ptr); + break; + + default: + break; + } + + ++(*ptr); + } + + void DoVoid(void *data, u32 size) + { + for(u32 i = 0; i != size; ++i) + DoByte(reinterpret_cast(data)[i]); + } }; - class CChunkFileReader { public: // Load file template template - static bool Load(const std::string& _rFilename, int _Revision, T& _class) + static bool Load(const std::string& _rFilename, u32 _Revision, T& _class) { INFO_LOG(COMMON, "ChunkReader: Loading %s" , _rFilename.c_str()); @@ -300,7 +310,7 @@ public: } // get size - const int sz = (int)(fileSize - headerSize); + const u32 sz = (u32)(fileSize - headerSize); if (header.ExpectedSize != sz) { ERROR_LOG(COMMON,"ChunkReader: Bad file size, got %d expected %d", @@ -309,17 +319,16 @@ public: } // read the state - u8* buffer = new u8[sz]; - if (!pFile.ReadBytes(buffer, sz)) + std::vector buffer(sz); + if (!pFile.ReadArray(&buffer[0], sz)) { ERROR_LOG(COMMON,"ChunkReader: Error reading file"); return false; } - u8 *ptr = buffer; + u8* ptr = &buffer[0]; PointerWrap p(&ptr, PointerWrap::MODE_READ); _class.DoState(p); - delete[] buffer; INFO_LOG(COMMON, "ChunkReader: Done loading %s" , _rFilename.c_str()); return true; @@ -327,7 +336,7 @@ public: // Save file template template - static bool Save(const std::string& _rFilename, int _Revision, T& _class) + static bool Save(const std::string& _rFilename, u32 _Revision, T& _class) { INFO_LOG(COMMON, "ChunkReader: Writing %s" , _rFilename.c_str()); File::IOFile pFile(_rFilename, "wb"); @@ -349,9 +358,8 @@ public: // Create header SChunkHeader header; - header.Compress = 0; header.Revision = _Revision; - header.ExpectedSize = (int)sz; + header.ExpectedSize = (u32)sz; // Write to file if (!pFile.WriteArray(&header, 1)) @@ -360,23 +368,21 @@ public: return false; } - if (!pFile.WriteBytes(&buffer[0], sz)) + if (!pFile.WriteArray(&buffer[0], sz)) { ERROR_LOG(COMMON,"ChunkReader: Failed writing data"); return false; } - INFO_LOG(COMMON,"ChunkReader: Done writing %s", - _rFilename.c_str()); + INFO_LOG(COMMON,"ChunkReader: Done writing %s", _rFilename.c_str()); return true; } private: struct SChunkHeader { - int Revision; - int Compress; - int ExpectedSize; + u32 Revision; + u32 ExpectedSize; }; }; diff --git a/Source/Core/Core/Src/HW/Wiimote.cpp b/Source/Core/Core/Src/HW/Wiimote.cpp index 59fe8b7fa5..e45856f5f5 100644 --- a/Source/Core/Core/Src/HW/Wiimote.cpp +++ b/Source/Core/Core/Src/HW/Wiimote.cpp @@ -133,7 +133,7 @@ unsigned int GetAttached() // input/output: ptr // input: mode // -void DoState(unsigned char **ptr, int mode) +void DoState(u8 **ptr, PointerWrap::Mode mode) { // TODO: diff --git a/Source/Core/Core/Src/HW/Wiimote.h b/Source/Core/Core/Src/HW/Wiimote.h index dd0e6df389..6b758abb5a 100644 --- a/Source/Core/Core/Src/HW/Wiimote.h +++ b/Source/Core/Core/Src/HW/Wiimote.h @@ -3,6 +3,7 @@ #define _WIIMOTE_H_ #include "../../InputCommon/Src/InputConfig.h" +#include "ChunkFile.h" #define MAX_WIIMOTES 4 @@ -25,7 +26,7 @@ void Shutdown(); void Initialize(void* const hwnd); unsigned int GetAttached(); -void DoState(unsigned char **ptr, int mode); +void DoState(u8 **ptr, PointerWrap::Mode mode); void EmuStateChange(EMUSTATE_CHANGE newState); InputPlugin *GetPlugin(); diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 773d757337..e0a9ab7858 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 15; +static const u32 STATE_VERSION = 16; struct StateHeader { diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index 833268ad63..496a6304d4 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -36,7 +36,7 @@ #include "ChunkFile.h" #include "ConfigManager.h" -#define CACHE_REVISION 0x10F +#define CACHE_REVISION 0x110 #define DVD_BANNER_WIDTH 96 #define DVD_BANNER_HEIGHT 32 From 6c8adf6130b32a0ffc113f4ce30f70b9d5994f10 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 2 Mar 2013 19:46:55 -0600 Subject: [PATCH 133/167] Eliminate the wstring game name. Some cleanup throughout related code. (try to make logic in ISOFile understandable by a human) Encode strings in UTF-8 rather than somehow trying to determine the encoding in the GUI code. Non-windows OSes temporarily broken. --- Source/Core/Common/Src/StringUtil.cpp | 30 +++- Source/Core/Common/Src/StringUtil.h | 4 +- Source/Core/DiscIO/Src/BannerLoader.cpp | 52 ------- Source/Core/DiscIO/Src/BannerLoader.h | 15 +- Source/Core/DiscIO/Src/BannerLoaderGC.cpp | 138 ++++++++----------- Source/Core/DiscIO/Src/BannerLoaderGC.h | 30 ++-- Source/Core/DiscIO/Src/BannerLoaderWii.cpp | 25 ++-- Source/Core/DiscIO/Src/BannerLoaderWii.h | 10 +- Source/Core/DiscIO/Src/Volume.h | 4 +- Source/Core/DiscIO/Src/VolumeCommon.cpp | 10 +- Source/Core/DiscIO/Src/VolumeDirectory.cpp | 5 +- Source/Core/DiscIO/Src/VolumeDirectory.h | 2 +- Source/Core/DiscIO/Src/VolumeGC.cpp | 13 +- Source/Core/DiscIO/Src/VolumeGC.h | 2 +- Source/Core/DiscIO/Src/VolumeWad.cpp | 48 ++----- Source/Core/DiscIO/Src/VolumeWad.h | 3 +- Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp | 18 +-- Source/Core/DiscIO/Src/VolumeWiiCrypted.h | 2 +- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 26 ++-- Source/Core/DolphinWX/Src/ISOFile.cpp | 144 +++++++------------- Source/Core/DolphinWX/Src/ISOFile.h | 23 ++-- Source/Core/DolphinWX/Src/ISOProperties.cpp | 50 ++----- 22 files changed, 243 insertions(+), 411 deletions(-) diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index 38ac107ec1..aab0f3bd58 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -395,17 +395,41 @@ std::string UTF16ToUTF8(const std::wstring& input) return output; } -std::wstring UTF8ToUTF16(const std::string& input) +std::wstring CPToUTF16(u32 code_page, const std::string& input) { - auto const size = MultiByteToWideChar(CP_UTF8, 0, input.data(), input.size(), nullptr, 0); + auto const size = MultiByteToWideChar(code_page, 0, input.data(), input.size(), nullptr, 0); std::wstring output; output.resize(size); - if (size != MultiByteToWideChar(CP_UTF8, 0, input.data(), input.size(), &output[0], output.size())) + if (size != MultiByteToWideChar(code_page, 0, input.data(), input.size(), &output[0], output.size())) output.clear(); return output; } +std::wstring UTF8ToUTF16(const std::string& input) +{ + return CPToUTF16(CP_UTF8, input); +} + +std::string SHIFTJISToUTF8(const std::string& input) +{ + return UTF16ToUTF8(CPToUTF16(932, input)); +} + +#else + +std::string UTF16ToUTF8(const std::wstring& input) +{ + // TODO: implement + return std::string(); +} + +std::string SHIFTJISToUTF8(const std::string& input) +{ + // TODO: implement + return std::string(); +} + #endif diff --git a/Source/Core/Common/Src/StringUtil.h b/Source/Core/Common/Src/StringUtil.h index 5177bc8ed8..ce5751f80b 100644 --- a/Source/Core/Common/Src/StringUtil.h +++ b/Source/Core/Common/Src/StringUtil.h @@ -97,9 +97,11 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st std::string UriDecode(const std::string & sSrc); std::string UriEncode(const std::string & sSrc); +std::string SHIFTJISToUTF8(const std::string& str); +std::string UTF16ToUTF8(const std::wstring& str); + #ifdef _WIN32 -std::string UTF16ToUTF8(const std::wstring& str); std::wstring UTF8ToUTF16(const std::string& str); #ifdef _UNICODE diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp index 2c28401c93..7e641aa85b 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.cpp +++ b/Source/Core/DiscIO/Src/BannerLoader.cpp @@ -24,58 +24,6 @@ namespace DiscIO { -void IBannerLoader::CopyToStringAndCheck(std::string& _rDestination, const char* _src) -{ - static bool bValidChars[256]; - static bool bInitialized = false; - - if (!bInitialized) - { - for (int i = 0; i < 0x20; i++) - { - bValidChars[i] = false; - } - - // generate valid chars - for (int i = 0x20; i < 256; i++) - { - bValidChars[i] = true; - } - - bValidChars[0x0a] = true; - //bValidChars[0xa9] = true; - //bValidChars[0xe9] = true; - - bInitialized = true; - } - - char destBuffer[2048] = {0}; - char* dest = destBuffer; - const char* src = _src; - - // copy the string and check for "unknown" characters - while (*src != 0x00) - { - u8 c = *src; - - if (c == 0x0a){c = 0x20;} - - if (bValidChars[c] == false) - { - src++; - continue; - } - - *dest = c; - dest++; - src++; - } - - // finalize the string - *dest = 0x00; - - _rDestination = destBuffer; -} IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume) { diff --git a/Source/Core/DiscIO/Src/BannerLoader.h b/Source/Core/DiscIO/Src/BannerLoader.h index ef2e0e64b9..92bb874979 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.h +++ b/Source/Core/DiscIO/Src/BannerLoader.h @@ -18,6 +18,9 @@ #ifndef _BANNER_LOADER_H_ #define _BANNER_LOADER_H_ +#include +#include + #include "Filesystem.h" namespace DiscIO @@ -38,15 +41,9 @@ class IBannerLoader virtual bool GetBanner(u32* _pBannerImage) = 0; - virtual bool GetName(std::string* _rName) = 0; - virtual bool GetName(std::vector& _rNames) {return false;}; - virtual bool GetCompany(std::string& _rCompany) = 0; - - virtual bool GetDescription(std::string* _rDescription) = 0; - - protected: - - void CopyToStringAndCheck(std::string& _rDestination, const char* _src); + virtual std::vector GetNames() = 0; + virtual std::string GetCompany() = 0; + virtual std::vector GetDescriptions() = 0; private: u16 swap16(u16 data) diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp index bf9f634ff8..bf087cbfb6 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp @@ -29,7 +29,7 @@ CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem) { // load the opening.bnr size_t FileSize = (size_t) _rFileSystem.GetFileSize("opening.bnr"); - if (FileSize == sizeof(DVDBanner) || FileSize == sizeof(DVDBanner2)) + if (FileSize == BNR1_SIZE || FileSize == BNR2_SIZE) { m_pBannerFile = new u8[FileSize]; if (m_pBannerFile) @@ -62,7 +62,6 @@ bool CBannerLoaderGC::IsValid() return m_IsValid; } - bool CBannerLoaderGC::GetBanner(u32* _pBannerImage) { if (!IsValid()) @@ -70,132 +69,111 @@ bool CBannerLoaderGC::GetBanner(u32* _pBannerImage) return false; } - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; + auto const pBanner = (DVDBanner*)m_pBannerFile; decode5A3image(_pBannerImage, pBanner->image, DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT); return true; } -bool CBannerLoaderGC::GetName(std::string _rName[]) +std::vector CBannerLoaderGC::GetNames() { - bool returnCode = false; + std::vector names; if (!IsValid()) { - return false; + return names; } + u32 name_count = 0; + // find Banner type switch (m_BNRType) { case CBannerLoaderGC::BANNER_BNR1: - { - DVDBanner* pBanner = (DVDBanner*)m_pBannerFile; - char tempBuffer[65] = {0}; - if (pBanner->comment.longTitle[0]) - { - memcpy(tempBuffer, pBanner->comment.longTitle, 64); - } - else - { - memcpy(tempBuffer, pBanner->comment.shortTitle, 32); - } - for (int i = 0; i < 6; i++) - { - CopyToStringAndCheck(_rName[i], tempBuffer); - } - returnCode = true; - } + name_count = 1; break; + case CBannerLoaderGC::BANNER_BNR2: - { - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; - - for (int i = 0; i < 6; i++) - { - char tempBuffer[65] = {0}; - if (pBanner->comment[i].longTitle[0]) - { - memcpy(tempBuffer, pBanner->comment[i].longTitle, 64); - } - else - { - memcpy(tempBuffer, pBanner->comment[i].shortTitle, 32); - } - CopyToStringAndCheck(_rName[i], tempBuffer); - } - - returnCode = true; - - } + name_count = 6; break; + default: break; } + + auto const banner = reinterpret_cast(m_pBannerFile); + + for (int i = 0; i != name_count; ++i) + { + auto& comment = banner->comment[i]; + + if (comment.longTitle[0]) + { + auto& data = comment.longTitle; + names.push_back(GetDecodedString(data)); + } + else + { + auto& data = comment.shortTitle; + names.push_back(GetDecodedString(data)); + } + } - return returnCode; + return names; } -bool CBannerLoaderGC::GetCompany(std::string& _rCompany) +std::string CBannerLoaderGC::GetCompany() { - _rCompany = "N/A"; + std::string company; - if (!IsValid()) + if (IsValid()) { - return(false); + auto const pBanner = (DVDBanner*)m_pBannerFile; + auto& data = pBanner->comment[0].shortMaker; + company = GetDecodedString(data); } - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; - - CopyToStringAndCheck(_rCompany, pBanner->comment[0].shortMaker); - - return true; + return company; } -bool CBannerLoaderGC::GetDescription(std::string* _rDescription) +std::vector CBannerLoaderGC::GetDescriptions() { - bool returnCode = false; + std::vector descriptions; if (!IsValid()) { - return false; + return descriptions; } + u32 desc_count = 0; + // find Banner type switch (m_BNRType) { case CBannerLoaderGC::BANNER_BNR1: - { - DVDBanner* pBanner = (DVDBanner*)m_pBannerFile; - char tempBuffer[129] = {0}; - memcpy(tempBuffer, pBanner->comment.comment, 128); - for (int i = 0; i < 6; i++) - { - CopyToStringAndCheck(_rDescription[i], tempBuffer); - } - returnCode = true; - } + desc_count = 1; break; - case CBannerLoaderGC::BANNER_BNR2: - { - DVDBanner2* pBanner = (DVDBanner2*)m_pBannerFile; - for (int i = 0; i< 6; i++) - { - char tempBuffer[129] = {0}; - memcpy(tempBuffer, pBanner->comment[i].comment, 128); - CopyToStringAndCheck(_rDescription[i], tempBuffer); - } - returnCode = true; - } + case CBannerLoaderGC::BANNER_BNR2: + desc_count = 6; break; + default: break; } - return returnCode; + + auto banner = reinterpret_cast(m_pBannerFile); + + for (int i = 0; i != desc_count; ++i) + { + auto& data = banner->comment[i].comment; + descriptions.push_back(GetDecodedString(data)); + } + + return descriptions; } @@ -223,13 +201,17 @@ CBannerLoaderGC::BANNER_TYPE CBannerLoaderGC::getBannerType() CBannerLoaderGC::BANNER_TYPE type = CBannerLoaderGC::BANNER_UNKNOWN; switch (bannerSignature) { + // "BNR1" case 0x31524e42: type = CBannerLoaderGC::BANNER_BNR1; break; + + // "BNR2" case 0x32524e42: type = CBannerLoaderGC::BANNER_BNR2; break; } return type; } + } // namespace diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.h b/Source/Core/DiscIO/Src/BannerLoaderGC.h index 0527c721c1..b4903561e4 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.h +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.h @@ -32,9 +32,10 @@ class CBannerLoaderGC virtual bool IsValid(); virtual bool GetBanner(u32* _pBannerImage); - virtual bool GetName(std::string* _rName); - virtual bool GetCompany(std::string& _rCompany); - virtual bool GetDescription(std::string* _rDescription); + + virtual std::vector GetNames(); + virtual std::string GetCompany(); + virtual std::vector GetDescriptions(); private: enum @@ -60,24 +61,25 @@ class CBannerLoaderGC char comment[128]; // Game description shown in IPL game start screen in two lines. }; - // "opening.bnr" file format for JP/US console - struct DVDBanner - { - u32 id; // 'BNR1' - u32 padding[7]; - u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image - DVDBannerComment comment; - }; - // "opening.bnr" file format for EU console - struct DVDBanner2 + struct DVDBanner { u32 id; // 'BNR2' u32 padding[7]; u16 image[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; // RGB5A3 96x32 texture image - DVDBannerComment comment[6]; // Comments in six languages + DVDBannerComment comment[6]; // Comments in six languages (only 1 for BNR1 type) }; + static const u32 BNR1_SIZE = sizeof(DVDBanner) - sizeof(DVDBannerComment) * 5; + static const u32 BNR2_SIZE = sizeof(DVDBanner); + + template + std::string GetDecodedString(const char (&data)[N]) + { + // Can I always assume SHIFT-JIS? + return SHIFTJISToUTF8(std::string(data, strnlen(data, sizeof(data)))); + } + u8* m_pBannerFile; bool m_IsValid; BANNER_TYPE m_BNRType; diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp index d8d8076721..b94e299f04 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp @@ -196,28 +196,27 @@ bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::wstr return false; } -bool CBannerLoaderWii::GetName(std::string* _rName) +std::vector CBannerLoaderWii::GetNames() { - return GetStringFromComments(NAME_IDX, *_rName); -} + std::vector ret(1); + + if (!GetStringFromComments(NAME_IDX, ret[0])) + ret.clear(); -bool CBannerLoaderWii::GetName(std::vector& _rNames) -{ - std::wstring temp; - bool ret = GetStringFromComments(NAME_IDX, temp); - _rNames.push_back(temp); return ret; } -bool CBannerLoaderWii::GetCompany(std::string& _rCompany) +std::string CBannerLoaderWii::GetCompany() { - _rCompany = "N/A"; - return true; + return ""; } -bool CBannerLoaderWii::GetDescription(std::string* _rDescription) +std::vector CBannerLoaderWii::GetDescriptions() { - return GetStringFromComments(DESC_IDX, *_rDescription); + std::vector result(1); + if (!GetStringFromComments(DESC_IDX, result[0])) + result.clear(); + return result; } void CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height) diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.h b/Source/Core/DiscIO/Src/BannerLoaderWii.h index d7150d7009..60d317155b 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.h +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.h @@ -35,13 +35,9 @@ class CBannerLoaderWii virtual bool GetBanner(u32* _pBannerImage); - virtual bool GetName(std::string* _rName); - - bool GetName(std::vector& _rNames); - - virtual bool GetCompany(std::string& _rCompany); - - virtual bool GetDescription(std::string* _rDescription); + virtual std::vector GetNames(); + virtual std::string GetCompany(); + virtual std::vector GetDescriptions(); private: diff --git a/Source/Core/DiscIO/Src/Volume.h b/Source/Core/DiscIO/Src/Volume.h index 557c71c31f..4743cfce89 100644 --- a/Source/Core/DiscIO/Src/Volume.h +++ b/Source/Core/DiscIO/Src/Volume.h @@ -37,8 +37,8 @@ public: virtual void GetTMD(u8*, u32 *_sz) const { *_sz=0; } virtual std::string GetUniqueID() const = 0; virtual std::string GetMakerID() const = 0; - virtual std::string GetName() const = 0; - virtual bool GetWName(std::vector& _rwNames) const { return false; } + virtual std::string GetName() const; + virtual std::vector GetNames() const = 0; virtual u32 GetFSTSize() const = 0; virtual std::string GetApploaderDate() const = 0; virtual bool SupportsIntegrityCheck() const { return false; } diff --git a/Source/Core/DiscIO/Src/VolumeCommon.cpp b/Source/Core/DiscIO/Src/VolumeCommon.cpp index 415af2725a..4ab433680d 100644 --- a/Source/Core/DiscIO/Src/VolumeCommon.cpp +++ b/Source/Core/DiscIO/Src/VolumeCommon.cpp @@ -111,5 +111,13 @@ u8 GetSysMenuRegion(u16 _TitleVersion) } } -}; +std::string IVolume::GetName() const +{ + auto names = GetNames(); + if (names.empty()) + return ""; + else + return names[0]; +} +} diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp index dc76e2e641..be7cdeb565 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp @@ -207,11 +207,10 @@ std::string CVolumeDirectory::GetMakerID() const return "VOID"; } -std::string CVolumeDirectory::GetName() const +std::vector CVolumeDirectory::GetNames() const { _dbg_assert_(DVDINTERFACE, m_diskHeader); - std::string name = (char*)(m_diskHeader + 0x20); - return name; + return std::vector(1, (char*)(m_diskHeader + 0x20)); } void CVolumeDirectory::SetName(std::string _Name) diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.h b/Source/Core/DiscIO/Src/VolumeDirectory.h index 0547be3b8a..880a6eebc1 100644 --- a/Source/Core/DiscIO/Src/VolumeDirectory.h +++ b/Source/Core/DiscIO/Src/VolumeDirectory.h @@ -50,7 +50,7 @@ public: std::string GetMakerID() const; - std::string GetName() const; + std::vector GetNames() const; void SetName(std::string); u32 GetFSTSize() const; diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp index 09e2c5eaa9..6e9579571a 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.cpp +++ b/Source/Core/DiscIO/Src/VolumeGC.cpp @@ -91,16 +91,15 @@ std::string CVolumeGC::GetMakerID() const return makerID; } -std::string CVolumeGC::GetName() const +std::vector CVolumeGC::GetNames() const { - if (m_pReader == NULL) - return ""; + std::vector names; - char name[128]; - if (!Read(0x20, 0x60, (u8*)&name)) - return ""; + char name[128] = {}; + if (m_pReader != NULL && Read(0x20, 0x60, (u8*)&name)) + names.push_back(name); - return name; + return names; } u32 CVolumeGC::GetFSTSize() const diff --git a/Source/Core/DiscIO/Src/VolumeGC.h b/Source/Core/DiscIO/Src/VolumeGC.h index 4221df9493..dab1ad7a9d 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.h +++ b/Source/Core/DiscIO/Src/VolumeGC.h @@ -34,7 +34,7 @@ public: bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const; std::string GetUniqueID() const; std::string GetMakerID() const; - std::string GetName() const; + std::vector GetNames() const; u32 GetFSTSize() const; std::string GetApploaderDate() const; ECountry GetCountry() const; diff --git a/Source/Core/DiscIO/Src/VolumeWad.cpp b/Source/Core/DiscIO/Src/VolumeWad.cpp index 2f9f0ef961..72788f1017 100644 --- a/Source/Core/DiscIO/Src/VolumeWad.cpp +++ b/Source/Core/DiscIO/Src/VolumeWad.cpp @@ -107,13 +107,15 @@ bool CVolumeWAD::GetTitleID(u8* _pBuffer) const return true; } -bool CVolumeWAD::GetWName(std::vector& _rwNames) const +std::vector CVolumeWAD::GetNames() const { - u32 footer_size; + std::vector names; + return names; + u32 footer_size; if (!Read(0x1C, 4, (u8*)&footer_size)) { - return false; + return names; } //Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean @@ -126,7 +128,7 @@ bool CVolumeWAD::GetWName(std::vector& _rwNames) const if (!Read(0x9C + (i*84) + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1 || !temp[0]) { - _rwNames.push_back(L""); + names.push_back(""); continue; } for (int j = 0; j < 42; ++j) @@ -141,44 +143,10 @@ bool CVolumeWAD::GetWName(std::vector& _rwNames) const out_temp.push_back(t); } - _rwNames.push_back(out_temp); + names.push_back(UTF16ToUTF8(out_temp)); } - return true; -} -std::string CVolumeWAD::GetName() const -{ - u32 footer_size; - - if (!Read(0x1C, 4, (u8*)&footer_size)) - return ""; - - - //Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean - - // Offset to the english title - char temp[84]; - if (!Read(0xF1 + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1 || - !Common::swap16(temp[0])) - return ""; - - // Remove the null bytes due to 16bit char length - std::string out_temp; - for (unsigned int i = 0; i < sizeof(temp); i+=2) - { - // Replace null chars with a single space per null section - if (temp[i] == '\0' && i > 0) - { - if (out_temp.at(out_temp.size()-1) != ' ') - out_temp.push_back(' '); - } - else - out_temp.push_back(temp[i]); - } - // Make it a null terminated string - out_temp.replace(out_temp.end()-1, out_temp.end(), 1, '\0'); - - return out_temp; + return names; } u64 CVolumeWAD::GetSize() const diff --git a/Source/Core/DiscIO/Src/VolumeWad.h b/Source/Core/DiscIO/Src/VolumeWad.h index 956844acd1..afc16766a2 100644 --- a/Source/Core/DiscIO/Src/VolumeWad.h +++ b/Source/Core/DiscIO/Src/VolumeWad.h @@ -38,8 +38,7 @@ public: bool GetTitleID(u8* _pBuffer) const; std::string GetUniqueID() const; std::string GetMakerID() const; - std::string GetName() const; - bool GetWName(std::vector& _rwNames) const; + std::vector GetNames() const; u32 GetFSTSize() const { return 0; } std::string GetApploaderDate() const { return "0"; } ECountry GetCountry() const; diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp index ca010b5ae4..f375b9e66d 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp @@ -168,21 +168,17 @@ std::string CVolumeWiiCrypted::GetMakerID() const return makerID; } -std::string CVolumeWiiCrypted::GetName() const +std::vector CVolumeWiiCrypted::GetNames() const { - if (m_pReader == NULL) + std::vector names; + + char name[0xFF] = {}; + if (m_pReader != NULL && Read(0x20, 0x60, (u8*)&name)) { - return std::string(); + names.push_back(name); } - char name[0xFF]; - - if (!Read(0x20, 0x60, (u8*)&name)) - { - return std::string(); - } - - return name; + return names; } u32 CVolumeWiiCrypted::GetFSTSize() const diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h index 5010e46bbd..56c2a8a363 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.h @@ -37,7 +37,7 @@ public: void GetTMD(u8* _pBuffer, u32* _sz) const; std::string GetUniqueID() const; std::string GetMakerID() const; - std::string GetName() const; + std::vector GetNames() const; u32 GetFSTSize() const; std::string GetApploaderDate() const; ECountry GetCountry() const; diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index c24f0509ba..6a6df49ee5 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -454,10 +454,8 @@ void CGameListCtrl::InsertItemInReportView(long _Index) // Set the game's banner in the second column SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex); - - std::wstring wstring_name; - wxString name; + std::string name; int SelectedLanguage = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage; switch (rISOFile.GetCountry()) @@ -465,9 +463,8 @@ void CGameListCtrl::InsertItemInReportView(long _Index) case DiscIO::IVolume::COUNTRY_TAIWAN: case DiscIO::IVolume::COUNTRY_JAPAN: { - rISOFile.GetName(wstring_name, -1); - name = wxString(rISOFile.GetName(0).c_str(), SJISConv); - m_gameList.append(StringFromFormat("%s (J)\n", (const char *)name.c_str())); + name = rISOFile.GetName(-1); + m_gameList.append(StringFromFormat("%s (J)\n", name.c_str())); } break; case DiscIO::IVolume::COUNTRY_USA: @@ -475,22 +472,15 @@ void CGameListCtrl::InsertItemInReportView(long _Index) SelectedLanguage = 0; default: { - wxCSConv WindowsCP1252(wxFontMapper::GetEncodingName(wxFONTENCODING_CP1252)); - rISOFile.GetName(wstring_name, SelectedLanguage); - - name = wxString(rISOFile.GetName(SelectedLanguage).c_str(), WindowsCP1252); - m_gameList.append(StringFromFormat("%s (%c)\n", - rISOFile.GetName(SelectedLanguage).c_str(), - (rISOFile.GetCountry() == DiscIO::IVolume::COUNTRY_USA) ? 'U' : 'E')); + name = rISOFile.GetName(SelectedLanguage); + m_gameList.append(StringFromFormat("%s (%c)\n", name.c_str(), + (rISOFile.GetCountry() == DiscIO::IVolume::COUNTRY_USA) ? 'U' : 'E')); } break; } - - if (wstring_name.length()) - name = wstring_name.c_str(); - - SetItem(_Index, COLUMN_TITLE, name, -1); + + SetItem(_Index, COLUMN_TITLE, StrToWxStr(name), -1); // We show the company string on Gamecube only // On Wii we show the description instead as the company string is empty diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index 918a72b0bf..ec8280a726 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -37,7 +37,7 @@ #include "ChunkFile.h" #include "ConfigManager.h" -#define CACHE_REVISION 0x110 +#define CACHE_REVISION 0x112 #define DVD_BANNER_WIDTH 96 #define DVD_BANNER_HEIGHT 32 @@ -66,26 +66,10 @@ GameListItem::GameListItem(const std::string& _rFileName) else { m_Platform = WII_WAD; - pVolume->GetWName(m_wNames); } - m_Company = "N/A"; + m_volume_names = pVolume->GetNames(); - - m_Name[0] = pVolume->GetName(); - - if(m_Name[0] == "") // Couldn't find the name in the WAD... - { - std::string FileName; - SplitPath(m_FileName, NULL, &FileName, NULL); - m_Name[0] = FileName; // Then just display the filename... Better than something like "No Name" - } - - for (int i = 0; i < 6; i++) - { - m_Name[i] = m_Name[0]; - m_Description[i] = "No Description"; - } m_Country = pVolume->GetCountry(); m_FileSize = File::GetSize(_rFileName); m_VolumeSize = pVolume->GetSize(); @@ -105,11 +89,9 @@ GameListItem::GameListItem(const std::string& _rFileName) { if (pBannerLoader->IsValid()) { - m_wNames.clear(); - pBannerLoader->GetName(m_wNames); - pBannerLoader->GetName(m_Name); - pBannerLoader->GetCompany(m_Company); - pBannerLoader->GetDescription(m_Description); + m_names = pBannerLoader->GetNames(); + m_company = pBannerLoader->GetCompany(); + m_descriptions = pBannerLoader->GetDescriptions(); if (pBannerLoader->GetBanner(g_ImageTemp)) { @@ -129,25 +111,6 @@ GameListItem::GameListItem(const std::string& _rFileName) delete pFileSystem; } - std::vector::iterator i, end = m_wNames.end(); - std::wstring wFileName; - for (i = m_wNames.begin(); i != end; ++i) - { - if (*i == L"") - { - if (!wFileName.length()) - { - std::string FileName; - SplitPath(m_FileName, NULL, &FileName, NULL); - int length = FileName.length(); - wFileName.reserve(length+1); - for (int j = 0; j < length; ++j) - wFileName.push_back(FileName[j]); - wFileName.push_back(0); - } - *i = wFileName; - } - } delete pVolume; @@ -208,32 +171,10 @@ void GameListItem::SaveToCache() void GameListItem::DoState(PointerWrap &p) { - p.Do(m_Name[0]); p.Do(m_Name[1]); p.Do(m_Name[2]); - p.Do(m_Name[3]); p.Do(m_Name[4]); p.Do(m_Name[5]); - - int wNamesSize = m_wNames.size(); - p.Do(wNamesSize); - - if (p.mode == p.MODE_READ) - { - for (int i = 0; i < wNamesSize; ++i) - { - std::wstring temp; - p.Do(temp); - m_wNames.push_back(temp); - } - } - else - { - for (int i = 0; i < wNamesSize; ++i) - { - p.Do(m_wNames[i]); - } - } - - p.Do(m_Company); - p.Do(m_Description[0]); p.Do(m_Description[1]); p.Do(m_Description[2]); - p.Do(m_Description[3]); p.Do(m_Description[4]); p.Do(m_Description[5]); + p.Do(m_volume_names); + p.Do(m_company); + p.Do(m_names); + p.Do(m_descriptions); p.Do(m_UniqueID); p.Do(m_FileSize); p.Do(m_VolumeSize); @@ -262,44 +203,51 @@ std::string GameListItem::CreateCacheFilename() return fullname; } -const std::string& GameListItem::GetDescription(int index) const +std::string GameListItem::GetCompany() const { - if ((index >=0) && (index < 6)) - { - return m_Description[index]; - } - return m_Description[0]; + if (m_company.empty()) + return "N/A"; + else + return m_company; } -const std::string& GameListItem::GetName(int index) const +// (-1 = Japanese, 0 = English, etc) +std::string GameListItem::GetDescription(int _index) const { - if ((index >=0) && (index < 6)) - { - return m_Name[index]; - } - return m_Name[0]; + const u32 index = _index + 1; + + if (index < m_descriptions.size()) + return m_descriptions[index]; + + if (!m_descriptions.empty()) + return m_descriptions[0]; + + return ""; } -bool GameListItem::GetName(std::wstring& wName, int index) const +// (-1 = Japanese, 0 = English, etc) +std::string GameListItem::GetName(int _index) const { - // This function will only succeed for wii discs with banners or WADs - // utilize the same array as for gc discs (-1= Japanese, 0 = English etc - index++; - if ((index >= 0) && (index < 10)) - { - if (m_wNames.size() > (size_t)index) - { - wName = m_wNames[index]; - return true; - } - } - if (m_wNames.size() > 0) - { - wName = m_wNames[0]; - return true; - } - return false; + u32 const index = _index + 1; + // banner name + if (index < m_names.size() && !m_names[index].empty()) + return m_names[index]; + + if (!m_names.empty() && !m_names[0].empty()) + return m_names[0]; + + // volume name + if (index < m_volume_names.size() && !m_volume_names[index].empty()) + return m_volume_names[index]; + + if (!m_volume_names.empty() && !m_volume_names[0].empty()) + return m_volume_names[0]; + + // No usable name, return filename (better than nothing) + std::string FileName; + SplitPath(m_FileName, NULL, &FileName, NULL); + return FileName; } const std::string GameListItem::GetWiiFSPath() const diff --git a/Source/Core/DolphinWX/Src/ISOFile.h b/Source/Core/DolphinWX/Src/ISOFile.h index 1f3ecaa261..ded392f56a 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.h +++ b/Source/Core/DolphinWX/Src/ISOFile.h @@ -18,6 +18,9 @@ #ifndef __ISOFILE_H_ #define __ISOFILE_H_ +#include +#include + #include "Volume.h" #include "VolumeCreator.h" @@ -34,10 +37,9 @@ public: bool IsValid() const {return m_Valid;} const std::string& GetFileName() const {return m_FileName;} - const std::string& GetName(int index) const; - bool GetName(std::wstring& wName, int index=0) const; - const std::string& GetCompany() const {return m_Company;} - const std::string& GetDescription(int index = 0) const; + std::string GetName(int index) const; + std::string GetCompany() const; + std::string GetDescription(int index = 0) const; const std::string& GetUniqueID() const {return m_UniqueID;} const std::string GetWiiFSPath() const; DiscIO::IVolume::ECountry GetCountry() const {return m_Country;} @@ -64,10 +66,15 @@ public: private: std::string m_FileName; - std::string m_Name[6]; - std::vector m_wNames; - std::string m_Company; - std::string m_Description[6]; + + // TODO: eliminate this and overwrite with names from banner when available? + std::vector m_volume_names; + + // Stuff from banner + std::string m_company; + std::vector m_names; + std::vector m_descriptions; + std::string m_UniqueID; std::string m_issues; diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 21d451a1ac..5993111698 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -158,15 +158,8 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW // Disk header and apploader - std::wstring wname; - wxString name; - if (OpenGameListItem->GetName(wname)) - name = wname.c_str(); - else - name = wxString(OpenISO->GetName().c_str(), wxConvUTF8); - m_Name->SetValue(name); - - m_GameID->SetValue(wxString(OpenISO->GetUniqueID().c_str(), wxConvUTF8)); + m_Name->SetValue(StrToWxStr(OpenISO->GetName())); + m_GameID->SetValue(StrToWxStr(OpenISO->GetUniqueID())); switch (OpenISO->GetCountry()) { case DiscIO::IVolume::COUNTRY_EUROPE: @@ -1308,54 +1301,29 @@ void CISOProperties::OnChangeBannerLang(wxCommandEvent& event) void CISOProperties::ChangeBannerDetails(int lang) { - std::wstring wname; + std::string name; wxString shortName, comment, maker; -#ifdef _WIN32 - wxCSConv SJISConv(*(wxCSConv*)wxConvCurrent); - static bool validCP932 = ::IsValidCodePage(932) != 0; - if (validCP932) - { - SJISConv = wxCSConv(wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS)); - } - else - { - WARN_LOG(COMMON, "Cannot Convert from Charset Windows Japanese cp 932"); - } -#else - // on linux the wrong string is returned from wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS) - // it returns CP-932, in order to use iconv we need to use CP932 - wxCSConv SJISConv(wxT("CP932")); -#endif switch (OpenGameListItem->GetCountry()) { case DiscIO::IVolume::COUNTRY_TAIWAN: case DiscIO::IVolume::COUNTRY_JAPAN: - - if (OpenGameListItem->GetName(wname, -1)) - shortName = wname.c_str(); - else - shortName = wxString(OpenGameListItem->GetName(0).c_str(), SJISConv); - + shortName = StrToWxStr(OpenGameListItem->GetName(-1)); comment = StrToWxStr(OpenGameListItem->GetDescription()); - maker = wxString(OpenGameListItem->GetCompany().c_str(), SJISConv); break; case DiscIO::IVolume::COUNTRY_USA: + // why? lang = 0; default: - { - wxCSConv WindowsCP1252(wxFontMapper::GetEncodingName(wxFONTENCODING_CP1252)); - if (OpenGameListItem->GetName(wname, lang)) - shortName = wname.c_str(); - else - shortName = wxString(OpenGameListItem->GetName(lang).c_str(), WindowsCP1252); + shortName = StrToWxStr(OpenGameListItem->GetName(lang)); comment = StrToWxStr(OpenGameListItem->GetDescription(lang)); - maker = wxString(OpenGameListItem->GetCompany().c_str(), WindowsCP1252); - } break; } + + maker = StrToWxStr(OpenGameListItem->GetCompany()); + // Updates the informations shown in the window m_ShortName->SetValue(shortName); m_Comment->SetValue(comment); From e183711d749fefd480ef8091acfd1230ae8c604e Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 2 Mar 2013 20:34:53 -0600 Subject: [PATCH 134/167] wxString conversion cleanup. --- .../Src/Debugger/CodeWindowFunctions.cpp | 2 +- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 17 ----------------- Source/Core/DolphinWX/Src/ISOProperties.cpp | 16 ++++++++-------- Source/Core/DolphinWX/Src/MemcardManager.cpp | 10 +++++----- Source/Core/DolphinWX/Src/NetWindow.cpp | 2 +- 5 files changed, 15 insertions(+), 32 deletions(-) diff --git a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp index fad0380eca..ef4622d14f 100644 --- a/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp +++ b/Source/Core/DolphinWX/Src/Debugger/CodeWindowFunctions.cpp @@ -209,7 +209,7 @@ void CCodeWindow::OnProfilerMenu(wxCommandEvent& event) break; } wxString OpenCommand; - OpenCommand = filetype->GetOpenCommand(wxString::From8BitData(filename.c_str())); + OpenCommand = filetype->GetOpenCommand(StrToWxStr(filename)); if(!OpenCommand.IsEmpty()) wxExecute(OpenCommand, wxEXEC_SYNC); } diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index 6a6df49ee5..562d2234cd 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -423,23 +423,6 @@ void CGameListCtrl::InsertItemInReportView(long _Index) // company: 0x007030 int ImageIndex = -1; -#ifdef _WIN32 - wxCSConv SJISConv(*(wxCSConv*)wxConvCurrent); - static bool validCP932 = ::IsValidCodePage(932) != 0; - if (validCP932) - { - SJISConv = wxCSConv(wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS)); - } - else - { - WARN_LOG(COMMON, "Cannot Convert from Charset Windows Japanese cp 932"); - } -#else - // on linux the wrong string is returned from wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS) - // it returns CP-932, in order to use iconv we need to use CP932 - wxCSConv SJISConv(wxT("CP932")); -#endif - GameListItem& rISOFile = *m_ISOFiles[_Index]; m_gamePath.append(rISOFile.GetFileName() + '\n'); diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 5993111698..43657300cb 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -152,7 +152,7 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW LoadGameConfig(); else wxMessageBox(wxString::Format(_("Could not create %s"), - wxString::From8BitData(GameIniFile.c_str()).c_str()), + StrToWxStr(GameIniFile).c_str()), _("Error"), wxOK|wxICON_ERROR, this); } @@ -199,9 +199,9 @@ CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxW m_Country->SetValue(_("UNKNOWN")); break; } - wxString temp = _T("0x") + wxString::From8BitData(OpenISO->GetMakerID().c_str()); + wxString temp = _T("0x") + StrToWxStr(OpenISO->GetMakerID()); m_MakerID->SetValue(temp); - m_Date->SetValue(wxString::From8BitData(OpenISO->GetApploaderDate().c_str())); + m_Date->SetValue(StrToWxStr(OpenISO->GetApploaderDate())); m_FST->SetValue(wxString::Format(wxT("%u"), OpenISO->GetFSTSize())); // Here we set all the info to be shown (be it SJIS or Ascii) + we set the window title @@ -266,12 +266,12 @@ size_t CISOProperties::CreateDirectoryTree(wxTreeItemId& parent, // check next index if (rFileInfo->IsDirectory()) { - wxTreeItemId item = m_Treectrl->AppendItem(parent, wxString::From8BitData(itemName), 1, 1); + wxTreeItemId item = m_Treectrl->AppendItem(parent, StrToWxStr(itemName), 1, 1); CurrentIndex = CreateDirectoryTree(item, fileInfos, CurrentIndex + 1, (size_t)rFileInfo->m_FileSize); } else { - m_Treectrl->AppendItem(parent, wxString::From8BitData(itemName), 2, 2); + m_Treectrl->AppendItem(parent, StrToWxStr(itemName), 2, 2); CurrentIndex++; } } @@ -1081,7 +1081,7 @@ bool CISOProperties::SaveGameConfig() void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event)) { - if (wxFileExists(wxString::From8BitData(GameIniFile.c_str()))) + if (File::Exists(GameIniFile)) { SaveGameConfig(); @@ -1102,7 +1102,7 @@ void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event)) } } wxString OpenCommand; - OpenCommand = filetype->GetOpenCommand(wxString::From8BitData(GameIniFile.c_str())); + OpenCommand = filetype->GetOpenCommand(StrToWxStr(GameIniFile)); if(OpenCommand.IsEmpty()) PanicAlertT("Couldn't find open command for extension 'ini'!"); else @@ -1275,7 +1275,7 @@ void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event) CARCodeAddEdit dlg(-1, this, 1, _("Add ActionReplay Code")); if (dlg.ShowModal() == wxID_OK) { - Cheats->Append(wxString::From8BitData(arCodes.back().name.c_str())); + Cheats->Append(StrToWxStr(arCodes.back().name)); Cheats->Check((unsigned int)(arCodes.size() - 1), arCodes.back().active); } } diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp index d9fd4d3ae6..b9b26b6da8 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.cpp +++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp @@ -214,7 +214,7 @@ void CMemcardManager::CreateGUIControls() sPages->Add(m_NextPage[slot], 0, wxEXPAND|wxALL, 1); m_MemcardPath[slot] = new wxFilePickerCtrl(this, ID_MEMCARDPATH_A + slot, - wxString::From8BitData(File::GetUserPath(D_GCUSER_IDX).c_str()), _("Choose a memory card:"), + StrToWxStr(File::GetUserPath(D_GCUSER_IDX)), _("Choose a memory card:"), _("Gamecube Memory Cards (*.raw,*.gcp)") + wxString(wxT("|*.raw;*.gcp")), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_OPEN); m_MemcardList[slot] = new CMemcardListCtrl(this, ID_MEMCARDLIST_A + slot, wxDefaultPosition, wxSize(350,400), @@ -265,7 +265,7 @@ void CMemcardManager::CreateGUIControls() m_Delete[i]->Disable(); if (DefaultMemcard[i].length()) { - m_MemcardPath[i]->SetPath(wxString::From8BitData(DefaultMemcard[i].c_str())); + m_MemcardPath[i]->SetPath(StrToWxStr(DefaultMemcard[i])); ChangePath(i); } } @@ -520,7 +520,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) _("Select a save file to import"), (strcmp(DefaultIOPath.c_str(), "/Users/GC") == 0) ? StrToWxStr("") - : wxString::From8BitData(DefaultIOPath.c_str()), + : StrToWxStr(DefaultIOPath), wxEmptyString, wxEmptyString, _("GameCube Savegame files(*.gci;*.gcs;*.sav)") + wxString(wxT("|*.gci;*.gcs;*.sav|")) + _("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) + @@ -557,8 +557,8 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) } wxString fileName = wxFileSelector( _("Export save as..."), - wxString::From8BitData(DefaultIOPath.c_str()), - wxString::From8BitData(gciFilename.c_str()), wxT(".gci"), + StrToWxStr(DefaultIOPath), + StrToWxStr(gciFilename), wxT(".gci"), _("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) + _("MadCatz Gameshark files(*.gcs)") + wxString(wxT("|*.gcs|")) + _("Datel MaxDrive/Pro files(*.sav)") + wxString(wxT("|*.sav")), diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 988ccae83e..60efcedc6f 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -51,7 +51,7 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* std::string nickname; netplay_section.Get("Nickname", &nickname, "Player"); - m_nickname_text = new wxTextCtrl(panel, wxID_ANY, wxString::From8BitData(nickname.c_str())); + m_nickname_text = new wxTextCtrl(panel, wxID_ANY, StrToWxStr(nickname)); wxBoxSizer* const nick_szr = new wxBoxSizer(wxHORIZONTAL); nick_szr->Add(nick_lbl, 0, wxCENTER); From 88cb11ba0a24e0fb841b4fc4367f4d61ae18558e Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 2 Mar 2013 20:38:40 -0600 Subject: [PATCH 135/167] I'm confused at why SHIFT-JIS was being used here. --- Source/Core/DolphinWX/Src/LogWindow.cpp | 23 ++++------------------- Source/Core/DolphinWX/Src/LogWindow.h | 2 -- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/Source/Core/DolphinWX/Src/LogWindow.cpp b/Source/Core/DolphinWX/Src/LogWindow.cpp index 7af1de1aaa..57e2ac6b58 100644 --- a/Source/Core/DolphinWX/Src/LogWindow.cpp +++ b/Source/Core/DolphinWX/Src/LogWindow.cpp @@ -21,6 +21,8 @@ #include "IniFile.h" #include "FileUtil.h" #include "Debugger/DebuggerUIUtil.h" +#include "WxUtils.h" + #include // Milliseconds between msgQueue flushes to wxTextCtrl @@ -41,25 +43,7 @@ CLogWindow::CLogWindow(CFrame *parent, wxWindowID id, const wxPoint& pos, , x(0), y(0), winpos(0) , Parent(parent), m_ignoreLogTimer(false), m_LogAccess(true) , m_Log(NULL), m_cmdline(NULL), m_FontChoice(NULL) - , m_SJISConv(wxT("")) { -#ifdef _WIN32 - static bool validCP932 = ::IsValidCodePage(932) != 0; - if (validCP932) - { - m_SJISConv = wxCSConv(wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS)); - } - else - { - WARN_LOG(COMMON, "Cannot Convert from Charset Windows Japanese cp 932"); - m_SJISConv = *(wxCSConv*)wxConvCurrent; - } -#else - // on linux the wrong string is returned from wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS) - // it returns CP-932, in order to use iconv we need to use CP932 - m_SJISConv = wxCSConv(wxT("CP932")); -#endif - m_LogManager = LogManager::GetInstance(); CreateGUIControls(); @@ -370,5 +354,6 @@ void CLogWindow::Log(LogTypes::LOG_LEVELS level, const char *text) if (msgQueue.size() >= 100) msgQueue.pop(); - msgQueue.push(std::pair((u8)level, wxString(text, m_SJISConv))); + + msgQueue.push(std::make_pair(u8(level), StrToWxStr(text))); } diff --git a/Source/Core/DolphinWX/Src/LogWindow.h b/Source/Core/DolphinWX/Src/LogWindow.h index 86fd1d3b4f..54a59c4d91 100644 --- a/Source/Core/DolphinWX/Src/LogWindow.h +++ b/Source/Core/DolphinWX/Src/LogWindow.h @@ -75,8 +75,6 @@ private: std::mutex m_LogSection; - wxCSConv m_SJISConv; - DECLARE_EVENT_TABLE() wxTextCtrl * CreateTextCtrl(wxPanel* parent, wxWindowID id = wxID_ANY, long Style = NULL); From ed90feb2b4169a98167ba90846aa27f8cd4bf50e Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 2 Mar 2013 22:59:55 -0600 Subject: [PATCH 136/167] Kill warning. --- Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp | 4 ++-- Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp index 95311eb98d..db47217655 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.cpp @@ -9,7 +9,7 @@ PerfQuery::PerfQuery() : m_query_read_pos() , m_query_count() { - for (int i = 0; i != ARRAYSIZE(m_query_buffer); ++i) + for (u32 i = 0; i != ARRAYSIZE(m_query_buffer); ++i) glGenQueries(1, &m_query_buffer[i].query_id); ResetQuery(); @@ -17,7 +17,7 @@ PerfQuery::PerfQuery() PerfQuery::~PerfQuery() { - for (int i = 0; i != ARRAYSIZE(m_query_buffer); ++i) + for (u32 i = 0; i != ARRAYSIZE(m_query_buffer); ++i) glDeleteQueries(1, &m_query_buffer[i].query_id); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h index 34c64e43a1..b96fe7a4a0 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/PerfQuery.h @@ -26,7 +26,7 @@ private: }; // when testing in SMS: 64 was too small, 128 was ok - static const int PERF_QUERY_BUFFER_SIZE = 512; + static const u32 PERF_QUERY_BUFFER_SIZE = 512; void WeakFlush(); // Only use when non-empty @@ -34,10 +34,10 @@ private: // This contains gl query objects with unretrieved results. ActiveQuery m_query_buffer[PERF_QUERY_BUFFER_SIZE]; - int m_query_read_pos; + u32 m_query_read_pos; // TODO: sloppy - volatile int m_query_count; + volatile u32 m_query_count; volatile u32 m_results[PQG_NUM_MEMBERS]; }; From a01f793f5986747392080ccea2bfd22821e3f4e3 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 3 Mar 2013 07:37:22 +0000 Subject: [PATCH 137/167] Fix ARM build. --- .../VideoCommon/Src/GenericTextureDecoder.cpp | 34 +++++++++++++++++++ Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp b/Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp index ad7cfeebf9..7546511515 100644 --- a/Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp +++ b/Source/Core/VideoCommon/Src/GenericTextureDecoder.cpp @@ -1442,6 +1442,40 @@ void TexDecoder_DecodeTexel(u8 *dst, const u8 *src, int s, int t, int imageWidth } } +void TexDecoder_DecodeTexelRGBA8FromTmem(u8 *dst, const u8 *src_ar, const u8* src_gb, int s, int t, int imageWidth) +{ + u16 sBlk = s >> 2; + u16 tBlk = t >> 2; + u16 widthBlks = (imageWidth >> 2) + 1; // TODO: Looks wrong. Shouldn't this be ((imageWidth-1)>>2)+1 ? + u32 base_ar = (tBlk * widthBlks + sBlk) << 4; + u32 base_gb = (tBlk * widthBlks + sBlk) << 4; + u16 blkS = s & 3; + u16 blkT = t & 3; + u32 blk_off = (blkT << 2) + blkS; + + u32 offset_ar = (base_ar + blk_off) << 1; + u32 offset_gb = (base_gb + blk_off) << 1; + const u8* val_addr_ar = src_ar + offset_ar; + const u8* val_addr_gb = src_gb + offset_gb; + + dst[3] = val_addr_ar[0]; // A + dst[0] = val_addr_ar[1]; // R + dst[1] = val_addr_gb[0]; // G + dst[2] = val_addr_gb[1]; // B +} + +PC_TexFormat TexDecoder_DecodeRGBA8FromTmem(u8* dst, const u8 *src_ar, const u8 *src_gb, int width, int height) +{ + // TODO for someone who cares: Make this less slow! + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + { + TexDecoder_DecodeTexelRGBA8FromTmem(dst, src_ar, src_gb, x, y, width-1); + dst += 4; + } + + return PC_TEX_FMT_RGBA32; +} const char* texfmt[] = { // pixel diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h index 09d38bb731..be46f047ca 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h @@ -69,7 +69,7 @@ bool OpenGL_ReportFBOError(const char *function, const char *file, int line); #define GL_REPORT_PROGRAM_ERROR() (void)0 #endif -#if defined __APPLE__ || defined __linux__ || defined _WIN32 +#if (defined __APPLE__ || defined __linux__ || defined _WIN32) && !(defined _M_ARM) #include #include #define HAVE_CG 1 From aeb4fc9846f19d78248994b72c0902c17df3947b Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 2 Mar 2013 22:57:49 -0600 Subject: [PATCH 138/167] Fix what I broke. --- Source/Core/Common/Src/StringUtil.cpp | 80 +++++++++++- Source/Core/Common/Src/StringUtil.h | 1 + Source/Core/DiscIO/Src/BannerLoader.cpp | 4 +- Source/Core/DiscIO/Src/BannerLoader.h | 6 - Source/Core/DiscIO/Src/BannerLoaderGC.cpp | 11 +- Source/Core/DiscIO/Src/BannerLoaderGC.h | 13 +- Source/Core/DiscIO/Src/BannerLoaderWii.cpp | 139 ++------------------- Source/Core/DiscIO/Src/BannerLoaderWii.h | 3 - Source/Core/DiscIO/Src/Volume.h | 2 + 9 files changed, 108 insertions(+), 151 deletions(-) diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index aab0f3bd58..e499fc40c3 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -17,13 +17,19 @@ #include #include +#include #include "Common.h" #include "CommonPaths.h" #include "StringUtil.h" #ifdef _WIN32 -#include + #include +#elif defined(ANDROID) + +#else + #include + #include #endif // faster than sscanf @@ -418,18 +424,80 @@ std::string SHIFTJISToUTF8(const std::string& input) return UTF16ToUTF8(CPToUTF16(932, input)); } +std::string CP1252ToUTF8(const std::string& input) +{ + return UTF16ToUTF8(CPToUTF16(1252, input)); +} + #else -std::string UTF16ToUTF8(const std::wstring& input) +template +std::string CodeToUTF8(const char* fromcode, const std::basic_string& input) { - // TODO: implement - return std::string(); + std::string result; + +#if defined(ANDROID) + result = "Not implemented on Android!"; + +#else + iconv_t const conv_desc = iconv_open("UTF-8", fromcode); + if ((iconv_t)-1 == conv_desc) + { + ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); + } + else + { + size_t const in_bytes = sizeof(T) * input.size(); + size_t const out_buffer_size = 4 * in_bytes; + + std::string out_buffer; + out_buffer.resize(out_buffer_size); + + auto src_buffer = &input[0]; + size_t src_bytes = in_bytes; + auto dst_buffer = &out_buffer[0]; + size_t dst_bytes = out_buffer.size(); + + size_t const iconv_size = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, + &dst_buffer, &dst_bytes); + + if ((size_t)-1 == iconv_size) + { + ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); + } + else + { + out_buffer.resize(out_buffer_size - dst_bytes); + out_buffer.swap(result); + + // TODO: why is this needed? + result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); + } + + iconv_close(conv_desc); + } + +#endif + return result; +} + +std::string CP1252ToUTF8(const std::string& input) +{ + return CodeToUTF8("CP1252", input); } std::string SHIFTJISToUTF8(const std::string& input) { - // TODO: implement - return std::string(); + //return CodeToUTF8("CP932", input); + return CodeToUTF8("SJIS", input); +} + +std::string UTF16ToUTF8(const std::wstring& input) +{ + //return CodeToUTF8("UCS-2", input); + //return CodeToUTF8("UCS-2LE", input); + //return CodeToUTF8("UTF-16", input); + return CodeToUTF8("UTF-16LE", input); } #endif diff --git a/Source/Core/Common/Src/StringUtil.h b/Source/Core/Common/Src/StringUtil.h index ce5751f80b..9463db5bb1 100644 --- a/Source/Core/Common/Src/StringUtil.h +++ b/Source/Core/Common/Src/StringUtil.h @@ -97,6 +97,7 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st std::string UriDecode(const std::string & sSrc); std::string UriEncode(const std::string & sSrc); +std::string CP1252ToUTF8(const std::string& str); std::string SHIFTJISToUTF8(const std::string& str); std::string UTF16ToUTF8(const std::wstring& str); diff --git a/Source/Core/DiscIO/Src/BannerLoader.cpp b/Source/Core/DiscIO/Src/BannerLoader.cpp index 7e641aa85b..d38c7e9ea4 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.cpp +++ b/Source/Core/DiscIO/Src/BannerLoader.cpp @@ -31,9 +31,9 @@ IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVo { return new CBannerLoaderWii(pVolume); } - if (_rFileSystem.IsValid()) + if (_rFileSystem.IsValid()) { - return new CBannerLoaderGC(_rFileSystem); + return new CBannerLoaderGC(_rFileSystem, pVolume); } return NULL; diff --git a/Source/Core/DiscIO/Src/BannerLoader.h b/Source/Core/DiscIO/Src/BannerLoader.h index 92bb874979..b30ee17a46 100644 --- a/Source/Core/DiscIO/Src/BannerLoader.h +++ b/Source/Core/DiscIO/Src/BannerLoader.h @@ -44,12 +44,6 @@ class IBannerLoader virtual std::vector GetNames() = 0; virtual std::string GetCompany() = 0; virtual std::vector GetDescriptions() = 0; - - private: - u16 swap16(u16 data) - { - return ((data & 0xff00) >> 8) | ((data & 0xff) << 8); - } }; IBannerLoader* CreateBannerLoader(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume *pVolume); diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp index bf087cbfb6..d8ae259b16 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.cpp @@ -23,9 +23,10 @@ namespace DiscIO { -CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem) - : m_pBannerFile(NULL), - m_IsValid(false) +CBannerLoaderGC::CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume) + : m_pBannerFile(NULL) + , m_IsValid(false) + , m_country(volume->GetCountry()) { // load the opening.bnr size_t FileSize = (size_t) _rFileSystem.GetFileSize("opening.bnr"); @@ -104,7 +105,7 @@ std::vector CBannerLoaderGC::GetNames() auto const banner = reinterpret_cast(m_pBannerFile); - for (int i = 0; i != name_count; ++i) + for (u32 i = 0; i != name_count; ++i) { auto& comment = banner->comment[i]; @@ -167,7 +168,7 @@ std::vector CBannerLoaderGC::GetDescriptions() auto banner = reinterpret_cast(m_pBannerFile); - for (int i = 0; i != desc_count; ++i) + for (u32 i = 0; i != desc_count; ++i) { auto& data = banner->comment[i].comment; descriptions.push_back(GetDecodedString(data)); diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.h b/Source/Core/DiscIO/Src/BannerLoaderGC.h index b4903561e4..8bc8c46483 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.h +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.h @@ -19,6 +19,7 @@ #define _BANNER_LOADER_GC_H_ #include "BannerLoader.h" +#include "StringUtil.h" namespace DiscIO { @@ -26,7 +27,7 @@ class CBannerLoaderGC : public IBannerLoader { public: - CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem); + CBannerLoaderGC(DiscIO::IFileSystem& _rFileSystem, DiscIO::IVolume* volume); virtual ~CBannerLoaderGC(); virtual bool IsValid(); @@ -76,8 +77,12 @@ class CBannerLoaderGC template std::string GetDecodedString(const char (&data)[N]) { - // Can I always assume SHIFT-JIS? - return SHIFTJISToUTF8(std::string(data, strnlen(data, sizeof(data)))); + auto const string_decoder = (DiscIO::IVolume::COUNTRY_JAPAN == m_country || + DiscIO::IVolume::COUNTRY_TAIWAN == m_country) ? + SHIFTJISToUTF8 : CP1252ToUTF8; + + // strnlen to trim NULLs + return string_decoder(std::string(data, strnlen(data, sizeof(data)))); } u8* m_pBannerFile; @@ -86,6 +91,8 @@ class CBannerLoaderGC void decode5A3image(u32* dst, u16* src, int width, int height); BANNER_TYPE getBannerType(); + + DiscIO::IVolume::ECountry const m_country; }; } // namespace diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp index b94e299f04..f606ed8876 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.cpp +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.cpp @@ -25,25 +25,6 @@ #include "FileUtil.h" #include "FileHandlerARC.h" -// HyperIris: dunno if this suitable, may be need move. -#ifdef _WIN32 -#include -#else -#include -#ifndef ANDROID -#include -#endif -#include -#endif - -#ifndef ICONV_CONST -#if defined __FreeBSD__ || __NetBSD__ -#define ICONV_CONST const -#else -#define ICONV_CONST -#endif -#endif - namespace DiscIO { @@ -164,35 +145,24 @@ bool CBannerLoaderWii::GetBanner(u32* _pBannerImage) return true; } -bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& s) -{ - bool ret = false; - - if (IsValid()) - { - // find Banner type - SWiiBanner *pBanner = (SWiiBanner*)m_pBannerFile; - // TODO: trim NULLs - ret = CopyBeUnicodeToString(s, pBanner->m_Comment[index], COMMENT_SIZE); - } - - return ret; -} - -bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::wstring& s) +bool CBannerLoaderWii::GetStringFromComments(const CommentIndex index, std::string& result) { if (IsValid()) { - // find Banner type - SWiiBanner* pBanner = (SWiiBanner*)m_pBannerFile; - - std::wstring description; - for (int i = 0; i < COMMENT_SIZE; ++i) - description.push_back(Common::swap16(pBanner->m_Comment[index][i])); - - s = description; + auto const banner = reinterpret_cast(m_pBannerFile); + auto const src_ptr = banner->m_Comment[index]; + + // Trim at first NULL + auto const length = std::find(src_ptr, src_ptr + COMMENT_SIZE, 0x0) - src_ptr; + + std::wstring src; + src.resize(length); + std::transform(src_ptr, src_ptr + src.size(), src.begin(), (u16(&)(u16))Common::swap16); + result = UTF16ToUTF8(src); + return true; } + return false; } @@ -237,87 +207,4 @@ void CBannerLoaderWii::decode5A3image(u32* dst, u16* src, int width, int height) } } -bool CBannerLoaderWii::CopyBeUnicodeToString( std::string& _rDestination, const u16* _src, int length ) -{ - bool returnCode = false; -#ifdef _WIN32 - if (_src) - { - std::wstring src; - src.resize(length); - std::transform(_src, _src + length, &src[0], (u16(&)(u16))Common::swap16); - - _rDestination = UTF16ToUTF8(src); - returnCode = true; - } -#else -#ifdef ANDROID - return false; -#else - if (_src) - { - iconv_t conv_desc = iconv_open("UTF-8", "CP932"); - if (conv_desc == (iconv_t) -1) - { - // Initialization failure. - if (errno == EINVAL) - { - ERROR_LOG(DISCIO, "Conversion from CP932 to UTF-8 is not supported."); - } - else - { - ERROR_LOG(DISCIO, "Iconv initialization failure: %s\n", strerror (errno)); - } - return false; - } - - char* src_buffer = new char[length]; - for (int i = 0; i < length; i++) - src_buffer[i] = swap16(_src[i]); - - size_t inbytes = sizeof(char) * length; - size_t outbytes = 2 * inbytes; - char* utf8_buffer = new char[outbytes + 1]; - memset(utf8_buffer, 0, (outbytes + 1) * sizeof(char)); - - // Save the buffer locations because iconv increments them - char* utf8_buffer_start = utf8_buffer; - char* src_buffer_start = src_buffer; - - size_t iconv_size = iconv(conv_desc, - (ICONV_CONST char**)&src_buffer, &inbytes, - &utf8_buffer, &outbytes); - - // Handle failures - if (iconv_size == (size_t) -1) - { - ERROR_LOG(DISCIO, "iconv failed."); - switch (errno) { - case EILSEQ: - ERROR_LOG(DISCIO, "Invalid multibyte sequence."); - break; - case EINVAL: - ERROR_LOG(DISCIO, "Incomplete multibyte sequence."); - break; - case E2BIG: - ERROR_LOG(DISCIO, "Insufficient space allocated for output buffer."); - break; - default: - ERROR_LOG(DISCIO, "Error: %s.", strerror(errno)); - } - } - else - { - _rDestination = utf8_buffer_start; - returnCode = true; - } - delete[] utf8_buffer_start; - delete[] src_buffer_start; - iconv_close(conv_desc); - } -#endif -#endif - return returnCode; -} - } // namespace diff --git a/Source/Core/DiscIO/Src/BannerLoaderWii.h b/Source/Core/DiscIO/Src/BannerLoaderWii.h index 60d317155b..036eeeacbd 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderWii.h +++ b/Source/Core/DiscIO/Src/BannerLoaderWii.h @@ -75,9 +75,6 @@ class CBannerLoaderWii void decode5A3image(u32* dst, u16* src, int width, int height); bool GetStringFromComments(const CommentIndex index, std::string& s); - bool GetStringFromComments(const CommentIndex index, std::wstring& s); - - bool CopyBeUnicodeToString(std::string& _rDestination, const u16* _src, int length); }; } // namespace diff --git a/Source/Core/DiscIO/Src/Volume.h b/Source/Core/DiscIO/Src/Volume.h index 4743cfce89..c19aaf93a8 100644 --- a/Source/Core/DiscIO/Src/Volume.h +++ b/Source/Core/DiscIO/Src/Volume.h @@ -22,6 +22,7 @@ #include #include "Common.h" +#include "StringUtil.h" namespace DiscIO { @@ -37,6 +38,7 @@ public: virtual void GetTMD(u8*, u32 *_sz) const { *_sz=0; } virtual std::string GetUniqueID() const = 0; virtual std::string GetMakerID() const = 0; + // TODO: eliminate? virtual std::string GetName() const; virtual std::vector GetNames() const = 0; virtual u32 GetFSTSize() const = 0; From fad2b65d76dc9f0108c5ed3638c4d1ec6403c00e Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 02:30:45 -0600 Subject: [PATCH 139/167] More wxString conversion cleanup. --- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 3 +-- Source/Core/DolphinWX/Src/MemcardManager.cpp | 25 ++++---------------- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index 562d2234cd..15df0fa3ee 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -966,8 +966,7 @@ void CGameListCtrl::OnOpenContainingFolder(wxCommandEvent& WXUNUSED (event)) if (!iso) return; - wxString strPath(iso->GetFileName().c_str(), wxConvUTF8); - wxFileName path = wxFileName::FileName(strPath); + wxFileName path = wxFileName::FileName(StrToWxStr(iso->GetFileName())); path.MakeAbsolute(); WxUtils::Explore(path.GetPath().char_str()); } diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp index b9b26b6da8..0bbbbd0a7b 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.cpp +++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp @@ -704,26 +704,11 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card) std::string title = memoryCard[card]->GetSaveComment1(fileIndex); std::string comment = memoryCard[card]->GetSaveComment2(fileIndex); - bool ascii = memoryCard[card]->IsAsciiEncoding(); - -#ifdef _WIN32 - wxCSConv SJISConv(*(wxCSConv*)wxConvCurrent); - static bool validCP932 = ::IsValidCodePage(932) != 0; - if (validCP932) - { - SJISConv = wxCSConv(wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS)); - } - else - { - WARN_LOG(COMMON, "Cannot Convert from Charset Windows Japanese cp 932"); - } -#else - // on linux the wrong string is returned from wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS) - // it returns CP-932, in order to use iconv we need to use CP932 - wxCSConv SJISConv(wxT("CP932")); -#endif - wxTitle = wxString(title.c_str(), ascii ? *wxConvCurrent : SJISConv); - wxComment = wxString(comment.c_str(), ascii ? *wxConvCurrent : SJISConv); + auto const string_decoder = memoryCard[card]->IsAsciiEncoding() ? + CP1252ToUTF8 : SHIFTJISToUTF8; + + wxTitle = StrToWxStr(string_decoder(title)); + wxComment = StrToWxStr(string_decoder(comment)); m_MemcardList[card]->SetItem(index, COLUMN_TITLE, wxTitle); m_MemcardList[card]->SetItem(index, COLUMN_COMMENT, wxComment); From 11e4403fb24519ed1a7c2a63f1e76ffdf7f5fa0d Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 3 Mar 2013 08:38:13 +0000 Subject: [PATCH 140/167] Fix accidental change from libpulse-simple to libpulse --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea531f030c..5560b195e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,7 +331,7 @@ if(NOT ANDROID) message("bluez NOT found, disabling bluetooth support") endif(BLUEZ_FOUND) - check_lib(PULSEAUDIO libpulse QUIET) + check_lib(PULSEAUDIO libpulse-simple QUIET) if(PULSEAUDIO_FOUND) add_definitions(-DHAVE_PULSEAUDIO=1) message("PulseAudio found, enabling PulseAudio sound backend") From cedfa452b4497590f828306b42b1e7c24915fd58 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 14:20:45 -0600 Subject: [PATCH 141/167] Windows: Open wiimotes with the FILE_SHARE_WRITE flag like before. This should fix issues introduced by real-wiimote-scanning. --- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 1119ae3f1d..c3824e21be 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ #include //#define AUTHENTICATE_WIIMOTES +#define SHARE_WRITE_WIIMOTES typedef struct _HIDD_ATTRIBUTES { @@ -84,6 +86,11 @@ static int initialized = 0; std::unordered_map g_connect_times; +#ifdef SHARE_WRITE_WIIMOTES +std::unordered_set g_connected_wiimotes; +std::mutex g_connected_wiimotes_lock; +#endif + inline void init_lib() { if (!initialized) @@ -259,11 +266,22 @@ bool Wiimote::Connect() if (IsConnected()) return false; +#ifdef SHARE_WRITE_WIIMOTES + std::lock_guard lk(g_connected_wiimotes_lock); + if (g_connected_wiimotes.count(devicepath) != 0) + return false; + + auto const open_flags = FILE_SHARE_READ | FILE_SHARE_WRITE; +#else + // Having no FILE_SHARE_WRITE disallows us from connecting to the same wiimote twice. + // (And disallows using wiimotes in use by other programs) + // This is what "WiiYourself" does. + // Apparently this doesn't work for everyone. It might be their fault. + auto const open_flags = FILE_SHARE_READ; +#endif + dev_handle = CreateFile(devicepath.c_str(), - GENERIC_READ | GENERIC_WRITE, - // Having no FILE_SHARE_WRITE disallows us from connecting to the same wiimote twice. - // This is what "WiiYourself" does. - FILE_SHARE_READ, + GENERIC_READ | GENERIC_WRITE, open_flags, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (dev_handle == INVALID_HANDLE_VALUE) @@ -298,6 +316,10 @@ bool Wiimote::Connect() ERROR_LOG(WIIMOTE, "Failed to set wiimote thread priority"); } */ +#ifdef SHARE_WRITE_WIIMOTES + g_connected_wiimotes.insert(devicepath); +#endif + return true; } @@ -311,6 +333,11 @@ void Wiimote::Disconnect() CloseHandle(hid_overlap_read.hEvent); CloseHandle(hid_overlap_write.hEvent); + +#ifdef SHARE_WRITE_WIIMOTES + std::lock_guard lk(g_connected_wiimotes_lock); + g_connected_wiimotes.erase(devicepath); +#endif } bool Wiimote::IsConnected() const From c07b8a6e3754abb4be5d962d84550d4b10827240 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 16:51:26 -0600 Subject: [PATCH 142/167] Fix more of what I broke. --- Source/Core/Common/Src/StringUtil.cpp | 52 ++++++++++++++------- Source/Core/DiscIO/Src/BannerLoaderGC.h | 5 +- Source/Core/DiscIO/Src/FileSystemGCWii.cpp | 32 +++++++------ Source/Core/DiscIO/Src/FileSystemGCWii.h | 6 +-- Source/Core/DiscIO/Src/VolumeGC.cpp | 14 ++++-- Source/Core/DiscIO/Src/VolumeGC.h | 4 ++ Source/Core/DiscIO/Src/VolumeWad.cpp | 38 +++++++-------- Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp | 7 +-- 8 files changed, 97 insertions(+), 61 deletions(-) diff --git a/Source/Core/Common/Src/StringUtil.cpp b/Source/Core/Common/Src/StringUtil.cpp index e499fc40c3..c38184776b 100644 --- a/Source/Core/Common/Src/StringUtil.cpp +++ b/Source/Core/Common/Src/StringUtil.cpp @@ -457,22 +457,33 @@ std::string CodeToUTF8(const char* fromcode, const std::basic_string& input) size_t src_bytes = in_bytes; auto dst_buffer = &out_buffer[0]; size_t dst_bytes = out_buffer.size(); - - size_t const iconv_size = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, - &dst_buffer, &dst_bytes); - - if ((size_t)-1 == iconv_size) + + while (src_bytes != 0) { - ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); - } - else - { - out_buffer.resize(out_buffer_size - dst_bytes); - out_buffer.swap(result); + size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, + &dst_buffer, &dst_bytes); - // TODO: why is this needed? - result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); + if ((size_t)-1 == iconv_result) + { + if (EILSEQ == errno || EINVAL == errno) + { + // Try to skip the bad character + if (src_bytes != 0) + { + --src_bytes; + ++src_buffer; + } + } + else + { + ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno)); + break; + } + } } + + out_buffer.resize(out_buffer_size - dst_bytes); + out_buffer.swap(result); iconv_close(conv_desc); } @@ -483,6 +494,8 @@ std::string CodeToUTF8(const char* fromcode, const std::basic_string& input) std::string CP1252ToUTF8(const std::string& input) { + //return CodeToUTF8("CP1252//TRANSLIT", input); + //return CodeToUTF8("CP1252//IGNORE", input); return CodeToUTF8("CP1252", input); } @@ -494,10 +507,15 @@ std::string SHIFTJISToUTF8(const std::string& input) std::string UTF16ToUTF8(const std::wstring& input) { - //return CodeToUTF8("UCS-2", input); - //return CodeToUTF8("UCS-2LE", input); - //return CodeToUTF8("UTF-16", input); - return CodeToUTF8("UTF-16LE", input); + std::string result = + // CodeToUTF8("UCS-2", input); + // CodeToUTF8("UCS-2LE", input); + // CodeToUTF8("UTF-16", input); + CodeToUTF8("UTF-16LE", input); + + // TODO: why is this needed? + result.erase(std::remove(result.begin(), result.end(), 0x00), result.end()); + return result; } #endif diff --git a/Source/Core/DiscIO/Src/BannerLoaderGC.h b/Source/Core/DiscIO/Src/BannerLoaderGC.h index 8bc8c46483..8b14a45d43 100644 --- a/Source/Core/DiscIO/Src/BannerLoaderGC.h +++ b/Source/Core/DiscIO/Src/BannerLoaderGC.h @@ -19,6 +19,7 @@ #define _BANNER_LOADER_GC_H_ #include "BannerLoader.h" +#include "VolumeGC.h" #include "StringUtil.h" namespace DiscIO @@ -77,9 +78,7 @@ class CBannerLoaderGC template std::string GetDecodedString(const char (&data)[N]) { - auto const string_decoder = (DiscIO::IVolume::COUNTRY_JAPAN == m_country || - DiscIO::IVolume::COUNTRY_TAIWAN == m_country) ? - SHIFTJISToUTF8 : CP1252ToUTF8; + auto const string_decoder = CVolumeGC::GetStringDecoder(m_country); // strnlen to trim NULLs return string_decoder(std::string(data, strnlen(data, sizeof(data)))); diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp index 47651e2f23..93b569e043 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp @@ -20,6 +20,7 @@ #include #include +#include #include "FileSystemGCWii.h" #include "StringUtil.h" @@ -27,10 +28,10 @@ namespace DiscIO { CFileSystemGCWii::CFileSystemGCWii(const IVolume *_rVolume) - : IFileSystem(_rVolume), - m_Initialized(false), - m_Valid(false), - m_OffsetShift(0) + : IFileSystem(_rVolume) + , m_Initialized(false) + , m_Valid(false) + , m_OffsetShift(0) { m_Valid = DetectFileSystem(); } @@ -213,9 +214,16 @@ u32 CFileSystemGCWii::Read32(u64 _Offset) const return Common::swap32(Temp); } -void CFileSystemGCWii::GetStringFromOffset(u64 _Offset, char* Filename) const +std::string CFileSystemGCWii::GetStringFromOffset(u64 _Offset) const { - m_rVolume->Read(_Offset, 255, (u8*)Filename); + std::string data; + data.resize(255); + m_rVolume->Read(_Offset, data.size(), (u8*)&data[0]); + data.erase(std::find(data.begin(), data.end(), 0x00), data.end()); + + // TODO: Should we really always use SHIFT-JIS? + // It makes some filenames in Pikmin (NTSC-U) sane, but is it correct? + return SHIFTJISToUTF8(data); } size_t CFileSystemGCWii::GetFileList(std::vector &_rFilenames) @@ -311,18 +319,16 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _ { SFileInfo *rFileInfo = &m_FileInfoVector[CurrentIndex]; u64 uOffset = _NameTableOffset + (rFileInfo->m_NameOffset & 0xFFFFFF); - char filename[512]; - memset(filename, 0, sizeof(filename)); - GetStringFromOffset(uOffset, filename); + std::string filename = GetStringFromOffset(uOffset); // check next index if (rFileInfo->IsDirectory()) { // this is a directory, build up the new szDirectory if (_szDirectory != NULL) - CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s/", _szDirectory, filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s/", _szDirectory, filename.c_str()); else - CharArrayFromFormat(rFileInfo->m_FullPath, "%s/", filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s/", filename.c_str()); CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo->m_FileSize, rFileInfo->m_FullPath, _NameTableOffset); } @@ -330,9 +336,9 @@ size_t CFileSystemGCWii::BuildFilenames(const size_t _FirstIndex, const size_t _ { // this is a filename if (_szDirectory != NULL) - CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s%s", _szDirectory, filename.c_str()); else - CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename); + CharArrayFromFormat(rFileInfo->m_FullPath, "%s", filename.c_str()); CurrentIndex++; } diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.h b/Source/Core/DiscIO/Src/FileSystemGCWii.h index 0e7d836d75..9054ade272 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.h +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.h @@ -28,7 +28,7 @@ namespace DiscIO class CFileSystemGCWii : public IFileSystem { public: - CFileSystemGCWii(const IVolume *_rVolume); + CFileSystemGCWii(const IVolume* _rVolume); virtual ~CFileSystemGCWii(); virtual bool IsValid() const { return m_Valid; } virtual u64 GetFileSize(const char* _rFullPath); @@ -44,11 +44,11 @@ public: private: bool m_Initialized; bool m_Valid; - u32 m_OffsetShift; // WII offsets are all shifted + std::vector m_FileInfoVector; u32 Read32(u64 _Offset) const; - void GetStringFromOffset(u64 _Offset, char* Filename) const; + std::string GetStringFromOffset(u64 _Offset) const; const SFileInfo* FindFileInfo(const char* _rFullPath); bool DetectFileSystem(); void InitFileSystem(); diff --git a/Source/Core/DiscIO/Src/VolumeGC.cpp b/Source/Core/DiscIO/Src/VolumeGC.cpp index 6e9579571a..6210172790 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.cpp +++ b/Source/Core/DiscIO/Src/VolumeGC.cpp @@ -94,10 +94,12 @@ std::string CVolumeGC::GetMakerID() const std::vector CVolumeGC::GetNames() const { std::vector names; + + auto const string_decoder = GetStringDecoder(GetCountry()); - char name[128] = {}; - if (m_pReader != NULL && Read(0x20, 0x60, (u8*)&name)) - names.push_back(name); + char name[0x60 + 1] = {}; + if (m_pReader != NULL && Read(0x20, 0x60, (u8*)name)) + names.push_back(string_decoder(name)); return names; } @@ -143,4 +145,10 @@ bool CVolumeGC::IsDiscTwo() const return discTwo; } +auto CVolumeGC::GetStringDecoder(ECountry country) -> StringDecoder +{ + return (COUNTRY_JAPAN == country || COUNTRY_TAIWAN == country) ? + SHIFTJISToUTF8 : CP1252ToUTF8; +} + } // namespace diff --git a/Source/Core/DiscIO/Src/VolumeGC.h b/Source/Core/DiscIO/Src/VolumeGC.h index dab1ad7a9d..d7729ee04c 100644 --- a/Source/Core/DiscIO/Src/VolumeGC.h +++ b/Source/Core/DiscIO/Src/VolumeGC.h @@ -40,6 +40,10 @@ public: ECountry GetCountry() const; u64 GetSize() const; bool IsDiscTwo() const; + + typedef std::string(*StringDecoder)(const std::string&); + + static StringDecoder GetStringDecoder(ECountry country); private: IBlobReader* m_pReader; diff --git a/Source/Core/DiscIO/Src/VolumeWad.cpp b/Source/Core/DiscIO/Src/VolumeWad.cpp index 72788f1017..ed95774b2e 100644 --- a/Source/Core/DiscIO/Src/VolumeWad.cpp +++ b/Source/Core/DiscIO/Src/VolumeWad.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include #include #include "VolumeWad.h" @@ -117,33 +118,32 @@ std::vector CVolumeWAD::GetNames() const { return names; } + + footer_size = Common::swap32(footer_size); + //Japanese, English, German, French, Spanish, Italian, Dutch, unknown, unknown, Korean - - // Offset to the english title - for (int i = 0; i < 10; i++) + for (int i = 0; i != 10; ++i) { - u16 temp[42]; - std::wstring out_temp; + static const u32 string_length = 42; + static const u32 bytes_length = string_length * sizeof(u16); + + u16 temp[string_length]; - if (!Read(0x9C + (i*84) + OpeningBnrOffset, 84, (u8*)&temp) || Common::swap32(footer_size) < 0xF1 - || !temp[0]) + if (footer_size < 0xF1 || !Read(0x9C + (i * bytes_length) + OpeningBnrOffset, bytes_length, (u8*)&temp)) { names.push_back(""); - continue; + ERROR_LOG(COMMON, "added empty WAD name"); } - for (int j = 0; j < 42; ++j) + else { - u16 t = Common::swap16(temp[j]); - if (t == 0 && j > 0) - { - if (out_temp.at(out_temp.size()-1) != ' ') - out_temp.push_back(' '); - } - else - out_temp.push_back(t); + std::wstring out_temp; + out_temp.resize(string_length); + std::transform(temp, temp + out_temp.size(), out_temp.begin(), (u16(&)(u16))Common::swap16); + out_temp.erase(std::find(out_temp.begin(), out_temp.end(), 0x00), out_temp.end()); + + names.push_back(UTF16ToUTF8(out_temp)); + ERROR_LOG(COMMON, "decoded WAD name: %s", names.back().c_str()); } - - names.push_back(UTF16ToUTF8(out_temp)); } return names; diff --git a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp index f375b9e66d..32aa92bd08 100644 --- a/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/Src/VolumeWiiCrypted.cpp @@ -16,6 +16,7 @@ // http://code.google.com/p/dolphin-emu/ #include "VolumeWiiCrypted.h" +#include "VolumeGC.h" #include "StringUtil.h" #include "Crypto/sha1.h" @@ -171,12 +172,12 @@ std::string CVolumeWiiCrypted::GetMakerID() const std::vector CVolumeWiiCrypted::GetNames() const { std::vector names; + + auto const string_decoder = CVolumeGC::GetStringDecoder(GetCountry()); char name[0xFF] = {}; if (m_pReader != NULL && Read(0x20, 0x60, (u8*)&name)) - { - names.push_back(name); - } + names.push_back(string_decoder(name)); return names; } From ae14578bc5bddd5ebc3e97483dc844bfe5a0e7de Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 17:56:40 -0600 Subject: [PATCH 143/167] Eliminate some netplay gamelist ugliness. --- Source/Core/Core/Src/NetPlay.h | 2 +- Source/Core/DolphinWX/Src/Frame.cpp | 4 +- Source/Core/DolphinWX/Src/GameListCtrl.cpp | 34 +++------------ Source/Core/DolphinWX/Src/GameListCtrl.h | 8 ---- Source/Core/DolphinWX/Src/NetWindow.cpp | 50 +++++++++++----------- 5 files changed, 36 insertions(+), 62 deletions(-) diff --git a/Source/Core/Core/Src/NetPlay.h b/Source/Core/Core/Src/NetPlay.h index e77f972785..96ff78995a 100644 --- a/Source/Core/Core/Src/NetPlay.h +++ b/Source/Core/Core/Src/NetPlay.h @@ -34,7 +34,7 @@ struct Rpt : public std::vector typedef std::vector NetWiimote; -#define NETPLAY_VERSION "Dolphin NetPlay r6423" +#define NETPLAY_VERSION "Dolphin NetPlay 2013-03-03" // messages enum diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index b0b53cc5ea..a0a030081e 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -659,7 +659,7 @@ void CFrame::OnGameListCtrl_ItemActivated(wxListEvent& WXUNUSED (event)) // 1. Boot the selected iso // 2. Boot the default or last loaded iso. // 3. Call BrowseForDirectory if the gamelist is empty - if (!m_GameListCtrl->GetGameNames().size() && + if (!m_GameListCtrl->GetISO(0) && !((SConfig::GetInstance().m_ListGC && SConfig::GetInstance().m_ListWii && SConfig::GetInstance().m_ListWad) && @@ -693,7 +693,7 @@ void CFrame::OnGameListCtrl_ItemActivated(wxListEvent& WXUNUSED (event)) m_GameListCtrl->Update(); } - else if (!m_GameListCtrl->GetGameNames().size()) + else if (!m_GameListCtrl->GetISO(0)) m_GameListCtrl->BrowseForDirectory(); else // Game started by double click diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index 15df0fa3ee..1a828bbf14 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -285,10 +285,6 @@ void CGameListCtrl::Update() m_imageListSmall = NULL; } - // NetPlay : Set/Reset the GameList string - m_gameList.clear(); - m_gamePath.clear(); - Hide(); ScanForISOs(); @@ -406,15 +402,6 @@ wxString NiceSizeFormat(s64 _size) return(NiceString); } -std::string CGameListCtrl::GetGamePaths() const -{ - return m_gamePath; -} -std::string CGameListCtrl::GetGameNames() const -{ - return m_gameList; -} - void CGameListCtrl::InsertItemInReportView(long _Index) { // When using wxListCtrl, there is no hope of per-column text colors. @@ -424,7 +411,6 @@ void CGameListCtrl::InsertItemInReportView(long _Index) int ImageIndex = -1; GameListItem& rISOFile = *m_ISOFiles[_Index]; - m_gamePath.append(rISOFile.GetFileName() + '\n'); // Insert a first row with nothing in it, that will be used as the Index long ItemIndex = InsertItem(_Index, wxEmptyString); @@ -438,31 +424,25 @@ void CGameListCtrl::InsertItemInReportView(long _Index) // Set the game's banner in the second column SetItemColumnImage(_Index, COLUMN_BANNER, ImageIndex); - std::string name; - int SelectedLanguage = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage; + + // Is this sane? switch (rISOFile.GetCountry()) { case DiscIO::IVolume::COUNTRY_TAIWAN: case DiscIO::IVolume::COUNTRY_JAPAN: - { - name = rISOFile.GetName(-1); - m_gameList.append(StringFromFormat("%s (J)\n", name.c_str())); - } + SelectedLanguage = -1; break; + case DiscIO::IVolume::COUNTRY_USA: - // Is this sane? SelectedLanguage = 0; + break; + default: - { - name = rISOFile.GetName(SelectedLanguage); - m_gameList.append(StringFromFormat("%s (%c)\n", name.c_str(), - (rISOFile.GetCountry() == DiscIO::IVolume::COUNTRY_USA) ? 'U' : 'E')); - - } break; } + std::string const name = rISOFile.GetName(SelectedLanguage); SetItem(_Index, COLUMN_TITLE, StrToWxStr(name), -1); // We show the company string on Gamecube only diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.h b/Source/Core/DolphinWX/Src/GameListCtrl.h index 5d97c12724..f1923e97c5 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.h +++ b/Source/Core/DolphinWX/Src/GameListCtrl.h @@ -47,10 +47,6 @@ public: void Update(); - // Net Play method - std::string GetGamePaths() const; - std::string GetGameNames() const; - void BrowseForDirectory(); const GameListItem *GetSelectedISO(); const GameListItem *GetISO(size_t index) const; @@ -84,10 +80,6 @@ private: } } - // NetPlay string for the gamelist - std::string m_gameList; - std::string m_gamePath; - int last_column; int last_sort; wxSize lastpos; diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 60efcedc6f..8cfe41dc93 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -24,6 +24,7 @@ #include "Frame.h" #include +#include #define NETPLAY_TITLEBAR "Dolphin NetPlay" @@ -35,6 +36,21 @@ static NetPlay* netplay_ptr = NULL; extern CFrame* main_frame; NetPlayDiag *NetPlayDiag::npd = NULL; +std::string BuildGameName(const GameListItem& game) +{ + auto const selected_lang = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage; + + // TODO: this should use the name from the volume not the banner + // (I seems banner name can sometimes depend on save contents) + return game.GetName(selected_lang) + " (" + game.GetUniqueID() + ")"; +} + +void FillWithGameNames(wxListBox* game_lbox, const CGameListCtrl& game_list) +{ + for (u32 i = 0 ; auto game = game_list.GetISO(i); ++i) + game_lbox->Append(StrToWxStr(BuildGameName(*game))); +} + NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* const game_list) : wxFrame(parent, wxID_ANY, wxT(NETPLAY_TITLEBAR), wxDefaultPosition, wxDefaultSize) , m_game_list(game_list) @@ -121,11 +137,8 @@ NetPlaySetupDiag::NetPlaySetupDiag(wxWindow* const parent, const CGameListCtrl* m_game_lbox = new wxListBox(host_tab, wxID_ANY); m_game_lbox->Bind(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, &NetPlaySetupDiag::OnHost, this); - - std::istringstream ss(game_list->GetGameNames()); - std::string game; - while (std::getline(ss,game)) - m_game_lbox->Append(StrToWxStr(game)); + + FillWithGameNames(m_game_lbox, *game_list); wxBoxSizer* const top_szr = new wxBoxSizer(wxHORIZONTAL); top_szr->Add(port_lbl, 0, wxCENTER | wxRIGHT, 5); @@ -360,24 +373,17 @@ void NetPlayDiag::OnChat(wxCommandEvent&) void NetPlayDiag::OnStart(wxCommandEvent&) { - // find path for selected game - std::string ntmp, ptmp, path; - std::istringstream nss(m_game_list->GetGameNames()), pss(m_game_list->GetGamePaths()); - - while(std::getline(nss,ntmp)) + // find path for selected game, sloppy.. + for (u32 i = 0 ; auto game = m_game_list->GetISO(i); ++i) { - std::getline(pss,ptmp); - if (m_selected_game == ntmp) + if (m_selected_game == BuildGameName(*game)) { - path = ptmp; - break; + netplay_ptr->StartGame(game->GetFileName()); + return; } } - - if (path.length()) - netplay_ptr->StartGame(path); - else - PanicAlertT("Game not found!!"); + + PanicAlertT("Game not found!"); } void NetPlayDiag::OnStop(wxCommandEvent&) @@ -550,11 +556,7 @@ ChangeGameDiag::ChangeGameDiag(wxWindow* const parent, const CGameListCtrl* cons m_game_lbox = new wxListBox(this, wxID_ANY); m_game_lbox->Bind(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, &ChangeGameDiag::OnPick, this); - // fill list with games - std::istringstream ss(game_list->GetGameNames()); - std::string game; - while (std::getline(ss,game)) - m_game_lbox->Append(StrToWxStr(game)); + FillWithGameNames(m_game_lbox, *game_list); wxButton* const ok_btn = new wxButton(this, wxID_OK, _("Change")); ok_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &ChangeGameDiag::OnPick, this); From a30636cb88679d5f7a886aba6e5de83f4123f968 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 18:00:48 -0600 Subject: [PATCH 144/167] Buildfix. --- Source/Core/DolphinWX/Src/NetWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 8cfe41dc93..28c7f930d7 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -22,6 +22,7 @@ #include "NetPlay.h" #include "NetWindow.h" #include "Frame.h" +#include "ConfigManager.h" #include #include From 6026b298449f480ea96285242c4ed9253c854a22 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 18:29:56 -0600 Subject: [PATCH 145/167] Separate banner and volume name getting functions. Game properties now shows the correct "banner" name in more cases. --- Source/Core/DolphinWX/Src/ISOFile.cpp | 50 +++++++++++++++------ Source/Core/DolphinWX/Src/ISOFile.h | 2 + Source/Core/DolphinWX/Src/ISOProperties.cpp | 21 ++++----- Source/Core/DolphinWX/Src/NetWindow.cpp | 12 ++--- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp index ec8280a726..797780c32e 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.cpp +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -226,28 +226,50 @@ std::string GameListItem::GetDescription(int _index) const } // (-1 = Japanese, 0 = English, etc) -std::string GameListItem::GetName(int _index) const +std::string GameListItem::GetVolumeName(int _index) const { u32 const index = _index + 1; - // banner name - if (index < m_names.size() && !m_names[index].empty()) - return m_names[index]; - - if (!m_names.empty() && !m_names[0].empty()) - return m_names[0]; - - // volume name if (index < m_volume_names.size() && !m_volume_names[index].empty()) return m_volume_names[index]; - if (!m_volume_names.empty() && !m_volume_names[0].empty()) + if (!m_volume_names.empty()) return m_volume_names[0]; + + return ""; +} - // No usable name, return filename (better than nothing) - std::string FileName; - SplitPath(m_FileName, NULL, &FileName, NULL); - return FileName; +// (-1 = Japanese, 0 = English, etc) +std::string GameListItem::GetBannerName(int _index) const +{ + u32 const index = _index + 1; + + if (index < m_names.size() && !m_names[index].empty()) + return m_names[index]; + + if (!m_names.empty()) + return m_names[0]; + + return ""; +} + +// (-1 = Japanese, 0 = English, etc) +std::string GameListItem::GetName(int _index) const +{ + // Prefer name from banner, fallback to name from volume, fallback to filename + + std::string name = GetBannerName(_index); + + if (name.empty()) + name = GetVolumeName(_index); + + if (name.empty()) + { + // No usable name, return filename (better than nothing) + SplitPath(GetFileName(), NULL, &name, NULL); + } + + return name; } const std::string GameListItem::GetWiiFSPath() const diff --git a/Source/Core/DolphinWX/Src/ISOFile.h b/Source/Core/DolphinWX/Src/ISOFile.h index ded392f56a..354a2f7fad 100644 --- a/Source/Core/DolphinWX/Src/ISOFile.h +++ b/Source/Core/DolphinWX/Src/ISOFile.h @@ -37,6 +37,8 @@ public: bool IsValid() const {return m_Valid;} const std::string& GetFileName() const {return m_FileName;} + std::string GetBannerName(int index) const; + std::string GetVolumeName(int index) const; std::string GetName(int index) const; std::string GetCompany() const; std::string GetDescription(int index = 0) const; diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index 43657300cb..f6ca1cb851 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -1301,28 +1301,25 @@ void CISOProperties::OnChangeBannerLang(wxCommandEvent& event) void CISOProperties::ChangeBannerDetails(int lang) { - std::string name; - wxString shortName, - comment, - maker; - + // why? switch (OpenGameListItem->GetCountry()) { case DiscIO::IVolume::COUNTRY_TAIWAN: case DiscIO::IVolume::COUNTRY_JAPAN: - shortName = StrToWxStr(OpenGameListItem->GetName(-1)); - comment = StrToWxStr(OpenGameListItem->GetDescription()); + lang = -1; break; + case DiscIO::IVolume::COUNTRY_USA: - // why? lang = 0; + break; + default: - shortName = StrToWxStr(OpenGameListItem->GetName(lang)); - comment = StrToWxStr(OpenGameListItem->GetDescription(lang)); break; } - - maker = StrToWxStr(OpenGameListItem->GetCompany()); + + wxString const shortName = StrToWxStr(OpenGameListItem->GetBannerName(lang)); + wxString const comment = StrToWxStr(OpenGameListItem->GetDescription(lang)); + wxString const maker = StrToWxStr(OpenGameListItem->GetCompany()); // Updates the informations shown in the window m_ShortName->SetValue(shortName); diff --git a/Source/Core/DolphinWX/Src/NetWindow.cpp b/Source/Core/DolphinWX/Src/NetWindow.cpp index 28c7f930d7..76bb76881b 100644 --- a/Source/Core/DolphinWX/Src/NetWindow.cpp +++ b/Source/Core/DolphinWX/Src/NetWindow.cpp @@ -22,7 +22,6 @@ #include "NetPlay.h" #include "NetWindow.h" #include "Frame.h" -#include "ConfigManager.h" #include #include @@ -39,11 +38,14 @@ NetPlayDiag *NetPlayDiag::npd = NULL; std::string BuildGameName(const GameListItem& game) { - auto const selected_lang = SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage; + // Lang needs to be consistent + auto const lang = 0; - // TODO: this should use the name from the volume not the banner - // (I seems banner name can sometimes depend on save contents) - return game.GetName(selected_lang) + " (" + game.GetUniqueID() + ")"; + std::string name(game.GetBannerName(lang)); + if (name.empty()) + name = game.GetVolumeName(lang); + + return name + " (" + game.GetUniqueID() + ")"; } void FillWithGameNames(wxListBox* game_lbox, const CGameListCtrl& game_list) From bdc96342baa369fc63c013ce385aa780e096ff8f Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 18:40:50 -0600 Subject: [PATCH 146/167] More string conversion cleanup. --- Source/Core/DolphinWX/Src/LogWindow.cpp | 2 +- Source/Core/DolphinWX/Src/Main.cpp | 2 +- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/Core/DolphinWX/Src/LogWindow.cpp b/Source/Core/DolphinWX/Src/LogWindow.cpp index 57e2ac6b58..27e5856410 100644 --- a/Source/Core/DolphinWX/Src/LogWindow.cpp +++ b/Source/Core/DolphinWX/Src/LogWindow.cpp @@ -192,7 +192,7 @@ void CLogWindow::SaveSettings() void CLogWindow::OnSubmit(wxCommandEvent& WXUNUSED (event)) { if (!m_cmdline) return; - Console_Submit(m_cmdline->GetValue().To8BitData()); + Console_Submit(WxStrToStr(m_cmdline->GetValue()).c_str()); m_cmdline->SetValue(wxEmptyString); } diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index 60a8157c28..09387f2764 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -445,7 +445,7 @@ bool wxMsgAlert(const char* caption, const char* text, bool yes_no, int /*Style* std::string wxStringTranslator(const char *text) { - return WxStrToStr(wxGetTranslation(wxString::From8BitData(text))); + return WxStrToStr(wxGetTranslation(wxString::FromUTF8(text))); } // Accessor for the main window class diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 154a5bc602..cf44c231fe 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -180,8 +180,7 @@ wxArrayString GetListOfResolutions() VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, const std::string& _ininame) : wxDialog(parent, -1, - wxString::Format(_("Dolphin %s Graphics Configuration"), - wxGetTranslation(wxString::From8BitData(title.c_str()))), + wxString::Format(_("Dolphin %s Graphics Configuration"), wxGetTranslation(StrToWxStr(title))), wxDefaultPosition, wxDefaultSize) , vconfig(g_Config) , ininame(_ininame) From 6b2818199c0674abcbd40b258ca9de2d65d0d132 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 19:00:29 -0600 Subject: [PATCH 147/167] Fix WAD volume name extracting. --- Source/Core/DiscIO/Src/VolumeWad.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/Core/DiscIO/Src/VolumeWad.cpp b/Source/Core/DiscIO/Src/VolumeWad.cpp index ed95774b2e..a10e5bdb42 100644 --- a/Source/Core/DiscIO/Src/VolumeWad.cpp +++ b/Source/Core/DiscIO/Src/VolumeWad.cpp @@ -111,7 +111,6 @@ bool CVolumeWAD::GetTitleID(u8* _pBuffer) const std::vector CVolumeWAD::GetNames() const { std::vector names; - return names; u32 footer_size; if (!Read(0x1C, 4, (u8*)&footer_size)) @@ -132,7 +131,6 @@ std::vector CVolumeWAD::GetNames() const if (footer_size < 0xF1 || !Read(0x9C + (i * bytes_length) + OpeningBnrOffset, bytes_length, (u8*)&temp)) { names.push_back(""); - ERROR_LOG(COMMON, "added empty WAD name"); } else { @@ -142,7 +140,6 @@ std::vector CVolumeWAD::GetNames() const out_temp.erase(std::find(out_temp.begin(), out_temp.end(), 0x00), out_temp.end()); names.push_back(UTF16ToUTF8(out_temp)); - ERROR_LOG(COMMON, "decoded WAD name: %s", names.back().c_str()); } } From 989f0663eb212164e11e80626fa89900d2f1ae3e Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 19:14:13 -0600 Subject: [PATCH 148/167] Make "Crypto" file opening unicode-safe on Windows. --- Source/Core/Common/Src/Crypto/md5.cpp | 9 ++++++--- Source/Core/Common/Src/Crypto/sha1.cpp | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Source/Core/Common/Src/Crypto/md5.cpp b/Source/Core/Common/Src/Crypto/md5.cpp index 7fff7713da..ef31636aea 100644 --- a/Source/Core/Common/Src/Crypto/md5.cpp +++ b/Source/Core/Common/Src/Crypto/md5.cpp @@ -37,6 +37,8 @@ #include #include +#include "FileUtil.h" + /* * 32-bit integer manipulation macros (little endian) */ @@ -301,7 +303,10 @@ int md5_file( char *path, unsigned char output[16] ) md5_context ctx; unsigned char buf[1024]; - if( ( f = fopen( path, "rb" ) ) == NULL ) + File::IOFile file(path, "rb"); + f = file.GetHandle(); + + if (f == NULL) return( 1 ); md5_starts( &ctx ); @@ -315,11 +320,9 @@ int md5_file( char *path, unsigned char output[16] ) if( ferror( f ) != 0 ) { - fclose( f ); return( 2 ); } - fclose( f ); return( 0 ); } diff --git a/Source/Core/Common/Src/Crypto/sha1.cpp b/Source/Core/Common/Src/Crypto/sha1.cpp index 17ad930986..3d26dc8a50 100644 --- a/Source/Core/Common/Src/Crypto/sha1.cpp +++ b/Source/Core/Common/Src/Crypto/sha1.cpp @@ -36,6 +36,8 @@ #include #include +#include "FileUtil.h" + /* * 32-bit integer manipulation macros (big endian) */ @@ -335,7 +337,10 @@ int sha1_file( char *path, unsigned char output[20] ) sha1_context ctx; unsigned char buf[1024]; - if( ( f = fopen( path, "rb" ) ) == NULL ) + File::IOFile file(path, "rb"); + f = file.GetHandle(); + + if (f == NULL) return( 1 ); sha1_starts( &ctx ); @@ -349,11 +354,9 @@ int sha1_file( char *path, unsigned char output[20] ) if( ferror( f ) != 0 ) { - fclose( f ); return( 2 ); } - fclose( f ); return( 0 ); } From 814c2ffdfd213dfa78078471d298e2657b7e14e9 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 19:18:04 -0600 Subject: [PATCH 149/167] Fix some leaking file handles and buildfix probably. --- Source/Core/Common/Src/ArmCPUDetect.cpp | 17 +++++++++-------- Source/Core/Common/Src/Crypto/md5.cpp | 2 +- Source/Core/Common/Src/Crypto/sha1.cpp | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Source/Core/Common/Src/ArmCPUDetect.cpp b/Source/Core/Common/Src/ArmCPUDetect.cpp index c03ab08c48..8b5cbf9b79 100644 --- a/Source/Core/Common/Src/ArmCPUDetect.cpp +++ b/Source/Core/Common/Src/ArmCPUDetect.cpp @@ -18,6 +18,7 @@ #include "Common.h" #include "CPUDetect.h" #include "StringUtil.h" +#include "FileUtil.h" const char procfile[] = "/proc/cpuinfo"; @@ -27,9 +28,9 @@ char *GetCPUString() char *cpu_string = 0; // Count the number of processor lines in /proc/cpuinfo char buf[1024]; - FILE *fp; - fp = fopen(procfile, "r"); + File::IOFile file(procfile, "r"); + auto const fp = file.GetHandle(); if (!fp) return 0; @@ -47,9 +48,9 @@ bool CheckCPUFeature(const char *feature) { const char marker[] = "Features\t: "; char buf[1024]; - FILE *fp; - - fp = fopen(procfile, "r"); + + File::IOFile file(procfile, "r"); + auto const fp = file.GetHandle(); if (!fp) return 0; @@ -73,9 +74,9 @@ int GetCoreCount() const char marker[] = "processor\t: "; int cores = 0; char buf[1024]; - FILE *fp; - - fp = fopen(procfile, "r"); + + File::IOFile file(procfile, "r"); + auto const fp = file.GetHandle(); if (!fp) return 0; diff --git a/Source/Core/Common/Src/Crypto/md5.cpp b/Source/Core/Common/Src/Crypto/md5.cpp index ef31636aea..7b8dc149f4 100644 --- a/Source/Core/Common/Src/Crypto/md5.cpp +++ b/Source/Core/Common/Src/Crypto/md5.cpp @@ -37,7 +37,7 @@ #include #include -#include "FileUtil.h" +#include "../FileUtil.h" /* * 32-bit integer manipulation macros (little endian) diff --git a/Source/Core/Common/Src/Crypto/sha1.cpp b/Source/Core/Common/Src/Crypto/sha1.cpp index 3d26dc8a50..45b88b2b6e 100644 --- a/Source/Core/Common/Src/Crypto/sha1.cpp +++ b/Source/Core/Common/Src/Crypto/sha1.cpp @@ -36,7 +36,7 @@ #include #include -#include "FileUtil.h" +#include "../FileUtil.h" /* * 32-bit integer manipulation macros (big endian) From 0041ec618c46ea2bf99fb1fc068e7c4a263cb4c2 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2013 20:16:01 -0600 Subject: [PATCH 150/167] Don't null-terminate some random std::string. --- Source/Core/Core/Src/HW/GCMemcard.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/Core/Core/Src/HW/GCMemcard.cpp b/Source/Core/Core/Src/HW/GCMemcard.cpp index dd15a32914..a2c9690b4e 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.cpp +++ b/Source/Core/Core/Src/HW/GCMemcard.cpp @@ -432,7 +432,6 @@ std::string GCMemcard::DEntry_BIFlags(u8 index) const flags.push_back((x & 0x80) ? '1' : '0'); x = x << 1; } - flags.push_back(0); return flags; } @@ -469,7 +468,6 @@ std::string GCMemcard::DEntry_IconFmt(u8 index) const format.push_back((x & 0x80) ? '1' : '0'); x = x << 1; } - format.push_back(0); return format; } @@ -485,7 +483,6 @@ std::string GCMemcard::DEntry_AnimSpeed(u8 index) const speed.push_back((x & 0x80) ? '1' : '0'); x = x << 1; } - speed.push_back(0); return speed; } @@ -498,7 +495,6 @@ std::string GCMemcard::DEntry_Permissions(u8 index) const permissionsString.push_back((Permissions & 16) ? 'x' : 'M'); permissionsString.push_back((Permissions & 8) ? 'x' : 'C'); permissionsString.push_back((Permissions & 4) ? 'P' : 'x'); - permissionsString.push_back(0); return permissionsString; } From 0efe6c2124ab5e59a43a41b0e665787f2acf7f43 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 15:13:44 -0600 Subject: [PATCH 151/167] GET_ATTR should not be returning the real filepath that we built. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp index 38100e5d7a..5424542a73 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -377,7 +377,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B u32 Addr = _BufferOut; Memory::Write_U32(OwnerID, Addr); Addr += 4; Memory::Write_U16(GroupID, Addr); Addr += 2; - memcpy(Memory::GetPointer(Addr), Filename.c_str(), Filename.size()); Addr += 64; + memcpy(Memory::GetPointer(Addr), Memory::GetPointer(_BufferIn), 64); Addr += 64; Memory::Write_U8(OwnerPerm, Addr); Addr += 1; Memory::Write_U8(GroupPerm, Addr); Addr += 1; Memory::Write_U8(OtherPerm, Addr); Addr += 1; From 04a33b177a8784dc1d2a4fe8cae8b558d28a1a34 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Wed, 20 Feb 2013 15:15:04 -0600 Subject: [PATCH 152/167] Make seek mode 2 (offset from end of file) make sense. I doubt any games use this. --- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 63 ++++++++----------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 711d360874..4ac9cb0eaa 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -165,7 +165,7 @@ File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile() bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) { u32 ReturnValue = FS_RESULT_FATAL; - const u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC); + const u32 SeekOffset = Memory::Read_U32(_CommandAddress + 0xC); const u32 Mode = Memory::Read_U32(_CommandAddress + 0x10); if (auto file = OpenFile()) @@ -173,48 +173,37 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) ReturnValue = FS_RESULT_FATAL; const u64 fileSize = file.GetSize(); - INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekPosition, Mode, m_Name.c_str(), fileSize); + INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekOffset, Mode, m_Name.c_str(), fileSize); + u64 wantedPos = 0; switch (Mode) { - case 0: - { - if (SeekPosition <= fileSize) - { - m_SeekPos = SeekPosition; - ReturnValue = m_SeekPos; - } - break; - } - case 1: - { - u32 wantedPos = SeekPosition+m_SeekPos; - if (wantedPos <= fileSize) - { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; - } - break; - } - case 2: - { - u64 wantedPos = fileSize+m_SeekPos; - if (wantedPos <= fileSize) - { - m_SeekPos = wantedPos; - ReturnValue = m_SeekPos; - } - break; - } - default: - { - PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode); - ReturnValue = FS_RESULT_FATAL; - break; - } + case 0: + wantedPos = SeekOffset; + break; + + case 1: + wantedPos = m_SeekPos + SeekOffset; + break; + + case 2: + wantedPos = fileSize + (s32)SeekOffset; + break; + + default: + PanicAlert("CWII_IPC_HLE_Device_FileIO Unsupported seek mode %i", Mode); + ReturnValue = FS_RESULT_FATAL; + break; + } + + if (wantedPos <= fileSize) + { + m_SeekPos = wantedPos; + ReturnValue = m_SeekPos; } } else { + // TODO: This can't be right. ReturnValue = FS_FILE_NOT_EXIST; } Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); From efcb2abe9bf60978d2e5e776268179671bfef87a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 4 Mar 2013 02:01:23 -0600 Subject: [PATCH 153/167] Don't open/close file for every file operation. --- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 76 +++++++++++-------- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h | 5 +- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 4ac9cb0eaa..5655e9b46d 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -139,27 +139,36 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) return true; } -File::IOFile CWII_IPC_HLE_Device_FileIO::OpenFile() +// Opens file if needed. +// Clears any error state. +// Seeks to proper position position. +void CWII_IPC_HLE_Device_FileIO::PrepareFile() { - const char* open_mode = ""; - - switch (m_Mode) + if (!m_file.IsOpen()) { - case ISFS_OPEN_READ: - open_mode = "rb"; - break; - - case ISFS_OPEN_WRITE: - case ISFS_OPEN_RW: - open_mode = "r+b"; - break; - - default: - PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode); - break; + const char* open_mode = ""; + + switch (m_Mode) + { + case ISFS_OPEN_READ: + open_mode = "rb"; + break; + + case ISFS_OPEN_WRITE: + case ISFS_OPEN_RW: + open_mode = "r+b"; + break; + + default: + PanicAlertT("FileIO: Unknown open mode : 0x%02x", m_Mode); + break; + } + + m_file.Open(m_filepath, open_mode); } - return File::IOFile(m_filepath, open_mode); + m_file.Clear(); + m_file.Seek(m_SeekPos, SEEK_SET); } bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) @@ -168,11 +177,12 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) const u32 SeekOffset = Memory::Read_U32(_CommandAddress + 0xC); const u32 Mode = Memory::Read_U32(_CommandAddress + 0x10); - if (auto file = OpenFile()) + PrepareFile(); + if (m_file) { ReturnValue = FS_RESULT_FATAL; - const u64 fileSize = file.GetSize(); + const u64 fileSize = m_file.GetSize(); INFO_LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: 0x%08x, Mode: %i (%s, Length=0x%08llx)", SeekOffset, Mode, m_Name.c_str(), fileSize); u64 wantedPos = 0; switch (Mode) @@ -182,7 +192,7 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) break; case 1: - wantedPos = m_SeekPos + SeekOffset; + wantedPos = m_SeekPos + (s32)SeekOffset; break; case 2: @@ -216,9 +226,9 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) u32 ReturnValue = FS_EACCESS; const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Read to this memory address const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - - - if (auto file = OpenFile()) + + PrepareFile(); + if (m_file) { if (m_Mode == ISFS_OPEN_WRITE) { @@ -227,9 +237,8 @@ bool CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress) else { INFO_LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, m_Name.c_str()); - file.Seek(m_SeekPos, SEEK_SET); - ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, file.GetHandle()); - if (ReturnValue != Size && ferror(file.GetHandle())) + ReturnValue = (u32)fread(Memory::GetPointer(Address), 1, Size, m_file.GetHandle()); + if (ReturnValue != Size && ferror(m_file.GetHandle())) { ReturnValue = FS_EACCESS; } @@ -256,8 +265,8 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) const u32 Address = Memory::Read_U32(_CommandAddress + 0xC); // Write data from this memory address const u32 Size = Memory::Read_U32(_CommandAddress + 0x10); - - if (auto file = OpenFile()) + PrepareFile(); + if (m_file) { if (m_Mode == ISFS_OPEN_READ) { @@ -266,8 +275,7 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) else { INFO_LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes from 0x%08x to %s", Size, Address, m_Name.c_str()); - file.Seek(m_SeekPos, SEEK_SET); - if (file.WriteBytes(Memory::GetPointer(Address), Size)) + if (m_file.WriteBytes(Memory::GetPointer(Address), Size)) { ReturnValue = Size; m_SeekPos += Size; @@ -297,9 +305,10 @@ bool CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress) { case ISFS_IOCTL_GETFILESTATS: { - if (auto file = OpenFile()) + PrepareFile(); + if (m_file) { - u32 m_FileLength = (u32)file.GetSize(); + u32 m_FileLength = (u32)m_file.GetSize(); const u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); INFO_LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS"); @@ -334,6 +343,7 @@ void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p) p.Do(m_Mode); p.Do(m_SeekPos); - + + m_file.Close(); m_filepath = HLE_IPC_BuildFilename(m_Name, 64); } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index 3698d05c9f..f5a0e9008a 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -39,9 +39,9 @@ public: bool IOCtl(u32 _CommandAddress); void DoState(PointerWrap &p); - File::IOFile OpenFile(); - private: + void PrepareFile(); + enum { ISFS_OPEN_READ = 1, @@ -77,6 +77,7 @@ private: u32 m_Mode; u32 m_SeekPos; + File::IOFile m_file; std::string m_filepath; }; From 6d50bd127da8b34bb02327c0a375a19ff881ec34 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 4 Mar 2013 02:22:11 -0600 Subject: [PATCH 154/167] Remove hack that seems to be no longer needed. --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 5655e9b46d..1aad48592c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -33,9 +33,6 @@ std::string HLE_IPC_BuildFilename(std::string path_wii, int _size) { std::string path_full = File::GetUserPath(D_WIIROOT_IDX); - if ((path_wii.length() > 0) && (path_wii[1] == '0')) - path_full += std::string("/title"); // this looks and feel like a hack... - // Replaces chars that FAT32 can't support with strings defined in /sys/replace for (auto i = replacements.begin(); i != replacements.end(); ++i) { From 5d47fd1dde3ccdc286e2248db9967c278d694f5a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 4 Mar 2013 02:38:35 -0600 Subject: [PATCH 155/167] Remove HLE_IPC_CreateVirtualFATFilesystem as it no longer takes 3 minutes to LLE like the comment says. --- Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp | 4 +-- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 33 ------------------- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h | 1 - 3 files changed, 1 insertion(+), 37 deletions(-) diff --git a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp index d3fa172621..a86c38286d 100644 --- a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp @@ -90,9 +90,7 @@ bool CBoot::Boot_WiiWAD(const char* _pFilename) u64 titleID = ContentLoader.GetTitleID(); // create data directory File::CreateFullPath(Common::GetTitleDataPath(titleID)); - - if (titleID == TITLEID_SYSMENU) - HLE_IPC_CreateVirtualFATFilesystem(); + // setup wii mem if (!SetupWiiMemory(ContentLoader.GetCountry())) return false; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 1aad48592c..acf5c921e9 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -45,39 +45,6 @@ std::string HLE_IPC_BuildFilename(std::string path_wii, int _size) return path_full; } -void HLE_IPC_CreateVirtualFATFilesystem() -{ - const int cdbSize = 0x01400000; - const std::string cdbPath = Common::GetTitleDataPath(TITLEID_SYSMENU) + "cdb.vff"; - if ((int)File::GetSize(cdbPath) < cdbSize) - { - // cdb.vff is a virtual Fat filesystem created on first launch of sysmenu - // we create it here as it is faster ~3 minutes for me when sysmenu does it ~1 second created here - const u8 cdbHDR[0x20] = {'V', 'F', 'F', 0x20, 0xfe, 0xff, 1, 0, 1, 0x40, 0, 0, 0, 0x20}; - const u8 cdbFAT[4] = {0xf0, 0xff, 0xff, 0xff}; - - File::IOFile cdbFile(cdbPath, "wb"); - if (cdbFile) - { - cdbFile.WriteBytes(cdbHDR, 0x20); - cdbFile.WriteBytes(cdbFAT, 0x4); - cdbFile.Seek(0x14020, SEEK_SET); - cdbFile.WriteBytes(cdbFAT, 0x4); - // 20 MiB file - cdbFile.Seek(cdbSize - 1, SEEK_SET); - // write the final 0 to 0 file from the second FAT to 20 MiB - cdbFile.WriteBytes(cdbHDR + 14, 1); - if (!cdbFile.IsGood()) - { - cdbFile.Close(); - File::Delete(cdbPath); - } - cdbFile.Flush(); - cdbFile.Close(); - } - } -} - CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware , m_Mode(0) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index f5a0e9008a..fd33d7d69c 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -22,7 +22,6 @@ #include "FileUtil.h" std::string HLE_IPC_BuildFilename(std::string _pFilename, int _size); -void HLE_IPC_CreateVirtualFATFilesystem(); class CWII_IPC_HLE_Device_FileIO : public IWII_IPC_HLE_Device { From 642eab92bc8ceb86f5306e26bc3374e464a1ef55 Mon Sep 17 00:00:00 2001 From: degasus Date: Mon, 4 Mar 2013 20:12:58 +0100 Subject: [PATCH 156/167] disable per pixel depth if depth textures aren't used --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 29 ++++++++++++------- .../Core/VideoCommon/Src/VertexShaderGen.cpp | 1 - 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 6793862ef9..77242a0925 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -276,7 +276,7 @@ void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std:: static void WriteStage(char *&p, int n, API_TYPE ApiType); static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); // static void WriteAlphaCompare(char *&p, int num, int comp); -static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode); +static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool depthTextureEnable); static void WriteFog(char *&p); static const char *tevKSelTableC[] = // KCSEL @@ -493,6 +493,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType BuildSwapModeTable(); // Needed for WriteStage int numStages = bpmem.genMode.numtevstages + 1; int numTexgen = bpmem.genMode.numtexgens; + + bool depthTextureEnable = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable; char *p = text; WRITE(p, "//Pixel Shader for TEV stages\n"); @@ -563,14 +565,14 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType { WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "", - "\n out float depth : DEPTH,", + depthTextureEnable ? "\n out float depth : DEPTH," : "", ApiType & API_OPENGL ? "WPOS" : ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS"); } else { WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "", - "\n out float depth : SV_Depth,"); + depthTextureEnable ? "\n out float depth : SV_Depth," : ""); } WRITE(p, " in float4 colors_0 : COLOR0,\n"); @@ -710,13 +712,18 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); if (Pretest == AlphaTest::UNDETERMINED) - WriteAlphaTest(p, ApiType, dstAlphaMode); + WriteAlphaTest(p, ApiType, dstAlphaMode, depthTextureEnable); + // the screen space depth value = far z + (clip z / clip w) * z range - WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); - + if(ApiType == API_OPENGL || ApiType == API_D3D11) + WRITE(p, "float zCoord = rawpos.z;\n"); + else + // dx9 doesn't support 4 component position, so we have to calculate it again + WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n"); + // Note: depth textures are disabled if early depth test is enabled - if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) + if (depthTextureEnable) { // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n", @@ -726,8 +733,9 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); WRITE(p, "zCoord = frac(zCoord);\n"); WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); + + WRITE(p, "depth = zCoord;\n"); } - WRITE(p, "depth = zCoord;\n"); if (dstAlphaMode == DSTALPHA_ALPHA_PASS) WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n"); @@ -1138,7 +1146,7 @@ static const char *tevAlphaFunclogicTable[] = " == " // xnor }; -static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode) +static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool depthTextureEnable) { static const char *alphaRef[2] = { @@ -1161,7 +1169,8 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode WRITE(p, "ocol0 = 0;\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) WRITE(p, "ocol1 = 0;\n"); - WRITE(p, "depth = 1.f;\n"); + if(depthTextureEnable) + WRITE(p, "depth = 1.f;\n"); // HAXX: zcomploc (aka early_ztest) is a way to control whether depth test is done before // or after texturing and alpha test. PC GPUs have no way to support this diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index 2ca6f67077..0ca7b1bd30 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -466,7 +466,6 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed - // TODO: Can probably be dropped? if (is_d3d) { WRITE(p, "o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); From bf58c70e9b5a16c56113fe5114a845f8000d4a9d Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 4 Mar 2013 15:24:39 -0600 Subject: [PATCH 157/167] Move copy-pasted code into function. --- Source/Core/VideoCommon/Src/VertexLoader.cpp | 69 +++++--------------- Source/Core/VideoCommon/Src/VertexLoader.h | 2 + 2 files changed, 18 insertions(+), 53 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.cpp b/Source/Core/VideoCommon/Src/VertexLoader.cpp index ca128b4f86..bbee1c0411 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.cpp +++ b/Source/Core/VideoCommon/Src/VertexLoader.cpp @@ -517,7 +517,7 @@ void VertexLoader::WriteSetVariable(int bits, void *address, OpArg value) #endif } -void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const count) +int VertexLoader::SetupRunVertices(int vtx_attr_group, int primitive, int const count) { m_numLoadedVertices += count; @@ -536,7 +536,7 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const coun { // if cull mode is none, ignore triangles and quads DataSkip(count * m_VertexSize); - return; + return 0; } m_NativeFmt->EnableComponents(m_NativeFmt->m_components); @@ -561,8 +561,15 @@ void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const coun colElements[i] = m_VtxAttr.color[i].Elements; VertexManager::PrepareForAdditionalData(primitive, count, native_stride); - ConvertVertices(count); - VertexManager::AddVertices(primitive, count); + + return count; +} + +void VertexLoader::RunVertices(int vtx_attr_group, int primitive, int const count) +{ + auto const new_count = SetupRunVertices(vtx_attr_group, primitive, count); + ConvertVertices(new_count); + VertexManager::AddVertices(primitive, new_count); } void VertexLoader::ConvertVertices ( int count ) @@ -585,59 +592,15 @@ void VertexLoader::ConvertVertices ( int count ) #endif } - - - void VertexLoader::RunCompiledVertices(int vtx_attr_group, int primitive, int const count, u8* Data) { - m_numLoadedVertices += count; - - // Flush if our vertex format is different from the currently set. - if (g_nativeVertexFmt != NULL && g_nativeVertexFmt != m_NativeFmt) - { - // We really must flush here. It's possible that the native representations - // of the two vtx formats are the same, but we have no way to easily check that - // now. - VertexManager::Flush(); - // Also move the Set() here? - } - g_nativeVertexFmt = m_NativeFmt; - - if (bpmem.genMode.cullmode == 3 && primitive < 5) - { - // if cull mode is none, ignore triangles and quads - DataSkip(count * m_VertexSize); - return; - } - - m_NativeFmt->EnableComponents(m_NativeFmt->m_components); - - // Load position and texcoord scale factors. - m_VtxAttr.PosFrac = g_VtxAttr[vtx_attr_group].g0.PosFrac; - m_VtxAttr.texCoord[0].Frac = g_VtxAttr[vtx_attr_group].g0.Tex0Frac; - m_VtxAttr.texCoord[1].Frac = g_VtxAttr[vtx_attr_group].g1.Tex1Frac; - m_VtxAttr.texCoord[2].Frac = g_VtxAttr[vtx_attr_group].g1.Tex2Frac; - m_VtxAttr.texCoord[3].Frac = g_VtxAttr[vtx_attr_group].g1.Tex3Frac; - m_VtxAttr.texCoord[4].Frac = g_VtxAttr[vtx_attr_group].g2.Tex4Frac; - m_VtxAttr.texCoord[5].Frac = g_VtxAttr[vtx_attr_group].g2.Tex5Frac; - m_VtxAttr.texCoord[6].Frac = g_VtxAttr[vtx_attr_group].g2.Tex6Frac; - m_VtxAttr.texCoord[7].Frac = g_VtxAttr[vtx_attr_group].g2.Tex7Frac; - - pVtxAttr = &m_VtxAttr; - posScale = fractionTable[m_VtxAttr.PosFrac]; - if (m_NativeFmt->m_components & VB_HAS_UVALL) - for (int i = 0; i < 8; i++) - tcScale[i] = fractionTable[m_VtxAttr.texCoord[i].Frac]; - for (int i = 0; i < 2; i++) - colElements[i] = m_VtxAttr.color[i].Elements; - - VertexManager::PrepareForAdditionalData(primitive, count, native_stride); + auto const new_count = SetupRunVertices(vtx_attr_group, primitive, count); - memcpy_gc(VertexManager::s_pCurBufferPointer, Data, native_stride * count); - VertexManager::s_pCurBufferPointer += native_stride * count; - DataSkip(count * m_VertexSize); + memcpy_gc(VertexManager::s_pCurBufferPointer, Data, native_stride * new_count); + VertexManager::s_pCurBufferPointer += native_stride * new_count; + DataSkip(new_count * m_VertexSize); - VertexManager::AddVertices(primitive, count); + VertexManager::AddVertices(primitive, new_count); } void VertexLoader::SetVAT(u32 _group0, u32 _group1, u32 _group2) diff --git a/Source/Core/VideoCommon/Src/VertexLoader.h b/Source/Core/VideoCommon/Src/VertexLoader.h index 4f4fc19e99..b7afbe4ba6 100644 --- a/Source/Core/VideoCommon/Src/VertexLoader.h +++ b/Source/Core/VideoCommon/Src/VertexLoader.h @@ -83,6 +83,8 @@ public: ~VertexLoader(); int GetVertexSize() const {return m_VertexSize;} + + int SetupRunVertices(int vtx_attr_group, int primitive, int const count); void RunVertices(int vtx_attr_group, int primitive, int count); void RunCompiledVertices(int vtx_attr_group, int primitive, int count, u8* Data); From 3ac7ee4623afb4beea59662024a211a4a53b9606 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 5 Mar 2013 03:53:25 +0000 Subject: [PATCH 158/167] Fix compiling Dolphin on devices that provide crazy GLES drivers --- Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp | 2 +- Source/Core/DolphinWX/Src/GLInterface/EGL_X11.h | 1 + Source/Core/DolphinWX/Src/X11Utils.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp b/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp index c092aced64..ccb2fc04b8 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp +++ b/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.cpp @@ -141,7 +141,7 @@ bool cInterfaceEGL::Create(void *&window_handle) return false; } - GLWin.egl_surf = eglCreateWindowSurface(GLWin.egl_dpy, config, GLWin.win, NULL); + GLWin.egl_surf = eglCreateWindowSurface(GLWin.egl_dpy, config, (NativeWindowType)GLWin.win, NULL); if (!GLWin.egl_surf) { ERROR_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n"); return false; diff --git a/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.h b/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.h index 513fb2ce4a..e47573e4d8 100644 --- a/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.h +++ b/Source/Core/DolphinWX/Src/GLInterface/EGL_X11.h @@ -20,6 +20,7 @@ #include #ifdef USE_GLES #include +#include #else #include #include diff --git a/Source/Core/DolphinWX/Src/X11Utils.cpp b/Source/Core/DolphinWX/Src/X11Utils.cpp index 3582b9b576..6c4282cceb 100644 --- a/Source/Core/DolphinWX/Src/X11Utils.cpp +++ b/Source/Core/DolphinWX/Src/X11Utils.cpp @@ -16,7 +16,6 @@ // http://code.google.com/p/dolphin-emu/ #include "X11Utils.h" -#include "WxUtils.h" #include #include @@ -27,6 +26,7 @@ extern char **environ; #if defined(HAVE_WX) && HAVE_WX #include #include +#include "WxUtils.h" #endif namespace X11Utils From 33a13b1a37ab18ecbff43ed9224135602441348a Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 5 Mar 2013 00:28:41 -0600 Subject: [PATCH 159/167] Fixed issue 5270. Don't ask me how, I just clean up code and then it works! I think it was int overflow. --- Source/Core/DiscIO/Src/CISOBlob.cpp | 66 ++++++++++++++++++----------- Source/Core/DiscIO/Src/CISOBlob.h | 44 ++++++++++--------- 2 files changed, 65 insertions(+), 45 deletions(-) diff --git a/Source/Core/DiscIO/Src/CISOBlob.cpp b/Source/Core/DiscIO/Src/CISOBlob.cpp index b3a2e31b2b..8d267c15fb 100644 --- a/Source/Core/DiscIO/Src/CISOBlob.cpp +++ b/Source/Core/DiscIO/Src/CISOBlob.cpp @@ -15,24 +15,30 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include +#include + #include "Blob.h" #include "CISOBlob.h" namespace DiscIO { +static const char CISO_MAGIC[] = "CISO"; + CISOFileReader::CISOFileReader(std::FILE* file) : m_file(file) { m_size = m_file.GetSize(); - - memset(&header, 0, sizeof(header)); + + CISOHeader header; m_file.ReadArray(&header, 1); + + m_block_size = header.block_size; - CISO_Map_t count = 0; - int idx; - for (idx = 0; idx < CISO_MAP_SIZE; idx++) - ciso_map[idx] = (header.map[idx] == 1) ? count++ : CISO_UNUSED_BLOCK; + MapType count = 0; + for (u32 idx = 0; idx < CISO_MAP_SIZE; idx++) + m_ciso_map[idx] = (1 == header.map[idx]) ? count++ : UNUSED_BLOCK_ID; } CISOFileReader* CISOFileReader::Create(const char* filename) @@ -46,34 +52,45 @@ CISOFileReader* CISOFileReader::Create(const char* filename) return NULL; } +u64 CISOFileReader::GetDataSize() const +{ + return GetRawSize(); +} + +u64 CISOFileReader::GetRawSize() const +{ + return m_size; +} + bool CISOFileReader::Read(u64 offset, u64 nbytes, u8* out_ptr) { - u64 bytesRead = 0; - while (bytesRead < nbytes) + while (nbytes != 0) { - u32 block = (u32)(offset / header.block_size); - u32 data_offset = offset % header.block_size; - u32 bytes_to_read = (u32)min((u64)(header.block_size - data_offset), nbytes); - if ((block >= CISO_MAP_SIZE) || (ciso_map[block] == CISO_UNUSED_BLOCK)) - { - memset(out_ptr, 0, bytes_to_read); - out_ptr += bytes_to_read; - offset += bytes_to_read; - bytesRead += bytes_to_read; - } - else + auto const block = offset / m_block_size; + auto const data_offset = offset % m_block_size; + + auto const bytes_to_read = std::min(m_block_size - data_offset, nbytes); + if (block < CISO_MAP_SIZE && UNUSED_BLOCK_ID != m_ciso_map[block]) { // calcualte the base address - u64 file_off = CISO_HEAD_SIZE + ciso_map[block] * (u64)header.block_size + data_offset; + auto const file_off = CISO_HEADER_SIZE + m_ciso_map[block] * m_block_size + data_offset; - if (!(m_file.Seek(file_off, SEEK_SET) && m_file.ReadBytes(out_ptr, bytes_to_read))) + if (!(m_file.Seek(file_off, SEEK_SET) && m_file.ReadArray(out_ptr, bytes_to_read))) return false; out_ptr += bytes_to_read; offset += bytes_to_read; - bytesRead += bytes_to_read; + nbytes -= bytes_to_read; + } + else + { + std::fill_n(out_ptr, bytes_to_read, 0); + out_ptr += bytes_to_read; + offset += bytes_to_read; + nbytes -= bytes_to_read; } } + return true; } @@ -81,8 +98,9 @@ bool IsCISOBlob(const char* filename) { File::IOFile f(filename, "rb"); - CISO_Head_t header; - return (f.ReadArray(&header, 1) && (memcmp(header.magic, CISO_MAGIC, sizeof(header.magic)) == 0)); + CISOHeader header; + return (f.ReadArray(&header, 1) && + std::equal(header.magic, header.magic + sizeof(header.magic), CISO_MAGIC)); } } // namespace diff --git a/Source/Core/DiscIO/Src/CISOBlob.h b/Source/Core/DiscIO/Src/CISOBlob.h index e87e616a21..9b490f0638 100644 --- a/Source/Core/DiscIO/Src/CISOBlob.h +++ b/Source/Core/DiscIO/Src/CISOBlob.h @@ -21,43 +21,45 @@ #include "Blob.h" #include "FileUtil.h" -#define CISO_MAGIC "CISO" -#define CISO_HEAD_SIZE (0x8000) -#define CISO_MAP_SIZE (CISO_HEAD_SIZE - 8) - namespace DiscIO { bool IsCISOBlob(const char* filename); -// Blocks that won't compress to less than 97% of the original size are stored as-is. -struct CISO_Head_t +static const u32 CISO_HEADER_SIZE = 0x8000; +static const u32 CISO_MAP_SIZE = CISO_HEADER_SIZE - sizeof(u32) - sizeof(char) * 4; + +struct CISOHeader { - u8 magic[4]; // "CISO" - u32 block_size; // stored as litte endian (not network byte order) - u8 map[CISO_MAP_SIZE]; // 0=unused, 1=used, others=invalid + // "CISO" + char magic[4]; + + // little endian + u32 block_size; + + // 0=unused, 1=used, others=invalid + u8 map[CISO_MAP_SIZE]; }; -typedef u16 CISO_Map_t; - -const CISO_Map_t CISO_UNUSED_BLOCK = (CISO_Map_t)~0; - class CISOFileReader : public IBlobReader { - File::IOFile m_file; - CISOFileReader(std::FILE* file); - s64 m_size; - public: static CISOFileReader* Create(const char* filename); - u64 GetDataSize() const { return m_size; } - u64 GetRawSize() const { return m_size; } + u64 GetDataSize() const; + u64 GetRawSize() const; bool Read(u64 offset, u64 nbytes, u8* out_ptr); private: - CISO_Head_t header; - CISO_Map_t ciso_map[CISO_MAP_SIZE]; + CISOFileReader(std::FILE* file); + + typedef u16 MapType; + static const MapType UNUSED_BLOCK_ID = -1; + + File::IOFile m_file; + u64 m_size; + u32 m_block_size; + MapType m_ciso_map[CISO_MAP_SIZE]; }; } // namespace From 240238308cd0501e83ea5077548ca02bbb0bc578 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 5 Mar 2013 14:03:01 +0000 Subject: [PATCH 160/167] Disable SSE2 check in the GUI when building ARM. --- Source/Core/DolphinWX/Src/Main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp index 09387f2764..37311c84bf 100644 --- a/Source/Core/DolphinWX/Src/Main.cpp +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -202,6 +202,7 @@ bool DolphinApp::OnInit() wxHandleFatalExceptions(true); #endif +#ifndef _M_ARM // TODO: if First Boot if (!cpu_info.bSSE2) { @@ -210,6 +211,7 @@ bool DolphinApp::OnInit() "Sayonara!\n"); return false; } +#endif #ifdef _WIN32 if (!wxSetWorkingDirectory(StrToWxStr(File::GetExeDirectory()))) From 10d57a3402cc698cffc4bf3299113073264eb314 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 5 Mar 2013 03:12:17 -0600 Subject: [PATCH 161/167] Use standard binary multiple unit symbols for game size display. Use integer math for the calculation as we cannot rely on floats for something as important as game size display! --- Source/Core/Common/Src/MathUtil.h | 22 ++++++++++++++++ Source/Core/DolphinWX/Src/GameListCtrl.cpp | 29 ++++++++-------------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h index 114a91bf3c..c6c29ff368 100644 --- a/Source/Core/Common/Src/MathUtil.h +++ b/Source/Core/Common/Src/MathUtil.h @@ -152,6 +152,28 @@ float MathFloatVectorSum(const std::vector&); #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) +template +T Log2(T val) +{ +#if defined(_M_X64) + T result; + asm + ( + "bsr %1, %0" + : "=r"(result) + : "r"(val) + ); + return result; +#else + T result = -1; + while (val != 0) + { + val >>= 1; + ++result; + } + return result; +#endif +} // Tiny matrix/vector library. // Used for things like Free-Look in the gfx backend. diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp index 1a828bbf14..bf09161555 100644 --- a/Source/Core/DolphinWX/Src/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -35,6 +35,7 @@ #include "CDUtils.h" #include "WxUtils.h" #include "Main.h" +#include "MathUtil.h" #include "../resources/Flag_Europe.xpm" #include "../resources/Flag_Germany.xpm" @@ -380,26 +381,18 @@ void CGameListCtrl::Update() SetFocus(); } -wxString NiceSizeFormat(s64 _size) +wxString NiceSizeFormat(u64 _size) { - const char* sizes[] = {"b", "KB", "MB", "GB", "TB", "PB", "EB"}; - int s = 0; - int frac = 0; + const char* const unit_symbols[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"}; + + auto const unit = Log2(std::max(_size, 1)) / 10; + auto const unit_size = (1 << (unit * 10)); + + // ugly rounding integer math + auto const value = (_size + unit_size / 2) / unit_size; + auto const frac = (_size % unit_size * 10 + unit_size / 2) / unit_size % 10; - while (_size > (s64)1024) - { - s++; - frac = (int)_size & 1023; - _size /= (s64)1024; - } - - float f = (float)_size + ((float)frac / 1024.0f); - - wxString NiceString; - char tempstr[32]; - sprintf(tempstr,"%3.1f %s", f, sizes[s]); - NiceString = StrToWxStr(tempstr); - return(NiceString); + return StrToWxStr(StringFromFormat("%llu.%llu %s", value, frac, unit_symbols[unit])); } void CGameListCtrl::InsertItemInReportView(long _Index) From fe3a54d7fd8c85960fed04d28d5dedbc1d94845d Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 5 Mar 2013 15:48:57 -0600 Subject: [PATCH 162/167] Buildfix! --- Source/Core/Common/Src/MathUtil.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h index c6c29ff368..ec9c9cc8a3 100644 --- a/Source/Core/Common/Src/MathUtil.h +++ b/Source/Core/Common/Src/MathUtil.h @@ -152,18 +152,17 @@ float MathFloatVectorSum(const std::vector&); #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define ROUND_DOWN(x, a) ((x) & ~((a) - 1)) -template -T Log2(T val) +// Rounds down. 0 -> undefined +inline u64 Log2(u64 val) { -#if defined(_M_X64) - T result; - asm - ( - "bsr %1, %0" - : "=r"(result) - : "r"(val) - ); +#if defined(__GNUC__) + return 63 - __builtin_clzll(val); + +#elif defined(_MSC_VER) + unsigned long result = -1; + _BitScanReverse64(&result, val); return result; + #else T result = -1; while (val != 0) From b34991c4c344832d92183a5cd9d7b591e99e74be Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 5 Mar 2013 16:07:32 -0600 Subject: [PATCH 163/167] Buildfix for real. --- Source/Core/Common/Src/MathUtil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h index ec9c9cc8a3..b4c73e6457 100644 --- a/Source/Core/Common/Src/MathUtil.h +++ b/Source/Core/Common/Src/MathUtil.h @@ -158,7 +158,7 @@ inline u64 Log2(u64 val) #if defined(__GNUC__) return 63 - __builtin_clzll(val); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && defined(_M_X64) unsigned long result = -1; _BitScanReverse64(&result, val); return result; From 2095641af0348b40befe91f4f36d81d992f822e2 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 5 Mar 2013 16:16:33 -0600 Subject: [PATCH 164/167] OK, seriously, buildfix. I shouldn't even have commit access! --- Source/Core/Common/Src/MathUtil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h index b4c73e6457..506412a0cb 100644 --- a/Source/Core/Common/Src/MathUtil.h +++ b/Source/Core/Common/Src/MathUtil.h @@ -164,7 +164,7 @@ inline u64 Log2(u64 val) return result; #else - T result = -1; + u64 result = -1; while (val != 0) { val >>= 1; From d6558e1c314a71754def04faf260b25307e22449 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 6 Mar 2013 01:51:24 +0000 Subject: [PATCH 165/167] Make the (V)LDR/(V)STR instructions support negative offsets. This fixes a bug where Arm Jit couldn't load the top 33 FPRs. Also makes it so the core can access all GPRs, FPRs, and SPRs in ppcState. This increases VPS 15-20 on SSBM intro movie on ODROIDX --- Source/Core/Common/Src/ArmEmitter.cpp | 58 ++++++------ Source/Core/Common/Src/ArmEmitter.h | 44 ++++----- Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp | 13 ++- Source/Core/Core/Src/PowerPC/JitArm32/Jit.h | 2 +- .../Core/Src/PowerPC/JitArm32/JitArmCache.cpp | 3 +- .../Src/PowerPC/JitArm32/JitArm_Branch.cpp | 90 ++++++++++--------- .../Src/PowerPC/JitArm32/JitArm_Integer.cpp | 6 +- .../Src/PowerPC/JitArm32/JitArm_LoadStore.cpp | 10 +-- .../JitArm32/JitArm_LoadStoreFloating.cpp | 2 +- .../JitArm32/JitArm_SystemRegisters.cpp | 13 +-- .../Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp | 22 ++--- .../Core/Src/PowerPC/JitArm32/JitFPRCache.cpp | 9 +- .../Core/Src/PowerPC/JitArm32/JitRegCache.cpp | 9 +- 13 files changed, 145 insertions(+), 136 deletions(-) diff --git a/Source/Core/Common/Src/ArmEmitter.cpp b/Source/Core/Common/Src/ArmEmitter.cpp index 3b3bf7c550..a56724b78b 100644 --- a/Source/Core/Common/Src/ArmEmitter.cpp +++ b/Source/Core/Common/Src/ArmEmitter.cpp @@ -533,15 +533,15 @@ void ARMXEmitter::MRS (ARMReg dest) Write32(condition | (16 << 20) | (15 << 16) | (dest << 12)); } -void ARMXEmitter::WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2) +void ARMXEmitter::WriteStoreOp(u32 op, ARMReg dest, ARMReg src, s16 op2) { - if (op2.GetData() == 0) // set the preindex bit, but not the W bit! - Write32(condition | 0x01800000 | (op << 20) | (dest << 16) | (src << 12) | op2.Imm12()); - else - Write32(condition | (op << 20) | (3 << 23) | (dest << 16) | (src << 12) | op2.Imm12()); + bool Index = op2 != 0 ? true : false; + bool Add = op2 >= 0 ? true : false; + u32 imm = abs(op2); + Write32(condition | (op << 20) | (Index << 24) | (Add << 23) | (dest << 16) | (src << 12) | imm); } -void ARMXEmitter::STR (ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x40, dest, src, op);} -void ARMXEmitter::STRB(ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x44, dest, src, op);} +void ARMXEmitter::STR (ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x40, dest, src, op);} +void ARMXEmitter::STRB(ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x44, dest, src, op);} void ARMXEmitter::STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) { Write32(condition | (0x60 << 20) | (Index << 24) | (Add << 23) | (dest << 16) | (base << 12) | offset); @@ -564,13 +564,13 @@ void ARMXEmitter::SVC(Operand2 op) Write32(condition | (0x0F << 24) | op.Imm24()); } -void ARMXEmitter::LDR (ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x41, src, dest, op);} +void ARMXEmitter::LDR (ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x41, src, dest, op);} void ARMXEmitter::LDRH(ARMReg dest, ARMReg src, Operand2 op) { u8 Imm = op.Imm8(); Write32(condition | (0x05 << 20) | (src << 16) | (dest << 12) | ((Imm >> 4) << 8) | (0xB << 4) | (Imm & 0x0F)); } -void ARMXEmitter::LDRB(ARMReg dest, ARMReg src, Operand2 op) { WriteStoreOp(0x45, src, dest, op);} +void ARMXEmitter::LDRB(ARMReg dest, ARMReg src, s16 op) { WriteStoreOp(0x45, src, dest, op);} void ARMXEmitter::LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add) { @@ -661,14 +661,18 @@ void ARMXEmitter::VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm) // VFP Specific -void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 offset) +void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset) { _assert_msg_(DYNA_REC, Dest >= S0 && Dest <= D31, "Passed Invalid dest register to VLDR"); _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid Base register to VLDR"); - _assert_msg_(DYNA_REC, (offset & 0xC03) == 0, "VLDR: Offset needs to be word aligned and small enough"); - if (offset & 0xC03) { - ERROR_LOG(DYNA_REC, "VLDR: Bad offset %08x", offset); + bool Add = offset >= 0 ? true : false; + u32 imm = abs(offset); + + _assert_msg_(DYNA_REC, (imm & 0xC03) == 0, "VLDR: Offset needs to be word aligned and small enough"); + + if (imm & 0xC03) { + ERROR_LOG(DYNA_REC, "VLDR: Bad offset %08x", imm); } bool single_reg = Dest < D0; @@ -677,24 +681,28 @@ void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, u16 offset) if (single_reg) { - Write32(NO_COND | (0x1B << 23) | ((Dest & 0x1) << 22) | (1 << 20) | (Base << 16) \ - | ((Dest & 0x1E) << 11) | (10 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Dest & 0x1) << 22) | (1 << 20) | (Base << 16) \ + | ((Dest & 0x1E) << 11) | (10 << 8) | (imm >> 2)); } else { - Write32(NO_COND | (0x1B << 23) | ((Dest & 0x10) << 18) | (1 << 20) | (Base << 16) \ - | ((Dest & 0xF) << 12) | (11 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Dest & 0x10) << 18) | (1 << 20) | (Base << 16) \ + | ((Dest & 0xF) << 12) | (11 << 8) | (imm >> 2)); } } -void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 offset) +void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, s16 offset) { _assert_msg_(DYNA_REC, Src >= S0 && Src <= D31, "Passed invalid src register to VSTR"); _assert_msg_(DYNA_REC, Base <= R15, "Passed invalid base register to VSTR"); - _assert_msg_(DYNA_REC, (offset & 0xC03) == 0, "VSTR: Offset needs to be word aligned"); - if (offset & 0xC03) { - ERROR_LOG(DYNA_REC, "VSTR: Bad offset %08x", offset); + bool Add = offset >= 0 ? true : false; + u32 imm = abs(offset); + + _assert_msg_(DYNA_REC, (imm & 0xC03) == 0, "VSTR: Offset needs to be word aligned and small enough"); + + if (imm & 0xC03) { + ERROR_LOG(DYNA_REC, "VSTR: Bad offset %08x", imm); } bool single_reg = Src < D0; @@ -703,14 +711,14 @@ void ARMXEmitter::VSTR(ARMReg Src, ARMReg Base, u16 offset) if (single_reg) { - Write32(NO_COND | (0x1B << 23) | ((Src & 0x1) << 22) | (Base << 16) \ - | ((Src & 0x1E) << 11) | (10 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Src & 0x1) << 22) | (Base << 16) \ + | ((Src & 0x1E) << 11) | (10 << 8) | (imm >> 2)); } else { - Write32(NO_COND | (0x1B << 23) | ((Src & 0x10) << 18) | (Base << 16) \ - | ((Src & 0xF) << 12) | (11 << 8) | (offset >> 2)); + Write32(NO_COND | (0xD << 24) | (Add << 23) | ((Src & 0x10) << 18) | (Base << 16) \ + | ((Src & 0xF) << 12) | (11 << 8) | (imm >> 2)); } } void ARMXEmitter::VCMP(ARMReg Vd, ARMReg Vm) diff --git a/Source/Core/Common/Src/ArmEmitter.h b/Source/Core/Common/Src/ArmEmitter.h index a3ff7d25ae..d3155285f3 100644 --- a/Source/Core/Common/Src/ArmEmitter.h +++ b/Source/Core/Common/Src/ArmEmitter.h @@ -208,7 +208,7 @@ public: Value = base; Type = TYPE_IMMSREG; } - const u32 GetData() + u32 GetData() { switch(Type) { @@ -225,45 +225,45 @@ public: return 0; } } - const u32 IMMSR() // IMM shifted register + u32 IMMSR() // IMM shifted register { _assert_msg_(DYNA_REC, Type == TYPE_IMMSREG, "IMMSR must be imm shifted register"); return ((IndexOrShift & 0x1f) << 7 | (Shift << 5) | Value); } - const u32 RSR() // Register shifted register + u32 RSR() // Register shifted register { _assert_msg_(DYNA_REC, Type == TYPE_RSR, "RSR must be RSR Of Course"); return (IndexOrShift << 8) | (Shift << 5) | 0x10 | Value; } - const u32 Rm() + u32 Rm() { _assert_msg_(DYNA_REC, Type == TYPE_REG, "Rm must be with Reg"); return Value; } - const u32 Imm5() + u32 Imm5() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm5 not IMM value"); return ((Value & 0x0000001F) << 7); } - const u32 Imm8() + u32 Imm8() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8Rot not IMM value"); return Value & 0xFF; } - const u32 Imm8Rot() // IMM8 with Rotation + u32 Imm8Rot() // IMM8 with Rotation { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8Rot not IMM value"); _assert_msg_(DYNA_REC, (Rotation & 0xE1) != 0, "Invalid Operand2: immediate rotation %u", Rotation); return (1 << 25) | (Rotation << 7) | (Value & 0x000000FF); } - const u32 Imm12() + u32 Imm12() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm12 not IMM"); return (Value & 0x00000FFF); } - const u32 Imm12Mod() + u32 Imm12Mod() { // This is a IMM12 with the top four bits being rotation and the // bottom eight being a IMM. This is for instructions that need to @@ -273,32 +273,32 @@ public: _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm12Mod not IMM"); return ((Rotation & 0xF) << 8) | (Value & 0xFF); } - const u32 Imm16() + u32 Imm16() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); return ( (Value & 0xF000) << 4) | (Value & 0x0FFF); } - const u32 Imm16Low() + u32 Imm16Low() { return Imm16(); } - const u32 Imm16High() // Returns high 16bits + u32 Imm16High() // Returns high 16bits { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); return ( ((Value >> 16) & 0xF000) << 4) | ((Value >> 16) & 0x0FFF); } - const u32 Imm24() + u32 Imm24() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm16 not IMM"); return (Value & 0x0FFFFFFF); } // NEON and ASIMD specific - const u32 Imm8ASIMD() + u32 Imm8ASIMD() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8ASIMD not IMM"); return ((Value & 0x80) << 17) | ((Value & 0x70) << 12) | (Value & 0xF); } - const u32 Imm8VFP() + u32 Imm8VFP() { _assert_msg_(DYNA_REC, (Type == TYPE_IMM), "Imm8VFP not IMM"); return ((Value & 0xF0) << 12) | (Value & 0xF); @@ -337,7 +337,7 @@ private: u8 *lastCacheFlushEnd; u32 condition; - void WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2); + void WriteStoreOp(u32 op, ARMReg dest, ARMReg src, s16 op2); void WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, ARMReg op2); void WriteShiftedDataOp(u32 op, bool SetFlags, ARMReg dest, ARMReg src, Operand2 op2); @@ -467,16 +467,16 @@ public: void MRS (ARMReg dest); // Memory load/store operations - void LDR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + void LDR (ARMReg dest, ARMReg src, s16 op2 = 0); // Offset adds to the base register in LDR void LDR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); void LDRH(ARMReg dest, ARMReg src, Operand2 op = 0); - void LDRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); - void STR (ARMReg dest, ARMReg src, Operand2 op2 = 0); + void LDRB(ARMReg dest, ARMReg src, s16 op2 = 0); + void STR (ARMReg dest, ARMReg src, s16 op2 = 0); // Offset adds on to the destination register in STR void STR (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add); - void STRB(ARMReg dest, ARMReg src, Operand2 op2 = 0); + void STRB(ARMReg dest, ARMReg src, s16 op2 = 0); void STMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); void LDMFD(ARMReg dest, bool WriteBack, const int Regnum, ...); @@ -499,8 +499,8 @@ public: void VSUB(IntegerSize Size, ARMReg Vd, ARMReg Vn, ARMReg Vm); // VFP Only - void VLDR(ARMReg Dest, ARMReg Base, u16 offset); - void VSTR(ARMReg Src, ARMReg Base, u16 offset); + void VLDR(ARMReg Dest, ARMReg Base, s16 offset); + void VSTR(ARMReg Src, ARMReg Base, s16 offset); void VCMP(ARMReg Vd, ARMReg Vm); // Compares against zero void VCMP(ARMReg Vd); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp index e4b0ffd714..3b2ee45111 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.cpp @@ -100,7 +100,7 @@ void JitArm::HLEFunction(UGeckoInstruction _inst) MOVI2R(R1, _inst.hex); QuickCallFunction(R14, (void*)&HLE::Execute); ARMReg rA = gpr.GetReg(); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, npc)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, npc)); WriteExitDestInR(rA); } @@ -161,7 +161,7 @@ void JitArm::DoDownCount() } void JitArm::WriteExitDestInR(ARMReg Reg) { - STR(R9, Reg, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, Reg, PPCSTATE_OFF(PowerPC::ppcState, pc)); Cleanup(); DoDownCount(); MOVI2R(Reg, (u32)asm_routines.dispatcher); @@ -170,7 +170,7 @@ void JitArm::WriteExitDestInR(ARMReg Reg) } void JitArm::WriteRfiExitDestInR(ARMReg Reg) { - STR(R9, Reg, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, Reg, PPCSTATE_OFF(PowerPC::ppcState, pc)); Cleanup(); DoDownCount(); @@ -209,7 +209,7 @@ void JitArm::WriteExit(u32 destination, int exit_num) { ARMReg A = gpr.GetReg(false); MOVI2R(A, destination); - STR(R9, A, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, A, PPCSTATE_OFF(PowerPC::ppcState, pc)); MOVI2R(A, (u32)asm_routines.dispatcher); B(A); } @@ -303,7 +303,6 @@ void JitArm::Break(UGeckoInstruction inst) const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlock *b) { int blockSize = code_buf->GetSize(); - // Memory exception on instruction fetch bool memory_exception = false; @@ -382,10 +381,10 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo ARMReg C = gpr.GetReg(); Operand2 Shift(2, 10); // 1 << 13 MOVI2R(C, js.blockStart); // R3 - LDR(A, R9, STRUCT_OFF(PowerPC::ppcState, msr)); + LDR(A, R9, PPCSTATE_OFF(PowerPC::ppcState, msr)); TST(A, Shift); FixupBranch b1 = B_CC(CC_NEQ); - STR(R9, C, STRUCT_OFF(PowerPC::ppcState, pc)); + STR(R9, C, PPCSTATE_OFF(PowerPC::ppcState, pc)); MOVI2R(A, (u32)asm_routines.fpException); B(A); SetJumpTarget(b1); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index c736ae77a1..1dde0fa55f 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -47,7 +47,7 @@ if (Core::g_CoreStartupParameter.bJITOff || \ Core::g_CoreStartupParameter.bJIT##type##Off) \ {Default(inst); return;} - +#define PPCSTATE_OFF(str, elem) ((s32)STRUCT_OFF(PowerPC::ppcState, elem) - (s32)STRUCT_OFF(PowerPC::ppcState, spr[0])) class JitArm : public JitBase, public ArmGen::ARMXCodeBlock { private: diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp index 296ca736a9..dd85699a6d 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArmCache.cpp @@ -36,10 +36,9 @@ using namespace ArmGen; void JitArmBlockCache::WriteDestroyBlock(const u8* location, u32 address) { ARMXEmitter emit((u8 *)location); - emit.MOVI2R(R10, (u32)&PC); emit.MOVI2R(R11, address); emit.MOVI2R(R12, (u32)jit->GetAsmRoutines()->dispatcher); - emit.STR(R10, R11); + emit.STR(R9, R11, PPCSTATE_OFF(PowerPC::ppcState, pc)); emit.B(R12); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp index 27d5c23141..1c401771d7 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Branch.cpp @@ -50,9 +50,9 @@ void JitArm::sc(UGeckoInstruction inst) ARMABI_MOVI2M((u32)&PC, js.compilerPC + 4); // Destroys R12 and R14 ARMReg rA = gpr.GetReg(); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); ORR(rA, rA, EXCEPTION_SYSCALL); - STR(R9, rA, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); gpr.Unlock(rA); WriteExceptionExit(); @@ -78,25 +78,22 @@ void JitArm::rfi(UGeckoInstruction inst) ARMReg rB = gpr.GetReg(); ARMReg rC = gpr.GetReg(); ARMReg rD = gpr.GetReg(); - MOVI2R(rA, (u32)&MSR); MOVI2R(rB, (~mask) & clearMSR13); MOVI2R(rC, mask & clearMSR13); - LDR(rD, rA); + LDR(rD, R9, PPCSTATE_OFF(PowerPC::ppcState, msr)); AND(rD, rD, rB); // rD = Masked MSR - STR(rA, rD); + STR(R9, rD, PPCSTATE_OFF(PowerPC::ppcState, msr)); - MOVI2R(rB, (u32)&SRR1); - LDR(rB, rB); // rB contains SRR1 here + LDR(rB, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_SRR1])); // rB contains SRR1 here AND(rB, rB, rC); // rB contains masked SRR1 here ORR(rB, rD, rB); // rB = Masked MSR OR masked SRR1 - STR(rA, rB); // STR rB in to rA + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, msr)); // STR rB in to rA - MOVI2R(rA, (u32)&SRR0); - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_SRR0])); gpr.Unlock(rB, rC, rD); WriteRfiExitDestInR(rA); // rA gets unlocked here @@ -116,8 +113,13 @@ void JitArm::bx(UGeckoInstruction inst) // We must always process the following sentence // even if the blocks are merged by PPCAnalyst::Flatten(). if (inst.LK) - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); - + { + ARMReg rA = gpr.GetReg(false); + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rA, Jumpto); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + } // If this is not the last instruction of a block, // we will skip the rest process. // Because PPCAnalyst::Flatten() merged the blocks. @@ -164,10 +166,9 @@ void JitArm::bcx(UGeckoInstruction inst) FixupBranch pCTRDontBranch; if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) // Decrement and test CTR { - MOVI2R(rA, (u32)&CTR); - LDR(rB, rA); + LDR(rB, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); SUBS(rB, rB, 1); - STR(rA, rB); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); //SUB(32, M(&CTR), Imm8(1)); if (inst.BO & BO_BRANCH_IF_CTR_0) @@ -179,7 +180,7 @@ void JitArm::bcx(UGeckoInstruction inst) FixupBranch pConditionDontBranch; if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit { - LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + LDRB(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); TST(rA, 8 >> (inst.BI & 3)); //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3))); @@ -188,10 +189,15 @@ void JitArm::bcx(UGeckoInstruction inst) else pConditionDontBranch = B_CC(CC_NEQ); // Not Zero } - gpr.Unlock(rA, rB); if (inst.LK) - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); // Careful, destroys R14, R12 - + { + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rB, Jumpto); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); // Careful, destroys R14, R12 + } + gpr.Unlock(rA, rB); + u32 destination; if(inst.AA) destination = SignExt16(inst.BD << 2); @@ -222,13 +228,18 @@ void JitArm::bcctrx(UGeckoInstruction inst) // BO_2 == 1z1zz -> b always //NPC = CTR & 0xfffffffc; - if(inst.LK_3) - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - MOVI2R(rA, (u32)&CTR); + + if(inst.LK_3) + { + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rA, Jumpto); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + // ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + } MVN(rB, 0x3); // 0xFFFFFFFC - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); AND(rA, rA, rB); gpr.Unlock(rB); WriteExitDestInR(rA); @@ -242,7 +253,7 @@ void JitArm::bcctrx(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + LDRB(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); TST(rA, 8 >> (inst.BI & 3)); CCFlags branch; if (inst.BO_2 & BO_BRANCH_IF_TRUE) @@ -251,17 +262,14 @@ void JitArm::bcctrx(UGeckoInstruction inst) branch = CC_NEQ; FixupBranch b = B_CC(branch); - MOVI2R(rA, (u32)&CTR); - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); MVN(rB, 0x3); // 0xFFFFFFFC AND(rA, rA, rB); if (inst.LK_3){ - ARMReg rC = gpr.GetReg(false); u32 Jumpto = js.compilerPC + 4; - MOVI2R(rB, (u32)&LR); - MOVI2R(rC, Jumpto); - STR(rB, rC); + MOVI2R(rB, Jumpto); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); } gpr.Unlock(rB); // rA gets unlocked in WriteExitDestInR @@ -279,7 +287,11 @@ void JitArm::bclrx(UGeckoInstruction inst) (inst.BO & (1 << 4)) && (inst.BO & (1 << 2))) { if (inst.LK) { - ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); + ARMReg rA = gpr.GetReg(false); + u32 Jumpto = js.compilerPC + 4; + MOVI2R(rA, Jumpto); + STR(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); + // ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); } return; } @@ -291,10 +303,9 @@ void JitArm::bclrx(UGeckoInstruction inst) FixupBranch pCTRDontBranch; if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) // Decrement and test CTR { - MOVI2R(rA, (u32)&CTR); - LDR(rB, rA); + LDR(rB, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); SUBS(rB, rB, 1); - STR(rA, rB); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_CTR])); //SUB(32, M(&CTR), Imm8(1)); if (inst.BO & BO_BRANCH_IF_CTR_0) @@ -306,7 +317,7 @@ void JitArm::bclrx(UGeckoInstruction inst) FixupBranch pConditionDontBranch; if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0) // Test a CR bit { - LDRB(rA, R9, STRUCT_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); + LDRB(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + (inst.BI >> 2)); TST(rA, 8 >> (inst.BI & 3)); //TEST(8, M(&PowerPC::ppcState.cr_fast[inst.BI >> 2]), Imm8(8 >> (inst.BI & 3))); if (inst.BO & BO_BRANCH_IF_TRUE) // Conditional branch @@ -324,16 +335,13 @@ void JitArm::bclrx(UGeckoInstruction inst) //MOV(32, R(EAX), M(&LR)); //AND(32, R(EAX), Imm32(0xFFFFFFFC)); - MOVI2R(rA, (u32)&LR); MVN(rB, 0x3); // 0xFFFFFFFC - LDR(rA, rA); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); AND(rA, rA, rB); if (inst.LK){ - ARMReg rC = gpr.GetReg(false); u32 Jumpto = js.compilerPC + 4; - MOVI2R(rB, (u32)&LR); - MOVI2R(rC, Jumpto); - STR(rB, rC); + MOVI2R(rB, Jumpto); + STR(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, spr[SPR_LR])); //ARMABI_MOVI2M((u32)&LR, js.compilerPC + 4); } gpr.Unlock(rB); // rA gets unlocked in WriteExitDestInR diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp index 753568c9d3..4b77830ef3 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -40,7 +40,7 @@ void JitArm::GenerateRC(int cr) { SetCC(CC_MI); MOV(rB, 0x8); // Result < 0 SetCC(); - STRB(R9, rB, STRUCT_OFF(PowerPC::ppcState, cr_fast) + cr); + STRB(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + cr); gpr.Unlock(rB); } void JitArm::ComputeRC(int cr) { @@ -51,7 +51,7 @@ void JitArm::ComputeRC(int cr) { SetCC(CC_GT); MOV(rB, 0x4); // Result > 0 SetCC(); - STRB(R9, rB, STRUCT_OFF(PowerPC::ppcState, cr_fast) + cr); + STRB(R9, rB, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + cr); gpr.Unlock(rB); } @@ -232,7 +232,7 @@ void JitArm::cmpli(UGeckoInstruction inst) SetCC(CC_HI); MOV(rA, 0x4); // Result > 0 SetCC(); - STRB(R9, rA, STRUCT_OFF(PowerPC::ppcState, cr_fast) + crf); + STRB(R9, rA, PPCSTATE_OFF(PowerPC::ppcState, cr_fast) + crf); gpr.Unlock(rA); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp index 80c8a96cbb..dd9f7cd807 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStore.cpp @@ -100,7 +100,7 @@ void JitArm::stwu(UGeckoInstruction inst) // Check and set the update before writing since calling a function can // mess with the "special registers R11+ which may cause some issues. - LDR(Function, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(Function, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(Function, EXCEPTION_DSI); FixupBranch DoNotWrite = B_CC(CC_EQ); MOV(RA, Addr); @@ -198,7 +198,7 @@ void JitArm::lbz(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); #if FASTMEM @@ -245,7 +245,7 @@ void JitArm::lhz(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); #if 0 // FASTMEM @@ -295,7 +295,7 @@ void JitArm::lwz(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); @@ -369,7 +369,7 @@ void JitArm::lwzx(UGeckoInstruction inst) ARMReg RB = gpr.R(inst.RB); ARMReg RD = gpr.R(inst.RD); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); #if FASTMEM diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp index d9e320ab22..5134dd9e88 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_LoadStoreFloating.cpp @@ -40,7 +40,7 @@ void JitArm::lfs(UGeckoInstruction inst) ARMReg rA = gpr.GetReg(); ARMReg rB = gpr.GetReg(); - LDR(rA, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(rA, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); CMP(rA, EXCEPTION_DSI); FixupBranch DoNotLoad = B_CC(CC_EQ); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp index a99114df67..512240537a 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_SystemRegisters.cpp @@ -70,9 +70,7 @@ void JitArm::mtspr(UGeckoInstruction inst) } // OK, this is easy. - ARMReg rA = gpr.GetReg(false); - MOVI2R(rA, (u32)&PowerPC::ppcState.spr); - STR(rA, RD, iIndex * 4); + STR(R9, RD, PPCSTATE_OFF(PowerPC::ppcState, spr) + iIndex * 4); } void JitArm::mfspr(UGeckoInstruction inst) @@ -91,9 +89,7 @@ void JitArm::mfspr(UGeckoInstruction inst) Default(inst); return; default: - ARMReg rA = gpr.GetReg(false); - MOVI2R(rA, (u32)&PowerPC::ppcState.spr); - LDR(RD, rA, iIndex * 4); + LDR(RD, R9, PPCSTATE_OFF(PowerPC::ppcState, spr) + iIndex * 4); break; } } @@ -103,9 +99,6 @@ void JitArm::mtmsr(UGeckoInstruction inst) // Don't interpret this, if we do we get thrown out //JITDISABLE(SystemRegisters) - ARMReg rA = gpr.GetReg(); - MOVI2R(rA, (u32)&MSR); - STR(rA, gpr.R(inst.RS)); - gpr.Unlock(rA); + STR(R9, gpr.R(inst.RS), PPCSTATE_OFF(PowerPC::ppcState, msr)); WriteExit(js.compilerPC + 4, 0); } diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp index e45058b57b..5084ab44d6 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitAsm.cpp @@ -47,7 +47,7 @@ void JitArmAsmRoutineManager::Generate() PUSH(2, R11, _LR); // R11 is frame pointer in Debug. MOVI2R(R0, (u32)&CoreTiming::downcount); - MOVI2R(R9, (u32)&PowerPC::ppcState); + MOVI2R(R9, (u32)&PowerPC::ppcState.spr[0]); FixupBranch skipToRealDispatcher = B(); dispatcher = GetCodePtr(); @@ -63,7 +63,7 @@ void JitArmAsmRoutineManager::Generate() // This block of code gets the address of the compiled block of code // It runs though to the compiling portion if it isn't found - LDR(R12, R9, STRUCT_OFF(PowerPC::ppcState, pc));// Load the current PC into R12 + LDR(R12, R9, PPCSTATE_OFF(PowerPC::ppcState, pc));// Load the current PC into R12 MOVI2R(R14, JIT_ICACHE_MASK); // Potential for optimization AND(R12, R12, R14); // R12 contains PC & JIT_ICACHE_MASK here. @@ -92,7 +92,7 @@ void JitArmAsmRoutineManager::Generate() // If we get to this point, that means that we don't have the block cached to execute // So call ArmJit to compile the block and then execute it. MOVI2R(R14, (u32)&Jit); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, pc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, pc)); BL(R14); B(dispatcherNoCheck); @@ -100,12 +100,12 @@ void JitArmAsmRoutineManager::Generate() // fpException() // Floating Point Exception Check, Jumped to if false fpException = GetCodePtr(); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); ORR(R0, R0, EXCEPTION_FPU_UNAVAILABLE); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, Exceptions)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, Exceptions)); QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, npc)); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, pc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, npc)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, pc)); B(dispatcher); SetJumpTarget(bail); @@ -116,11 +116,11 @@ void JitArmAsmRoutineManager::Generate() // Does exception checking testExceptions = GetCodePtr(); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, pc)); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, npc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, pc)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, npc)); QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); - LDR(R0, R9, STRUCT_OFF(PowerPC::ppcState, npc)); - STR(R9, R0, STRUCT_OFF(PowerPC::ppcState, pc)); + LDR(R0, R9, PPCSTATE_OFF(PowerPC::ppcState, npc)); + STR(R9, R0, PPCSTATE_OFF(PowerPC::ppcState, pc)); // Check the state pointer to see if we are exiting // Gets checked on every exception check MOVI2R(R0, (u32)PowerPC::GetStatePtr()); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp index 08f10df826..99139d2c71 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitFPRCache.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Jit.h" #include "JitFPRCache.h" ArmFPRCache::ArmFPRCache() @@ -122,7 +123,7 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad) for (u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg == 33) { - u16 offset = STRUCT_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); + u16 offset = PPCSTATE_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); if (preLoad) emit->VLDR(ArmCRegs[a].Reg, R9, offset); ArmCRegs[a].PPCReg = preg; @@ -131,10 +132,10 @@ ARMReg ArmFPRCache::GetPPCReg(u32 preg, bool PS1, bool preLoad) return ArmCRegs[a].Reg; } // Alright, we couldn't get a free space, dump that least used register - u16 offsetOld = STRUCT_OFF(PowerPC::ppcState, ps) + (ArmCRegs[Num].PPCReg * 16) + (ArmCRegs[Num].PS1 ? 8 : 0); + u16 offsetOld = PPCSTATE_OFF(PowerPC::ppcState, ps) + (ArmCRegs[Num].PPCReg * 16) + (ArmCRegs[Num].PS1 ? 8 : 0); emit->VSTR(ArmCRegs[Num].Reg, R9, offsetOld); - u16 offsetNew = STRUCT_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); + u16 offsetNew = PPCSTATE_OFF(PowerPC::ppcState, ps) + (preg * 16) + (PS1 ? 8 : 0); if (preLoad) emit->VLDR(ArmCRegs[Num].Reg, R9, offsetNew); ArmCRegs[Num].PPCReg = preg; @@ -159,7 +160,7 @@ void ArmFPRCache::Flush() for(u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg != 33) { - u16 offset = STRUCT_OFF(PowerPC::ppcState, ps) + (ArmCRegs[a].PPCReg * 16) + (ArmCRegs[a].PS1 ? 8 : 0); + u16 offset = PPCSTATE_OFF(PowerPC::ppcState, ps) + (ArmCRegs[a].PPCReg * 16) + (ArmCRegs[a].PS1 ? 8 : 0); emit->VSTR(ArmCRegs[a].Reg, R9, offset); ArmCRegs[a].PPCReg = 33; ArmCRegs[a].LastLoad = 0; diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp index 9c6ffdbac4..0e5bc8d68a 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitRegCache.cpp @@ -15,6 +15,7 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include "Jit.h" #include "JitRegCache.h" ArmRegCache::ArmRegCache() @@ -141,14 +142,14 @@ ARMReg ArmRegCache::R(u32 preg) for (u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg == 33) { - emit->LDR(ArmCRegs[a].Reg, R9, STRUCT_OFF(PowerPC::ppcState, gpr) + preg * 4); + emit->LDR(ArmCRegs[a].Reg, R9, PPCSTATE_OFF(PowerPC::ppcState, gpr) + preg * 4); ArmCRegs[a].PPCReg = preg; ArmCRegs[a].LastLoad = 0; return ArmCRegs[a].Reg; } // Alright, we couldn't get a free space, dump that least used register - emit->STR(R9, ArmCRegs[Num].Reg, STRUCT_OFF(PowerPC::ppcState, gpr) + ArmCRegs[Num].PPCReg * 4); - emit->LDR(ArmCRegs[Num].Reg, R9, STRUCT_OFF(PowerPC::ppcState, gpr) + preg * 4); + emit->STR(R9, ArmCRegs[Num].Reg, PPCSTATE_OFF(PowerPC::ppcState, gpr) + ArmCRegs[Num].PPCReg * 4); + emit->LDR(ArmCRegs[Num].Reg, R9, PPCSTATE_OFF(PowerPC::ppcState, gpr) + preg * 4); ArmCRegs[Num].PPCReg = preg; ArmCRegs[Num].LastLoad = 0; return ArmCRegs[Num].Reg; @@ -159,7 +160,7 @@ void ArmRegCache::Flush() for(u8 a = 0; a < NUMPPCREG; ++a) if (ArmCRegs[a].PPCReg != 33) { - emit->STR(R9, ArmCRegs[a].Reg, STRUCT_OFF(PowerPC::ppcState, gpr) + ArmCRegs[a].PPCReg * 4); + emit->STR(R9, ArmCRegs[a].Reg, PPCSTATE_OFF(PowerPC::ppcState, gpr) + ArmCRegs[a].PPCReg * 4); ArmCRegs[a].PPCReg = 33; ArmCRegs[a].LastLoad = 0; } From 1214bf1359d3715931ccfdcb13f7e8295d0ef656 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 6 Mar 2013 03:25:45 +0000 Subject: [PATCH 166/167] Add ARM Jit to GUI when built on ARM --- Source/Core/DolphinWX/Src/ConfigMain.cpp | 29 ++++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp index 068501c432..329906a301 100644 --- a/Source/Core/DolphinWX/Src/ConfigMain.cpp +++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp @@ -53,6 +53,21 @@ using std::function; #define TEXT_BOX(page, text) new wxStaticText(page, wxID_ANY, text, wxDefaultPosition, wxDefaultSize) +struct CPUCore +{ + int CPUid; + const char *name; +}; +const CPUCore CPUCores[] = { + {0, "Interpreter (VERY slow)"}, +#ifdef _M_ARM + {3, "Arm JIT (experimental)"}, +#else + {1, "JIT Recompiler (recommended)"}, + {2, "JITIL experimental recompiler"}, +#endif +}; + extern CFrame* main_frame; // keep these in sync with CConfigMain::InitializeGUILists @@ -241,7 +256,6 @@ void CConfigMain::UpdateGUI() PathsPage->Disable(); } } - void CConfigMain::InitializeGUILists() { // General page @@ -253,10 +267,9 @@ void CConfigMain::InitializeGUILists() arrayStringFor_Framelimit.Add(wxString::Format(wxT("%i"), i)); // Emulator Engine - arrayStringFor_CPUEngine.Add(_("Interpreter (VERY slow)")); - arrayStringFor_CPUEngine.Add(_("JIT Recompiler (recommended)")); - arrayStringFor_CPUEngine.Add(_("JITIL experimental recompiler")); - + for (unsigned int a = 0; a < (sizeof(CPUCores) / sizeof(CPUCore)); ++a) + arrayStringFor_CPUEngine.Add(_(CPUCores[a].name)); + // DSP Engine arrayStringFor_DSPEngine.Add(_("DSP HLE emulation (fast)")); arrayStringFor_DSPEngine.Add(_("DSP LLE recompiler")); @@ -329,7 +342,9 @@ void CConfigMain::InitializeGUIValues() UseFPSForLimiting->SetValue(SConfig::GetInstance().b_UseFPS); // General - Advanced - CPUEngine->SetSelection(startup_params.iCPUCore); + for (unsigned int a = 0; a < (sizeof(CPUCores) / sizeof(CPUCore)); ++a) + if (CPUCores[a].CPUid == startup_params.iCPUCore) + CPUEngine->SetSelection(a); _NTSCJ->SetValue(startup_params.bForceNTSCJ); @@ -888,7 +903,7 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event) break; // Core - Advanced case ID_CPUENGINE: - SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore = CPUEngine->GetSelection(); + SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore = CPUCores[CPUEngine->GetSelection()].CPUid; if (main_frame->g_pCodeWindow) main_frame->g_pCodeWindow->GetMenuBar()->Check(IDM_INTERPRETER, SConfig::GetInstance().m_LocalCoreStartupParameter.iCPUCore?false:true); From 10983b0eae0124b89d777b441d9916257a50f200 Mon Sep 17 00:00:00 2001 From: degasus Date: Wed, 6 Mar 2013 12:33:02 +0100 Subject: [PATCH 167/167] fix VertexManager::GetRemainingIndices the old implementation returns the amound of primitives fit into index buffers but also gc needs more than one index per primitve --- Source/Core/VideoCommon/Src/VertexManagerBase.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp index 55f55954c5..54830bcbea 100644 --- a/Source/Core/VideoCommon/Src/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/Src/VertexManagerBase.cpp @@ -59,6 +59,9 @@ void VertexManager::PrepareForAdditionalData(int primitive, u32 count, u32 strid if (needed_vertex_bytes > GetRemainingSize()) ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all vertices! " "Increase MAXVBUFFERSIZE or we need primitive breaking afterall."); + if (count > GetRemainingIndices(primitive)) + ERROR_LOG(VIDEO, "VertexManager: Buffer not large enough for all indices! " + "Increase MAXIBUFFERSIZE or we need primitive breaking afterall."); } } @@ -72,24 +75,24 @@ u32 VertexManager::GetRemainingIndices(int primitive) switch (primitive) { case GX_DRAW_QUADS: + return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 6 * 4; case GX_DRAW_TRIANGLES: + return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()); case GX_DRAW_TRIANGLE_STRIP: + return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3 + 2; case GX_DRAW_TRIANGLE_FAN: - return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3; - break; + return (MAXIBUFFERSIZE - IndexGenerator::GetTriangleindexLen()) / 3 + 2; case GX_DRAW_LINES: + return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()); case GX_DRAW_LINE_STRIP: - return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2; - break; + return (MAXIBUFFERSIZE - IndexGenerator::GetLineindexLen()) / 2 + 1; case GX_DRAW_POINTS: return (MAXIBUFFERSIZE - IndexGenerator::GetPointindexLen()); - break; default: return 0; - break; } }