diff --git a/Src/OSD/SDL/Crosshair.cpp b/Src/OSD/SDL/Crosshair.cpp index 02501de..d4755ae 100644 --- a/Src/OSD/SDL/Crosshair.cpp +++ b/Src/OSD/SDL/Crosshair.cpp @@ -26,13 +26,27 @@ #include "SDLIncludes.h" #include #include +#include "Inputs/Inputs.h" +#include "Util/Format.h" bool CCrosshair::Init() { const std::string p1CrosshairFile = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Assets) << "p1crosshair.bmp"; const std::string p2CrosshairFile = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Assets) << "p2crosshair.bmp"; - m_isBitmapCrosshair = m_config["CrosshairStyle"].ValueAs(); + m_crosshairStyle = Util::ToLower(m_config["CrosshairStyle"].ValueAs()); + if (m_crosshairStyle == "bmp") + m_isBitmapCrosshair = true; + else if (m_crosshairStyle == "vector") + m_isBitmapCrosshair = false; + else + { + ErrorLog("Invalid crosshair style '%s', must be 'vector' or 'bmp'. Reverting to 'vector'.\n", m_crosshairStyle.c_str()); + m_isBitmapCrosshair = false; + } + + m_crosshairs = m_config["Crosshairs"].ValueAs(); + m_xRes = m_config["XResolution"].ValueAs(); m_yRes = m_config["YResolution"].ValueAs(); m_a = (float)m_xRes / (float)m_yRes; @@ -76,7 +90,7 @@ bool CCrosshair::Init() m_uvCoord.emplace_back(1.0f, 1.0f); m_uvCoord.emplace_back(0.0f, 1.0f); - if (m_isBitmapCrosshair != "bmp") + if (!m_isBitmapCrosshair) { m_verts.emplace_back(0.0f, m_dist); // bottom triangle m_verts.emplace_back(m_base / 2.0f, (m_dist + m_height) * m_a); @@ -178,16 +192,16 @@ void CCrosshair::DrawCrosshair(New3D::Mat4 matrix, float x, float y, int player) m_shader.EnableShader(); matrix.Translate(x, y, 0); - if (m_isBitmapCrosshair != "bmp") + if (!m_isBitmapCrosshair) { switch (player) { - case 0: + case 0: // P1 red color r = 1.0f; g = 0.0f; b = 0.0f; break; - case 1: + case 1: // P2 green color r = 0.0f; g = 1.0f; b = 0.0f; @@ -236,6 +250,82 @@ void CCrosshair::DrawCrosshair(New3D::Mat4 matrix, float x, float y, int player) m_shader.DisableShader(); } +void CCrosshair::Update(uint32_t currentInputs, CInputs* Inputs, unsigned int xOffset, unsigned int yOffset) +{ + bool offscreenTrigger[2]{false}; + float x[2]{ 0.0f }, y[2]{ 0.0f }; + + m_crosshairs &= 3; + if (!m_crosshairs) + return; + + // Set up the viewport and orthogonal projection + glUseProgram(0); // no shaders + glViewport(xOffset, yOffset, m_xRes, m_yRes); + glDisable(GL_DEPTH_TEST); // no Z-buffering needed + + if (!m_isBitmapCrosshair) + { + glDisable(GL_BLEND); // no blending + } + else + { + glEnable(GL_TEXTURE_2D); // enable texture mapping, blending and alpha chanel + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + New3D::Mat4 m; + m.Ortho(0.0, 1.0, 1.0, 0.0, -1.0f, 1.0f); + + // Convert gun coordinates to viewspace coordinates + if (currentInputs & Game::INPUT_ANALOG_GUN1) + { + x[0] = ((float)Inputs->analogGunX[0]->value / 255.0f); + y[0] = ((255.0f - (float)Inputs->analogGunY[0]->value) / 255.0f); + offscreenTrigger[0] = Inputs->analogTriggerLeft[0]->value || Inputs->analogTriggerRight[0]->value; + } + else if (currentInputs & Game::INPUT_GUN1) + { + x[0] = (float)Inputs->gunX[0]->value; + y[0] = (float)Inputs->gunY[0]->value; + GunToViewCoords(&x[0], &y[0]); + offscreenTrigger[0] = (Inputs->trigger[0]->offscreenValue) > 0; + } + if (currentInputs & Game::INPUT_ANALOG_GUN2) + { + x[1] = ((float)Inputs->analogGunX[1]->value / 255.0f); + y[1] = ((255.0f - (float)Inputs->analogGunY[1]->value) / 255.0f); + offscreenTrigger[1] = Inputs->analogTriggerLeft[1]->value || Inputs->analogTriggerRight[1]->value; + } + else if (currentInputs & Game::INPUT_GUN2) + { + x[1] = (float)Inputs->gunX[1]->value; + y[1] = (float)Inputs->gunY[1]->value; + GunToViewCoords(&x[1], &y[1]); + offscreenTrigger[1] = (Inputs->trigger[1]->offscreenValue) > 0; + } + + // Draw visible crosshairs + + if ((m_crosshairs & 1) && !offscreenTrigger[0]) // Player 1 + { + DrawCrosshair(m, x[0], y[0], 0); + } + if ((m_crosshairs & 2) && !offscreenTrigger[1]) // Player 2 + { + DrawCrosshair(m, x[1], y[1], 1); + } + + //PrintGLError(glGetError()); +} + +void CCrosshair::GunToViewCoords(float* x, float* y) +{ + *x = (*x - 150.0f) / (651.0f - 150.0f); // Scale [150,651] -> [0.0,1.0] + *y = (*y - 80.0f) / (465.0f - 80.0f); // Scale [80,465] -> [0.0,1.0] +} + CCrosshair::CCrosshair(const Util::Config::Node& config) : m_config(config),m_xRes(0),m_yRes(0) { m_vertexShader = nullptr; diff --git a/Src/OSD/SDL/Crosshair.h b/Src/OSD/SDL/Crosshair.h index 0ac6c07..8303a5e 100644 --- a/Src/OSD/SDL/Crosshair.h +++ b/Src/OSD/SDL/Crosshair.h @@ -24,13 +24,16 @@ #include "Supermodel.h" #include "Graphics/New3D/New3D.h" +#include "Inputs/Inputs.h" class CCrosshair { private: const Util::Config::Node& m_config; - std::string m_isBitmapCrosshair = ""; + bool m_isBitmapCrosshair = false; + std::string m_crosshairStyle = ""; GLuint m_crosshairTexId[2] = { 0 }; + unsigned int m_crosshairs = 0; int m_p1CrosshairW = 0, m_p1CrosshairH = 0, m_p2CrosshairW = 0, m_p2CrosshairH = 0; float m_diagDpi = 0.0f, m_hDpi = 0.0f, m_vDpi = 0.0f; unsigned int m_xRes=0; @@ -69,11 +72,14 @@ private: const int MaxVerts = 1024; // per draw call + void DrawCrosshair(New3D::Mat4 matrix, float x, float y, int player); + void GunToViewCoords(float* x, float* y); + public: CCrosshair(const Util::Config::Node& config); ~CCrosshair(); bool Init(); - void DrawCrosshair(New3D::Mat4 matrix, float x, float y, int player); + void Update(uint32_t currentInputs, CInputs* Inputs, unsigned int, unsigned int); }; #endif diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp index 7d14893..9b8e899 100644 --- a/Src/OSD/SDL/Main.cpp +++ b/Src/OSD/SDL/Main.cpp @@ -781,18 +781,6 @@ static void LoadNVRAM(IEmulator *Model3) } -/****************************************************************************** - UI Rendering - - Currently, only does crosshairs for light gun games. -******************************************************************************/ - -static void GunToViewCoords(float *x, float *y) -{ - *x = (*x-150.0f)/(651.0f-150.0f); // Scale [150,651] -> [0.0,1.0] - *y = (*y-80.0f)/(465.0f-80.0f); // Scale [80,465] -> [0.0,1.0] -} - /* static void PrintGLError(GLenum error) { @@ -811,77 +799,6 @@ static void PrintGLError(GLenum error) } */ -static void UpdateCrosshairs(uint32_t currentInputs, CInputs *Inputs, unsigned crosshairs, std::string crosshairStyle) -{ - bool offscreenTrigger[2]; - float x[2], y[2]; - - crosshairs &= 3; - if (!crosshairs) - return; - - // Set up the viewport and orthogonal projection - glUseProgram(0); // no shaders - glViewport(xOffset, yOffset, xRes, yRes); - glDisable(GL_DEPTH_TEST); // no Z-buffering needed - - if(crosshairStyle != "bmp") - { - glDisable(GL_BLEND); // no blending - } - else - { - glEnable(GL_TEXTURE_2D); // enable texture mapping, blending and alpha chanel - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - New3D::Mat4 m; - m.Ortho(0.0, 1.0, 1.0, 0.0, -1.0f, 1.0f); - - // Convert gun coordinates to viewspace coordinates - if (currentInputs & Game::INPUT_ANALOG_GUN1) - { - x[0] = ((float)Inputs->analogGunX[0]->value / 255.0f); - y[0] = ((255.0f - (float)Inputs->analogGunY[0]->value) / 255.0f); - offscreenTrigger[0] = Inputs->analogTriggerLeft[0]->value || Inputs->analogTriggerRight[0]->value; - } - else if (currentInputs & Game::INPUT_GUN1) - { - x[0] = (float)Inputs->gunX[0]->value; - y[0] = (float)Inputs->gunY[0]->value; - GunToViewCoords(&x[0], &y[0]); - offscreenTrigger[0] = (Inputs->trigger[0]->offscreenValue) > 0; - } - if (currentInputs & Game::INPUT_ANALOG_GUN2) - { - x[1] = ((float)Inputs->analogGunX[1]->value / 255.0f); - y[1] = ((255.0f - (float)Inputs->analogGunY[1]->value) / 255.0f); - offscreenTrigger[1] = Inputs->analogTriggerLeft[1]->value || Inputs->analogTriggerRight[1]->value; - } - else if (currentInputs & Game::INPUT_GUN2) - { - x[1] = (float)Inputs->gunX[1]->value; - y[1] = (float)Inputs->gunY[1]->value; - GunToViewCoords(&x[1], &y[1]); - offscreenTrigger[1] = (Inputs->trigger[1]->offscreenValue) > 0; - } - - // Draw visible crosshairs - - if ((crosshairs & 1) && !offscreenTrigger[0]) // Player 1 - { - s_crosshair->DrawCrosshair(m, x[0], y[0], 0); - } - if ((crosshairs & 2) && !offscreenTrigger[1]) // Player 2 - { - s_crosshair->DrawCrosshair(m, x[1], y[1], 1); - } - - //PrintGLError(glGetError()); -} - - /****************************************************************************** Video Callbacks ******************************************************************************/ @@ -898,7 +815,7 @@ void EndFrameVideo() { // Show crosshairs for light gun games if (videoInputs) - UpdateCrosshairs(currentInputs, videoInputs, s_runtime_config["Crosshairs"].ValueAs(), s_runtime_config["CrosshairStyle"].ValueAs()); + s_crosshair->Update(currentInputs, videoInputs, xOffset, yOffset); // Swap the buffers SDL_GL_SwapWindow(s_window);