libretro: vmu and crosshair display. lightgun fixes
This commit is contained in:
parent
80a5b44fe9
commit
5c952021b7
|
@ -19,6 +19,7 @@
|
|||
#include "dxcontext.h"
|
||||
#include "d3d_renderer.h"
|
||||
#include "rend/gui.h"
|
||||
#include "rend/osd.h"
|
||||
#ifdef USE_SDL
|
||||
#include "sdl/sdl.h"
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "gl4.h"
|
||||
#include "rend/gles/glcache.h"
|
||||
#include "rend/tileclip.h"
|
||||
#include "rend/osd.h"
|
||||
|
||||
static gl4PipelineShader* CurrentShader;
|
||||
extern u32 gcflip;
|
||||
|
@ -680,3 +681,157 @@ void gl4DrawStrips(GLuint output_fbo, int width, int height)
|
|||
glBindTexture(GL_TEXTURE_2D, opaqueTexId);
|
||||
renderABuffer();
|
||||
}
|
||||
|
||||
#ifdef LIBRETRO
|
||||
#include "vmu_xhair.h"
|
||||
|
||||
extern GLuint vmuTextureId[4];
|
||||
extern GLuint lightgunTextureId[4];
|
||||
|
||||
void UpdateVmuTexture(int vmu_screen_number);
|
||||
void UpdateLightGunTexture(int port);
|
||||
|
||||
void gl4DrawVmuTexture(u8 vmu_screen_number)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
const float vmu_padding = 8.f;
|
||||
float x = (config::Widescreen && config::ScreenStretching == 100 ? -(640.f * 4.f / 3.f - 640.f) / 2 : 0) + vmu_padding;
|
||||
float y = vmu_padding;
|
||||
float w = VMU_SCREEN_WIDTH * vmu_screen_params[vmu_screen_number].vmu_screen_size_mult;
|
||||
float h = VMU_SCREEN_HEIGHT * vmu_screen_params[vmu_screen_number].vmu_screen_size_mult;
|
||||
|
||||
if (vmu_lcd_changed[vmu_screen_number * 2] || vmuTextureId[vmu_screen_number] == 0)
|
||||
UpdateVmuTexture(vmu_screen_number);
|
||||
|
||||
switch (vmu_screen_params[vmu_screen_number].vmu_screen_position)
|
||||
{
|
||||
case UPPER_LEFT:
|
||||
break;
|
||||
case UPPER_RIGHT:
|
||||
x = 640 - x - w;
|
||||
break;
|
||||
case LOWER_LEFT:
|
||||
y = 480 - y - h;
|
||||
break;
|
||||
case LOWER_RIGHT:
|
||||
x = 640 - x - w;
|
||||
y = 480 - y - h;
|
||||
break;
|
||||
}
|
||||
|
||||
glcache.BindTexture(GL_TEXTURE_2D, vmuTextureId[vmu_screen_number]);
|
||||
|
||||
glcache.Disable(GL_SCISSOR_TEST);
|
||||
glcache.Disable(GL_DEPTH_TEST);
|
||||
glcache.Disable(GL_STENCIL_TEST);
|
||||
glcache.Disable(GL_CULL_FACE);
|
||||
glcache.Enable(GL_BLEND);
|
||||
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl4SetupMainVBO();
|
||||
|
||||
gl4ShaderUniforms.trilinear_alpha = 1.0;
|
||||
|
||||
CurrentShader = gl4GetProgram(false,
|
||||
0,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
false,
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
Pass::Color);
|
||||
glcache.UseProgram(CurrentShader->program);
|
||||
gl4ShaderUniforms.Set(CurrentShader);
|
||||
|
||||
{
|
||||
struct Vertex vertices[] = {
|
||||
{ x, y+h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0 },
|
||||
{ x, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1 },
|
||||
{ x+w, y+h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0 },
|
||||
{ x+w, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1 },
|
||||
};
|
||||
GLushort indices[] = { 0, 1, 2, 1, 3 };
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gl4.vbo.geometry);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl4.vbo.idxs);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, (void *)0);
|
||||
}
|
||||
|
||||
void gl4DrawGunCrosshair(u8 port)
|
||||
{
|
||||
if ( lightgun_params[port].offscreen || (lightgun_params[port].colour==0) )
|
||||
return;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
float x=0;
|
||||
float y=0;
|
||||
float w=LIGHTGUN_CROSSHAIR_SIZE;
|
||||
float h=LIGHTGUN_CROSSHAIR_SIZE;
|
||||
|
||||
x = lightgun_params[port].x - ( LIGHTGUN_CROSSHAIR_SIZE / 2 );
|
||||
y = lightgun_params[port].y - ( LIGHTGUN_CROSSHAIR_SIZE / 2 );
|
||||
|
||||
if (lightgun_params[port].dirty || lightgunTextureId[port] == 0)
|
||||
UpdateLightGunTexture(port);
|
||||
|
||||
glcache.BindTexture(GL_TEXTURE_2D, lightgunTextureId[port]);
|
||||
|
||||
glcache.Disable(GL_SCISSOR_TEST);
|
||||
glcache.Disable(GL_DEPTH_TEST);
|
||||
glcache.Disable(GL_STENCIL_TEST);
|
||||
glcache.Disable(GL_CULL_FACE);
|
||||
glcache.Enable(GL_BLEND);
|
||||
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
gl4SetupMainVBO();
|
||||
|
||||
gl4ShaderUniforms.trilinear_alpha = 1.0;
|
||||
CurrentShader = gl4GetProgram(false,
|
||||
0,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
false,
|
||||
2,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
Pass::Color);
|
||||
glcache.UseProgram(CurrentShader->program);
|
||||
gl4ShaderUniforms.Set(CurrentShader);
|
||||
|
||||
{
|
||||
struct Vertex vertices[] = {
|
||||
{ x, y+h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 1 },
|
||||
{ x, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 0, 0 },
|
||||
{ x+w, y+h, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 1 },
|
||||
{ x+w, y, 1, { 255, 255, 255, 255 }, { 0, 0, 0, 0 }, 1, 0 },
|
||||
};
|
||||
GLushort indices[] = { 0, 1, 2, 1, 3 };
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gl4.vbo.geometry);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl4.vbo.idxs);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
glDrawElements(GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, (void *)0);
|
||||
|
||||
glcache.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "gl4.h"
|
||||
#include "rend/gles/glcache.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
#include "rend/osd.h"
|
||||
|
||||
//Fragment and vertex shaders code
|
||||
|
||||
|
@ -916,6 +917,24 @@ struct OpenGL4Renderer : OpenGLRenderer
|
|||
{
|
||||
return render_output_framebuffer();
|
||||
}
|
||||
|
||||
#ifdef LIBRETRO
|
||||
void DrawOSD(bool clearScreen) override
|
||||
{
|
||||
void gl4DrawVmuTexture(u8 vmu_screen_number);
|
||||
void gl4DrawGunCrosshair(u8 port);
|
||||
|
||||
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
||||
{
|
||||
for (int vmu_screen_number = 0 ; vmu_screen_number < 4 ; vmu_screen_number++)
|
||||
if (vmu_lcd_status[vmu_screen_number * 2])
|
||||
gl4DrawVmuTexture(vmu_screen_number);
|
||||
}
|
||||
|
||||
for (int lightgun_port = 0 ; lightgun_port < 4 ; lightgun_port++)
|
||||
gl4DrawGunCrosshair(lightgun_port);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
Renderer* rend_GL4()
|
||||
|
|
|
@ -749,18 +749,6 @@ GLuint lightgunTextureId[4]={0,0,0,0};
|
|||
|
||||
void UpdateVmuTexture(int vmu_screen_number)
|
||||
{
|
||||
// s32 x,y ;
|
||||
// u8 temp_tex_buffer[VMU_SCREEN_HEIGHT*VMU_SCREEN_WIDTH*4];
|
||||
// u8 *dst = temp_tex_buffer;
|
||||
// u8 *src = NULL ;
|
||||
// u8 vmu_pixel_on_R = vmu_screen_params[vmu_screen_number].vmu_pixel_on_R ;
|
||||
// u8 vmu_pixel_on_G = vmu_screen_params[vmu_screen_number].vmu_pixel_on_G ;
|
||||
// u8 vmu_pixel_on_B = vmu_screen_params[vmu_screen_number].vmu_pixel_on_B ;
|
||||
// u8 vmu_pixel_off_R = vmu_screen_params[vmu_screen_number].vmu_pixel_off_R ;
|
||||
// u8 vmu_pixel_off_G = vmu_screen_params[vmu_screen_number].vmu_pixel_off_G ;
|
||||
// u8 vmu_pixel_off_B = vmu_screen_params[vmu_screen_number].vmu_pixel_off_B ;
|
||||
// u8 vmu_screen_opacity = vmu_screen_params[vmu_screen_number].vmu_screen_opacity ;
|
||||
|
||||
if (vmuTextureId[vmu_screen_number] == 0)
|
||||
{
|
||||
vmuTextureId[vmu_screen_number] = glcache.GenTexture();
|
||||
|
@ -772,79 +760,39 @@ void UpdateVmuTexture(int vmu_screen_number)
|
|||
glcache.BindTexture(GL_TEXTURE_2D, vmuTextureId[vmu_screen_number]);
|
||||
|
||||
|
||||
u8 *origsrc = (u8 *)vmu_lcd_data[vmu_screen_number];
|
||||
|
||||
if ( origsrc == NULL )
|
||||
return ;
|
||||
/* TODO
|
||||
|
||||
for ( y = VMU_SCREEN_HEIGHT-1 ; y >= 0 ; y--)
|
||||
{
|
||||
src = origsrc + (y*VMU_SCREEN_WIDTH) ;
|
||||
|
||||
for ( x = 0 ; x < VMU_SCREEN_WIDTH ; x++)
|
||||
{
|
||||
if ( *src++ > 0 )
|
||||
{
|
||||
*dst++ = vmu_pixel_on_R ;
|
||||
*dst++ = vmu_pixel_on_G ;
|
||||
*dst++ = vmu_pixel_on_B ;
|
||||
*dst++ = vmu_screen_opacity ;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dst++ = vmu_pixel_off_R ;
|
||||
*dst++ = vmu_pixel_off_G ;
|
||||
*dst++ = vmu_pixel_off_B ;
|
||||
*dst++ = vmu_screen_opacity ;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VMU_SCREEN_WIDTH, VMU_SCREEN_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, origsrc);
|
||||
|
||||
vmu_lcd_changed[vmu_screen_number] = false;
|
||||
const u32 *data = vmu_lcd_data[vmu_screen_number * 2];
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VMU_SCREEN_WIDTH, VMU_SCREEN_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
vmu_lcd_changed[vmu_screen_number * 2] = false;
|
||||
}
|
||||
|
||||
void DrawVmuTexture(u8 vmu_screen_number)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
float x=0 ;
|
||||
float y=0 ;
|
||||
float w=VMU_SCREEN_WIDTH*vmu_screen_params[vmu_screen_number].vmu_screen_size_mult ;
|
||||
float h=VMU_SCREEN_HEIGHT*vmu_screen_params[vmu_screen_number].vmu_screen_size_mult ;
|
||||
const float vmu_padding = 8.f;
|
||||
float x = (config::Widescreen && config::ScreenStretching == 100 ? -(640.f * 4.f / 3.f - 640.f) / 2 : 0) + vmu_padding;
|
||||
float y = vmu_padding;
|
||||
float w = VMU_SCREEN_WIDTH * vmu_screen_params[vmu_screen_number].vmu_screen_size_mult;
|
||||
float h = VMU_SCREEN_HEIGHT * vmu_screen_params[vmu_screen_number].vmu_screen_size_mult;
|
||||
|
||||
if (vmu_lcd_changed[vmu_screen_number] || vmuTextureId[vmu_screen_number] == 0)
|
||||
UpdateVmuTexture(vmu_screen_number) ;
|
||||
if (vmu_lcd_changed[vmu_screen_number * 2] || vmuTextureId[vmu_screen_number] == 0)
|
||||
UpdateVmuTexture(vmu_screen_number);
|
||||
|
||||
switch ( vmu_screen_params[vmu_screen_number].vmu_screen_position )
|
||||
switch (vmu_screen_params[vmu_screen_number].vmu_screen_position)
|
||||
{
|
||||
case UPPER_LEFT :
|
||||
{
|
||||
x = 0 ;
|
||||
y = 0 ;
|
||||
break ;
|
||||
}
|
||||
case UPPER_RIGHT :
|
||||
{
|
||||
x = 640-w ;
|
||||
y = 0 ;
|
||||
break ;
|
||||
}
|
||||
case LOWER_LEFT :
|
||||
{
|
||||
x = 0 ;
|
||||
y = 480-h ;
|
||||
break ;
|
||||
}
|
||||
case LOWER_RIGHT :
|
||||
{
|
||||
x = 640-w ;
|
||||
y = 480-h ;
|
||||
break ;
|
||||
}
|
||||
case UPPER_LEFT:
|
||||
break;
|
||||
case UPPER_RIGHT:
|
||||
x = 640 - x - w;
|
||||
break;
|
||||
case LOWER_LEFT:
|
||||
y = 480 - y - h;
|
||||
break;
|
||||
case LOWER_RIGHT:
|
||||
x = 640 - x - w;
|
||||
y = 480 - y - h;
|
||||
break;
|
||||
}
|
||||
|
||||
glcache.BindTexture(GL_TEXTURE_2D, vmuTextureId[vmu_screen_number]);
|
||||
|
@ -930,15 +878,15 @@ void DrawGunCrosshair(u8 port)
|
|||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
float x=0;
|
||||
float y=0;
|
||||
float w=LIGHTGUN_CROSSHAIR_SIZE;
|
||||
float h=LIGHTGUN_CROSSHAIR_SIZE;
|
||||
float x = lightgun_params[port].x;
|
||||
float y = lightgun_params[port].y;
|
||||
|
||||
x = lightgun_params[port].x - ( LIGHTGUN_CROSSHAIR_SIZE / 2 );
|
||||
y = lightgun_params[port].y - ( LIGHTGUN_CROSSHAIR_SIZE / 2 );
|
||||
float w = LIGHTGUN_CROSSHAIR_SIZE;
|
||||
float h = LIGHTGUN_CROSSHAIR_SIZE;
|
||||
x -= w / 2;
|
||||
y -= h / 2;
|
||||
|
||||
if ( lightgun_params[port].dirty || lightgunTextureId[port] == 0)
|
||||
if (lightgun_params[port].dirty || lightgunTextureId[port] == 0)
|
||||
UpdateLightGunTexture(port);
|
||||
|
||||
glcache.BindTexture(GL_TEXTURE_2D, lightgunTextureId[port]);
|
||||
|
|
|
@ -948,12 +948,12 @@ void OSD_DRAW(bool clear_screen)
|
|||
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
||||
{
|
||||
for (int vmu_screen_number = 0 ; vmu_screen_number < 4 ; vmu_screen_number++)
|
||||
if (vmu_lcd_status[vmu_screen_number])
|
||||
if (vmu_lcd_status[vmu_screen_number * 2])
|
||||
DrawVmuTexture(vmu_screen_number);
|
||||
}
|
||||
|
||||
// for (int lightgun_port = 0 ; lightgun_port < 4 ; lightgun_port++)
|
||||
// DrawGunCrosshair(lightgun_port);
|
||||
for (int lightgun_port = 0 ; lightgun_port < 4 ; lightgun_port++)
|
||||
DrawGunCrosshair(lightgun_port);
|
||||
|
||||
#else
|
||||
gui_display_osd();
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#include "input/gamepad_device.h"
|
||||
#include "TexCache.h"
|
||||
#include "hw/maple/maple_devs.h"
|
||||
#ifdef LIBRETRO
|
||||
#include "vmu_xhair.h"
|
||||
#endif
|
||||
|
||||
#include <stb_image.h>
|
||||
|
||||
|
@ -179,7 +182,14 @@ void push_vmu_screen(int bus_id, int bus_port, u8* buffer)
|
|||
return;
|
||||
u32 *p = &vmu_lcd_data[vmu_id][0];
|
||||
for (int i = 0; i < (int)ARRAY_SIZE(vmu_lcd_data[vmu_id]); i++, buffer++)
|
||||
#ifdef LIBRETRO
|
||||
*p++ = (*buffer != 0
|
||||
? vmu_screen_params[bus_id].vmu_pixel_on_R | (vmu_screen_params[bus_id].vmu_pixel_on_G << 8) | (vmu_screen_params[bus_id].vmu_pixel_on_B << 16)
|
||||
: vmu_screen_params[bus_id].vmu_pixel_off_R | (vmu_screen_params[bus_id].vmu_pixel_off_G << 8) | (vmu_screen_params[bus_id].vmu_pixel_off_B << 16))
|
||||
| (vmu_screen_params[bus_id].vmu_screen_opacity << 24);
|
||||
#else
|
||||
*p++ = *buffer != 0 ? 0xFFFFFFFFu : 0xFF000000u;
|
||||
#endif
|
||||
#ifndef LIBRETRO
|
||||
vmu_lcd_status[vmu_id] = true;
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include "overlay.h"
|
||||
#include "cfg/option.h"
|
||||
#include "rend/osd.h"
|
||||
#ifdef LIBRETRO
|
||||
#include "vmu_xhair.h"
|
||||
#endif
|
||||
|
||||
VulkanOverlay::~VulkanOverlay() = default;
|
||||
|
||||
|
@ -93,38 +96,70 @@ void VulkanOverlay::Draw(vk::CommandBuffer commandBuffer, vk::Extent2D viewport,
|
|||
if (vmu)
|
||||
{
|
||||
f32 vmu_padding = 8.f * scaling;
|
||||
f32 vmu_height = 70.f * scaling;
|
||||
f32 vmu_width = 48.f / 32.f * vmu_height;
|
||||
f32 vmu_height = 32.f * scaling;
|
||||
f32 vmu_width = 48.f * scaling;
|
||||
|
||||
pipeline->BindPipeline(commandBuffer);
|
||||
#ifndef LIBRETRO
|
||||
vmu_height *= 2.f;
|
||||
vmu_width *= 2.f;
|
||||
float blendConstants[4] = { 0.75f, 0.75f, 0.75f, 0.75f };
|
||||
commandBuffer.setBlendConstants(blendConstants);
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < vmuTextures.size(); i++)
|
||||
{
|
||||
if (!vmuTextures[i])
|
||||
continue;
|
||||
f32 x;
|
||||
float x;
|
||||
float y;
|
||||
float w = vmu_width;
|
||||
float h = vmu_height;
|
||||
#ifdef LIBRETRO
|
||||
if (i & 1)
|
||||
continue;
|
||||
w *= vmu_screen_params[i / 2].vmu_screen_size_mult;
|
||||
h *= vmu_screen_params[i / 2].vmu_screen_size_mult;
|
||||
switch (vmu_screen_params[i / 2].vmu_screen_position)
|
||||
{
|
||||
case UPPER_LEFT:
|
||||
x = vmu_padding;
|
||||
y = vmu_padding;
|
||||
break;
|
||||
case UPPER_RIGHT:
|
||||
x = viewport.width - vmu_padding - w;
|
||||
y = vmu_padding;
|
||||
break;
|
||||
case LOWER_LEFT:
|
||||
x = vmu_padding;
|
||||
y = viewport.height - vmu_padding - h;
|
||||
break;
|
||||
case LOWER_RIGHT:
|
||||
x = viewport.width - vmu_padding - w;
|
||||
y = viewport.height - vmu_padding - h;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (i & 2)
|
||||
x = viewport.width - vmu_padding - vmu_width;
|
||||
x = viewport.width - vmu_padding - w;
|
||||
else
|
||||
x = vmu_padding;
|
||||
f32 y;
|
||||
if (i & 4)
|
||||
{
|
||||
y = viewport.height - vmu_padding - vmu_height;
|
||||
y = viewport.height - vmu_padding - h;
|
||||
if (i & 1)
|
||||
y -= vmu_padding + vmu_height;
|
||||
y -= vmu_padding + h;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = vmu_padding;
|
||||
if (i & 1)
|
||||
y += vmu_padding + vmu_height;
|
||||
y += vmu_padding + h;
|
||||
}
|
||||
vk::Viewport viewport(x, y, vmu_width, vmu_height);
|
||||
#endif
|
||||
vk::Viewport viewport(x, y, w, h);
|
||||
commandBuffer.setViewport(0, 1, &viewport);
|
||||
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(x, y), vk::Extent2D(vmu_width, vmu_height)));
|
||||
commandBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(x, y), vk::Extent2D(w, h)));
|
||||
|
||||
drawers[i]->Draw(commandBuffer, vmuTextures[i]->GetImageView(), vtx, true);
|
||||
}
|
||||
|
@ -141,8 +176,14 @@ void VulkanOverlay::Draw(vk::CommandBuffer commandBuffer, vk::Extent2D viewport,
|
|||
|
||||
float x, y;
|
||||
std::tie(x, y) = getCrosshairPosition(i);
|
||||
|
||||
#ifdef LIBRETRO
|
||||
float w = LIGHTGUN_CROSSHAIR_SIZE * scaling;
|
||||
float h = LIGHTGUN_CROSSHAIR_SIZE * scaling;
|
||||
#else
|
||||
float w = XHAIR_WIDTH * scaling;
|
||||
float h = XHAIR_HEIGHT * scaling;
|
||||
#endif
|
||||
x -= w / 2;
|
||||
y -= h / 2;
|
||||
vk::Viewport viewport(x, y, w, h);
|
||||
|
|
|
@ -66,7 +66,7 @@ protected:
|
|||
}
|
||||
#endif
|
||||
#ifdef LIBRETRO
|
||||
quadPipeline = std::unique_ptr<QuadPipeline>(new QuadPipeline());
|
||||
quadPipeline = std::unique_ptr<QuadPipeline>(new QuadPipeline(true));
|
||||
quadPipeline->Init(&shaderManager, renderPass);
|
||||
overlay = std::unique_ptr<VulkanOverlay>(new VulkanOverlay());
|
||||
overlay->Init(quadPipeline.get());
|
||||
|
|
|
@ -147,6 +147,8 @@ unsigned per_content_vmus = 0;
|
|||
static bool first_run = true;
|
||||
static bool mute_messages;
|
||||
static bool rotate_screen;
|
||||
static int framebufferWidth;
|
||||
static int framebufferHeight;
|
||||
|
||||
static retro_perf_callback perf_cb;
|
||||
static retro_get_cpu_features_t perf_get_cpu_features_cb;
|
||||
|
@ -638,27 +640,31 @@ static void update_variables(bool first_startup)
|
|||
else if (!strcmp("Blue", var.value))
|
||||
lightgun_params[i].colour = LIGHTGUN_COLOR_BLUE;
|
||||
}
|
||||
config::CrosshairColor[i] = lightgun_palette[lightgun_params[i].colour * 3]
|
||||
| (lightgun_palette[lightgun_params[i].colour * 3 + 1] << 8)
|
||||
| (lightgun_palette[lightgun_params[i].colour * 3 + 2] << 16)
|
||||
| 0xff000000;
|
||||
|
||||
vmu_lcd_status[i] = false;
|
||||
vmu_lcd_changed[i] = true;
|
||||
vmu_screen_params[i].vmu_screen_position = UPPER_LEFT ;
|
||||
vmu_screen_params[i].vmu_screen_size_mult = 1 ;
|
||||
vmu_screen_params[i].vmu_pixel_on_R = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_ON].r ;
|
||||
vmu_screen_params[i].vmu_pixel_on_G = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_ON].g ;
|
||||
vmu_screen_params[i].vmu_pixel_on_B = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_ON].b ;
|
||||
vmu_screen_params[i].vmu_pixel_off_R = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_OFF].r ;
|
||||
vmu_screen_params[i].vmu_pixel_off_G = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_OFF].g ;
|
||||
vmu_screen_params[i].vmu_pixel_off_B = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_OFF].b ;
|
||||
vmu_screen_params[i].vmu_screen_opacity = 0xFF ;
|
||||
vmu_screen_params[i].vmu_screen_position = UPPER_LEFT;
|
||||
vmu_screen_params[i].vmu_screen_size_mult = 1;
|
||||
vmu_screen_params[i].vmu_pixel_on_R = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_ON].r;
|
||||
vmu_screen_params[i].vmu_pixel_on_G = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_ON].g;
|
||||
vmu_screen_params[i].vmu_pixel_on_B = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_ON].b;
|
||||
vmu_screen_params[i].vmu_pixel_off_R = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_OFF].r;
|
||||
vmu_screen_params[i].vmu_pixel_off_G = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_OFF].g;
|
||||
vmu_screen_params[i].vmu_pixel_off_B = VMU_SCREEN_COLOR_MAP[VMU_DEFAULT_OFF].b;
|
||||
vmu_screen_params[i].vmu_screen_opacity = 0xFF;
|
||||
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_display", i+1) ;
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_display", i+1);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && !strcmp("enabled", var.value) )
|
||||
vmu_lcd_status[i] = true;
|
||||
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_position", i+1) ;
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_position", i+1);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value )
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (!strcmp("Upper Left", var.value))
|
||||
vmu_screen_params[i].vmu_screen_position = UPPER_LEFT;
|
||||
|
@ -670,9 +676,9 @@ static void update_variables(bool first_startup)
|
|||
vmu_screen_params[i].vmu_screen_position = LOWER_RIGHT;
|
||||
}
|
||||
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_size_mult", i+1) ;
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_size_mult", i+1);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value )
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (!strcmp("1x", var.value))
|
||||
vmu_screen_params[i].vmu_screen_size_mult = 1;
|
||||
|
@ -686,9 +692,9 @@ static void update_variables(bool first_startup)
|
|||
vmu_screen_params[i].vmu_screen_size_mult = 5;
|
||||
}
|
||||
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_opacity", i+1) ;
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_screen_opacity", i + 1);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value )
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
|
||||
{
|
||||
if (!strcmp("100%", var.value))
|
||||
vmu_screen_params[i].vmu_screen_opacity = 255;
|
||||
|
@ -712,24 +718,24 @@ static void update_variables(bool first_startup)
|
|||
vmu_screen_params[i].vmu_screen_opacity = 1*25.5;
|
||||
}
|
||||
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_pixel_on_color", i+1) ;
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_pixel_on_color", i + 1);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && strlen(var.value)>1 )
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && strlen(var.value)>1)
|
||||
{
|
||||
int color_idx = atoi(var.value+(strlen(var.value)-2)) ;
|
||||
vmu_screen_params[i].vmu_pixel_on_R = VMU_SCREEN_COLOR_MAP[color_idx].r ;
|
||||
vmu_screen_params[i].vmu_pixel_on_G = VMU_SCREEN_COLOR_MAP[color_idx].g ;
|
||||
vmu_screen_params[i].vmu_pixel_on_B = VMU_SCREEN_COLOR_MAP[color_idx].b ;
|
||||
int color_idx = atoi(var.value+(strlen(var.value)-2));
|
||||
vmu_screen_params[i].vmu_pixel_on_R = VMU_SCREEN_COLOR_MAP[color_idx].r;
|
||||
vmu_screen_params[i].vmu_pixel_on_G = VMU_SCREEN_COLOR_MAP[color_idx].g;
|
||||
vmu_screen_params[i].vmu_pixel_on_B = VMU_SCREEN_COLOR_MAP[color_idx].b;
|
||||
}
|
||||
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_pixel_off_color", i+1) ;
|
||||
snprintf(key, sizeof(key), CORE_OPTION_NAME "_vmu%d_pixel_off_color", i+1);
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && strlen(var.value)>1 )
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value && strlen(var.value)>1)
|
||||
{
|
||||
int color_idx = atoi(var.value+(strlen(var.value)-2)) ;
|
||||
vmu_screen_params[i].vmu_pixel_off_R = VMU_SCREEN_COLOR_MAP[color_idx].r ;
|
||||
vmu_screen_params[i].vmu_pixel_off_G = VMU_SCREEN_COLOR_MAP[color_idx].g ;
|
||||
vmu_screen_params[i].vmu_pixel_off_B = VMU_SCREEN_COLOR_MAP[color_idx].b ;
|
||||
int color_idx = atoi(var.value+(strlen(var.value)-2));
|
||||
vmu_screen_params[i].vmu_pixel_off_R = VMU_SCREEN_COLOR_MAP[color_idx].r;
|
||||
vmu_screen_params[i].vmu_pixel_off_G = VMU_SCREEN_COLOR_MAP[color_idx].g;
|
||||
vmu_screen_params[i].vmu_pixel_off_B = VMU_SCREEN_COLOR_MAP[color_idx].b;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -774,11 +780,8 @@ void retro_run()
|
|||
startTime = sh4_sched_now64();
|
||||
dc_run(nullptr);
|
||||
}
|
||||
int width = config::RenderResolution * 4 / 3;
|
||||
if (config::Widescreen && !rotate_screen)
|
||||
width = width * 4 / 3;
|
||||
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(HAVE_VULKAN)
|
||||
video_cb(is_dupe ? 0 : RETRO_HW_FRAME_BUFFER_VALID, width, config::RenderResolution, 0);
|
||||
video_cb(is_dupe ? 0 : RETRO_HW_FRAME_BUFFER_VALID, framebufferWidth, framebufferHeight, 0);
|
||||
#endif
|
||||
if (!config::ThreadedRendering)
|
||||
is_dupe = true;
|
||||
|
@ -1255,10 +1258,7 @@ static void retro_vk_context_reset()
|
|||
ERROR_LOG(RENDERER, "Get Vulkan HW interface failed");
|
||||
return;
|
||||
}
|
||||
int width = config::RenderResolution * 4 / 3;
|
||||
if (config::Widescreen && !rotate_screen)
|
||||
width = width * 4 / 3;
|
||||
theVulkanContext.SetWindowSize(width, config::RenderResolution);
|
||||
theVulkanContext.SetWindowSize(framebufferWidth, framebufferHeight);
|
||||
theVulkanContext.Init((retro_hw_render_interface_vulkan *)vulkan);
|
||||
rend_term_renderer();
|
||||
rend_init_renderer();
|
||||
|
@ -1579,6 +1579,13 @@ bool retro_load_game(const struct retro_game_info *game)
|
|||
config::Rotate90 = false; // actual framebuffer rotation is done by frontend
|
||||
if (rotate_screen)
|
||||
config::Widescreen.override(false);
|
||||
framebufferHeight = config::RenderResolution;
|
||||
if (config::Widescreen)
|
||||
framebufferWidth = config::RenderResolution * 16.f / 9.f;
|
||||
else if (!rotate_screen)
|
||||
framebufferWidth = config::RenderResolution * 4.f * config::ScreenStretching / 3.f / 100.f;
|
||||
else
|
||||
framebufferWidth = config::RenderResolution * 4.f / 3.f;
|
||||
|
||||
if (devices_need_refresh)
|
||||
refresh_devices(true);
|
||||
|
@ -1733,31 +1740,19 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
|
|||
const int spg_clks[4] = { 26944080, 13458568, 13462800, 26944080 };
|
||||
u32 pixel_clock= spg_clks[(SPG_CONTROL.full >> 6) & 3];
|
||||
|
||||
int width = config::RenderResolution * 4 / 3;
|
||||
cheatManager.reset(config::Settings::instance().getGameId());
|
||||
if (cheatManager.isWidescreen())
|
||||
{
|
||||
info->geometry.aspect_ratio = 16.0 / 9.0;
|
||||
struct retro_message msg;
|
||||
msg.msg = "Widescreen cheat activated";
|
||||
msg.frames = 120;
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config::Widescreen)
|
||||
{
|
||||
width = (int)lround(width * 4.0 / 3.0);
|
||||
info->geometry.aspect_ratio = 16.0 / 9.0;
|
||||
}
|
||||
else
|
||||
info->geometry.aspect_ratio = 4.0 / 3.0;
|
||||
}
|
||||
info->geometry.aspect_ratio = (float)framebufferWidth / framebufferHeight;
|
||||
if (rotate_screen)
|
||||
info->geometry.aspect_ratio = 1 / info->geometry.aspect_ratio;
|
||||
int maximum = width > config::RenderResolution ? width : config::RenderResolution;
|
||||
info->geometry.base_width = width;
|
||||
info->geometry.base_height = config::RenderResolution;
|
||||
info->geometry.base_width = framebufferWidth;
|
||||
info->geometry.base_height = framebufferHeight;
|
||||
int maximum = std::max(framebufferWidth, framebufferHeight);
|
||||
info->geometry.max_width = maximum;
|
||||
info->geometry.max_height = maximum;
|
||||
|
||||
|
@ -2065,6 +2060,21 @@ static void updateMouseState(u32 port)
|
|||
mo_wheel_delta[port] += 10;
|
||||
}
|
||||
|
||||
static void updateLightgunCoordinates(u32 port)
|
||||
{
|
||||
int x = input_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
|
||||
int y = input_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y);
|
||||
if (config::Widescreen && config::ScreenStretching == 100)
|
||||
mo_x_abs[port] = 640.f * ((x + 0x8000) * 4.f / 3.f / 0x10000 - (4.f / 3.f - 1.f) / 2.f);
|
||||
else
|
||||
mo_x_abs[port] = (x + 0x8000) * 640.f / 0x10000;
|
||||
mo_y_abs[port] = (y + 0x8000) * 480.f / 0x10000;
|
||||
|
||||
lightgun_params[port].offscreen = false;
|
||||
lightgun_params[port].x = mo_x_abs[port];
|
||||
lightgun_params[port].y = mo_y_abs[port];
|
||||
}
|
||||
|
||||
static void UpdateInputStateNaomi(u32 port)
|
||||
{
|
||||
switch (config::MapleMainDevices[port])
|
||||
|
@ -2109,14 +2119,7 @@ static void UpdateInputStateNaomi(u32 port)
|
|||
}
|
||||
else
|
||||
{
|
||||
int x = input_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X);
|
||||
int y = input_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y);
|
||||
mo_x_abs[port] = (x + 0x8000) * 640.f / 0x10000;
|
||||
mo_y_abs[port] = (y + 0x8000) * 480.f / 0x10000;
|
||||
|
||||
lightgun_params[port].offscreen = false;
|
||||
lightgun_params[port].x = mo_x_abs[port];
|
||||
lightgun_params[port].y = mo_y_abs[port];
|
||||
updateLightgunCoordinates(port);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2521,12 +2524,7 @@ static void UpdateInputState(u32 port)
|
|||
}
|
||||
else
|
||||
{
|
||||
mo_x_abs[port] = (input_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X) + 0x8000) * 640.f / 0x10000;
|
||||
mo_y_abs[port] = (input_cb(port, RETRO_DEVICE_LIGHTGUN, 0, RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y) + 0x8000) * 480.f / 0x10000;
|
||||
|
||||
lightgun_params[port].offscreen = false;
|
||||
lightgun_params[port].x = mo_x_abs[port];
|
||||
lightgun_params[port].y = mo_y_abs[port];
|
||||
updateLightgunCoordinates(port);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "vmu_xhair.h"
|
||||
#include "cfg/option.h"
|
||||
|
||||
const char* VMU_SCREEN_COLOR_NAMES[VMU_NUM_COLORS] = {
|
||||
"DEFAULT_ON",
|
||||
|
@ -114,5 +115,10 @@ lightgun_params_t lightgun_params[4];
|
|||
|
||||
std::pair<float, float> getCrosshairPosition(int playerNum)
|
||||
{
|
||||
return std::make_pair(lightgun_params[playerNum].x, lightgun_params[playerNum].y);
|
||||
float fx = lightgun_params[playerNum].x * config::RenderResolution * config::ScreenStretching / 480.f / 100.f;
|
||||
float fy = lightgun_params[playerNum].y * config::RenderResolution / 480.f;
|
||||
if (config::Widescreen && config::ScreenStretching == 100)
|
||||
fx += (480.f * 16.f / 9.f - 640.f) / 2.f * config::RenderResolution / 480.f;
|
||||
|
||||
return std::make_pair(fx, fy);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue