SDL 1.2 fullscreen position fix


ouzle

Very Active Member
Joined
Jun 3, 2019
Messages
136
Location
England
The SDL1.2 games I've tried on the Pyra put the game in the wrong place on the screen, usually clipping the game. The fix for the position and scaling looks quick, but does need both SDL1.2 and OpenTyrian to be recompiled.

OpenTyrian.png
OpenTyrian2.png
 
I downloaded the libSDL1.2 code from github using "git clone https://github.com/libsdl-org/SDL-1.2.git".

I swapped all the w's and h's (width and heights) in the get_real_resolution(_THIS, int* w, int* h) function of src/video/x11/SDL_x11modes.c

We need to tell SDL1.2 to use xrandr to query the resolution as this understands the screen rotation. There is a configure option for this so build as follows:

Bash:
git clone https://github.com/libsdl-org/SDL-1.2.git
cd SDL-1.2
CFLAGS="-O3 -pipe -march=armv7ve -mcpu=cortex-a15 -mfloat-abi=hard -mfpu=neon-vfpv4 -fPIC" ./configure --disable-video-x11-vm --enable-video-x11-xrandr --enable-arm-neon --prefix=/usr
make
sudo make install

I then found some comments on the tyrian2k proboards about building open tyrian on Raspberry Pi. It mentioned how to change the scaling and suggested starting from this source code.

I modified the scaling lines of src/video_scale.c to just have one scale:
C:
const struct Scalers scalers[] =
{
{ 3 * vga_width, 3 * vga_height, NULL,     scale3x_16, scale3x_32, "Scale3x" }
};

I also changed the OpenTyrian Makefile to include the pyra flags and set the SDL include directory:
Makefile:
# FLAGS ####################################################

ifneq ($(MAKECMDGOALS), release)
    EXTRA_CFLAGS += -g3 -O0 -pipe -march=armv7ve -mcpu=cortex-a15 -mfloat-abi=hard -mfpu=neon-vfpv4 -fPIC
else
    EXTRA_CFLAGS += -g0 -O2 -DNDEBUG
endif
EXTRA_CFLAGS += -I/usr/include/SDL -MMD -pedantic -Wall -Wextra -Wno-missing-field-initializers
Post automatically merged:


Note, to toggle fullscreen you need to press <Alt>+<Enter>

Sooo... packaging? I know how to do the dbp but any tips on libSDL deb?
 
Last edited:
Nice work @ouzle I suspected something to that effect to be the issue, but never had the time to look into it further.
 
Could we possibly use neon scalers like we did on the Pandora at some point?
Do you mean like from the NEON scalers thread and from GitHub - M-HT/neon_scalers ?

OpenTyrian does the surface scaling itself in video_scale.c without any help from SDL. Is the idea for the games to pick up the NEON scaler functions from a Pyra specific SDL library with function prototypes like:

static void neon_scale3x_16_16( SDL_Surface *src_surface, SDL_Surface *dst_surface );

We'd then modify each game to make it reference the NEON scalars rather than their slow versions? For example, in OpenTyrian we'd add the scaler as follows:

C:
extern void neon_scale3x_16_16( SDL_Surface *src_surface, SDL_Surface *dst_surface );
extern void neon_scale3x_32_32( SDL_Surface *src_surface, SDL_Surface *dst_surface );

const struct Scalers scalers[] =
{
{ 3 * vga_width, 3 * vga_height, NULL,     neon_scale3x_16_16, neon_scale3x_32_32, "Scale3x" }
}
Post automatically merged:

I saw that the NEON bitblit optimisations are already enabled in the SDL1.2 source. You just need to give the --enable-arm-neon flag to configure. That looks to be connected up
 
Although this works, I'd rather fix the thing actually causing the problem, instead of working around it.
Which is probably to do with the tiler rotation, and/or the xorg driver, which are all a lot less fun to work on :)

I'd also like to keep our own packages to an absolute minimum, and let debian worry about maintaining everything else.
Unless of course there's a huge advantage to having a custom version.
 
Can we now follow up the function calls from this fix up to the problem in Xorg and fix it there?

The graphics already appear to be rotated. Is the rotation not fast yet?
 
Rotation is "fast", but it's all a bit of a hack.
I didn't write the code, so im not 100% sure how everything works and why, but somewhere along the line half the stuff sees the unrotated framebuffer , and the other half sees the rotated framebuffer. Which is why some things end up in the wrong place.
I'm also not sure where exactly that happens, if it's from the xorg driver up, or some stuff like sdl trying to poke to deeper levels and somehow getting the underlying unrotated resolution.
 
