Skip to content

Commit 3744ec7

Browse files
committed
Added integer scaling option
Might help with #81
1 parent 0d6235a commit 3744ec7

File tree

6 files changed

+42
-13
lines changed

6 files changed

+42
-13
lines changed

src/core/n64video.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct n64video_config
100100
bool hide_overscan; // crop to visible area if true
101101
bool vsync; // enable vsync if true
102102
bool exclusive; // run in exclusive mode when in fullscreen if true
103+
bool integer_scaling; // one native pixel is displayed as a multiple of a screen pixel if true
103104
} vi;
104105
struct {
105106
enum dp_compat_profile compat; // multithreading compatibility mode

src/output/vdac.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
static bool m_fbo_enabled;
2121
static GLuint m_fbo;
22+
static bool m_integer_scaling;
2223

2324
static GLuint m_fbtex;
2425
static uint32_t m_fbtex_width;
@@ -278,6 +279,9 @@ void vdac_init(struct n64video_config* config)
278279
// read with exact FB size in non-filtered modes
279280
m_rawtex_read = config->vi.mode != VI_MODE_NORMAL;
280281

282+
// save integer scaling flag, will be used later
283+
m_integer_scaling = config->vi.integer_scaling;
284+
281285
// check if there was an error when using any of the commands above
282286
gl_check_errors();
283287
}
@@ -393,19 +397,37 @@ void vdac_sync(bool valid)
393397
return;
394398
}
395399

396-
int32_t hw = m_fbtex_height * win_width;
397-
int32_t wh = m_fbtex_width * win_height;
398-
399-
// add letterboxes or pillarboxes if the window has a different aspect ratio
400-
// than the current display mode
401-
if (hw > wh) {
402-
int32_t w_max = wh / m_fbtex_height;
403-
win_x += (win_width - w_max) / 2;
404-
win_width = w_max;
405-
} else if (hw < wh) {
406-
int32_t h_max = hw / m_fbtex_width;
407-
win_y += (win_height - h_max) / 2;
408-
win_height = h_max;
400+
if (m_integer_scaling) {
401+
// get smallest integer scale that is at least 1
402+
uint32_t scale_x = (uint32_t)win_width < m_fbtex_width ? 1 : (uint32_t)win_width / m_fbtex_width;
403+
uint32_t scale_y = (uint32_t)win_height < m_fbtex_height ? 1 : (uint32_t)win_height / m_fbtex_height;
404+
uint32_t scale = scale_x > scale_y ? scale_x : scale_y;
405+
406+
// get new window size (or rather viewport size in this context)
407+
int32_t win_width_new = m_fbtex_width * scale;
408+
int32_t win_height_new = m_fbtex_height * scale;
409+
410+
// apply new size and offset
411+
win_x = (win_width - win_width_new) / 2;
412+
win_y = (win_height - win_height_new) / 2;
413+
414+
win_width = win_width_new;
415+
win_height = win_height_new;
416+
} else {
417+
int32_t hw = m_fbtex_height * win_width;
418+
int32_t wh = m_fbtex_width * win_height;
419+
420+
// add letterboxes or pillarboxes if the window has a different aspect ratio
421+
// than the current display mode
422+
if (hw > wh) {
423+
int32_t w_max = wh / m_fbtex_height;
424+
win_x += (win_width - w_max) / 2;
425+
win_width = w_max;
426+
} else if (hw < wh) {
427+
int32_t h_max = hw / m_fbtex_width;
428+
win_y += (win_height - h_max) / 2;
429+
win_height = h_max;
430+
}
409431
}
410432

411433
if (m_fbo_enabled) {

src/plugin/mupen64plus/gfx_m64p.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#define KEY_VI_INTERP "ViInterpolation"
3434
#define KEY_VI_WIDESCREEN "ViWidescreen"
3535
#define KEY_VI_HIDE_OVERSCAN "ViHideOverscan"
36+
#define KEY_VI_INTEGER_SCALING "ViIntegerScaling"
3637

3738
#define KEY_DP_COMPAT "DpCompat"
3839

@@ -117,6 +118,7 @@ EXPORT m64p_error CALL PluginStartup(m64p_dynlib_handle _CoreLibHandle, void *Co
117118
ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_VI_INTERP, config.vi.interp, "Scaling interpolation type (0=NN, 1=Linear)");
118119
ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_WIDESCREEN, config.vi.widescreen, "Use anamorphic 16:9 output mode if True");
119120
ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_HIDE_OVERSCAN, config.vi.hide_overscan, "Hide overscan area in filteded mode if True");
121+
ConfigSetDefaultBool(configVideoAngrylionPlus, KEY_VI_INTEGER_SCALING, config.vi.integer_scaling, "Display upscaled pixels as groups of 1x1, 2x2, 3x3, etc. if True");
120122
ConfigSetDefaultInt(configVideoAngrylionPlus, KEY_DP_COMPAT, config.dp.compat, "Compatibility mode (0=Fast 1=Moderate 2=Slow");
121123

