Skip to content

Commit

Permalink
Update to upstream Switchres.
Browse files Browse the repository at this point in the history
  • Loading branch information
antonioginer committed Aug 7, 2022
1 parent 350f452 commit 5dc682a
Show file tree
Hide file tree
Showing 7 changed files with 3,975 additions and 27 deletions.
2 changes: 1 addition & 1 deletion 3rdparty/switchres/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ modeline *display_manager::get_mode(int width, int height, float refresh, bool i
}

if ((best_mode.type & V_FREQ_EDITABLE) && !(best_mode.result.weight & R_OUT_OF_RANGE))
modeline_adjust(&best_mode, &m_ds.gs);
modeline_adjust(&best_mode, range[best_mode.range].hfreq_max, &m_ds.gs);

log_verbose("\nSwitchres: %s (%dx%d@%.6f)->(%dx%d@%.6f)\n", rotation()?"rotated":"normal",
width, height, refresh, best_mode.hactive, best_mode.vactive, best_mode.vfreq);
Expand Down
3,776 changes: 3,776 additions & 0 deletions 3rdparty/switchres/font.h

Large diffs are not rendered by default.

154 changes: 147 additions & 7 deletions 3rdparty/switchres/grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,36 @@
Switchres Modeline generation engine for emulation
License GPL-2.0+
Copyright 2010-2021 Chris Kennedy, Antonio Giner,
Alexandre Wodarczyk, Gil Delescluse
Copyright 2010-2022 Chris Kennedy, Antonio Giner,
Alexandre Wodarczyk, Gil Delescluse,
Radek Dutkiewicz
**************************************************************/

// To add additional text lines:
// export GRID_TEXT="$(echo -e "\nArrows - screen position, Page Up/Down - H size\n\nH size: 1.0\nH position: 0\nV position: 0")"

// To remove additional lines:
// unset GRID_TEXT


#define SDL_MAIN_HANDLED
#define NUM_GRIDS 2

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include "font.h"
#include <string.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>

#define FONT_SIZE 11

enum GRID_ADJUST
{
LEFT = 8000,
LEFT = 64,
RIGHT,
UP,
DOWN,
Expand All @@ -35,13 +52,19 @@ typedef struct grid_display

SDL_Window *window;
SDL_Renderer *renderer;
std::vector<SDL_Texture*> textures;
} GRID_DISPLAY;

SDL_Surface *surface;
TTF_Font *font;
std::vector<std::string> grid_texts;


//============================================================
// draw_grid
//============================================================

void draw_grid(int num_grid, int width, int height, SDL_Renderer *renderer)
void draw_grid(int num_grid, int width, int height, SDL_Renderer *renderer, std::vector<SDL_Texture*> textures)
{
// Clean the surface
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
Expand Down Expand Up @@ -119,6 +142,60 @@ void draw_grid(int num_grid, int width, int height, SDL_Renderer *renderer)
break;
}

// Compute text scaling factors
int text_scale_w = std::max(1, (int)floor(width / 320 + 0.5));
int text_scale_h = std::max(1, (int)floor(height / 240 + 0.5));

SDL_Rect text_frame = {0, 0, 0, 0};

// Compute text frame size
for (SDL_Texture *t : textures)
{
int texture_width = 0;
int texture_height = 0;

SDL_QueryTexture(t, NULL, NULL, &texture_width, &texture_height);

text_frame.w = std::max(text_frame.w, texture_width);
text_frame.h += texture_height;
}

text_frame.w *= text_scale_w;
text_frame.h *= text_scale_h;

text_frame.w += FONT_SIZE * text_scale_w; // margin x
text_frame.h += FONT_SIZE * text_scale_h; // margin y

text_frame.x = ceil((width - text_frame.w ) / 2);
text_frame.y = ceil((height - text_frame.h ) / 2);

// Draw Text background
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &text_frame);

// Draw Text frame
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDrawRect(renderer, &text_frame);

