Skip to content

Commit

Permalink
add option for choosing scaling alghoritm
Browse files Browse the repository at this point in the history
  • Loading branch information
pebri86 committed Jan 29, 2020
1 parent c651b8b commit 7b1daab
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 105 deletions.
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"files.associations": {
".blade.php": "html",
".tpl": "html",
"random": "c"
}
}
86 changes: 56 additions & 30 deletions esplay-gnuboy/main/display_gb.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,78 @@
#include "disp_spi.h"

extern uint16_t *line[];
extern int32_t scaleAlg;

#define NEAREST_NEIGHBOR_ALG
#define LINE_COUNT (8)
#define AVERAGE(a, b) ( ((((a) ^ (b)) & 0xf7deU) >> 1) + ((a) & (b)) )

static uint16_t getPixel(const uint16_t *bufs, int x, int y, int w1, int h1, int w2, int h2, int x_ratio, int y_ratio)
{
uint16_t col;
#ifdef NEAREST_NEIGHBOR_ALG
/* Resize using nearest neighbor alghorithm */
/* Simple and fastest way but low quality */
int x2 = ((x * x_ratio) >> 16);
int y2 = ((y * y_ratio) >> 16);
col = bufs[(y2 * w1) + x2];
if(scaleAlg == NEAREST_NEIGHBOR)
{
/* Resize using nearest neighbor alghorithm */
/* Simple and fastest way but low quality */
int x2 = ((x * x_ratio) >> 16);
int y2 = ((y * y_ratio) >> 16);
col = bufs[(y2 * w1) + x2];

return col;
}
else if (scaleAlg == BILINIER_INTERPOLATION)
{
/* Resize using bilinear interpolation */
/* higher quality but lower performance, */
int x_diff, y_diff, xv, yv, red, green, blue, a, b, c, d, index;

xv = (int)((x_ratio * x) >> 16);
yv = (int)((y_ratio * y) >> 16);

x_diff = ((x_ratio * x) >> 16) - (xv);
y_diff = ((y_ratio * y) >> 16) - (yv);

return col;
#else
/* Resize using bilinear interpolation */
/* higher quality but lower performance, */
int x_diff, y_diff, xv, yv, red, green, blue, a, b, c, d, index;
index = yv * w1 + xv;

xv = (int)((x_ratio * x) >> 16);
yv = (int)((y_ratio * y) >> 16);
a = bufs[index];
b = bufs[index + 1];
c = bufs[index + w1];
d = bufs[index + w1 + 1];

x_diff = ((x_ratio * x) >> 16) - (xv);
y_diff = ((y_ratio * y) >> 16) - (yv);
red = (((a >> 11) & 0x1f) * (1 - x_diff) * (1 - y_diff) + ((b >> 11) & 0x1f) * (x_diff) * (1 - y_diff) +
((c >> 11) & 0x1f) * (y_diff) * (1 - x_diff) + ((d >> 11) & 0x1f) * (x_diff * y_diff));

index = yv * w1 + xv;
green = (((a >> 5) & 0x3f) * (1 - x_diff) * (1 - y_diff) + ((b >> 5) & 0x3f) * (x_diff) * (1 - y_diff) +
((c >> 5) & 0x3f) * (y_diff) * (1 - x_diff) + ((d >> 5) & 0x3f) * (x_diff * y_diff));

a = bufs[index];
b = bufs[index + 1];
c = bufs[index + w1];
d = bufs[index + w1 + 1];
blue = (((a)&0x1f) * (1 - x_diff) * (1 - y_diff) + ((b)&0x1f) * (x_diff) * (1 - y_diff) +
((c)&0x1f) * (y_diff) * (1 - x_diff) + ((d)&0x1f) * (x_diff * y_diff));

red = (((a >> 11) & 0x1f) * (1 - x_diff) * (1 - y_diff) + ((b >> 11) & 0x1f) * (x_diff) * (1 - y_diff) +
((c >> 11) & 0x1f) * (y_diff) * (1 - x_diff) + ((d >> 11) & 0x1f) * (x_diff * y_diff));
col = ((int)red << 11) | ((int)green << 5) | ((int)blue);

green = (((a >> 5) & 0x3f) * (1 - x_diff) * (1 - y_diff) + ((b >> 5) & 0x3f) * (x_diff) * (1 - y_diff) +
((c >> 5) & 0x3f) * (y_diff) * (1 - x_diff) + ((d >> 5) & 0x3f) * (x_diff * y_diff));
return col;
}
else /* scaleAlg == BOX_FILTERED */
{
// experimental, currently disabled
int xv, yv, a, b, c, d, index, p, q;

xv = (int)((x_ratio * x) >> 16);
yv = (int)((y_ratio * y) >> 16);

blue = (((a)&0x1f) * (1 - x_diff) * (1 - y_diff) + ((b)&0x1f) * (x_diff) * (1 - y_diff) +
((c)&0x1f) * (y_diff) * (1 - x_diff) + ((d)&0x1f) * (x_diff * y_diff));
index = yv * w1 + xv;

col = ((int)red << 11) | ((int)green << 5) | ((int)blue);
a = bufs[index];
b = bufs[index + 1];
c = bufs[index + w1];
d = bufs[index + w1 + 1];

return col;
#endif
p = AVERAGE (a,b);
q = AVERAGE (c,d);

col = AVERAGE (p,q);

return col;
}
}

