Skip to content

Commit

Permalink
gtk: implement GPU scale factor feature (#764)
Browse files Browse the repository at this point in the history
* [WIP] gtk: implement GPU scale factor feature

* Replace combobox with spin button, fix taking screenshot

* Fix distorted image, add some checks for scale factor value

* Make OSD at least properly visible
  • Loading branch information
thesourcehim committed Jan 25, 2024
1 parent b06537c commit f2cfd23
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 17 deletions.
18 changes: 18 additions & 0 deletions desmume/src/frontend/posix/gtk/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ void value<int>::save() {
g_key_file_set_integer(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), this->mData);
}

/*class value<float> */

template<>
void value<float>::load() {
GError* err = NULL;
float val = g_key_file_get_double(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), &err);
if (err != NULL) {
g_error_free(err);
} else {
this->mData = val;
}
}

template<>
void value<float>::save() {
g_key_file_set_double(this->mKeyFile, this->mSection.c_str(), this->mKey.c_str(), this->mData);
}

/* class value<string> */

template<>
Expand Down
1 change: 1 addition & 0 deletions desmume/src/frontend/posix/gtk/config_opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ OPT(core3D, int, 1, Config, Core3D)
OPT(textureDeposterize, bool, false, Config, 3DTextureDeposterization)
OPT(textureSmoothing, bool, false, Config, 3DTextureSmoothing)
OPT(textureUpscale, int, 1, Config, 3DTextureUpscaling)
OPT(gpuScaleFactor, float, 1.0, Config, GPUScaleFactor)
OPT(highColorInterpolation, bool, true, Config, HighResolutionColorInterpolation)
OPT(multisampling, bool, false, Config, OpenGLMultisampling)
OPT(multisamplingSize, int, 0, Config, OpenGLMultisamplingSize)
Expand Down
29 changes: 24 additions & 5 deletions desmume/src/frontend/posix/gtk/graphics.ui
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,33 @@
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">GPU scale factor:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="gpuscale">
<property name="numeric">true</property>
<property name="digits">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="posterize">
<property name="label" translatable="yes">3D Texture Deposterization</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
Expand All @@ -111,7 +130,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
Expand All @@ -121,7 +140,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
Expand All @@ -130,7 +149,7 @@
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
Expand All @@ -146,7 +165,7 @@
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="top_attach">5</property>
</packing>
</child>
</object>
Expand Down
61 changes: 50 additions & 11 deletions desmume/src/frontend/posix/gtk/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ static int draw_count;
extern int _scanline_filter_a, _scanline_filter_b, _scanline_filter_c, _scanline_filter_d;
VideoFilter* video;

#define GPU_SCALE_FACTOR_MIN 1.0f
#define GPU_SCALE_FACTOR_MAX 10.0f

float gpu_scale_factor = 1.0f;
int real_framebuffer_width = GPU_FRAMEBUFFER_NATIVE_WIDTH;
int real_framebuffer_height = GPU_FRAMEBUFFER_NATIVE_HEIGHT;


desmume::config::Config config;