// Draw text lines
SDL_Rect text_rect = {0, text_frame.y + FONT_SIZE * text_scale_h / 2, 0, 0};

for (SDL_Texture *t : textures)
{
int texture_width = 0;
int texture_height = 0;

SDL_QueryTexture(t, NULL, NULL, &texture_width, &texture_height);

text_rect.w = texture_width *= text_scale_w;
text_rect.h = texture_height *= text_scale_h;
text_rect.x = ceil((width - text_rect.w ) / 2);

SDL_RenderCopy(renderer, t, NULL, &text_rect);

text_rect.y += text_rect.h;
}

SDL_RenderPresent(renderer);
}

Expand Down Expand Up @@ -167,6 +244,25 @@ int main(int argc, char **argv)
display_total = 1;
}

// Initialize text
TTF_Init();
SDL_RWops* font_resource = SDL_RWFromConstMem(ATTRACTPLUS_TTF, (sizeof(ATTRACTPLUS_TTF)) / (sizeof(ATTRACTPLUS_TTF[0])));
font = TTF_OpenFontRW(font_resource, 1, FONT_SIZE);

grid_texts.push_back(" "); // empty line for screen resolution

char *grid_text = getenv("GRID_TEXT");

if ( grid_text != NULL )
{
char* p = strtok(grid_text, "\n");
while(p)
{
grid_texts.push_back(p);
p = strtok(NULL, "\n");
}
}

// Create windows
for (int disp = 0; disp < display_total; disp++)
{
Expand All @@ -189,14 +285,27 @@ int main(int argc, char **argv)
display_array[disp].renderer = SDL_CreateRenderer(display_array[disp].window, -1, SDL_RENDERER_ACCELERATED);
SDL_RenderPresent(display_array[disp].renderer);

// Render first text
grid_texts[0] = "Mode: " + std::to_string(dm.w) + " x " + std::to_string(dm.h) + " @ " + std::to_string(dm.refresh_rate);

for ( int i = 0; i < grid_texts.size(); i++ )
{
surface = TTF_RenderText_Solid(font, grid_texts[i].c_str(), {255, 255, 255});
display_array[disp].textures.push_back(SDL_CreateTextureFromSurface(display_array[disp].renderer, surface));
}

// Draw grid
draw_grid(0, display_array[disp].width, display_array[disp].height, display_array[disp].renderer);
draw_grid(0, display_array[disp].width, display_array[disp].height, display_array[disp].renderer, display_array[disp].textures);
}




// Wait for escape key
bool close = false;
int num_grid = 0;
int return_code = 0;
int CTRL_modifier = 0;

while (!close)
{
Expand All @@ -211,16 +320,37 @@ int main(int argc, char **argv)
break;

case SDL_KEYDOWN:
if (event.key.keysym.mod & KMOD_LCTRL || event.key.keysym.mod & KMOD_RCTRL)
CTRL_modifier = 1<<7;

switch (event.key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
case SDL_SCANCODE_Q:
close = true;
return_code = 1;
break;

case SDL_SCANCODE_BACKSPACE:
case SDL_SCANCODE_DELETE:
close = true;
return_code = 2;
break;

case SDL_SCANCODE_R:
close = true;
return_code = 3;
break;

case SDL_SCANCODE_RETURN:
case SDL_SCANCODE_KP_ENTER:
close = true;
break;

case SDL_SCANCODE_TAB:
num_grid ++;
for (int disp = 0; disp < display_total; disp++)
draw_grid(num_grid % NUM_GRIDS, display_array[disp].width, display_array[disp].height, display_array[disp].renderer);
draw_grid(num_grid % NUM_GRIDS, display_array[disp].width, display_array[disp].height, display_array[disp].renderer, display_array[disp].textures);
break;

case SDL_SCANCODE_LEFT:
Expand Down Expand Up @@ -256,15 +386,25 @@ int main(int argc, char **argv)
default:
break;
}

}
}
}