void write_gb_frame(const uint16_t *data, esplay_scale_option scale)
Expand Down
5 changes: 5 additions & 0 deletions esplay-gnuboy/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ const char *StateFileName = "/gnuboy/data/gnuboy.sav";

const char *SD_BASE_PATH = "/sd";

int32_t scaleAlg;

#define GAMEBOY_WIDTH (160)
#define GAMEBOY_HEIGHT (144)

Expand Down Expand Up @@ -470,6 +472,9 @@ void app_main(void)
settings_load(SettingAudioVolume, &volume);
audio_volume_set(volume);

// load alghorithm
settings_load(SettingAlg, &scaleAlg);

// battery
battery_level_init();

Expand Down
26 changes: 23 additions & 3 deletions esplay-launcher/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ char emu_name[6][20] = {"Nintendo", "Gameboy", "Gameboy Color", "Sega Master Sys
int emu_slot[6] = {1, 2, 2, 3, 3, 3};
char *base_path = "/sd/roms/";
battery_state bat_state;
int num_menu = 5;
char menu_text[5][20] = {"WiFi AP *", "Volume", "Brightness", "Upscaler", "Quit"};
int num_menu = 6;
char menu_text[6][20] = {"WiFi AP *", "Volume", "Brightness", "Upscaler", "Scale Alg", "Quit"};
char scaling_text[3][20] = {"Native", "Normal", "Stretch"};
char scaling_alg_text[3][20] = {"Nearest Neighbor", "Bilinier Intrp.", "Box Filtered"};
int32_t wifi_en = 0;
int32_t volume = 25;
int32_t bright = 50;
int32_t scaling = SCALE_FIT;
int32_t scale_alg = NEAREST_NEIGHBOR;


esp_err_t start_file_server(const char *base_path);
Expand Down Expand Up @@ -272,6 +274,10 @@ static void showOptionPage(int selected)
UG_PutString(319 - (strlen(scaling_text[scaling]) * 9), top, scaling_text[scaling]);
break;

case 4:
UG_PutString(319 - (strlen(scaling_alg_text[scale_alg]) * 9), top, scaling_alg_text[scale_alg]);
break;

default:
break;
}
Expand Down Expand Up @@ -332,6 +338,12 @@ static int showOption()
scaling = 2;
settings_save(SettingScaleMode, (int32_t)scaling);
break;
case 4:
scale_alg--;
if (scale_alg < 0)
scale_alg = 1;
settings_save(SettingAlg, (int32_t)scale_alg);
break;

default:
break;
Expand Down Expand Up @@ -365,14 +377,20 @@ static int showOption()
scaling = 0;
settings_save(SettingScaleMode, (int32_t)scaling);
break;
case 4:
scale_alg++;
if (scale_alg > 1)
scale_alg = 0;
settings_save(SettingAlg, (int32_t)scale_alg);
break;

