libretro: vmu and crosshair display. lightgun fixes

This commit is contained in:
Flyinghead 2021-07-08 20:09:09 +02:00
parent 80a5b44fe9
commit 5c952021b7
10 changed files with 341 additions and 163 deletions

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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]);

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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());

View File

@ -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;

View File

@ -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);
}