diff --git a/Makefiles/Rules.inc b/Makefiles/Rules.inc
index 168336f..3ce1941 100644
--- a/Makefiles/Rules.inc
+++ b/Makefiles/Rules.inc
@@ -149,6 +149,7 @@ SRC_FILES = \
Src/Inputs/InputTypes.cpp \
Src/Inputs/MultiInputSource.cpp \
Src/OSD/SDL/SDLInputSystem.cpp \
+ Src/OSD/SDL/Crosshair.cpp \
Src/OSD/Outputs.cpp \
Src/Sound/MPEG/MpegAudio.cpp \
Src/Model3/Crypto.cpp \
diff --git a/Media/DIR.txt b/Media/DIR.txt
new file mode 100644
index 0000000..ad7d6b5
--- /dev/null
+++ b/Media/DIR.txt
@@ -0,0 +1,6 @@
+Crosshairs images needs to be placed in here.
+32bits bmp format + alpha
+size multiple of 2
+p1crosshair.bmp
+p2crosshair.bmp
+
diff --git a/Media/p1crosshair.bmp b/Media/p1crosshair.bmp
new file mode 100644
index 0000000..9e39127
Binary files /dev/null and b/Media/p1crosshair.bmp differ
diff --git a/Media/p2crosshair.bmp b/Media/p2crosshair.bmp
new file mode 100644
index 0000000..cc3f1ba
Binary files /dev/null and b/Media/p2crosshair.bmp differ
diff --git a/Src/OSD/FileSystemPath.h b/Src/OSD/FileSystemPath.h
index 3c04b62..e5ee179 100644
--- a/Src/OSD/FileSystemPath.h
+++ b/Src/OSD/FileSystemPath.h
@@ -32,7 +32,7 @@
namespace FileSystemPath
{
- enum PathType { Analysis, Config, Log, NVRAM, Saves, Screenshots }; // Filesystem path types
+ enum PathType { Analysis, Config, Log, NVRAM, Saves, Screenshots, Media }; // Filesystem path types
bool PathExists(std::string fileSystemPath); // Checks if a directory exists (returns true if exists, false if it doesn't)
std::string GetPath(PathType pathType); // Generates a path to be used by Supermodel files
}
diff --git a/Src/OSD/OSX/FileSystemPath.cpp b/Src/OSD/OSX/FileSystemPath.cpp
index 9536d27..a70463e 100644
--- a/Src/OSD/OSX/FileSystemPath.cpp
+++ b/Src/OSD/OSX/FileSystemPath.cpp
@@ -41,6 +41,8 @@ namespace FileSystemPath
return "Saves/";
case Screenshots:
return "";
+ case Media:
+ return "Media/";
}
}
}
diff --git a/Src/OSD/SDL/Crosshair.cpp b/Src/OSD/SDL/Crosshair.cpp
new file mode 100644
index 0000000..ce69c8e
--- /dev/null
+++ b/Src/OSD/SDL/Crosshair.cpp
@@ -0,0 +1,244 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2003-2022 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 .
+ **/
+
+#include "Crosshair.h"
+#include "Supermodel.h"
+#include "Graphics/New3D/New3D.h"
+#include "OSD/FileSystemPath.h"
+#include "SDLIncludes.h"
+#include
+#include
+
+bool CCrosshair::init()
+{
+ const std::string P1CrosshairFile = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Media) << "p1crosshair.bmp";
+ const std::string P2CrosshairFile = Util::Format() << FileSystemPath::GetPath(FileSystemPath::Media) << "p2crosshair.bmp";
+
+ IsBitmapCrosshair = m_config["BitmapCrosshair"].ValueAs();
+ xRes = m_config["XResolution"].ValueAs();
+ yRes = m_config["YResolution"].ValueAs();
+ a = (float)xRes / (float)yRes;
+
+ SDL_Surface* SurfaceCrosshairP1 = SDL_LoadBMP(P1CrosshairFile.c_str());
+ SDL_Surface* SurfaceCrosshairP2 = SDL_LoadBMP(P2CrosshairFile.c_str());
+ if (SurfaceCrosshairP1 == NULL || SurfaceCrosshairP2 == NULL)
+ return FAIL;
+
+ P1CrosshairW = SurfaceCrosshairP1->w;
+ P1CrosshairH = SurfaceCrosshairP1->h;
+ P2CrosshairW = SurfaceCrosshairP2->w;
+ P2CrosshairH = SurfaceCrosshairP2->h;
+
+ glGenTextures(2, CrosshairtxID);
+
+ glBindTexture(GL_TEXTURE_2D, CrosshairtxID[0]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, P1CrosshairW, P1CrosshairH, 0, GL_BGRA, GL_UNSIGNED_BYTE, SurfaceCrosshairP1->pixels);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glBindTexture(GL_TEXTURE_2D, CrosshairtxID[1]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, P1CrosshairW, P1CrosshairH, 0, GL_BGRA, GL_UNSIGNED_BYTE, SurfaceCrosshairP2->pixels);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ SDL_FreeSurface(SurfaceCrosshairP1);
+ SDL_FreeSurface(SurfaceCrosshairP2);
+
+ // Get DPI
+ SDL_GetDisplayDPI(0, &diagdpi, &hdpi, &vdpi);
+ dpiMultiplicator = hdpi / standardDpi; // note : on linux VM diagdpi returns 0
+
+ // 3d obj
+ UVCoord.emplace_back(0.0f, 0.0f);
+ UVCoord.emplace_back(1.0f, 0.0f);
+ UVCoord.emplace_back(1.0f, 1.0f);
+ UVCoord.emplace_back(0.0f, 0.0f);
+ UVCoord.emplace_back(1.0f, 1.0f);
+ UVCoord.emplace_back(0.0f, 1.0f);
+
+ if (!IsBitmapCrosshair)
+ {
+ verts.emplace_back(0.0f, dist); // bottom triangle
+ verts.emplace_back(base / 2.0f, (dist + height) * a);
+ verts.emplace_back(-base / 2.0f, (dist + height) * a);
+ verts.emplace_back(0.0f, -dist); // top triangle
+ verts.emplace_back(-base / 2.0f, -(dist + height) * a);
+ verts.emplace_back(base / 2.0f, -(dist + height) * a);
+ verts.emplace_back(-dist, 0.0f); // left triangle
+ verts.emplace_back(-dist - height, (base / 2.0f) * a);
+ verts.emplace_back(-dist - height, -(base / 2.0f) * a);
+ verts.emplace_back(dist, 0.0f); // right triangle
+ verts.emplace_back(dist + height, -(base / 2.0f) * a);
+ verts.emplace_back(dist + height, (base / 2.0f) * a);
+ }
+ else
+ {
+ verts.emplace_back(-squareSize / 2.0f, -squareSize / 2.0f * a);
+ verts.emplace_back(squareSize / 2.0f, -squareSize / 2.0f * a);
+ verts.emplace_back(squareSize / 2.0f, squareSize / 2.0f * a);
+ verts.emplace_back(-squareSize / 2.0f, -squareSize / 2.0f * a);
+ verts.emplace_back(squareSize / 2.0f, squareSize / 2.0f * a);
+ verts.emplace_back(-squareSize / 2.0f, squareSize / 2.0f * a);
+ }
+
+ vertexShader = R"glsl(
+
+ #version 410 core
+
+ uniform mat4 mvp;
+ layout(location = 0) in vec3 inVertices;
+ layout(location = 1) in vec2 vertexUV;
+ out vec2 UV;
+
+ void main(void)
+ {
+ gl_Position = mvp * vec4(inVertices,1.0);
+ UV = vertexUV;
+ }
+ )glsl";
+
+ fragmentShader = R"glsl(
+
+ #version 410 core
+
+ uniform vec4 colour;
+ uniform sampler2D CrosshairTexture;
+ uniform bool isBitmap;
+ out vec4 fragColour;
+ in vec2 UV;
+
+ void main(void)
+ {
+ if (!isBitmap)
+ fragColour = colour;
+ else
+ fragColour = colour * texture(CrosshairTexture, UV);
+ }
+ )glsl";
+
+ m_shader.LoadShaders(vertexShader, fragmentShader);
+ m_shader.GetUniformLocationMap("mvp");
+ m_shader.GetUniformLocationMap("CrosshairTexture");
+ m_shader.GetUniformLocationMap("colour");
+ m_shader.GetUniformLocationMap("isBitmap");
+
+ m_vbo.Create(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(BasicVertex) * (MaxVerts));
+ m_vbo.Bind(true);
+ m_textvbo.Create(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(UVCoords) * (int)UVCoord.size());
+ m_textvbo.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);
+
+ m_textvbo.Bind(true);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(UVCoords), 0);
+ m_textvbo.Bind(false);
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glBindVertexArray(0);
+
+ return OKAY;
+}
+
+void CCrosshair::DrawCrosshair(New3D::Mat4 matrix, float x, float y, float r, float g, float b)
+{
+ int count = (int)verts.size();
+ if (count > MaxVerts) {
+ count = MaxVerts; // maybe we could error out somehow
+ }
+
+
+ m_shader.EnableShader();
+
+ matrix.Translate(x, y, 0);
+ matrix.Scale(dpiMultiplicator, dpiMultiplicator, 0);
+
+ // update uniform memory
+ glUniformMatrix4fv(m_shader.uniformLocMap["mvp"], 1, GL_FALSE, matrix);
+ glUniform4f(m_shader.uniformLocMap["colour"], r, g, b, 1.0f);
+ glUniform1i(m_shader.uniformLocMap["isBitmap"], false);
+
+ // update vbo mem
+ m_vbo.Bind(true);
+ m_vbo.BufferSubData(0, count * sizeof(BasicVertex), verts.data());
+
+ glBindVertexArray(m_vao);
+ glDrawArrays(GL_TRIANGLES, 0, count);
+ glBindVertexArray(0);
+
+ m_shader.DisableShader();
+}
+
+void CCrosshair::DrawBitmapCrosshair(New3D::Mat4 matrix, float x, float y, int TextureNum)
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, CrosshairtxID[TextureNum]);
+
+
+ int count = (int)verts.size();
+ if (count > MaxVerts) {
+ count = MaxVerts; // maybe we could error out somehow
+ }
+ m_TextureCoordsCount = (int)UVCoord.size();
+
+ m_shader.EnableShader();
+
+ matrix.Translate(x, y, 0);
+ matrix.Scale(dpiMultiplicator * ScaleBitmap, dpiMultiplicator * ScaleBitmap, 0);
+
+ // update uniform memory
+ glUniformMatrix4fv(m_shader.uniformLocMap["mvp"], 1, GL_FALSE, matrix);
+ glUniform1i(m_shader.uniformLocMap["CrosshairTexture"], 0); // 0 or 1 or GL_TEXTURE0 GL_TEXTURE1
+ glUniform4f(m_shader.uniformLocMap["colour"], 1.0f, 1.0f, 1.0f, 1.0f);
+ glUniform1i(m_shader.uniformLocMap["isBitmap"], true);
+
+ // update vbo mem
+ m_vbo.Bind(true);
+ m_vbo.BufferSubData(0, count * sizeof(BasicVertex), verts.data());
+ m_vbo.Bind(false);
+ m_textvbo.Bind(true);
+ m_textvbo.BufferSubData(0, m_TextureCoordsCount * sizeof(UVCoords), UVCoord.data());
+ m_textvbo.Bind(false);
+
+ glBindVertexArray(m_vao);
+ glDrawArrays(GL_TRIANGLES, 0, count);
+ glBindVertexArray(0);
+
+ m_shader.DisableShader();
+}
+
+CCrosshair::CCrosshair(const Util::Config::Node& config) : m_config(config),xRes(0),yRes(0)
+{
+ vertexShader = nullptr;
+ fragmentShader = nullptr;
+}
+
+CCrosshair::~CCrosshair()
+{
+}
diff --git a/Src/OSD/SDL/Crosshair.h b/Src/OSD/SDL/Crosshair.h
new file mode 100644
index 0000000..e0f105c
--- /dev/null
+++ b/Src/OSD/SDL/Crosshair.h
@@ -0,0 +1,80 @@
+/**
+ ** Supermodel
+ ** A Sega Model 3 Arcade Emulator.
+ ** Copyright 2003-2022 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 .
+ **/
+
+#ifndef INCLUDED_CROSSHAIR_H
+#define INCLUDED_CROSSHAIR_H
+
+#include "Supermodel.h"
+#include "Graphics/New3D/New3D.h"
+
+class CCrosshair
+{
+private:
+ const Util::Config::Node& m_config;
+ bool IsBitmapCrosshair=false;
+ GLuint CrosshairtxID[2] = { 0 };
+ int P1CrosshairW = 0, P1CrosshairH = 0, P2CrosshairW = 0, P2CrosshairH = 0;
+ float diagdpi = 0.0f, hdpi = 0.0f, vdpi = 0.0f;
+ unsigned int xRes=0;
+ unsigned int yRes=0;
+ const float base = 0.01f, height = 0.02f; // geometric parameters of each triangle
+ const float dist = 0.004f; // distance of triangle tip from center
+ float a = 0.0f; // aspect ratio (to square the crosshair)
+ const float squareSize = 1.0f;
+ const float standardDpi = 96.0f; // normal dpi for usual monitor (full hd)
+ float dpiMultiplicator = 0.0f;
+ const float 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 verts;
+ std::vector UVCoord;
+
+ GLSLShader m_shader;
+ VBO m_vbo;
+ VBO m_textvbo;
+ GLuint m_vao = 0;
+ int m_TextureCoordsCount = 0;
+ const char* vertexShader;
+ const char* fragmentShader;
+
+ const int MaxVerts = 1024; // per draw call
+
+public:
+ CCrosshair(const Util::Config::Node& config);
+ ~CCrosshair();
+ bool init();
+ void DrawCrosshair(New3D::Mat4 matrix, float x, float y, float r, float g, float b);
+ void DrawBitmapCrosshair(New3D::Mat4 matrix, float x, float y, int TextureNum);
+};
+
+#endif
diff --git a/Src/OSD/SDL/Main.cpp b/Src/OSD/SDL/Main.cpp
index f87d71c..b601995 100644
--- a/Src/OSD/SDL/Main.cpp
+++ b/Src/OSD/SDL/Main.cpp
@@ -81,6 +81,7 @@
#include
#include "Util/BMPFile.h"
+#include "Crosshair.h"
/******************************************************************************
Global Run-time Config
@@ -105,6 +106,12 @@ static unsigned xOffset, yOffset; // offset of renderer output within Open
static unsigned xRes, yRes; // renderer output resolution (can be smaller than GL viewport)
static unsigned totalXRes, totalYRes; // total resolution (the whole GL viewport)
+/*
+ * Crosshair stuff
+ */
+static bool IsBitmapCrosshair = false;
+CCrosshair* Crosshair = nullptr;
+
static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio)
{
// What resolution did we actually get?
@@ -781,132 +788,12 @@ static void LoadNVRAM(IEmulator *Model3)
Currently, only does crosshairs for light gun games.
******************************************************************************/
-struct BasicDraw
-{
-public:
-
- 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.f) {}
- float x, y, z;
- };
-
- const int MaxVerts = 1024; // per draw call
-
- void Draw(GLenum mode, const float mvpMatrix[16], const BasicVertex* vertices, int count, float r, float g, float b, float a)
- {
- if (count > MaxVerts) {
- count = MaxVerts; // maybe we could error out somehow
- }
-
- if (!m_initialised) {
- Setup();
- }
-
- m_shader.EnableShader();
-
- // update uniform memory
- glUniformMatrix4fv(m_shader.uniformLocMap["mvp"], 1, GL_FALSE, mvpMatrix);
- glUniform4f(m_shader.uniformLocMap["colour"], r, g, b, a);
-
- // update vbo mem
- m_vbo.Bind(true);
- m_vbo.BufferSubData(0, count * sizeof(BasicVertex), vertices);
-
- glBindVertexArray(m_vao);
- glDrawArrays(mode, 0, count);
- glBindVertexArray(0);
-
- m_shader.DisableShader();
- }
-
-private:
-
- void Setup()
- {
- const char* 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";
-
- const char* fragmentShader = R"glsl(
-
- #version 410 core
-
- uniform vec4 colour;
- out vec4 fragColour;
-
- void main(void)
- {
- fragColour = colour;
- }
- )glsl";
-
- m_shader.LoadShaders(vertexShader, fragmentShader);
- m_shader.GetUniformLocationMap("mvp");
- m_shader.GetUniformLocationMap("colour");
-
- glGenVertexArrays(1, &m_vao);
- glBindVertexArray(m_vao);
-
- m_vbo.Create(GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, sizeof(BasicVertex) * (MaxVerts));
- m_vbo.Bind(true);
-
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(BasicVertex), 0);
-
- glBindVertexArray(0);
- m_vbo.Bind(false);
-
- m_initialised = true;
- }
-
- GLSLShader m_shader;
- VBO m_vbo;
- GLuint m_vao = 0;
- bool m_initialised = false;
-
-} basicDraw;
-
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 DrawCrosshair(const float* matrix, float x, float y, float r, float g, float b)
-{
- float base = 0.01f, height = 0.02f; // geometric parameters of each triangle
- float dist = 0.004f; // distance of triangle tip from center
- float a = (float)xRes/(float)yRes; // aspect ratio (to square the crosshair)
-
- std::vector verts;
-
- verts.emplace_back(x, y+dist); // bottom triangle
- verts.emplace_back(x+base/2.0f, y+(dist+height)*a);
- verts.emplace_back(x-base/2.0f, y+(dist+height)*a);
- verts.emplace_back(x, y-dist); // top triangle
- verts.emplace_back(x-base/2.0f, y-(dist+height)*a);
- verts.emplace_back(x+base/2.0f, y-(dist+height)*a);
- verts.emplace_back(x-dist, y); // left triangle
- verts.emplace_back(x-dist-height, y+(base/2.0f)*a);
- verts.emplace_back(x-dist-height, y-(base/2.0f)*a);
- verts.emplace_back(x+dist, y); // right triangle
- verts.emplace_back(x+dist+height, y-(base/2.0f)*a);
- verts.emplace_back(x+dist+height, y+(base/2.0f)*a);
-
- basicDraw.Draw(GL_TRIANGLES, matrix, verts.data(), (int)verts.size(), r, g, b, 1.0f);
-}
-
/*
static void PrintGLError(GLenum error)
{
@@ -937,8 +824,18 @@ static void UpdateCrosshairs(uint32_t currentInputs, CInputs *Inputs, unsigned c
// Set up the viewport and orthogonal projection
glUseProgram(0); // no shaders
glViewport(xOffset, yOffset, xRes, yRes);
- glDisable(GL_BLEND); // no blending
glDisable(GL_DEPTH_TEST); // no Z-buffering needed
+
+ if (!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);
@@ -970,11 +867,30 @@ static void UpdateCrosshairs(uint32_t currentInputs, CInputs *Inputs, unsigned c
GunToViewCoords(&x[1], &y[1]);
offscreenTrigger[1] = (Inputs->trigger[1]->offscreenValue) > 0;
}
+
// Draw visible crosshairs
- if ((crosshairs & 1) && !offscreenTrigger[0]) // Player 1
- DrawCrosshair(m,x[0], y[0], 1.0f, 0.0f, 0.0f);
- if ((crosshairs & 2) && !offscreenTrigger[1]) // Player 2
- DrawCrosshair(m,x[1], y[1], 0.0f, 1.0f, 0.0f);
+ if (!IsBitmapCrosshair)
+ {
+ if ((crosshairs & 1) && !offscreenTrigger[0]) // Player 1
+ {
+ Crosshair->DrawCrosshair(m, x[0], y[0], 1.0f, 0.0f, 0.0f);
+ }
+ if ((crosshairs & 2) && !offscreenTrigger[1]) // Player 2
+ {
+ Crosshair->DrawCrosshair(m, x[1], y[1], 0.0f, 1.0f, 0.0f);
+ }
+ }
+ else
+ {
+ if ((crosshairs & 1) && !offscreenTrigger[0]) // Player 1
+ {
+ Crosshair->DrawBitmapCrosshair(m, x[0], y[0], 0);
+ }
+ if ((crosshairs & 2) && !offscreenTrigger[1]) // Player 2
+ {
+ Crosshair->DrawBitmapCrosshair(m, x[1], y[1], 1);
+ }
+ }
//PrintGLError(glGetError());
}
@@ -1650,6 +1566,7 @@ static Util::Config::Node DefaultConfig()
config.Set("RefreshRate", 60.0f);
config.Set("ShowFrameRate", false);
config.Set("Crosshairs", int(0));
+ config.Set("BitmapCrosshair", false);
config.Set("FlipStereo", false);
#ifdef SUPERMODEL_WIN32
config.Set("InputSystem", "dinput");
@@ -1735,6 +1652,8 @@ static void Help(void)
puts(" -show-fps Display frame rate in window title bar");
puts(" -crosshairs= Crosshairs configuration for gun games:");
puts(" 0=none [Default], 1=P1 only, 2=P2 only, 3=P1 & P2");
+ puts(" -vectorcrosshair Use built-in crosshair [Default]");
+ puts(" -bitmapcrosshair Use image (.bmp) as crosshair (only for lost world)");
puts(" -new3d New 3D engine by Ian Curtis [Default]");
puts(" -quad-rendering Enable proper quad rendering");
puts(" -legacy3d Legacy 3D engine (faster but less accurate)");
@@ -1870,6 +1789,8 @@ static ParsedCommandLine ParseCommandLine(int argc, char **argv)
{ "-no-dsb", { "EmulateDSB", false } },
{ "-legacy-scsp", { "LegacySoundDSP", true } },
{ "-new-scsp", { "LegacySoundDSP", false } },
+ { "-bitmapcrosshair", { "BitmapCrosshair", true } },
+ { "-vectorcrosshair", { "BitmapCrosshair", false } },
#ifdef NET_BOARD
{ "-net", { "Network", true } },
{ "-no-net", { "Network", false } },
@@ -2131,6 +2052,17 @@ int main(int argc, char **argv)
goto Exit;
}
+ IsBitmapCrosshair = s_runtime_config["BitmapCrosshair"].ValueAs();
+
+ // Create Bitmap Crosshair
+ Crosshair = new CCrosshair(s_runtime_config);
+ if (Crosshair->init() != OKAY)
+ {
+ ErrorLog("Unable to load bitmap crosshair texture\n");
+ exitCode = 1;
+ goto Exit;
+ }
+
// Create Model 3 emulator
#ifdef DEBUG
Model3 = s_gfxStatePath.empty() ? static_cast(new CModel3(s_runtime_config)) : static_cast(new CModel3GraphicsState(s_runtime_config, s_gfxStatePath));
@@ -2232,6 +2164,8 @@ Exit:
delete InputSystem;
if (Outputs != NULL)
delete Outputs;
+ if (Crosshair != NULL)
+ delete Crosshair;
DestroyGLScreen();
SDL_Quit();
diff --git a/Src/OSD/Unix/FileSystemPath.cpp b/Src/OSD/Unix/FileSystemPath.cpp
index 4ab5916..be0f80f 100644
--- a/Src/OSD/Unix/FileSystemPath.cpp
+++ b/Src/OSD/Unix/FileSystemPath.cpp
@@ -73,6 +73,9 @@ namespace FileSystemPath
case Screenshots:
strPathType = "Screenshots";
break;
+ case Media:
+ strPathType = "Media/";
+ break;
}
// Get user's HOME directory
diff --git a/Src/OSD/Windows/FileSystemPath.cpp b/Src/OSD/Windows/FileSystemPath.cpp
index b0ca737..84e426a 100644
--- a/Src/OSD/Windows/FileSystemPath.cpp
+++ b/Src/OSD/Windows/FileSystemPath.cpp
@@ -41,6 +41,8 @@ namespace FileSystemPath
return "Saves/";
case Screenshots:
return "";
+ case Media:
+ return "Media/";
}
return "";
diff --git a/VS2008/Supermodel.vcxproj b/VS2008/Supermodel.vcxproj
index 068dd15..b75389e 100644
--- a/VS2008/Supermodel.vcxproj
+++ b/VS2008/Supermodel.vcxproj
@@ -114,8 +114,10 @@
if not exist "$(TargetDir)Config" mkdir "$(TargetDir)Config"
if not exist "$(TargetDir)NVRAM" mkdir "$(TargetDir)NVRAM"
if not exist "$(TargetDir)Saves" mkdir "$(TargetDir)Saves"
+if not exist "$(TargetDir)Media" mkdir "$(TargetDir)Media"
xcopy /D /Y "$(ProjectDir)..\Docs\*" "$(TargetDir)"
-xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Media\*" "$(TargetDir)Media"
@@ -145,8 +147,10 @@ xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
if not exist "$(TargetDir)Config" mkdir "$(TargetDir)Config"
if not exist "$(TargetDir)NVRAM" mkdir "$(TargetDir)NVRAM"
if not exist "$(TargetDir)Saves" mkdir "$(TargetDir)Saves"
+if not exist "$(TargetDir)Media" mkdir "$(TargetDir)Media"
xcopy /D /Y "$(ProjectDir)..\Docs\*" "$(TargetDir)"
-xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Media\*" "$(TargetDir)Media"
@@ -175,8 +179,10 @@ xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
if not exist "$(TargetDir)Config" mkdir "$(TargetDir)Config"
if not exist "$(TargetDir)NVRAM" mkdir "$(TargetDir)NVRAM"
if not exist "$(TargetDir)Saves" mkdir "$(TargetDir)Saves"
+if not exist "$(TargetDir)Media" mkdir "$(TargetDir)Media"
xcopy /D /Y "$(ProjectDir)..\Docs\*" "$(TargetDir)"
-xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Media\*" "$(TargetDir)Media"
@@ -209,8 +215,10 @@ xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
if not exist "$(TargetDir)Config" mkdir "$(TargetDir)Config"
if not exist "$(TargetDir)NVRAM" mkdir "$(TargetDir)NVRAM"
if not exist "$(TargetDir)Saves" mkdir "$(TargetDir)Saves"
+if not exist "$(TargetDir)Media" mkdir "$(TargetDir)Media"
xcopy /D /Y "$(ProjectDir)..\Docs\*" "$(TargetDir)"
-xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+xcopy /D /Y "$(ProjectDir)..\Media\*" "$(TargetDir)Media"
@@ -347,6 +355,7 @@ xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+
@@ -523,6 +532,7 @@ xcopy /D /Y "$(ProjectDir)..\Config\*" "$(TargetDir)Config"
+
diff --git a/VS2008/Supermodel.vcxproj.filters b/VS2008/Supermodel.vcxproj.filters
index e040fae..e554f3d 100644
--- a/VS2008/Supermodel.vcxproj.filters
+++ b/VS2008/Supermodel.vcxproj.filters
@@ -464,6 +464,9 @@
Source Files\Network
+
+ Source Files\OSD\SDL
+
@@ -841,6 +844,9 @@
Header Files\Util
+
+ Header Files\OSD\SDL
+