default:
break;
}
showOptionPage(selected);
}
if (!prevKey.values[GAMEPAD_INPUT_A] && key.values[GAMEPAD_INPUT_A])
if (selected == 4)
if (selected == 5)
{
vTaskDelay(10);
break;
Expand Down Expand Up @@ -443,6 +461,8 @@ void app_main(void)
settings_save(SettingBacklight, (int32_t)bright);
if(settings_load(SettingScaleMode, &scaling) != 0)
settings_save(SettingScaleMode, (int32_t)scaling);
if(settings_load(SettingAlg, &scale_alg) != 0)
settings_save(SettingAlg, (int32_t)scale_alg);

if (wifi_en)
{
Expand Down
90 changes: 58 additions & 32 deletions esplay-nofrendo/components/nofrendo-esp32/display_nes.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,78 @@

extern uint16_t myPalette[];
extern uint16_t *line[];
extern int32_t scaleAlg;

#define NEAREST_NEIGHBOR_ALG
#define LINE_COUNT (8)
#define AVERAGE(a, b) ( ((((a) ^ (b)) & 0xf7deU) >> 1) + ((a) & (b)) )

static uint8_t getPixelNes(const uint8_t *bufs, int x, int y, int w1, int h1, int w2, int h2, int x_ratio, int y_ratio)
{
uint8_t col;
#ifdef NEAREST_NEIGHBOR_ALG
/* Resize using nearest neighbor alghorithm */
/* Simple and fastest way but low quality */
int x2 = ((x*x_ratio)>>16);
int y2 = ((y*y_ratio)>>16);
col = bufs[(y2*w1)+x2];
if(scaleAlg == NEAREST_NEIGHBOR)
{
/* Resize using nearest neighbor alghorithm */
/* Simple and fastest way but low quality */
int x2 = ((x*x_ratio)>>16);
int y2 = ((y*y_ratio)>>16);
col = bufs[(y2*w1)+x2];

return col;
}
else if (scaleAlg == BILINIER_INTERPOLATION)
{
/* Resize using bilinear interpolation */
/* higher quality but lower performance, */
int x_diff, y_diff, xv, yv, red, green, blue, a, b, c, d, index;

xv = (int)((x_ratio * x) >> 16);
yv = (int)((y_ratio * y) >> 16);

x_diff = ((x_ratio * x) >> 16) - (xv);
y_diff = ((y_ratio * y) >> 16) - (yv);

return col;
#else
/* Resize using bilinear interpolation */
/* higher quality but lower performance, */
int x_diff, y_diff, xv, yv, red, green, blue, a, b, c, d, index;
index = yv * w1 + xv;

xv = (int)((x_ratio * x) >> 16);
yv = (int)((y_ratio * y) >> 16);
a = bufs[index];
b = bufs[index + 1];
c = bufs[index + w1];
d = bufs[index + w1 + 1];

x_diff = ((x_ratio * x) >> 16) - (xv);
y_diff = ((y_ratio * y) >> 16) - (yv);
red = (((a >> 11) & 0x1f) * (1 - x_diff) * (1 - y_diff) + ((b >> 11) & 0x1f) * (x_diff) * (1 - y_diff) +
((c >> 11) & 0x1f) * (y_diff) * (1 - x_diff) + ((d >> 11) & 0x1f) * (x_diff * y_diff));

index = yv * w1 + xv;
green = (((a >> 5) & 0x3f) * (1 - x_diff) * (1 - y_diff) + ((b >> 5) & 0x3f) * (x_diff) * (1 - y_diff) +
((c >> 5) & 0x3f) * (y_diff) * (1 - x_diff) + ((d >> 5) & 0x3f) * (x_diff * y_diff));

a = bufs[index];
b = bufs[index + 1];
c = bufs[index + w1];
d = bufs[index + w1 + 1];
blue = (((a)&0x1f) * (1 - x_diff) * (1 - y_diff) + ((b)&0x1f) * (x_diff) * (1 - y_diff) +
((c)&0x1f) * (y_diff) * (1 - x_diff) + ((d)&0x1f) * (x_diff * y_diff));

red = (((a >> 11) & 0x1f) * (1 - x_diff) * (1 - y_diff) + ((b >> 11) & 0x1f) * (x_diff) * (1 - y_diff) +
((c >> 11) & 0x1f) * (y_diff) * (1 - x_diff) + ((d >> 11) & 0x1f) * (x_diff * y_diff));
col = ((int)red << 11) | ((int)green << 5) | ((int)blue);

green = (((a >> 5) & 0x3f) * (1 - x_diff) * (1 - y_diff) + ((b >> 5) & 0x3f) * (x_diff) * (1 - y_diff) +
((c >> 5) & 0x3f) * (y_diff) * (1 - x_diff) + ((d >> 5) & 0x3f) * (x_diff * y_diff));
return col;
}
else /* scaleAlg == BOX_FILTERED */
{
// experimental, currently disabled
int xv, yv, a, b, c, d, index, p, q;

xv = (int)((x_ratio * x) >> 16);
yv = (int)((y_ratio * y) >> 16);

blue = (((a)&0x1f) * (1 - x_diff) * (1 - y_diff) + ((b)&0x1f) * (x_diff) * (1 - y_diff) +
((c)&0x1f) * (y_diff) * (1 - x_diff) + ((d)&0x1f) * (x_diff * y_diff));
index = yv * w1 + xv;

col = ((int)red << 11) | ((int)green << 5) | ((int)blue);
a = bufs[index];
b = bufs[index + 1];
c = bufs[index + w1];
d = bufs[index + w1 + 1];

return col;
#endif
p = AVERAGE(a,b);
q = AVERAGE(c,d);

col = AVERAGE(p,q);

return col;
}
}

void write_nes_frame(const uint8_t *data, esplay_scale_option scale)
Expand Down Expand Up @@ -118,7 +144,7 @@ void write_nes_frame(const uint8_t *data, esplay_scale_option scale)
outputHeight = LCD_HEIGHT;
outputWidth = LCD_WIDTH;
x_ratio = (int)((NES_FRAME_WIDTH<<16)/outputWidth) +1;
y_ratio = (int)((NES_FRAME_HEIGHT<<16)/outputHeight) +1;
y_ratio = (int)((NES_FRAME_HEIGHT<<16)/outputHeight) +1;

for (y = 0; y < outputHeight; y += LINE_COUNT)
{
Expand Down Expand Up @@ -148,7 +174,7 @@ void write_nes_frame(const uint8_t *data, esplay_scale_option scale)
outputWidth = NES_FRAME_WIDTH + (LCD_HEIGHT - NES_FRAME_HEIGHT);
xpos = (LCD_WIDTH - outputWidth) / 2;
x_ratio = (int)((NES_FRAME_WIDTH<<16)/outputWidth) +1;
y_ratio = (int)((NES_FRAME_HEIGHT<<16)/outputHeight) +1;
y_ratio = (int)((NES_FRAME_HEIGHT<<16)/outputHeight) +1;

for (y = 0; y < outputHeight; y += LINE_COUNT)
{
Expand Down
4 changes: 4 additions & 0 deletions esplay-nofrendo/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const char* SD_BASE_PATH = "/sd";
static char* ROM_DATA = (char*)0x3f800000;

extern bool forceConsoleReset;
int32_t scaleAlg;

char *osd_getromdata()
{
Expand Down Expand Up @@ -84,6 +85,9 @@ int app_main(void)
settings_load(SettingBacklight, &brightness);
set_display_brightness(brightness);

// load alghoritm
settings_load(SettingAlg, &scaleAlg);

// battery
battery_level_init();

Expand Down
7 changes: 7 additions & 0 deletions esplay-sdk/esplay-components/esplay-hal/include/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ typedef enum Setting {
SettingRomPath,
SettingScaleMode,
SettingWifi,
SettingAlg,
SettingMax,
} Setting;

typedef enum ScaleAlghorithm {
NEAREST_NEIGHBOR = 0,
BILINIER_INTERPOLATION,
BOX_FILTERED
} ScaleAlghorithm;

/**********************
* GLOBAL PROTOTYPES
**********************/
Expand Down
4 changes: 2 additions & 2 deletions esplay-sdk/esplay-components/esplay-hal/src/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ typedef enum KeyType {
static nvs_handle handle;

static KeyType settings_types[SettingMax] = {
TypeInt, TypeInt, TypeInt, TypeStr, TypeInt, TypeInt,
TypeInt, TypeInt, TypeInt, TypeStr, TypeInt, TypeInt, TypeInt
};

static char *settings_keys[SettingMax] = {
"volume", "backlight", "playmode", "rom_name", "scale", "wifi",
"volume", "backlight", "playmode", "rom_name", "scale", "wifi", "scale_alg"
};

/**********************
Expand Down
Loading

0 comments on commit 7b1daab

Please sign in to comment.