#ifdef GDB_STUB
Expand Down Expand Up @@ -1310,7 +1318,8 @@ static int ConfigureDrawingArea(GtkWidget *widget, GdkEventConfigure *event, gpo

static inline void gpu_screen_to_rgb(u32* dst)
{
ColorspaceConvertBuffer555To8888Opaque<false, false, BESwapDst>(GPU->GetDisplayInfo().masterNativeBuffer16, dst, GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
ColorspaceConvertBuffer555To8888Opaque<false, false, BESwapDst>(GPU->GetDisplayInfo().isCustomSizeRequested ? (u16*)(GPU->GetDisplayInfo().masterCustomBuffer) : GPU->GetDisplayInfo().masterNativeBuffer16,
dst, real_framebuffer_width * real_framebuffer_height * 2);
}

static inline void drawScreen(cairo_t* cr, u32* buf, gint w, gint h) {
Expand Down Expand Up @@ -1384,7 +1393,7 @@ static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpo
gint dstW = video->GetDstWidth();
gint dstH = video->GetDstHeight();

gint dstScale = dstW * 2 / 256; // Actual scale * 2 to handle 1.5x filters
gint dstScale = dstW * 2 / GPU_FRAMEBUFFER_NATIVE_WIDTH; // Actual scale * 2 to handle 1.5x filters

gint gap = nds_screen.orientation == ORIENT_VERTICAL ? nds_screen.gap_size * dstScale / 2 : 0;
gint imgW, imgH;
Expand Down Expand Up @@ -1436,9 +1445,11 @@ static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpo
}

static void RedrawScreen() {
ColorspaceConvertBuffer555To8888Opaque<true, false, BESwapDst>(GPU->GetDisplayInfo().masterNativeBuffer16, (uint32_t *)video->GetSrcBufferPtr(), GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2);
ColorspaceConvertBuffer555To8888Opaque<true, false, BESwapDst>(
GPU->GetDisplayInfo().isCustomSizeRequested ? (u16*)(GPU->GetDisplayInfo().masterCustomBuffer) : GPU->GetDisplayInfo().masterNativeBuffer16,
(uint32_t *)video->GetSrcBufferPtr(), real_framebuffer_width * real_framebuffer_height * 2);
#ifdef HAVE_LIBAGG
aggDraw.hud->attach((u8*)video->GetSrcBufferPtr(), 256, 384, 1024);
aggDraw.hud->attach((u8*)video->GetSrcBufferPtr(), real_framebuffer_width, real_framebuffer_height * 2, 1024 * gpu_scale_factor);
osd->update();
DrawHUD();
osd->clear();
Expand Down Expand Up @@ -1989,12 +2000,16 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
GtkGrid *wGrid;
GtkComboBox *coreCombo, *wScale, *wMultisample;
GtkToggleButton *wPosterize, *wSmoothing, *wHCInterpolate;
GtkSpinButton *wGPUScale;

GtkBuilder *builder = gtk_builder_new_from_resource("/org/desmume/DeSmuME/graphics.ui");
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "dialog"));
wGrid = GTK_GRID(gtk_builder_get_object(builder, "graphics_grid"));
coreCombo = GTK_COMBO_BOX(gtk_builder_get_object(builder, "core_combo"));
wScale = GTK_COMBO_BOX(gtk_builder_get_object(builder, "scale"));
wGPUScale = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "gpuscale"));
gtk_spin_button_set_range(wGPUScale, GPU_SCALE_FACTOR_MIN, GPU_SCALE_FACTOR_MAX);
gtk_spin_button_set_increments(wGPUScale, 1.0, 1.0);
wMultisample = GTK_COMBO_BOX(gtk_builder_get_object(builder, "multisample"));
wPosterize = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "posterize"));
wSmoothing = GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "smoothing"));
Expand All @@ -2010,6 +2025,9 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
// The shift it work for scale up to 4. For scaling more than 4, a mapping function is required
gtk_combo_box_set_active(wScale, CommonSettings.GFX3D_Renderer_TextureScalingFactor >> 1);

//GPU scaling factor
gtk_spin_button_set_value(wGPUScale, gpu_scale_factor);

// 3D Texture Deposterization
gtk_toggle_button_set_active(wPosterize, CommonSettings.GFX3D_Renderer_TextureDeposterize);

