-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sinden lightgun #69
base: master
Are you sure you want to change the base?
Sinden lightgun #69
Changes from all commits
6a531e5
b7a156f
1b5b38d
722c70b
65559cc
43833a2
bb8b31e
99a15c5
a13b9d4
9b9ff49
45e076d
7742836
3bf7133
ab2a8e9
31dbef3
490c492
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,8 +25,9 @@ | |
#include "Supermodel.h" | ||
#include "Graphics/New3D/New3D.h" | ||
#include "Inputs/Inputs.h" | ||
#include "basicDrawable.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. basicDrawable.h should be named BasicDrawable.h. Also please use full path (OSD/SDL/BasicDrawable.h) |
||
|
||
class CCrosshair | ||
class CCrosshair : public CBasicDrawable | ||
{ | ||
private: | ||
const Util::Config::Node& m_config; | ||
|
@@ -42,32 +43,6 @@ class CCrosshair | |
float m_dpiMultiplicator = 0.0f; | ||
const float m_scaleBitmap = 0.1f; | ||
|
||
struct BasicVertex | ||
{ | ||
BasicVertex(float x, float y, float z) : x(x), y(y), z(z) {} | ||
BasicVertex(float x, float y) : x(x), y(y), z(0.0f) {} | ||
float x, y, z; | ||
}; | ||
|
||
struct UVCoords | ||
{ | ||
UVCoords(float x, float y) : x(x), y(y) {} | ||
float x, y; | ||
}; | ||
|
||
std::vector<BasicVertex> m_verts; | ||
std::vector<UVCoords> m_uvCoord; | ||
|
||
GLSLShader m_shader; | ||
VBO m_vbo; | ||
VBO m_textvbo; | ||
GLuint m_vao = 0; | ||
int m_textureCoordsCount = 0; | ||
const char* m_vertexShader; | ||
const char* m_fragmentShader; | ||
|
||
const int MaxVerts = 1024; // per draw call | ||
|
||
void BuildCrosshairVertices(unsigned int xRes, unsigned int yRes); | ||
void DrawCrosshair(New3D::Mat4 matrix, float x, float y, int player, unsigned int xRes, unsigned int yRes); | ||
void GunToViewCoords(float* x, float* y); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -82,6 +82,7 @@ | |
#include "Util/BMPFile.h" | ||
|
||
#include "Crosshair.h" | ||
#include "WhiteBorder.h" | ||
|
||
/****************************************************************************** | ||
Global Run-time Config | ||
|
@@ -110,6 +111,7 @@ static unsigned totalXRes, totalYRes; // total resolution (the whole GL viewpo | |
* Crosshair stuff | ||
*/ | ||
static CCrosshair* s_crosshair = nullptr; | ||
static CWhiteBorder* s_whiteBorder = nullptr; | ||
|
||
static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio) | ||
{ | ||
|
@@ -123,6 +125,16 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned * | |
// If required, fix the aspect ratio of the resolution that the user passed to match Model 3 ratio | ||
float xRes = float(*xResPtr); | ||
float yRes = float(*yResPtr); | ||
|
||
//if we want to draw a white border, we have also to put a black border around it so we are sure lightgun will find it... | ||
if (s_whiteBorder->IsEnabled()) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blackborder -> blackBorder |
||
int blackborder = s_whiteBorder->Width(); | ||
int whiteBorder = s_whiteBorder->Width(); //50px borders | ||
xRes -= (whiteBorder + blackborder); | ||
yRes -= (whiteBorder + blackborder); | ||
} | ||
|
||
if (keepAspectRatio) | ||
{ | ||
float model3Ratio = float(496.0/384.0); | ||
|
@@ -174,6 +186,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned * | |
{ | ||
glScissor(*xOffsetPtr + correction, *yOffsetPtr + correction, *xResPtr - (correction * 2), *yResPtr - (correction * 2)); | ||
} | ||
|
||
return OKAY; | ||
} | ||
|
||
|
@@ -780,7 +793,6 @@ static void LoadNVRAM(IEmulator *Model3) | |
DebugLog("Loaded NVRAM from '%s'.\n", file_path.c_str()); | ||
} | ||
|
||
|
||
/* | ||
static void PrintGLError(GLenum error) | ||
{ | ||
|
@@ -817,6 +829,8 @@ void EndFrameVideo() | |
if (videoInputs) | ||
s_crosshair->Update(currentInputs, videoInputs, xOffset, yOffset, xRes, yRes); | ||
|
||
//Update whiteborders | ||
s_whiteBorder->Update(xOffset, yOffset, xRes, yRes, totalXRes, totalYRes); | ||
// Swap the buffers | ||
SDL_GL_SwapWindow(s_window); | ||
} | ||
|
@@ -1460,6 +1474,7 @@ static Util::Config::Node DefaultConfig() | |
config.SetEmpty("WindowYPosition"); | ||
config.Set("FullScreen", false); | ||
config.Set("BorderlessWindow", false); | ||
config.Set("DrawWhiteBorder", false); | ||
|
||
config.Set("WideScreen", false); | ||
config.Set("Stretch", false); | ||
|
@@ -1543,6 +1558,7 @@ static void Help(void) | |
puts(" -window-pos=<x>,<y> Window position [Default: centered]"); | ||
puts(" -window Windowed mode [Default]"); | ||
puts(" -borderless Windowed mode with no border"); | ||
puts(" -draw-white-border Draw a whiteborder around image: usefull for some lightgun type (Sinden LightGun)"); | ||
puts(" -fullscreen Full screen mode"); | ||
puts(" -wide-screen Expand 3D field of view to screen width"); | ||
puts(" -wide-bg When wide-screen mode is enabled, also expand the 2D"); | ||
|
@@ -1667,6 +1683,7 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv) | |
{ "-window", { "FullScreen", false } }, | ||
{ "-fullscreen", { "FullScreen", true } }, | ||
{ "-borderless", { "BorderlessWindow", true } }, | ||
{ "-draw-white-border", { "DrawWhiteBorder", true } }, | ||
{ "-no-wide-screen", { "WideScreen", false } }, | ||
{ "-wide-screen", { "WideScreen", true } }, | ||
{ "-stretch", { "Stretch", true } }, | ||
|
@@ -1943,6 +1960,8 @@ int main(int argc, char **argv) | |
std::shared_ptr<Debugger::CSupermodelDebugger> Debugger; | ||
#endif // SUPERMODEL_DEBUGGER | ||
std::string selectedInputSystem = s_runtime_config["InputSystem"].ValueAs<std::string>(); | ||
s_crosshair = new CCrosshair(s_runtime_config); | ||
s_whiteBorder = new CWhiteBorder(s_runtime_config); | ||
|
||
// Create a window | ||
xRes = 496; | ||
|
@@ -1954,14 +1973,23 @@ int main(int argc, char **argv) | |
} | ||
|
||
// Create Crosshair | ||
s_crosshair = new CCrosshair(s_runtime_config); | ||
if (s_crosshair->Init() != OKAY) | ||
{ | ||
ErrorLog("Unable to load bitmap crosshair texture\n"); | ||
exitCode = 1; | ||
goto Exit; | ||
} | ||
|
||
// Create WhiteBorder | ||
if (s_whiteBorder->Init() != OKAY) | ||
{ | ||
ErrorLog("Unable to create whiteborder\n"); | ||
exitCode = 1; | ||
goto Exit; | ||
} | ||
|
||
|
||
|
||
// Create Model 3 emulator | ||
#ifdef DEBUG | ||
Model3 = s_gfxStatePath.empty() ? static_cast<IEmulator *>(new CModel3(s_runtime_config)) : static_cast<IEmulator *>(new CModel3GraphicsState(s_runtime_config, s_gfxStatePath)); | ||
|
@@ -2064,7 +2092,9 @@ int main(int argc, char **argv) | |
if (Outputs != NULL) | ||
delete Outputs; | ||
if (s_crosshair != NULL) | ||
delete s_crosshair; | ||
delete s_crosshair; | ||
if (s_whiteBorder != NULL) | ||
delete s_whiteBorder; | ||
DestroyGLScreen(); | ||
SDL_Quit(); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
/** | ||
** Supermodel | ||
** A Sega Model 3 Arcade Emulator. | ||
** Copyright 2003-2023 The Supermodel Team | ||
** | ||
** This file is part of Supermodel. | ||
** | ||
** Supermodel is free software: you can redistribute it and/or modify it under | ||
** the terms of the GNU General Public License as published by the Free | ||
** Software Foundation, either version 3 of the License, or (at your option) | ||
** any later version. | ||
** | ||
** Supermodel is distributed in the hope that it will be useful, but WITHOUT | ||
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
** more details. | ||
** | ||
** You should have received a copy of the GNU General Public License along | ||
** with Supermodel. If not, see <http://www.gnu.org/licenses/>. | ||
**/ | ||
|
||
#include "WhiteBorder.h" | ||
#include "Supermodel.h" | ||
#include "Graphics/New3D/New3D.h" | ||
#include "OSD/FileSystemPath.h" | ||
#include "SDLIncludes.h" | ||
#include <GL/glew.h> | ||
#include <vector> | ||
#include "Inputs/Inputs.h" | ||
#include "Util/Format.h" | ||
|
||
|
||
bool CWhiteBorder::Init() | ||
{ | ||
//whiteBorders must change during runtime when resolution is chnaging | ||
if (m_drawWhiteBorder) | ||
{ | ||
m_vertexShader = R"glsl( | ||
|
||
#version 410 core | ||
|
||
uniform mat4 mvp; | ||
layout(location = 0) in vec3 inVertices; | ||
|
||
void main(void) | ||
{ | ||
gl_Position = mvp * vec4(inVertices,1.0); | ||
} | ||
)glsl"; | ||
|
||
m_fragmentShader = R"glsl( | ||
|
||
#version 410 core | ||
|
||
uniform vec4 colour; | ||
out vec4 fragColour; | ||
|
||
void main(void) | ||
{ | ||
fragColour = colour; | ||
} | ||
)glsl"; | ||
|
||
m_shader.LoadShaders(m_vertexShader, m_fragmentShader); | ||
m_shader.GetUniformLocationMap("mvp"); | ||
m_shader.GetUniformLocationMap("colour"); | ||
m_vbo.Create(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(BasicVertex) * (MaxVerts)); | ||
m_vbo.Bind(true); | ||
|
||
|
||
glGenVertexArrays(1, &m_vao); | ||
glBindVertexArray(m_vao); | ||
|
||
m_vbo.Bind(true); | ||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(BasicVertex), 0); | ||
m_vbo.Bind(false); | ||
|
||
glEnableVertexAttribArray(0); | ||
glEnableVertexAttribArray(1); | ||
|
||
glBindVertexArray(0); | ||
m_drawWhiteBorder = true; | ||
} | ||
return OKAY; | ||
} | ||
|
||
void CWhiteBorder::GenQuad(std::vector<CBasicDrawable::BasicVertex> &verts, unsigned int x, unsigned int y, unsigned int w, unsigned int h) | ||
{ | ||
verts.emplace_back(float(x), float(y)); | ||
verts.emplace_back(float(x), float(y + h)); | ||
verts.emplace_back(float(x + w), float(y + h)); | ||
verts.emplace_back(float(x), float(y)); | ||
verts.emplace_back(float(x + w), float(y + h)); | ||
verts.emplace_back(float(x + w), float(y)); | ||
} | ||
|
||
|
||
void CWhiteBorder::Update(unsigned int xOffset, unsigned int yOffset, unsigned int xRes, unsigned int yRes, unsigned int totalXRes, unsigned int totalYRes) | ||
{ | ||
//white border | ||
if (m_drawWhiteBorder) | ||
{ | ||
if(m_xRes != xRes || | ||
m_yRes != yRes || | ||
m_xOffset != xOffset || | ||
m_yOffset != yOffset ) | ||
{ | ||
m_xRes = xRes ; | ||
m_yRes = yRes ; | ||
m_xOffset = xOffset; | ||
m_yOffset = yOffset; | ||
int whiteBorder = m_width; | ||
int internalWhiteBorder = m_width / 2; | ||
//generate border geometry | ||
m_verts.clear(); | ||
GenQuad(m_verts, m_xOffset - internalWhiteBorder, m_yOffset - internalWhiteBorder, internalWhiteBorder, m_yRes + internalWhiteBorder * 2); | ||
GenQuad(m_verts, m_xOffset + m_xRes, m_yOffset - internalWhiteBorder, internalWhiteBorder, m_yRes + internalWhiteBorder * 2); | ||
GenQuad(m_verts, m_xOffset, m_yOffset - internalWhiteBorder, m_xRes , internalWhiteBorder); | ||
GenQuad(m_verts, m_xOffset, m_yOffset + m_yRes, m_xRes, internalWhiteBorder); | ||
|
||
// update vbo mem | ||
m_vbo.Bind(true); | ||
m_vbo.BufferSubData(0, m_verts.size() * sizeof(BasicVertex), m_verts.data()); | ||
} | ||
|
||
glUseProgram(0); | ||
glViewport(0, 0, totalXRes, totalYRes); | ||
glDisable(GL_BLEND); | ||
glDisable(GL_DEPTH_TEST); | ||
glDisable(GL_SCISSOR_TEST); | ||
|
||
New3D::Mat4 mvpMatrix; | ||
mvpMatrix.Ortho(0.0, float(totalXRes), float(totalYRes), 0.0, -1.0f, 1.0f); | ||
|
||
m_shader.EnableShader(); | ||
|
||
// update uniform memory | ||
glUniformMatrix4fv(m_shader.uniformLocMap["mvp"], 1, GL_FALSE, mvpMatrix); | ||
glUniform4f(m_shader.uniformLocMap["colour"], 1.0f, 1.0f, 1.0f, 1.0f); | ||
|
||
glBindVertexArray(m_vao); | ||
glDrawArrays(GL_TRIANGLES, 0, GLsizei(m_verts.size())); | ||
glBindVertexArray(0); | ||
|
||
m_shader.DisableShader(); | ||
|
||
glEnable(GL_SCISSOR_TEST); | ||
} | ||
} | ||
|
||
bool CWhiteBorder::IsEnabled() | ||
{ | ||
return m_drawWhiteBorder; | ||
} | ||
|
||
unsigned int CWhiteBorder::Width() | ||
{ | ||
return m_width; | ||
} | ||
|
||
|
||
CWhiteBorder::CWhiteBorder(const Util::Config::Node& config) : m_config(config) | ||
{ | ||
m_drawWhiteBorder = m_config["DrawWhiteBorder"].ValueAs<bool>(); | ||
m_vertexShader = nullptr; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these should probably just be moved up into the initializer list. |
||
m_fragmentShader = nullptr; | ||
m_xRes = 0; | ||
m_yRes = 0; | ||
m_xOffset = 0; | ||
m_yOffset = 0; | ||
m_width = 50; | ||
} | ||
|
||
CWhiteBorder::~CWhiteBorder() | ||
{ | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why were these moved?