Closed AltoRetrato closed 1 year ago
I added some debug messages in the middle of UnrealLibretro Delegates, hoping it might help understand the issue. It seems Flycast might be applying a "widescreen cheat" (see code at the bottom of this post).
Here's the slightly edited output log, after running for a few seconds: warning lines start with "**", debug messages with "##", repeated lines removed and marked with "[\<repetitions>x]".
From the log, I've noticed that the Libretro Framebuffer size is 853 × 853, which seems a bit odd. I saved the Emulator Texture to disk, and while the resolution is 853 × 853, the contents are 640 × 480.
I trimmed the image above to 640 × 480 and saved it (as a "raw" file), then loaded it as if it had 853 pixels of width - and it appeared as "normal" (only vertically flipped).
So it seems 853 pixels per line are being written in the 853 × 853 buffer, but they are wrapping at 640 pixels.
In the log it says the RenderResolution
is 480
:
Libretro: shell/libretro/libretro.cpp:2120 N[RENDERER]: retro_get_system_av_info: Res=480
In flycast's retro_get_system_av_info there is a mention to a widescreen cheat, but the same core and same ROM run in 4:3 in Retroarch.
But in setFramebufferSize:
static void setFramebufferSize()
{
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;
maxFramebufferHeight = std::max(maxFramebufferHeight, framebufferHeight);
maxFramebufferWidth = std::max(maxFramebufferWidth, framebufferWidth);
}
the line framebufferWidth = config::RenderResolution * 16.f / 9.f;
means that if config::Widescreen
is true, framebufferWidth
is 480 * 16 / 9, i.e., 853.33.
And right below, in setGameGeometry, it seems geometry.base_width
and geometry.base_height
are hardcoded:
static void setGameGeometry(retro_game_geometry& geometry)
{
geometry.aspect_ratio = (float)framebufferWidth / framebufferHeight;
if (rotate_screen)
geometry.aspect_ratio = 1 / geometry.aspect_ratio;
geometry.max_width = std::max(framebufferHeight * 16 / 9, framebufferWidth);
geometry.max_height = geometry.max_width;
// Avoid gigantic window size at startup
geometry.base_width = 640;
geometry.base_height = 480;
}
I'm not sure, but does it mean that a possible fix would be using geometry.max_width
and geometry.max_height
in ULibretroCoreInstance::Launch(), instead of geometry.base_width
and geometry.base_height
?
Following @AltoRetrato findings, I was able to find a fix.
The issue I found was definitely with the sizing of the render target. However, replacing geometry.base_width
and geometry.base_height
in ULibretroCoreInstance::Launch() is only part of the fix.
Replacing every instance of max_width
and max_height
in sdlarch.cpp with base_width
and base_height
resolved the issue. I'm unsure if this affects games that adjust the aspect ratio or rotate the screen.
This change seemed to have no impact on other cores from my testing, and I tested with Snes9x, Mupen 64, Nestopia.
Also, to fix Flycast being flipped, you could add a material parameter to the material then flip it just for Flycast, or add some code to toggle invert_y
's value in LibretroCoreInstance.h
Edit: Upon further testing, this does break compatibility with some cores.
Thanks for the detailed bug report @AltoRetrato and attempting to fix it @macdguy. I appreciate it. I think I found the issue. The first part was the pitch I was using when copying the framebuffer was wrong that explained the weird interlaced shifted look it had.
The other issue was I misinterpreted where the frame would be rendered into the framebuffer when retro_hw_render_callback::bottom_left_origin
was true
. I thought it would be rendered in the pink box below. This wasn't too hard to solve I just had to shift the uv coordinates however I moved the logic to the blueprints which aren't under source control yet. So you'll have to run the setup.sh
script again or just copy over the blueprints from a build artifact or the unversioned
branch to see the changes there.
I think this solved it. Just close the issue if it works
I was having issues building the plugin at first, but I managed to build it with the Unreal AutomationTool, via RunUAT.bat
!
The batch is in <UE_4.27_install_path>\Engine\Build\BatchFiles
. From there I run RunUAT.bat BuildPlugin -plugin="E:\Unreal\LibretroVR\Plugins\UnrealLibretro.uplugin" -package="E:\Unreal\LibretroVR\Plugins\Output" -TargetPlatforms=Win64 -VS2019
(without the -VS2019
parameter, it complained that I needed Visual Studio 2017, but with -VS2019
it worked with VS 2022 just fine).
After that, everything was working properly! Thank you! 😄
Hi, John!
Your UnrealLibretro is amazing! Thank you so much for sharing this with us! 😄
I just tested it with a couple of cores, and it seems to work perfectly with some of them, e.g., dosbox_svn_libretro.
OTOH, the Flycast core has sound and controllers working fine (just like in Retroarch), but the image is distorted:
Expected output (captured with the same core on Retroarch):
Other details:
Any idea of what is causing the issue, and what would be the solution?
Thanks!