1
0
mirror of https://github.com/pumpitupdev/pumptools.git synced 2024-09-23 19:08:23 +02:00

patch/gfx: Implement scaling using different screen and viewport resolutions

Define a set of fixed modes covering our use-cases to allow rendering
4:3 games to a pillarbox on widescreen monitors.
This commit is contained in:
icex2 2021-03-19 22:19:32 +01:00
parent 8bb157c206
commit 517adc153a
3 changed files with 128 additions and 18 deletions

View File

@ -5,20 +5,24 @@ LABEL description="Build environment for pumptools"
# Install build dependencies, multilib to get 32-bit versions
RUN dpkg --add-architecture i386
RUN apt-get update && apt-get install -y \
g++-multilib \
gcc-multilib \
zip \
cmake \
make \
git \
libc6-dev-i386 \
libusb-1.0-0-dev:i386 \
libusb-dev:i386 \
libasound2-dev:i386 \
libconfig++-dev:i386 \
libx11-dev:i386 \
libcurl4-gnutls-dev:i386
RUN apt-get update
RUN apt-get install -y g++-multilib
RUN apt-get install -y gcc-multilib
RUN apt-get install -y zip
RUN apt-get install -y cmake
RUN apt-get install -y make
RUN apt-get install -y git
RUN apt-get install -y libc6-dev-i386
RUN apt-get install -y libusb-1.0-0-dev:i386
RUN apt-get install -y libusb-dev:i386
RUN apt-get install -y libasound2-dev:i386
RUN apt-get install -y libconfig++-dev:i386
RUN apt-get install -y libx11-dev:i386
RUN apt-get install -y libcurl4-gnutls-dev:i386
RUN apt-get install -y libglu1-mesa-dev:i386
# Delete apt-cache to reduce image size
RUN rm -rf /var/lib/apt/lists/*
# Copy files for building to container
RUN mkdir /pumptools

View File

@ -2,6 +2,10 @@
#include <X11/Xutil.h>
#include <stdbool.h>
#include <GL/gl.h>
// OpenGL 3.x+
#include <GL/glx.h>
#include "capnhook/hook/lib.h"
@ -26,11 +30,21 @@ typedef Window (*XCreateWindow_t)(
typedef Display *(*XOpenDisplay_t)(const char *display_name);
typedef XVisualInfo *(*glXChooseVisual_t)(
Display *dpy, int screen, int *attribList);
typedef void (*glViewport_t)(GLint x, GLint y, GLsizei width, GLsizei height);
static bool patch_gfx_initialized;
static XCreateWindow_t patch_gfx_real_XCreateWindow;
static XOpenDisplay_t patch_gfx_real_XOpenDisplay;
static glXChooseVisual_t patch_gfx_real_GlXChooseVisual;
static glViewport_t patch_gfx_real_glViewport;
static bool _patch_gfx_scaling_enabled;
static uint16_t _patch_gfx_screen_width;
static uint16_t _patch_gfx_screen_height;
static uint16_t _patch_gfx_viewport_width;
static uint16_t _patch_gfx_viewport_height;
static uint16_t _patch_gfx_viewport_pos_x;
static uint16_t _patch_gfx_viewport_pos_y;
static char *patch_gfx_attrib_list_to_str(int *attrib_list)
{
@ -82,6 +96,11 @@ Window XCreateWindow(
}
}
if (_patch_gfx_scaling_enabled) {
width = _patch_gfx_screen_width;
height = _patch_gfx_screen_height;
}
return patch_gfx_real_XCreateWindow(
display,
parent,
@ -152,8 +171,80 @@ XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
return res;
}
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
if (!patch_gfx_real_glViewport) {
void* handle = cnh_lib_load("libGL.so");
patch_gfx_real_glViewport =
(glViewport_t) cnh_lib_get_func_addr_handle(handle, "glViewport");
}
// 0/0 at the bottom left
if (_patch_gfx_scaling_enabled) {
x = _patch_gfx_viewport_pos_x;
y = _patch_gfx_viewport_pos_y;
width = _patch_gfx_viewport_width;
height = _patch_gfx_viewport_height;
}
patch_gfx_real_glViewport(x, y, width, height);
}
void patch_gfx_init()
{
_patch_gfx_scaling_enabled = false;
patch_gfx_initialized = true;
log_info("Initialized");
}
// Note, consider improving scaling, see http://www.david-amador.com/2013/04/opengl-2d-independent-resolution-rendering/
void patch_gfx_scale(enum patch_gfx_scale_mode scale_mode)
{
switch (scale_mode) {
case PATCH_GFX_SCALE_MODE_SD_480_TO_PILLARBOX_HD_720:
_patch_gfx_screen_width = 1280;
_patch_gfx_screen_height = 720;
_patch_gfx_viewport_width = 960;
_patch_gfx_viewport_height = 720;
_patch_gfx_viewport_pos_x = 160;
_patch_gfx_viewport_pos_y = 0;
break;
case PATCH_GFX_SCALE_MODE_SD_480_TO_PILLARBOX_HD_1080:
_patch_gfx_screen_width = 1920;
_patch_gfx_screen_height = 1080;
_patch_gfx_viewport_width = 1440;
_patch_gfx_viewport_height = 1080;
_patch_gfx_viewport_pos_x = 240;
_patch_gfx_viewport_pos_y = 0;
break;
case PATCH_GFX_SCALE_MODE_SD_480_TO_SD_960:
_patch_gfx_screen_width = 1280;
_patch_gfx_screen_height = 960;
_patch_gfx_viewport_width = 1280;
_patch_gfx_viewport_height = 960;
_patch_gfx_viewport_pos_x = 0;
_patch_gfx_viewport_pos_y = 0;
break;
case PATCH_GFX_SCALE_MODE_HD_720_TO_HD_1080:
_patch_gfx_screen_width = 1920;
_patch_gfx_screen_height = 1080;
_patch_gfx_viewport_width = 1920;
_patch_gfx_viewport_height = 1080;
_patch_gfx_viewport_pos_x = 0;
_patch_gfx_viewport_pos_y = 0;
break;
case PATCH_GFX_SCALE_MODE_INVALID:
default:
log_error("Invalid scale mode: %d. Scaling disabled", scale_mode);
return;
}
log_info("Scaling enabled, mode: %d", scale_mode);
_patch_gfx_scaling_enabled = true;
}

View File

@ -1,12 +1,27 @@
#pragma once
/**
* Hook module to run the games on non NVIDIA cards
* Different modes for scaling different source resolutions to target
* resolutions including keeping the aspect ratio
*/
#ifndef PATCH_GFX_H
#define PATCH_GFX_H
enum patch_gfx_scale_mode {
PATCH_GFX_SCALE_MODE_INVALID = 0,
PATCH_GFX_SCALE_MODE_SD_480_TO_PILLARBOX_HD_720 = 1,
PATCH_GFX_SCALE_MODE_SD_480_TO_PILLARBOX_HD_1080 = 2,
PATCH_GFX_SCALE_MODE_SD_480_TO_SD_960 = 3,
PATCH_GFX_SCALE_MODE_HD_720_TO_HD_1080 = 4,
};
/**
* Initialize the patch module
*
* This takes care of running the games on non NVIDIA cards
*/
void patch_gfx_init();
#endif
/**
* Scale the rendered output according to the given mode (see enum)
*
* @param scale_mode The scaling mode to apply
*/
void patch_gfx_scale(enum patch_gfx_scale_mode scale_mode);