mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-22 23:49:50 +00:00
Bump switchres to 2.2.1 (#16782)
* Remove switchres before bump * Squashed 'deps/switchres/' content from commit 725e4d484a git-subtree-dir: deps/switchres git-subtree-split: 725e4d484a33632618dd44cdc2a61948dd833282
This commit is contained in:
parent
bd69602686
commit
f1a37f7c75
39
deps/switchres/.github/workflows/build.yml
vendored
39
deps/switchres/.github/workflows/build.yml
vendored
@ -9,16 +9,16 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- { name: Linux GCC }
|
||||
- { name: Windows MINGW, make_opts: PLATFORM=NT CROSS_COMPILE=x86_64-w64-mingw32- }
|
||||
- { name: linux_gcc }
|
||||
- { name: windows_mingw, make_opts: PLATFORM=NT CROSS_COMPILE=x86_64-w64-mingw32- }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install Linux dependencies
|
||||
if: matrix.platform.name == 'Linux GCC'
|
||||
if: matrix.platform.name == 'linux_gcc'
|
||||
run: sudo apt-get install libxrandr-dev libdrm-dev libsdl2-dev
|
||||
- name: Install Windows dependencies
|
||||
if: matrix.platform.name == 'Windows MINGW'
|
||||
if: matrix.platform.name == 'windows_mingw'
|
||||
run: |
|
||||
sudo apt-get install mingw-w64 wget tar
|
||||
sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
|
||||
@ -33,7 +33,7 @@ jobs:
|
||||
make libswitchres ${{matrix.platform.make_opts}}
|
||||
make ${{matrix.platform.make_opts}}
|
||||
- name: Build grid.exe (Windows only)
|
||||
if: matrix.platform.name == 'Windows MINGW'
|
||||
if: matrix.platform.name == 'windows_mingw'
|
||||
run: |
|
||||
make ${{matrix.platform.make_opts}} clean
|
||||
make ${{matrix.platform.make_opts}} grid
|
||||
@ -62,3 +62,32 @@ jobs:
|
||||
with:
|
||||
name: geometry-win32-x86_64
|
||||
path: dist/
|
||||
|
||||
release:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
needs: [buildx86_64, win32-build-x86_64-geometry]
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v2.0.5
|
||||
- name: Make packages
|
||||
run: |
|
||||
tag="${GITHUB_REF#refs/tags/}"
|
||||
mv ./geometry-win32-x86_64/geometry.exe ./switchres-windows_mingw-x86_64
|
||||
7z a "switchres-${tag}-windows_mingw-x86_64.7z" ./switchres-windows_mingw-x86_64
|
||||
tar cvjf switchres-${tag}-linux_gcc-x86_64.tar.bz2 ./switchres-linux_gcc-x86_64
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
name: Switchres ${{ steps.get_version.outputs.VERSION }}
|
||||
draft: true
|
||||
prerelease: false
|
||||
files: |
|
||||
./*.bz2
|
||||
./*.7z
|
||||
|
15
deps/switchres/README.md
vendored
15
deps/switchres/README.md
vendored
@ -1,4 +1,4 @@
|
||||
# What is Switchres 2.0
|
||||
# What is Switchres
|
||||
Switchres is a modeline generation engine for emulation.
|
||||
|
||||
Its purpose is on-the-fly creation of fully customized video modes that accurately reproduce those of the emulated systems. Based on a monitor profile, it will provide the best video mode for a given width, height, and refresh rate.
|
||||
@ -7,7 +7,7 @@ Switchres features the most versatile modeline generation ever, ranging from 15-
|
||||
|
||||
Switchres can be integrated into open-source emulators either as a library, or used as a standalone emulator launcher. It's written in C++ and a C wrapper is also available.
|
||||
|
||||
Switchres 2.0 is a rewrite of the original Switchres code used in GroovyMAME. It currently supports mode switching on the following platforms, with their respective backends:
|
||||
Switchres is a rewrite of the original Switchres code used in GroovyMAME. It currently supports mode switching on the following platforms, with their respective backends:
|
||||
- **Windows**:
|
||||
- AMD ADL (AMD Radeon HD 5000+)
|
||||
- ATI legacy (ATI Radeon pre-HD 5000)
|
||||
@ -37,12 +37,17 @@ Options:
|
||||
-l, --launch <command> Launch <command>
|
||||
-m, --monitor <preset> Monitor preset (generic_15, arcade_15, pal, ntsc, etc.)
|
||||
-a --aspect <num:den> Monitor aspect ratio
|
||||
-r --rotated Original mode's native orientation is rotated
|
||||
-d, --display <OS_display_name> Use target display (Windows: \\\\.\\DISPLAY1, ... Linux: VGA-0, ...)
|
||||
-r --rotated Rotate axes, preserving aspect ratio
|
||||
-d, --display <display_index> Use target display (index = 0, 1, 2...)
|
||||
-f, --force <w>x<h>@<r> Force a specific video mode from display mode list
|
||||
-i, --ini <file.ini> Specify an ini file
|
||||
-b, --backend <api_name> Specify the api name
|
||||
-k, --keep Keep changes on exit (warning: this disables cleanup)
|
||||
-g, --geometry <adjustment> Adjust geometry of generated modeline
|
||||
adjustment = <h_size>:<h_shift>:<v_shift>
|
||||
e.g. switchres 640 480 60 -c -g 1.1:-1:2
|
||||
|
||||
For more options, refer to switchres.ini. All options in switchres.ini can be applied in
|
||||
command line as long options, e.g.: switchres 256 224 57.55 -c --dotclock_min 8.0
|
||||
```
|
||||
|
||||
A default `switchres.ini` file will be searched in the current working directory, then in `.\ini` on Windows, `./ini` then `/etc` on Linux. The repo has a switchres.ini example.
|
||||
|
86
deps/switchres/custom_video_drmkms.cpp
vendored
86
deps/switchres/custom_video_drmkms.cpp
vendored
@ -47,11 +47,22 @@
|
||||
#define drmModeFreePlaneResources p_drmModeFreePlaneResources
|
||||
#define drmIoctl p_drmIoctl
|
||||
#define drmGetCap p_drmGetCap
|
||||
#define drmGetDevices2 p_drmGetDevices2
|
||||
#define drmIsMaster p_drmIsMaster
|
||||
#define drmSetMaster p_drmSetMaster
|
||||
#define drmDropMaster p_drmDropMaster
|
||||
|
||||
# define MAX_CARD_ID 10
|
||||
# define MAX_DRM_DEVICES 16
|
||||
|
||||
// To enable libdrmhook: make SR_WITH_DRMHOOK=1
|
||||
#ifdef SR_WITH_DRMHOOK
|
||||
#define hook_handle RTLD_DEFAULT
|
||||
#define hook_log " (will attempt hook)"
|
||||
#else
|
||||
#define hook_handle mp_drm_handle
|
||||
#define hook_log ""
|
||||
#endif
|
||||
|
||||
//============================================================
|
||||
// shared the privileges of the master fd
|
||||
@ -212,6 +223,13 @@ bool drmkms_timing::test_kernel_user_modes()
|
||||
// Count the number of existing modes, so it should be +1 when attaching
|
||||
// a new mode. Could also check the mode name, still better
|
||||
conn = drmModeGetConnector(fd, m_desktop_output);
|
||||
if (!conn)
|
||||
{
|
||||
log_verbose("DRM/KMS: <%d> (%s) Cannot get connector\n", m_id, __FUNCTION__);
|
||||
m_kernel_user_modes = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
first_modes_count = conn->count_modes;
|
||||
ret = drmModeAttachMode(fd, m_desktop_output, &mode);
|
||||
drmModeFreeConnector(conn);
|
||||
@ -329,7 +347,7 @@ drmkms_timing::~drmkms_timing()
|
||||
|
||||
bool drmkms_timing::init()
|
||||
{
|
||||
log_verbose("DRM/KMS: <%d> (init) loading DRM/KMS library\n", m_id);
|
||||
log_verbose("DRM/KMS: <%d> (init) loading DRM/KMS library%s\n", m_id, hook_log);
|
||||
mp_drm_handle = dlopen("libdrm.so", RTLD_NOW);
|
||||
if (mp_drm_handle)
|
||||
{
|
||||
@ -354,21 +372,21 @@ bool drmkms_timing::init()
|
||||
return false;
|
||||
}
|
||||
|
||||
p_drmModeGetConnector = (__typeof__(drmModeGetConnector)) dlsym(RTLD_DEFAULT, "drmModeGetConnector");
|
||||
p_drmModeGetConnector = (__typeof__(drmModeGetConnector)) dlsym(hook_handle, "drmModeGetConnector");
|
||||
if (p_drmModeGetConnector == NULL)
|
||||
{
|
||||
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeGetConnector", "DRM_LIBRARY");
|
||||
return false;
|
||||
}
|
||||
|
||||
p_drmModeGetConnectorCurrent = (__typeof__(drmModeGetConnectorCurrent)) dlsym(RTLD_DEFAULT, "drmModeGetConnectorCurrent");
|
||||
p_drmModeGetConnectorCurrent = (__typeof__(drmModeGetConnectorCurrent)) dlsym(hook_handle, "drmModeGetConnectorCurrent");
|
||||
if (p_drmModeGetConnectorCurrent == NULL)
|
||||
{
|
||||
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeGetConnectorCurrent", "DRM_LIBRARY");
|
||||
return false;
|
||||
}
|
||||
|
||||
p_drmModeFreeConnector = (__typeof__(drmModeFreeConnector)) dlsym(RTLD_DEFAULT, "drmModeFreeConnector");
|
||||
p_drmModeFreeConnector = (__typeof__(drmModeFreeConnector)) dlsym(hook_handle, "drmModeFreeConnector");
|
||||
if (p_drmModeFreeConnector == NULL)
|
||||
{
|
||||
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeFreeConnector", "DRM_LIBRARY");
|
||||
@ -494,6 +512,13 @@ bool drmkms_timing::init()
|
||||
return false;
|
||||
}
|
||||
|
||||
p_drmGetDevices2 = (__typeof__(drmGetDevices2)) dlsym(mp_drm_handle, "drmGetDevices2");
|
||||
if (p_drmGetDevices2 == NULL)
|
||||
{
|
||||
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmGetDevices2", "DRM_LIBRARY");
|
||||
return false;
|
||||
}
|
||||
|
||||
p_drmIsMaster = (__typeof__(drmIsMaster)) dlsym(mp_drm_handle, "drmIsMaster");
|
||||
if (p_drmIsMaster == NULL)
|
||||
{
|
||||
@ -529,14 +554,31 @@ bool drmkms_timing::init()
|
||||
else if (strlen(m_device_name) == 1 && m_device_name[0] >= '0' && m_device_name[0] <= '9')
|
||||
screen_pos = m_device_name[0] - '0';
|
||||
|
||||
char drm_name[15] = "/dev/dri/card_";
|
||||
// Get an array of drm devices to check
|
||||
drmDevicePtr devices[MAX_DRM_DEVICES];
|
||||
int num_devices = drmGetDevices2(0, NULL, 0);
|
||||
|
||||
if (num_devices > MAX_DRM_DEVICES)
|
||||
num_devices = MAX_DRM_DEVICES;
|
||||
|
||||
int ret = drmGetDevices2(0, devices, num_devices);
|
||||
if (ret < 0)
|
||||
{
|
||||
log_error("DRM/KMS: drmGetDevices2() returned an error %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
char *drm_name;
|
||||
drmModeRes *p_res;
|
||||
drmModeConnector *p_connector;
|
||||
|
||||
int output_position = 0;
|
||||
for (int num = 0; !m_desktop_output && num < MAX_CARD_ID; num++)
|
||||
for (int num = 0; num < num_devices; num++)
|
||||
{
|
||||
drm_name[13] = '0' + num;
|
||||
// Skip non-primary nodes
|
||||
if (devices[num]->available_nodes & (1 << DRM_NODE_PRIMARY))
|
||||
drm_name = devices[num]->nodes[DRM_NODE_PRIMARY];
|
||||
else continue;
|
||||
|
||||
if (!access(drm_name, F_OK) == 0)
|
||||
{
|
||||
@ -554,7 +596,10 @@ bool drmkms_timing::init()
|
||||
log_error("DRM/KMS: <%d> (init) [ERROR] ioctl DRM_CAP_DUMB_BUFFER\n", m_id);
|
||||
|
||||
if (!check_dumb)
|
||||
{
|
||||
log_error("DRM/KMS: <%d> (init) [ERROR] dumb buffer not supported\n", m_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
p_res = drmModeGetResources(m_drm_fd);
|
||||
|
||||
@ -582,6 +627,7 @@ bool drmkms_timing::init()
|
||||
}
|
||||
m_desktop_output = p_connector->connector_id;
|
||||
m_card_id = num;
|
||||
strcpy(m_drm_name, drm_name);
|
||||
log_verbose("DRM/KMS: <%d> (init) card %d connector %d id %d name %s selected as primary output\n", m_id, num, i, m_desktop_output, connector_name);
|
||||
|
||||
drmModeEncoder *p_encoder = drmModeGetEncoder(m_drm_fd, p_connector->encoder_id);
|
||||
@ -601,7 +647,10 @@ bool drmkms_timing::init()
|
||||
}
|
||||
}
|
||||
if (!mp_crtc_desktop)
|
||||
{
|
||||
m_desktop_output = 0;
|
||||
log_error("DRM/KMS: <%d> (init) [ERROR] no crtc found\n", m_id);
|
||||
}
|
||||
drmModeFreeEncoder(p_encoder);
|
||||
}
|
||||
output_position++;
|
||||
@ -649,9 +698,14 @@ bool drmkms_timing::init()
|
||||
s_shared_count[m_card_id] = 2;
|
||||
}
|
||||
if (!drmIsMaster(m_drm_fd))
|
||||
{
|
||||
m_desktop_output = 0;
|
||||
log_error("DRM/KMS: <%d> (%s) [ERROR] limited DRM rights on this screen\n", m_id, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we're here and we have a valid output, we're done.
|
||||
if (m_desktop_output) break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -697,9 +751,8 @@ bool drmkms_timing::init()
|
||||
|
||||
int drmkms_timing::get_master_fd()
|
||||
{
|
||||
const size_t path_length = 15;
|
||||
char dev_path[path_length];
|
||||
char procpath[50];
|
||||
const size_t path_length = 20;
|
||||
char procpath[path_length];
|
||||
char fullpath[512];
|
||||
char* actualpath;
|
||||
struct stat st;
|
||||
@ -721,10 +774,9 @@ int drmkms_timing::get_master_fd()
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(dev_path, path_length, "/dev/dri/card%d", m_card_id);
|
||||
if (!access(dev_path, F_OK) == 0)
|
||||
if (!access(m_drm_name, F_OK) == 0)
|
||||
{
|
||||
log_error("DRM/KMS: <%d> (%s) [ERROR] Device %s doesn't exist\n", m_id, __FUNCTION__, dev_path);
|
||||
log_error("DRM/KMS: <%d> (%s) [ERROR] Device %s doesn't exist\n", m_id, __FUNCTION__, m_drm_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -749,7 +801,7 @@ int drmkms_timing::get_master_fd()
|
||||
continue;
|
||||
actualpath = realpath(fullpath, NULL);
|
||||
// Only check the device we expect
|
||||
if (strncmp(dev_path, actualpath, path_length) != 0)
|
||||
if (strncmp(m_drm_name, actualpath, path_length) != 0)
|
||||
{
|
||||
free(actualpath);
|
||||
continue;
|
||||
@ -770,16 +822,16 @@ int drmkms_timing::get_master_fd()
|
||||
|
||||
// CASE 3: m_drm_fd is not a master (and probably not even a valid FD), the currend pid doesn't have master rights
|
||||
// Or master is owned by a 3rd party app (like a frontend ...)
|
||||
log_verbose("DRM/KMS: <%d> (%s) Couldn't find a master FD, opening default /dev/dri/card%d\n", m_id, __FUNCTION__, m_card_id);
|
||||
log_verbose("DRM/KMS: <%d> (%s) Couldn't find a master FD, opening default %s\n", m_id, __FUNCTION__, m_drm_name);
|
||||
|
||||
// mark our former hook as invalid
|
||||
m_hook_fd = -1;
|
||||
|
||||
fd = open(dev_path, O_RDWR | O_CLOEXEC);
|
||||
fd = open(m_drm_name, O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
{
|
||||
// Oh, we're totally screwed here, worst possible scenario
|
||||
log_error("DRM/KMS: <%d> (%s) Can't open /dev/dri/card%d, can't get master rights\n", m_id, __FUNCTION__, m_card_id);
|
||||
log_error("DRM/KMS: <%d> (%s) Can't open %s, can't get master rights\n", m_id, __FUNCTION__, m_drm_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
2
deps/switchres/custom_video_drmkms.h
vendored
2
deps/switchres/custom_video_drmkms.h
vendored
@ -53,6 +53,7 @@ class drmkms_timing : public custom_video
|
||||
int m_caps = 0;
|
||||
|
||||
char m_device_name[32];
|
||||
char m_drm_name[32];
|
||||
unsigned int m_desktop_output = 0;
|
||||
int m_video_modes_position = 0;
|
||||
|
||||
@ -83,6 +84,7 @@ class drmkms_timing : public custom_video
|
||||
__typeof__(drmModeFreePlaneResources) *p_drmModeFreePlaneResources;
|
||||
__typeof__(drmIoctl) *p_drmIoctl;
|
||||
__typeof__(drmGetCap) *p_drmGetCap;
|
||||
__typeof__(drmGetDevices2) *p_drmGetDevices2;
|
||||
__typeof__(drmIsMaster) *p_drmIsMaster;
|
||||
__typeof__(drmSetMaster) *p_drmSetMaster;
|
||||
__typeof__(drmDropMaster) *p_drmDropMaster;
|
||||
|
1
deps/switchres/display.cpp
vendored
1
deps/switchres/display.cpp
vendored
@ -104,7 +104,6 @@ void display_manager::parse_options()
|
||||
|
||||
void display_manager::set_preset(const char *preset)
|
||||
{
|
||||
strncpy(m_ds.monitor, preset, sizeof(m_ds.monitor)-1);
|
||||
for (size_t i = 0; i < strlen(m_ds.monitor); i++) m_ds.monitor[i] = tolower(m_ds.monitor[i]);
|
||||
|
||||
memset(&range[0], 0, sizeof(struct monitor_range) * MAX_RANGES);
|
||||
|
4
deps/switchres/display.h
vendored
4
deps/switchres/display.h
vendored
@ -97,6 +97,7 @@ public:
|
||||
int v_shift_correct() { return m_ds.gs.v_shift_correct; }
|
||||
int pixel_precision() { return m_ds.gs.pixel_precision; }
|
||||
int interlace_force_even() { return m_ds.gs.interlace_force_even; }
|
||||
int scale_proportional() { return m_ds.gs.scale_proportional; }
|
||||
|
||||
// getters (modeline result)
|
||||
bool got_mode() { return (m_selected_mode != nullptr); }
|
||||
@ -134,7 +135,7 @@ public:
|
||||
void set_current_mode(modeline *mode) { m_current_mode = mode; }
|
||||
|
||||
// setters (display_manager)
|
||||
void set_monitor(const char *preset) { set_preset(preset); }
|
||||
void set_monitor(const char *preset) { strncpy(m_ds.monitor, preset, sizeof(m_ds.monitor)-1); set_preset(preset); }
|
||||
void set_modeline(const char *modeline) { strncpy(m_ds.user_modeline, modeline, sizeof(m_ds.user_modeline)-1); }
|
||||
void set_crt_range(int i, const char *range) { strncpy(m_ds.crt_range[i], range, sizeof(m_ds.crt_range[i])-1); }
|
||||
void set_lcd_range(const char *range) { strncpy(m_ds.lcd_range, range, sizeof(m_ds.lcd_range)-1); }
|
||||
@ -161,6 +162,7 @@ public:
|
||||
void set_v_shift_correct(int value) { m_ds.gs.v_shift_correct = value; }
|
||||
void set_pixel_precision(int value) { m_ds.gs.pixel_precision = value; }
|
||||
void set_interlace_force_even(int value) { m_ds.gs.interlace_force_even = value; }
|
||||
void set_scale_proportional(int value) { m_ds.gs.scale_proportional = value; }
|
||||
|
||||
// setters (custom_video backend)
|
||||
void set_screen_compositing(bool value) { m_ds.vs.screen_compositing = value; }
|
||||
|
67
deps/switchres/display_sdl2.cpp
vendored
67
deps/switchres/display_sdl2.cpp
vendored
@ -19,65 +19,6 @@
|
||||
#include "display_sdl2.h"
|
||||
#include "log.h"
|
||||
|
||||
//============================================================
|
||||
// custom_video::get_sdl_hwinfo_from_sdl_window
|
||||
//============================================================
|
||||
void get_sdl_hwinfo_from_sdl_window(SDL_Window* window)
|
||||
{
|
||||
SDL_SysWMinfo m_sdlwminfo;
|
||||
|
||||
SDL_VERSION(&m_sdlwminfo.version);
|
||||
if(! SDL_GetWindowWMInfo(window, &m_sdlwminfo))
|
||||
{
|
||||
log_error("Couldn't get the SDL WMInfo\n");
|
||||
return;
|
||||
}
|
||||
const char *subsystem = "an unsupported or unknown system!";
|
||||
switch((int)m_sdlwminfo.subsystem)
|
||||
{
|
||||
case SDL_SYSWM_UNKNOWN:
|
||||
case SDL_SYSWM_COCOA:
|
||||
case SDL_SYSWM_UIKIT:
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 2)
|
||||
case SDL_SYSWM_WAYLAND:
|
||||
#endif
|
||||
case SDL_SYSWM_MIR:
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 3)
|
||||
case SDL_SYSWM_WINRT:
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
||||
case SDL_SYSWM_ANDROID:
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
||||
case SDL_SYSWM_VIVANTE:
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 6)
|
||||
case SDL_SYSWM_OS2:
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
case SDL_SYSWM_HAIKU:
|
||||
#endif
|
||||
case SDL_SYSWM_DIRECTFB:
|
||||
break;
|
||||
case SDL_SYSWM_WINDOWS:
|
||||
subsystem = "Microsoft Windows(TM)";
|
||||
break;
|
||||
case SDL_SYSWM_X11:
|
||||
subsystem = "X Window System";
|
||||
break;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
case SDL_SYSWM_KMSDRM:
|
||||
subsystem = "KMSDRM";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
log_info("Switchres/SDL2: Detected SDL version %d.%d.%d on %s\n",
|
||||
(int)m_sdlwminfo.version.major,
|
||||
(int)m_sdlwminfo.version.minor,
|
||||
(int)m_sdlwminfo.version.patch,
|
||||
subsystem);
|
||||
}
|
||||
|
||||
|
||||
//============================================================
|
||||
// sdl2_display::sdl2_display
|
||||
@ -147,6 +88,11 @@ bool sdl2_display::init(void* pf_data)
|
||||
|
||||
//SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
|
||||
|
||||
// Get SDL version information
|
||||
SDL_version version;
|
||||
SDL_GetVersion(&version);
|
||||
log_info("Switchres/SDL2: Detected SDL version %d.%d.%d\n", (int)version.major, (int)version.minor, (int)version.patch);
|
||||
|
||||
SDL_Window* window = NULL;
|
||||
Uint32 id = 0;
|
||||
|
||||
@ -185,9 +131,6 @@ bool sdl2_display::init(void* pf_data)
|
||||
log_verbose("Switchres/SDL2: (%s:%d) No SDL2 window found, don't expect things to work good\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
if(m_sdlwindow)
|
||||
get_sdl_hwinfo_from_sdl_window(m_sdlwindow);
|
||||
|
||||
// Need a check to see if SDL2 can refresh the modelist
|
||||
return true;
|
||||
}
|
||||
|
48
deps/switchres/examples/switch_refresh.cpp
vendored
Normal file
48
deps/switchres/examples/switch_refresh.cpp
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
// Test switching of refresh rate only
|
||||
// Requires working update method
|
||||
//
|
||||
// Build: g++ -o switch_refresh switch_refresh.cpp -I ../ -L ../ -ldl -lswitchres -lSDL2 -lSDL2_ttf -ldrm
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <switchres/switchres_wrapper.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
sr_mode srm;
|
||||
|
||||
sr_set_log_level(3);
|
||||
sr_init();
|
||||
sr_set_disp(-1);
|
||||
sr_set_monitor("arcade_31");
|
||||
sr_init_disp("1", NULL);
|
||||
|
||||
printf("Testing first refresh (50Hz). Press any key...\n");
|
||||
getchar();
|
||||
|
||||
if (!sr_add_mode(648, 480, 50, 0, &srm))
|
||||
goto error;
|
||||
|
||||
if (!sr_set_mode(srm.id))
|
||||
goto error;
|
||||
|
||||
printf("Testing second refresh (60Hz). Press any key...\n");
|
||||
getchar();
|
||||
|
||||
if(!sr_add_mode(648, 480, 60, 0, &srm))
|
||||
goto error;
|
||||
|
||||
if(!sr_set_mode(srm.id))
|
||||
goto error;
|
||||
|
||||
printf("Success. Press any key to quit.\n");
|
||||
getchar();
|
||||
|
||||
sr_deinit();
|
||||
exit(0);
|
||||
|
||||
error:
|
||||
printf("ERROR: Exiting!\n");
|
||||
sr_deinit();
|
||||
exit(1);
|
||||
}
|
7
deps/switchres/makefile
vendored
7
deps/switchres/makefile
vendored
@ -64,6 +64,9 @@ else
|
||||
CPPFLAGS += -DSR_WITH_KMSDRM
|
||||
EXTRA_LIBS = libdrm
|
||||
SRC += custom_video_drmkms.cpp
|
||||
ifeq ($(SR_WITH_DRMHOOK),1)
|
||||
CPPFLAGS += -DSR_WITH_DRMHOOK
|
||||
endif
|
||||
endif
|
||||
|
||||
# SDL2 misses a test for drm as drm.h is required
|
||||
@ -150,8 +153,8 @@ install:
|
||||
$(INSTALL) -Dm644 switchres.h $(INCDIR)/switchres/switchres.h
|
||||
$(INSTALL) -Dm644 switchres.pc $(PKGDIR)/switchres.pc
|
||||
ifneq ($(SO_NAME),)
|
||||
$(LN) -s $(REAL_SO_NAME) $(LIBDIR)/$(SO_NAME)
|
||||
$(LN) -s $(SO_NAME) $(LIBDIR)/$(LINKER_NAME)
|
||||
$(LN) -s -f $(REAL_SO_NAME) $(LIBDIR)/$(SO_NAME)
|
||||
$(LN) -s -f $(SO_NAME) $(LIBDIR)/$(LINKER_NAME)
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
|
6
deps/switchres/modeline.cpp
vendored
6
deps/switchres/modeline.cpp
vendored
@ -168,9 +168,9 @@ int modeline_create(modeline *s_mode, modeline *t_mode, monitor_range *range, ge
|
||||
// if we can, let's apply the same scaling to both directions
|
||||
if (t_mode->type & X_RES_EDITABLE)
|
||||
{
|
||||
x_scale = y_scale;
|
||||
x_scale = cs->scale_proportional? y_scale : 1;
|
||||
double aspect_corrector = max(1.0f, cs->monitor_aspect / source_aspect);
|
||||
t_mode->hactive = normalize(double(t_mode->hactive) * double(x_scale) * aspect_corrector, 8);
|
||||
t_mode->hactive = normalize(double(t_mode->hactive) * double(x_scale) * aspect_corrector, cs->pixel_precision? 1 : 8);
|
||||
}
|
||||
|
||||
// otherwise, try to get the best out of our current xres
|
||||
@ -204,7 +204,7 @@ int modeline_create(modeline *s_mode, modeline *t_mode, monitor_range *range, ge
|
||||
|
||||
// check if we can create a normal aspect resolution
|
||||
if (t_mode->type & X_RES_EDITABLE)
|
||||
t_mode->hactive = max(t_mode->hactive, normalize(STANDARD_CRT_ASPECT * t_mode->vactive, 8));
|
||||
t_mode->hactive = max(t_mode->hactive, normalize(STANDARD_CRT_ASPECT * t_mode->vactive, cs->pixel_precision? 1 : 8));
|
||||
|
||||
// calculate integer scale for prescaling
|
||||
x_scale = max(1, scale_into_aspect(s_mode->hactive, t_mode->hactive, source_aspect, cs->monitor_aspect, &x_diff));
|
||||
|
1
deps/switchres/modeline.h
vendored
1
deps/switchres/modeline.h
vendored
@ -117,6 +117,7 @@ typedef struct generator_settings
|
||||
int v_shift_correct;
|
||||
int pixel_precision;
|
||||
int interlace_force_even;
|
||||
int scale_proportional;
|
||||
} generator_settings;
|
||||
|
||||
//============================================================
|
||||
|
7
deps/switchres/switchres.cpp
vendored
7
deps/switchres/switchres.cpp
vendored
@ -89,7 +89,7 @@ switchres_manager::switchres_manager()
|
||||
display()->set_monitor("generic_15");
|
||||
display()->set_modeline("auto");
|
||||
display()->set_lcd_range("auto");
|
||||
for (int i = 0; i++ < MAX_RANGES;) display()->set_crt_range(i, "auto");
|
||||
for (int i = 0; i < MAX_RANGES; i++) display()->set_crt_range(i, "auto");
|
||||
display()->set_screen("auto");
|
||||
display()->set_modeline_generation(true);
|
||||
display()->set_lock_unsupported_modes(true);
|
||||
@ -109,6 +109,7 @@ switchres_manager::switchres_manager()
|
||||
display()->set_v_shift_correct(0);
|
||||
display()->set_pixel_precision(1);
|
||||
display()->set_interlace_force_even(0);
|
||||
display()->set_scale_proportional(1);
|
||||
|
||||
// Set logger properties
|
||||
set_log_info_fn((void*)printf);
|
||||
@ -359,6 +360,10 @@ void switchres_manager::set_option(const char* key, const char* value)
|
||||
display()->set_interlace_force_even(atoi(value));
|
||||
break;
|
||||
|
||||
case s2i("scale_proportional"):
|
||||
display()->set_scale_proportional(atoi(value));
|
||||
break;
|
||||
|
||||
// Custom video backend options
|
||||
case s2i("screen_compositing"):
|
||||
display()->set_screen_compositing(atoi(value));
|
||||
|
2
deps/switchres/switchres.h
vendored
2
deps/switchres/switchres.h
vendored
@ -27,7 +27,7 @@
|
||||
//============================================================
|
||||
|
||||
#ifndef SWITCHRES_VERSION
|
||||
#define SWITCHRES_VERSION "2.1.0"
|
||||
#define SWITCHRES_VERSION "2.2.1"
|
||||
#endif
|
||||
|
||||
|
||||
|
3
deps/switchres/switchres.ini
vendored
3
deps/switchres/switchres.ini
vendored
@ -122,6 +122,9 @@
|
||||
# Calculate all vertical values of interlaced modes as even numbers. Required by AMD APU hardware on Linux
|
||||
interlace_force_even 0
|
||||
|
||||
# Scale both axes by the same factor, when integer scaling is applied
|
||||
scale_proportional 1
|
||||
|
||||
|
||||
#
|
||||
# Custom video backend config
|
||||
|
1
deps/switchres/switchres_defines.h
vendored
1
deps/switchres/switchres_defines.h
vendored
@ -33,6 +33,7 @@
|
||||
#define SR_OPT_V_SHIFT "v_shift"
|
||||
#define SR_OPT_PIXEL_PRECISION "pixel_precision"
|
||||
#define SR_OPT_INTERLACE_FORCE_EVEN "interlace_force_even"
|
||||
#define SR_OPT_SCALE_PROPORTIONAL "scale_proportional"
|
||||
#define SR_OPT_SCREEN_COMPOSITING "screen_compositing"
|
||||
#define SR_OPT_SCREEN_REORDERING "screen_reordering"
|
||||
#define SR_OPT_ALLOW_HARDWARE_REFRESH "allow_hardware_refresh"
|
||||
|
158
deps/switchres/switchres_main.cpp
vendored
158
deps/switchres/switchres_main.cpp
vendored
@ -16,6 +16,7 @@
|
||||
#include <cstring>
|
||||
#include <getopt.h>
|
||||
#include "switchres.h"
|
||||
#include "switchres_defines.h"
|
||||
#include "log.h"
|
||||
|
||||
using namespace std;
|
||||
@ -25,7 +26,42 @@ int show_usage();
|
||||
|
||||
enum
|
||||
{
|
||||
OPT_MODELINE = 128
|
||||
OPT_CRT_RANGE0 = 128,
|
||||
OPT_CRT_RANGE1,
|
||||
OPT_CRT_RANGE2,
|
||||
OPT_CRT_RANGE3,
|
||||
OPT_CRT_RANGE4,
|
||||
OPT_CRT_RANGE5,
|
||||
OPT_CRT_RANGE6,
|
||||
OPT_CRT_RANGE7,
|
||||
OPT_CRT_RANGE8,
|
||||
OPT_CRT_RANGE9,
|
||||
OPT_LCD_RANGE,
|
||||
OPT_MODELINE,
|
||||
OPT_USER_MODE,
|
||||
OPT_API,
|
||||
OPT_LOCK_UNSUPPORTED_MODES,
|
||||
OPT_LOCK_SYSTEM_MODES,
|
||||
OPT_REFRESH_DONT_CARE,
|
||||
OPT_KEEP_CHANGES,
|
||||
OPT_MODELINE_GENERATION,
|
||||
OPT_INTERLACE,
|
||||
OPT_DOUBLESCAN,
|
||||
OPT_DOTCLOCK_MIN,
|
||||
OPT_SYNC_REFRESH_TOLERANCE,
|
||||
OPT_SUPER_WIDTH,
|
||||
OPT_V_SHIFT_CORRECT,
|
||||
OPT_H_SIZE,
|
||||
OPT_H_SHIFT,
|
||||
OPT_V_SHIFT,
|
||||
OPT_PIXEL_PRECISION,
|
||||
OPT_INTERLACE_FORCE_EVEN,
|
||||
OPT_SCALE_PROPORTIONAL,
|
||||
OPT_SCREEN_COMPOSITING,
|
||||
OPT_SCREEN_REORDERING,
|
||||
OPT_ALLOW_HARDWARE_REFRESH,
|
||||
OPT_CUSTOM_TIMING,
|
||||
OPT_VERBOSITY
|
||||
};
|
||||
|
||||
//============================================================
|
||||
@ -68,28 +104,65 @@ int main(int argc, char **argv)
|
||||
{
|
||||
static struct option long_options[] =
|
||||
{
|
||||
// Options unique to standalone Switchres
|
||||
{"version", no_argument, &version_flag, '1'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"calc", no_argument, 0, 'c'},
|
||||
{"switch", no_argument, 0, 's'},
|
||||
{"launch", required_argument, 0, 'l'},
|
||||
{"monitor", required_argument, 0, 'm'},
|
||||
{"aspect", required_argument, 0, 'a'},
|
||||
{"edid", no_argument, 0, 'e'},
|
||||
{"rotated", no_argument, 0, 'r'},
|
||||
{"display", required_argument, 0, 'd'},
|
||||
{"force", required_argument, 0, 'f'},
|
||||
{"force", required_argument, 0, 'f'}, // equ. --user_mode
|
||||
{"ini", required_argument, 0, 'i'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"backend", required_argument, 0, 'b'},
|
||||
{"keep", no_argument, 0, 'k'},
|
||||
{"keep", no_argument, 0, 'k'}, // equ. --keep_changes
|
||||
{"geometry", required_argument, 0, 'g'},
|
||||
{"modeline", required_argument, 0, OPT_MODELINE},
|
||||
// Options available in short and long forms
|
||||
{SR_OPT_VERBOSE, no_argument, 0, 'v'},
|
||||
{SR_OPT_DISPLAY, required_argument, 0, 'd'},
|
||||
{SR_OPT_MONITOR, required_argument, 0, 'm'},
|
||||
{SR_OPT_ASPECT, required_argument, 0, 'a'},
|
||||
// Long options, from switchres.ini
|
||||
{SR_OPT_CRT_RANGE0, required_argument, 0, OPT_CRT_RANGE0},
|
||||
{SR_OPT_CRT_RANGE1, required_argument, 0, OPT_CRT_RANGE1},
|
||||
{SR_OPT_CRT_RANGE2, required_argument, 0, OPT_CRT_RANGE2},
|
||||
{SR_OPT_CRT_RANGE3, required_argument, 0, OPT_CRT_RANGE3},
|
||||
{SR_OPT_CRT_RANGE4, required_argument, 0, OPT_CRT_RANGE4},
|
||||
{SR_OPT_CRT_RANGE5, required_argument, 0, OPT_CRT_RANGE5},
|
||||
{SR_OPT_CRT_RANGE6, required_argument, 0, OPT_CRT_RANGE6},
|
||||
{SR_OPT_CRT_RANGE7, required_argument, 0, OPT_CRT_RANGE7},
|
||||
{SR_OPT_CRT_RANGE8, required_argument, 0, OPT_CRT_RANGE8},
|
||||
{SR_OPT_CRT_RANGE9, required_argument, 0, OPT_CRT_RANGE9},
|
||||
{SR_OPT_LCD_RANGE, required_argument, 0, OPT_LCD_RANGE},
|
||||
{SR_OPT_MODELINE, required_argument, 0, OPT_MODELINE},
|
||||
{SR_OPT_USER_MODE, required_argument, 0, OPT_USER_MODE},
|
||||
{SR_OPT_API, required_argument, 0, OPT_API},
|
||||
{SR_OPT_LOCK_UNSUPPORTED_MODES, required_argument, 0, OPT_LOCK_UNSUPPORTED_MODES},
|
||||
{SR_OPT_LOCK_SYSTEM_MODES, required_argument, 0, OPT_LOCK_SYSTEM_MODES},
|
||||
{SR_OPT_REFRESH_DONT_CARE, required_argument, 0, OPT_REFRESH_DONT_CARE},
|
||||
{SR_OPT_KEEP_CHANGES, required_argument, 0, OPT_KEEP_CHANGES},
|
||||
{SR_OPT_MODELINE_GENERATION, required_argument, 0, OPT_MODELINE_GENERATION},
|
||||
{SR_OPT_INTERLACE, required_argument, 0, OPT_INTERLACE},
|
||||
{SR_OPT_DOUBLESCAN, required_argument, 0, OPT_DOUBLESCAN},
|
||||
{SR_OPT_DOTCLOCK_MIN, required_argument, 0, OPT_DOTCLOCK_MIN},
|
||||
{SR_OPT_SYNC_REFRESH_TOLERANCE, required_argument, 0, OPT_SYNC_REFRESH_TOLERANCE},
|
||||
{SR_OPT_SUPER_WIDTH, required_argument, 0, OPT_SUPER_WIDTH},
|
||||
{SR_OPT_V_SHIFT_CORRECT, required_argument, 0, OPT_V_SHIFT_CORRECT},
|
||||
{SR_OPT_H_SIZE, required_argument, 0, OPT_H_SIZE},
|
||||
{SR_OPT_H_SHIFT, required_argument, 0, OPT_H_SHIFT},
|
||||
{SR_OPT_V_SHIFT, required_argument, 0, OPT_V_SHIFT},
|
||||
{SR_OPT_PIXEL_PRECISION, required_argument, 0, OPT_PIXEL_PRECISION},
|
||||
{SR_OPT_INTERLACE_FORCE_EVEN, required_argument, 0, OPT_INTERLACE_FORCE_EVEN},
|
||||
{SR_OPT_SCALE_PROPORTIONAL, required_argument, 0, OPT_SCALE_PROPORTIONAL},
|
||||
{SR_OPT_SCREEN_COMPOSITING, required_argument, 0, OPT_SCREEN_COMPOSITING},
|
||||
{SR_OPT_SCREEN_REORDERING, required_argument, 0, OPT_SCREEN_REORDERING},
|
||||
{SR_OPT_ALLOW_HARDWARE_REFRESH, required_argument, 0, OPT_ALLOW_HARDWARE_REFRESH},
|
||||
{SR_OPT_CUSTOM_TIMING, required_argument, 0, OPT_CUSTOM_TIMING},
|
||||
{SR_OPT_VERBOSITY, required_argument, 0, OPT_VERBOSITY},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int option_index = 0;
|
||||
int c = getopt_long(argc, argv, "vhcsl:m:a:erd:f:i:b:kg:", long_options, &option_index);
|
||||
int c = getopt_long(argc, argv, "vhcsl:m:a:erd:f:i:kg:", long_options, &option_index);
|
||||
|
||||
if (c == -1)
|
||||
break;
|
||||
@ -102,10 +175,6 @@ int main(int argc, char **argv)
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case OPT_MODELINE:
|
||||
df->set_modeline(optarg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
switchres.set_log_level(3);
|
||||
switchres.set_log_error_fn((void*)printf);
|
||||
@ -142,7 +211,8 @@ int main(int argc, char **argv)
|
||||
// Add new display in multi-monitor case
|
||||
if (index > 0) switchres.add_display();
|
||||
index ++;
|
||||
df->set_screen(optarg);
|
||||
switchres.set_current_display(-1);
|
||||
switchres.set_option(SR_OPT_DISPLAY, optarg);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
@ -154,9 +224,10 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
case OPT_USER_MODE:
|
||||
force_flag = true;
|
||||
if (sscanf(optarg, "%dx%d@%d", &user_mode.width, &user_mode.height, &user_mode.refresh) < 1)
|
||||
log_error("Error: use format --force <w>x<h>@<r>\n");
|
||||
log_error("Error: use format <w>x<h>@<r>\n");
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
@ -183,6 +254,45 @@ int main(int argc, char **argv)
|
||||
df->set_v_shift(v_shift);
|
||||
break;
|
||||
|
||||
// Long options
|
||||
case OPT_CRT_RANGE0:
|
||||
case OPT_CRT_RANGE1:
|
||||
case OPT_CRT_RANGE2:
|
||||
case OPT_CRT_RANGE3:
|
||||
case OPT_CRT_RANGE4:
|
||||
case OPT_CRT_RANGE5:
|
||||
case OPT_CRT_RANGE6:
|
||||
case OPT_CRT_RANGE7:
|
||||
case OPT_CRT_RANGE8:
|
||||
case OPT_CRT_RANGE9:
|
||||
case OPT_LCD_RANGE:
|
||||
case OPT_MODELINE:
|
||||
case OPT_API:
|
||||
case OPT_LOCK_UNSUPPORTED_MODES:
|
||||
case OPT_LOCK_SYSTEM_MODES:
|
||||
case OPT_REFRESH_DONT_CARE:
|
||||
case OPT_KEEP_CHANGES:
|
||||
case OPT_MODELINE_GENERATION:
|
||||
case OPT_INTERLACE:
|
||||
case OPT_DOUBLESCAN:
|
||||
case OPT_DOTCLOCK_MIN:
|
||||
case OPT_SYNC_REFRESH_TOLERANCE:
|
||||
case OPT_SUPER_WIDTH:
|
||||
case OPT_V_SHIFT_CORRECT:
|
||||
case OPT_H_SIZE:
|
||||
case OPT_H_SHIFT:
|
||||
case OPT_V_SHIFT:
|
||||
case OPT_PIXEL_PRECISION:
|
||||
case OPT_INTERLACE_FORCE_EVEN:
|
||||
case OPT_SCALE_PROPORTIONAL:
|
||||
case OPT_SCREEN_COMPOSITING:
|
||||
case OPT_SCREEN_REORDERING:
|
||||
case OPT_ALLOW_HARDWARE_REFRESH:
|
||||
case OPT_CUSTOM_TIMING:
|
||||
case OPT_VERBOSITY:
|
||||
switchres.set_option(long_options[option_index].name, optarg);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -265,7 +375,7 @@ int main(int argc, char **argv)
|
||||
monitor_range *range = &switchres.display()->range[mode->range];
|
||||
edid_from_modeline(mode, range, switchres.display()->monitor(), &edid);
|
||||
|
||||
char file_name[strlen(switchres.display()->monitor()) + 4];
|
||||
char file_name[strlen(switchres.display()->monitor()) + 5];
|
||||
sprintf(file_name, "%s.bin", switchres.display()->monitor());
|
||||
|
||||
FILE *file = fopen(file_name, "wb");
|
||||
@ -313,7 +423,7 @@ int show_version()
|
||||
{
|
||||
"Switchres " SWITCHRES_VERSION "\n"
|
||||
"Modeline generation engine for emulation\n"
|
||||
"Copyright (C) 2010-2021 - Chris Kennedy, Antonio Giner, Alexandre Wodarczyk, Gil Delescluse\n"
|
||||
"Copyright (C) 2010-2024 - Chris Kennedy, Antonio Giner, Alexandre Wodarczyk, Gil Delescluse\n"
|
||||
"License GPL-2.0+\n"
|
||||
"This is free software: you are free to change and redistribute it.\n"
|
||||
"There is NO WARRANTY, to the extent permitted by law.\n"
|
||||
@ -338,15 +448,17 @@ int show_usage()
|
||||
" -l, --launch <command> Launch <command>\n"
|
||||
" -m, --monitor <preset> Monitor preset (generic_15, arcade_15, pal, ntsc, etc.)\n"
|
||||
" -a, --aspect <num:den> Monitor aspect ratio\n"
|
||||
" -r, --rotated Original mode's native orientation is rotated\n"
|
||||
" -d, --display <OS_display_name> Use target display (Windows: \\\\.\\DISPLAY1, ... Linux: VGA-0, ...)\n"
|
||||
" -r, --rotated Rotate axes, preserving aspect ratio.\n"
|
||||
" -d, --display <display_index> Use target display (index = 0, 1, 2...)\n"
|
||||
" -f, --force <w>x<h>@<r> Force a specific video mode from display mode list\n"
|
||||
" -i, --ini <file.ini> Specify an ini file\n"
|
||||
" -b, --backend <api_name> Specify the api name\n"
|
||||
" -e, --edid Create an EDID binary with calculated video modes\n"
|
||||
" -k, --keep Keep changes on exit (warning: this disables cleanup)\n"
|
||||
" -g, --geometry <h_size>:<h_shift>:<v_shift> Adjust geometry of generated modeline\n"
|
||||
" --modeline <\"pclk hdisp hsst hsend htot vdisp vsst vsend vtot flags\"> Force an XFree86 modeline\n"
|
||||
" -g, --geometry <adjustment> Adjust geometry of generated modeline\n"
|
||||
" adjustment = <h_size>:<h_shift>:<v_shift>\n"
|
||||
" e.g. switchres 640 480 60 -c -g 1.1:-1:2\n\n"
|
||||
"For more options, refer to switchres.ini. All options in switchres.ini can be applied in\n"
|
||||
"command line as long options, e.g.: switchres 256 224 57.55 -c --dotclock_min 8.0\n\n"
|
||||
};
|
||||
|
||||
log_info("%s", usage);
|
||||
|
Loading…
Reference in New Issue
Block a user