// Destroy font
SDL_FreeSurface(surface);
TTF_CloseFont(font);
TTF_Quit();

// Destroy all windows
for (int disp = 0; disp < display_total; disp++)
{
for (SDL_Texture *t : display_array[disp].textures)
SDL_DestroyTexture(t);
SDL_DestroyWindow(display_array[disp].window);
}

SDL_Quit();

return return_code;
return return_code | CTRL_modifier;
}
5 changes: 3 additions & 2 deletions 3rdparty/switchres/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ DYNAMIC_LIB_EXT = so
# Windows
else ifneq (,$(findstring NT,$(PLATFORM)))
SRC += display_windows.cpp custom_video_ati_family.cpp custom_video_ati.cpp custom_video_adl.cpp custom_video_pstrip.cpp resync_windows.cpp
CPPFLAGS += -static -static-libgcc -static-libstdc++
WIN_ONLY_FLAGS = -static-libgcc -static-libstdc++
CPPFLAGS += -static $(WIN_ONLY_FLAGS)
LIBS =
#REMOVE = del /f
REMOVE = rm -f
Expand Down Expand Up @@ -117,7 +118,7 @@ $(DRMHOOK_LIB):
$(FINAL_CXX) drm_hook.cpp -shared -ldl -fPIC -I/usr/include/libdrm -o libdrmhook.so

$(GRID):
$(FINAL_CXX) grid.cpp -lSDL2 -o grid
$(FINAL_CXX) grid.cpp $(WIN_ONLY_FLAGS) -lSDL2 -lSDL2_ttf -o grid

clean:
$(REMOVE) $(OBJS) $(STANDALONE) $(TARGET_LIB).*
Expand Down
55 changes: 41 additions & 14 deletions 3rdparty/switchres/modeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,26 +657,27 @@ int modeline_to_monitor_range(monitor_range *range, modeline *mode)

double line_time = 1 / mode->hfreq;
double pixel_time = line_time / mode->htotal * 1000000;
double interlace_factor = mode->interlace? 0.5 : 1.0;

range->hfront_porch = pixel_time * (mode->hbegin - mode->hactive);
range->hsync_pulse = pixel_time * (mode->hend - mode->hbegin);
range->hback_porch = pixel_time * (mode->htotal - mode->hend);

range->vfront_porch = line_time * (mode->vbegin - mode->vactive);
range->vsync_pulse = line_time * (mode->vend - mode->vbegin);
range->vback_porch = line_time * (mode->vtotal - mode->vend);
range->vfront_porch = line_time * (mode->vbegin - mode->vactive) * interlace_factor;
range->vsync_pulse = line_time * (mode->vend - mode->vbegin) * interlace_factor;
range->vback_porch = line_time * (mode->vtotal - mode->vend) * interlace_factor;
range->vertical_blank = range->vfront_porch + range->vsync_pulse + range->vback_porch;

range->hsync_polarity = mode->hsync;
range->vsync_polarity = mode->vsync;

range->progressive_lines_min = mode->interlace?0:mode->vactive;
range->progressive_lines_max = mode->interlace?0:mode->vactive;
range->interlaced_lines_min = mode->interlace?mode->vactive:0;
range->interlaced_lines_max= mode->interlace?mode->vactive:0;
range->progressive_lines_min = mode->interlace? 0 : mode->vactive;
range->progressive_lines_max = mode->interlace? 0 : mode->vactive;
range->interlaced_lines_min = mode->interlace? mode->vactive : 0;
range->interlaced_lines_max= mode->interlace? mode->vactive : 0;

range->hfreq_min = range->vfreq_min * mode->vtotal;
range->hfreq_max = range->vfreq_max * mode->vtotal;
range->hfreq_min = range->vfreq_min * mode->vtotal * interlace_factor;
range->hfreq_max = range->vfreq_max * mode->vtotal * interlace_factor;