122124
ConfigSaveSection("Video-General");
@@ -204,6 +206,7 @@ EXPORT int CALL RomOpen (void)
204206
config.vi.interp = ConfigGetParamInt(configVideoAngrylionPlus, KEY_VI_INTERP);
205207
config.vi.widescreen = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_WIDESCREEN);
206208
config.vi.hide_overscan = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_HIDE_OVERSCAN);
209+
config.vi.integer_scaling = ConfigGetParamBool(configVideoAngrylionPlus, KEY_VI_INTEGER_SCALING);
207210

208211
config.dp.compat = ConfigGetParamInt(configVideoAngrylionPlus, KEY_DP_COMPAT);
209212

src/plugin/zilmar/config.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static HWND dlg_check_vi_widescreen;
4949
static HWND dlg_check_vi_overscan;
5050
static HWND dlg_check_vi_exclusive;
5151
static HWND dlg_check_vi_vsync;
52+
static HWND dlg_check_vi_integer_scaling;
5253
static HWND dlg_combo_dp_compat;
5354
static HWND dlg_spin_workers;
5455
static HWND dlg_edit_workers;
@@ -119,6 +120,7 @@ INT_PTR CALLBACK config_dialog_proc(HWND hwnd, UINT iMessage, WPARAM wParam, LPA
119120
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_OVERSCAN, dlg_check_vi_overscan, config.vi.hide_overscan);
120121
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_EXCLUSIVE, dlg_check_vi_exclusive, config.vi.exclusive);
121122
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_VSYNC, dlg_check_vi_vsync, config.vi.vsync);
123+
CONFIG_DLG_INIT_CHECKBOX(IDC_CHECK_VI_INTEGER_SCALING, dlg_check_vi_integer_scaling, config.vi.integer_scaling);
122124

123125
dlg_edit_workers = GetDlgItem(hwnd, IDC_EDIT_WORKERS);
124126
SetDlgItemInt(hwnd, IDC_EDIT_WORKERS, config.num_workers, FALSE);
@@ -159,6 +161,7 @@ INT_PTR CALLBACK config_dialog_proc(HWND hwnd, UINT iMessage, WPARAM wParam, LPA
159161
config.vi.hide_overscan = SendMessage(dlg_check_vi_overscan, BM_GETCHECK, 0, 0);
160162
config.vi.exclusive = SendMessage(dlg_check_vi_exclusive, BM_GETCHECK, 0, 0);
161163
config.vi.vsync = SendMessage(dlg_check_vi_vsync, BM_GETCHECK, 0, 0);
164+
config.vi.integer_scaling = SendMessage(dlg_check_vi_integer_scaling, BM_GETCHECK, 0, 0);
162165
config.dp.compat = SendMessage(dlg_combo_dp_compat, CB_GETCURSEL, 0, 0);
163166
config.parallel = SendMessage(dlg_check_multithread, BM_GETCHECK, 0, 0);
164167
config.num_workers = GetDlgItemInt(hwnd, IDC_EDIT_WORKERS, FALSE, FALSE);

src/plugin/zilmar/config.rc

294 Bytes
Binary file not shown.

src/plugin/zilmar/resource.h

184 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)