I see daveshah noted that user space width/height still needs swapping in the TILER:
Comment 3 by daveshah, Jun 18, 2020

The TILER is now working again in 5.6. A new command line parameter
is added "drm.force_hw_rotation" that uses the panel
orientation to rotate the framebuffer using the TILER.

The situation is still not ideal, primarily as userspace stuff still
needs some changes to use TILER correctly. In particular,
width/height still need to be swapped, and anything using
DRM_IOCTL_MODE_CREATE_DUMB needs to be changed to
DRM_IOCTL_OMAP_GEM_NEW in order to create a tiled buffer.

However, I have implemented a shim to fix this for fullscreen stuff (
https://github.com/daveshah1/tiler_rotate_shim) and am currently
patching the xf86-video-armsoc-omap5 X11 driver to use TILER
rotation too, in order to get DRI3 support.
 
  • Like
Reactions: rSl
I've started digging up from SDL1.2 src/video/x11/SDL_x11modes.c : get_real_resolution(_THIS, int* w, int* h). I've verified that it uses XF86VidModeGetModeLine to query the screen resolution by default. We can make it use xrandr instead which does recognise the screen rotation!

Bash:
git clone https://github.com/libsdl-org/SDL-1.2.git
cd SDL-1.2
CFLAGS="-O3 -pipe -march=armv7ve -mcpu=cortex-a15 -mfloat-abi=hard -mfpu=neon-vfpv4 -fPIC" ./configure --disable-video-x11-vm --enable-video-x11-xrandr --enable-arm-neon --prefix=/usr
make
sudo make install

C:
static void get_real_resolution(_THIS, int* w, int* h)
{
...
#if SDL_VIDEO_DRIVER_X11_VIDMODE
    if ( use_vidmode ) {
        SDL_NAME(XF86VidModeModeLine) mode;
        int unused;

        if ( SDL_NAME(XF86VidModeGetModeLine)(SDL_Display, SDL_Screen, &unused, &mode) ) {
            /* Needed swapping for pyra rotation */
            *h = mode.hdisplay;
            *w = mode.vdisplay;
            return;
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */

#if SDL_VIDEO_DRIVER_X11_XRANDR
    if ( use_xrandr ) {
        int nsizes;
        XRRScreenSize* sizes;

        sizes = XRRConfigSizes(screen_config, &nsizes);
        if ( nsizes > 0 ) {
            int cur_size;
            Rotation cur_rotation;

            cur_size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation);
            if ( cur_size >= 0 && cur_size < nsizes ) {
                *w = sizes[cur_size].width;
                *h = sizes[cur_size].height;
            }
#ifdef X11MODES_DEBUG
            fprintf(stderr, "XRANDR: get_real_resolution: w = %d h = %d\n", *w, *h);
#endif
            return;
        }
    }
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */

...
}
 
Last edited:
So, SDL1.2 does work without any code changes. Its that the default configure flags don't let it read the rotation info that xrandr understands. The default result from XF86VidModeGetModeLine is technically correct when it reports the display size as it relates to hsync and vsync resolutions.

Is the solution to argue for the Debian packagers to change the SDL1.2 flags to use xrandr by default? It seems like a bug to use XF86VidModeGetModeLine method when it doesnt recognise the rotation flags when xrandr does.
 
  • Like
Reactions: rSl
Using the xrandr -q bash command shows that it understands the screen rotation. It reports the rotated frame buffer size correctly and then the not-rotated display size

Bash:
me@pyra:~$ xrandr -q
Screen 0: minimum 320 x 200, current 1280 x 720, maximum 8192 x 8192
Unknown16-1 connected primary 1280x720+0+0 right (normal right) 63mm x 112mm
   720x1280      60.00*+
HDMI-1 disconnected
 
Using the xrandr -q bash command shows that it understands the screen rotation. It reports the rotated frame buffer size correctly and then the not-rotated display size

Bash:
me@pyra:~$ xrandr -q
Screen 0: minimum 320 x 200, current 1280 x 720, maximum 8192 x 8192
Unknown16-1 connected primary 1280x720+0+0 right (normal right) 63mm x 112mm
   720x1280      60.00*+
HDMI-1 disconnected

I was actually thinking about the whole rotation method you chose last night before I went to sleep (It kept me awake damnit!) and thought HDMI connectivity would be impacted by your change.

This would ensure that HDMI would work fine after the fact correct?
 
Back
Top