return 1;
}
Expand All @@ -685,7 +686,7 @@ int modeline_to_monitor_range(monitor_range *range, modeline *mode)
// modeline_v_shift
//============================================================

int modeline_adjust(modeline *mode, generator_settings *cs)
int modeline_adjust(modeline *mode, double hfreq_max, generator_settings *cs)
{
// If input values are out of range, they are fixed within range and returned in the cs struct.

Expand Down Expand Up @@ -724,14 +725,40 @@ int modeline_adjust(modeline *mode, generator_settings *cs)
// V shift adjustment, positive or negative value
if (cs->v_shift != 0)
{
if (cs->v_shift >= mode->vbegin - mode->vactive)
cs->v_shift = mode->vbegin - mode->vactive - 1;
int v_front_porch = mode->vbegin - mode->vactive;
int v_back_porch = mode->vend - mode->vtotal;
int max_vtotal = hfreq_max / mode->vfreq * (mode->interlace? 2 : 1);
int border = max_vtotal - mode->vtotal;
int padding = 0;

else if (cs->v_shift <= mode->vend - mode->vtotal)
cs->v_shift = mode->vend - mode->vtotal + 1;
if (cs->v_shift >= v_front_porch)
{
int v_front_porch_ex = v_front_porch + border;
if (cs->v_shift >= v_front_porch_ex)
cs->v_shift = v_front_porch_ex - 1;

padding = cs->v_shift - v_front_porch + 1;
mode->vbegin += padding;
mode->vend += padding;
mode->vtotal += padding;
}

else if (cs->v_shift <= v_back_porch + 1)
cs->v_shift = v_back_porch + 2;

mode->vbegin -= cs->v_shift;
mode->vend -= cs->v_shift;

if (padding != 0)
{
mode->hfreq = mode->vfreq * mode->vtotal / (mode->interlace? 2.0 : 1.0);

monitor_range range;
memset(&range, 0, sizeof(monitor_range));
modeline_to_monitor_range(&range, mode);
monitor_show_range(&range);
modeline_create(mode, mode, &range, cs);
}
}

return 0;
Expand Down
2 changes: 1 addition & 1 deletion 3rdparty/switchres/modeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ char * modeline_result(modeline *mode, char *result);
int modeline_vesa_gtf(modeline *m);
int modeline_parse(const char *user_modeline, modeline *mode);
int modeline_to_monitor_range(monitor_range *range, modeline *mode);
int modeline_adjust(modeline *mode, generator_settings *cs);
int modeline_adjust(modeline *mode, double hfreq_max, generator_settings *cs);
int modeline_is_different(modeline *n, modeline *p);

int round_near(double number);
Expand Down
8 changes: 6 additions & 2 deletions 3rdparty/switchres/switchres_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,12 @@ int main(int argc, char **argv)
modeline *mode = display->get_mode(width, height, refresh, interlaced_flag);
if (mode) display->flush_modes();

if (geometry_flag)
if (mode && geometry_flag)
{
monitor_range range = {};
modeline_to_monitor_range(&range, mode);
log_info("Adjusted geometry: H: %.3f, %.3f, %.3f V: %.3f, %.3f, %.3f\n",
log_info("Adjusted geometry (%.3f:%d:%d) H: %.3f, %.3f, %.3f V: %.3f, %.3f, %.3f\n",
display->h_size(), display->h_shift(), display->v_shift(),
range.hfront_porch, range.hsync_pulse, range.hback_porch,
range.vfront_porch * 1000, range.vsync_pulse * 1000, range.vback_porch * 1000);
}
Expand Down Expand Up @@ -269,6 +270,9 @@ int main(int argc, char **argv)
if (launch_flag)
{
status_code = system(launch_command.c_str());
#ifdef __linux__
status_code = WEXITSTATUS(status_code);
#endif
log_info("Process exited with value %d\n", status_code);
}
}
Expand Down

0 comments on commit 5dc682a

Please sign in to comment.