Expand Down Expand Up @@ -2080,6 +2098,17 @@ static void GraphicsSettingsDialog(GSimpleAction *action, GVariant *parameter, g
default:
break;
}
gpu_scale_factor = gtk_spin_button_get_value(wGPUScale);
if(gpu_scale_factor < GPU_SCALE_FACTOR_MIN)
gpu_scale_factor = GPU_SCALE_FACTOR_MIN;
if(gpu_scale_factor > GPU_SCALE_FACTOR_MAX)
gpu_scale_factor = GPU_SCALE_FACTOR_MAX;
gtk_spin_button_set_value(wGPUScale, gpu_scale_factor);
config.gpuScaleFactor = gpu_scale_factor;
real_framebuffer_width = GPU_FRAMEBUFFER_NATIVE_WIDTH * gpu_scale_factor;
real_framebuffer_height = GPU_FRAMEBUFFER_NATIVE_HEIGHT * gpu_scale_factor;
GPU->SetCustomFramebufferSize(real_framebuffer_width, real_framebuffer_height);
video->SetSourceSize(real_framebuffer_width, real_framebuffer_height * 2);
CommonSettings.GFX3D_Renderer_TextureDeposterize = config.textureDeposterize = gtk_toggle_button_get_active(wPosterize);
CommonSettings.GFX3D_Renderer_TextureSmoothing = config.textureSmoothing = gtk_toggle_button_get_active(wSmoothing);
CommonSettings.GFX3D_Renderer_TextureScalingFactor = config.textureUpscale = scale;
Expand Down Expand Up @@ -2140,7 +2169,7 @@ static void Printscreen(GSimpleAction *action, GVariant *parameter, gpointer use
const gchar *dir;
gchar *filename = NULL, *filen = NULL;
GError *error = NULL;
u8 rgb[256 * 384 * 4];
u8 *rgb = (u8*)malloc(real_framebuffer_width * real_framebuffer_height * 2 * 4);
static int seq = 0;
gint H, W;

Expand All @@ -2149,11 +2178,11 @@ static void Printscreen(GSimpleAction *action, GVariant *parameter, gpointer use
// return;

if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
W = screen_size[nds_screen.orientation].width;
H = screen_size[nds_screen.orientation].height;
W = real_framebuffer_width;
H = real_framebuffer_height * 2;
} else {
W = screen_size[nds_screen.orientation].height;
H = screen_size[nds_screen.orientation].width;
W = real_framebuffer_height * 2;
H = real_framebuffer_width;
}

gpu_screen_to_rgb((u32*)rgb);
Expand Down Expand Up @@ -2190,7 +2219,7 @@ static void Printscreen(GSimpleAction *action, GVariant *parameter, gpointer use
seq--;
}

//free(rgb);
free(rgb);
g_object_unref(screenshot);
g_free(filename);
g_free(filen);
Expand Down Expand Up @@ -3026,8 +3055,18 @@ common_gtk_main(GApplication *app, gpointer user_data)
memset(&nds_screen, 0, sizeof(nds_screen));
nds_screen.orientation = ORIENT_VERTICAL;

gpu_scale_factor = config.gpuScaleFactor;
if(gpu_scale_factor < GPU_SCALE_FACTOR_MIN)
gpu_scale_factor = GPU_SCALE_FACTOR_MIN;
if(gpu_scale_factor > GPU_SCALE_FACTOR_MAX)
gpu_scale_factor = GPU_SCALE_FACTOR_MAX;
config.gpuScaleFactor = gpu_scale_factor;
real_framebuffer_width = GPU_FRAMEBUFFER_NATIVE_WIDTH * gpu_scale_factor;
real_framebuffer_height = GPU_FRAMEBUFFER_NATIVE_HEIGHT * gpu_scale_factor;

g_printerr("Using %d threads for video filter.\n", CommonSettings.num_cores);
video = new VideoFilter(256, 384, VideoFilterTypeID_None, CommonSettings.num_cores);
GPU->SetCustomFramebufferSize(real_framebuffer_width, real_framebuffer_height);
video = new VideoFilter(real_framebuffer_width, real_framebuffer_height * 2, VideoFilterTypeID_None, CommonSettings.num_cores);

/* Fetch the main elements from the window */
GtkBuilder *builder = gtk_builder_new_from_resource("/org/desmume/DeSmuME/main.ui");
Expand Down
6 changes: 5 additions & 1 deletion desmume/src/frontend/posix/gtk/sdl_3Demu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ static bool sdl_init(void) { return is_sdl_initialized(); }
static SDL_Window *win = NULL;
static SDL_GLContext ctx = NULL;

extern int real_framebuffer_width;
extern int real_framebuffer_height;

bool deinit_sdl_3Demu(void)
{
bool ret = false;
Expand Down Expand Up @@ -60,7 +63,8 @@ bool init_sdl_3Demu(void)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);

win = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 256, 192, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
win = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, real_framebuffer_width,
real_framebuffer_height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
if (!win) {
fprintf(stderr, "SDL: Failed to create a window: %s\n", SDL_GetError());
return false;
Expand Down

0 comments on commit f2cfd23

Please sign in to comment.