summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorneonloop2021-03-31 21:14:54 +0000
committerneonloop2021-03-31 21:14:54 +0000
commitae67b055fec6a8cc843554d8190e018a6ae9b89d (patch)
tree74f0dc135e830ba1699b422447150a0f859ea200
parent83932ce888f9148a8d49a5f9b7d3dd4ddf71822a (diff)
downloadsnes9x2002-ae67b055fec6a8cc843554d8190e018a6ae9b89d.tar.gz
snes9x2002-ae67b055fec6a8cc843554d8190e018a6ae9b89d.tar.bz2
snes9x2002-ae67b055fec6a8cc843554d8190e018a6ae9b89d.zip
Adds overscan scaler and fps display
-rw-r--r--shell/menu/config.h1
-rw-r--r--shell/menu/menu.c144
-rw-r--r--shell/menu/menu.h3
-rw-r--r--shell/scalers/scaler.c61
-rw-r--r--shell/scalers/scaler.h3
-rw-r--r--shell/video/sdl/video_blit.c15
-rw-r--r--src/gfx16.c7
7 files changed, 162 insertions, 72 deletions
diff --git a/shell/menu/config.h b/shell/menu/config.h
index 9b71fc2..b0c0711 100644
--- a/shell/menu/config.h
+++ b/shell/menu/config.h
@@ -5,6 +5,7 @@ typedef struct {
int32_t fullscreen;
/* For input remapping */
uint32_t config_buttons[6][19];
+ uint32_t showfps;
} t_config;
extern t_config option;
diff --git a/shell/menu/menu.c b/shell/menu/menu.c
index 01d1e53..4cdd8c7 100644
--- a/shell/menu/menu.c
+++ b/shell/menu/menu.c
@@ -15,6 +15,8 @@
#include "config.h"
#include "menu.h"
#include "buttons.h"
+#include "snes9x.h"
+#include "cpuexec.h"
t_config option;
uint32_t emulator_state = 0;
@@ -33,20 +35,20 @@ extern void SRAM_Save(char* path, uint_fast8_t state);
static uint8_t selectpressed = 0;
static uint8_t save_slot = 0;
-static const int8_t upscalers_available = 2
+static const int8_t upscalers_available = 4
#ifdef SCALE2X_UPSCALER
+1
#endif
;
-static void SaveState_Menu(uint_fast8_t load_mode, uint_fast8_t slot)
+void SaveState_Menu(uint_fast8_t load_mode, uint_fast8_t slot)
{
char tmp[512];
snprintf(tmp, sizeof(tmp), "%s/%s_%d.sts", save_path, GameName_emu, slot);
SaveState(tmp,load_mode);
}
-static void SRAM_Menu(uint_fast8_t load_mode)
+void SRAM_Menu(uint_fast8_t load_mode)
{
char tmp[512];
snprintf(tmp, sizeof(tmp), "%s/%s.srm", sram_path, GameName_emu);
@@ -85,8 +87,10 @@ static void config_load()
option.config_buttons[0][10] = BTN_START;
option.config_buttons[0][11] = BTN_SELECT;
- option.fullscreen = 0;
+ option.fullscreen = 3;
+ option.showfps = 0;
}
+ if (option.showfps == 0) Settings.DisplayFrameRate = false; else Settings.DisplayFrameRate = true;
}
static void config_save()
@@ -346,7 +350,7 @@ void Menu()
/* Save sram settings each time we bring up the menu */
SRAM_Menu(0);
- while (((currentselection != 1) && (currentselection != 6)) || (!pressed))
+ while (((currentselection != 1) && (currentselection != 7) && (currentselection != 8)) || (!pressed))
{
pressed = 0;
@@ -354,34 +358,39 @@ void Menu()
print_string("snes9x2002 - Built on " __DATE__, TextWhite, 0, 5, 15, backbuffer->pixels);
- if (currentselection == 1) print_string("Continue", TextRed, 0, 5, 45, backbuffer->pixels);
- else print_string("Continue", TextWhite, 0, 5, 45, backbuffer->pixels);
+#define MENU_Y(y) 29 + (18*y)
+
+ if (currentselection == 1) print_string("Continue", TextRed, 0, 5, MENU_Y(1), backbuffer->pixels);
+ else print_string("Continue", TextWhite, 0, 5, MENU_Y(1), backbuffer->pixels);
snprintf(text, sizeof(text), "Load State %d", save_slot);
- if (currentselection == 2) print_string(text, TextRed, 0, 5, 65, backbuffer->pixels);
- else print_string(text, TextWhite, 0, 5, 65, backbuffer->pixels);
+ if (currentselection == 2) print_string(text, TextRed, 0, 5, MENU_Y(2), backbuffer->pixels);
+ else print_string(text, TextWhite, 0, 5, MENU_Y(2), backbuffer->pixels);
snprintf(text, sizeof(text), "Save State %d", save_slot);
- if (currentselection == 3) print_string(text, TextRed, 0, 5, 85, backbuffer->pixels);
- else print_string(text, TextWhite, 0, 5, 85, backbuffer->pixels);
+ if (currentselection == 3) print_string(text, TextRed, 0, 5, MENU_Y(3), backbuffer->pixels);
+ else print_string(text, TextWhite, 0, 5, MENU_Y(3), backbuffer->pixels);
if (currentselection == 4)
{
switch(option.fullscreen)
{
case 0:
- print_string("Scaling : Native", TextRed, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : Native", TextRed, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
case 1:
- print_string("Scaling : Stretched", TextRed, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : FS Sharp", TextRed, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
case 2:
- print_string("Scaling : Bilinear", TextRed, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : FS Smooth", TextRed, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
case 3:
- print_string("Scaling : EPX/Scale2x", TextRed, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : Bilinear", TextRed, 0, 5, MENU_Y(4), backbuffer->pixels);
+ break;
+ case 4:
+ print_string("Scaling : Overscan", TextRed, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
}
}
@@ -390,25 +399,36 @@ void Menu()
switch(option.fullscreen)
{
case 0:
- print_string("Scaling : Native", TextWhite, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : Native", TextWhite, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
case 1:
- print_string("Scaling : Stretched", TextWhite, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : FS Sharp", TextWhite, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
case 2:
- print_string("Scaling : Bilinear", TextWhite, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : FS Smooth", TextWhite, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
case 3:
- print_string("Scaling : EPX/Scale2x", TextWhite, 0, 5, 105, backbuffer->pixels);
+ print_string("Scaling : Bilinear", TextWhite, 0, 5, MENU_Y(4), backbuffer->pixels);
+ break;
+ case 4:
+ print_string("Scaling : Overscan", TextWhite, 0, 5, MENU_Y(4), backbuffer->pixels);
break;
}
}
- if (currentselection == 5) print_string("Input remapping", TextRed, 0, 5, 125, backbuffer->pixels);
- else print_string("Input remapping", TextWhite, 0, 5, 125, backbuffer->pixels);
+ if (option.showfps == 0) snprintf(text, sizeof(text), "Show FPS : OFF");
+ else snprintf(text, sizeof(text), "Show FPS : ON");
+ if (currentselection == 5) print_string(text, TextRed, 0, 5, MENU_Y(5), backbuffer->pixels);
+ else print_string(text, TextWhite, 0, 5, MENU_Y(5), backbuffer->pixels);
- if (currentselection == 6) print_string("Quit", TextRed, 0, 5, 145, backbuffer->pixels);
- else print_string("Quit", TextWhite, 0, 5, 145, backbuffer->pixels);
+ if (currentselection == 6) print_string("Input remapping", TextRed, 0, 5, MENU_Y(6), backbuffer->pixels);
+ else print_string("Input remapping", TextWhite, 0, 5, MENU_Y(6), backbuffer->pixels);
+
+ if (currentselection == 7) print_string("Reset", TextRed, 0, 5, MENU_Y(7), backbuffer->pixels);
+ else print_string("Reset", TextWhite, 0, 5, MENU_Y(7), backbuffer->pixels);
+
+ if (currentselection == 8) print_string("Quit", TextRed, 0, 5, MENU_Y(8), backbuffer->pixels);
+ else print_string("Quit", TextWhite, 0, 5, MENU_Y(8), backbuffer->pixels);
print_string("Frontend by gameblabla", TextWhite, 0, 5, 205, backbuffer->pixels);
print_string("Credits: Snes9x dev team, libretro", TextWhite, 0, 5, 225, backbuffer->pixels);
@@ -422,19 +442,19 @@ void Menu()
case BTN_UP:
currentselection--;
if (currentselection == 0)
- currentselection = 6;
+ currentselection = 8;
break;
case BTN_DOWN:
currentselection++;
- if (currentselection == 7)
+ if (currentselection == 9)
currentselection = 1;
break;
case BTN_L2:
case BTN_SELECT:
case BTN_B:
- pressed = 1;
- currentselection = 1;
- break;
+ pressed = 1;
+ currentselection = 1;
+ break;
case BTN_A:
case BTN_START:
pressed = 1;
@@ -444,13 +464,16 @@ void Menu()
{
case 2:
case 3:
- if (save_slot > 0) save_slot--;
- break;
+ if (save_slot > 0) save_slot--;
+ break;
case 4:
- option.fullscreen--;
- if (option.fullscreen < 0)
- option.fullscreen = upscalers_available;
- break;
+ option.fullscreen--;
+ if (option.fullscreen < 0)
+ option.fullscreen = upscalers_available;
+ break;
+ case 5:
+ option.showfps ^= 1;
+ break;
}
break;
case BTN_RIGHT:
@@ -458,15 +481,16 @@ void Menu()
{
case 2:
case 3:
- save_slot++;
- if (save_slot == 10)
- save_slot = 9;
- break;
+ if (save_slot < 9) save_slot++;
+ break;
case 4:
- option.fullscreen++;
- if (option.fullscreen > upscalers_available)
- option.fullscreen = 0;
- break;
+ option.fullscreen++;
+ if (option.fullscreen > upscalers_available)
+ option.fullscreen = 0;
+ break;
+ case 5:
+ option.showfps ^= 1;
+ break;
}
break;
default:
@@ -475,7 +499,7 @@ void Menu()
}
else if (Event.type == SDL_QUIT)
{
- currentselection = 6;
+ currentselection = 8;
pressed = 1;
}
}
@@ -484,22 +508,28 @@ void Menu()
{
switch(currentselection)
{
- case 5:
+ case 7:
+ S9xReset();
+ break;
+ case 6:
Input_Remapping();
break;
- case 4 :
- option.fullscreen++;
- if (option.fullscreen > upscalers_available)
- option.fullscreen = 0;
- break;
- case 2 :
- SaveState_Menu(1, save_slot);
- currentselection = 1;
- break;
- case 3 :
+ case 5:
+ option.showfps ^= 1;
+ break;
+ case 4 :
+ option.fullscreen++;
+ if (option.fullscreen > upscalers_available)
+ option.fullscreen = 0;
+ break;
+ case 3 :
SaveState_Menu(0, save_slot);
currentselection = 1;
break;
+ case 2 :
+ SaveState_Menu(1, save_slot);
+ currentselection = 1;
+ break;
default:
break;
}
@@ -515,13 +545,11 @@ void Menu()
SDL_Flip(sdl_screen);
#endif
- if (currentselection == 6)
- {
- exit_snes = 1;
- }
+ if (currentselection == 8) exit_snes = 1;
/* Switch back to emulator core */
config_save();
+ if (option.showfps == 0) Settings.DisplayFrameRate = false; else Settings.DisplayFrameRate = true;
emulator_state = 0;
Set_Video_InGame();
}
diff --git a/shell/menu/menu.h b/shell/menu/menu.h
index 8b81ac3..9b8a7bb 100644
--- a/shell/menu/menu.h
+++ b/shell/menu/menu.h
@@ -15,4 +15,7 @@ extern uint32_t done;
extern void Menu(void);
extern void Init_Configuration(void);
+extern void SaveState_Menu(uint_fast8_t load_mode, uint_fast8_t slot);
+extern void SRAM_Menu(uint_fast8_t load_mode);
+
#endif
diff --git a/shell/scalers/scaler.c b/shell/scalers/scaler.c
index 8d85b8a..19c3cfd 100644
--- a/shell/scalers/scaler.c
+++ b/shell/scalers/scaler.c
@@ -27,6 +27,49 @@
// Halves
#define Weight1_1(A, B) (Half(A) + Half(B) + Corr1_1(A, B))
+#define AVERAGE16(c1, c2) (((c1) + (c2) + (((c1) ^ (c2)) & 0x0821))>>1) //More accurate
+
+void upscale_240x208_to_320x240(uint16_t *dst, uint16_t *src)
+{
+ int Eh = 0;
+ int dh = 8;
+ int width = 320;
+ int vf = 0;
+
+ for (int y = 0; y < 240; y++)
+ {
+ int source = dh * width + 8;
+ for (int x = 0; x < 320/4; x++)
+ {
+ register uint16_t a, b, c;
+
+ a = src[source];
+ b = src[source+1];
+ c = src[source+2];
+
+ if(vf == 1){
+ a = AVERAGE16(a, src[source+width]);
+ b = AVERAGE16(b, src[source+width+1]);
+ c = AVERAGE16(c, src[source+width+2]);
+ }
+ *dst++ = a;
+ *dst++ = (AVERAGE16(a,b) & 0b0000000000011111) | (b & 0b1111111111100000);
+ *dst++ = (b & 0b0000011111111111) | (AVERAGE16(b,c) & 0b1111100000000000);
+ *dst++ = c;
+ source+=3;
+
+ }
+ Eh += 208;
+ if(Eh >= 240) {
+ Eh -= 240;
+ dh++;
+ vf = 0;
+ }
+ else
+ vf = 1;
+ }
+}
+
void upscale_256x240_to_320x240_bilinearish(uint32_t* restrict dst, uint32_t* restrict src, uint_fast16_t width, uint_fast16_t height)
{
@@ -35,8 +78,10 @@ void upscale_256x240_to_320x240_bilinearish(uint32_t* restrict dst, uint32_t* re
// There are 64 blocks of 4 pixels horizontally, and 239 of 1 vertically.
// Each block of 4x1 becomes 5x1.
uint32_t BlockX, BlockY;
- uint16_t* BlockSrc;
- uint16_t* BlockDst;
+ register uint16_t _1,_2,_3,_4;
+ register uint16_t* BlockSrc;
+ register uint16_t* BlockDst;
+
for (BlockY = 0; BlockY < height; BlockY++)
{
BlockSrc = Src16 + BlockY * width * 1;
@@ -51,13 +96,13 @@ void upscale_256x240_to_320x240_bilinearish(uint32_t* restrict dst, uint32_t* re
*/
// -- Row 1 --
- uint16_t _1 = *(BlockSrc );
+ _1 = *(BlockSrc );
*(BlockDst ) = _1;
- uint16_t _2 = *(BlockSrc + 1);
+ _2 = *(BlockSrc + 1);
*(BlockDst + 1) = Weight1_3( _1, _2);
- uint16_t _3 = *(BlockSrc + 2);
+ _3 = *(BlockSrc + 2);
*(BlockDst + 2) = Weight1_1( _2, _3);
- uint16_t _4 = *(BlockSrc + 3);
+ _4 = *(BlockSrc + 3);
*(BlockDst + 3) = Weight3_1( _3, _4);
*(BlockDst + 4) = _4;
@@ -67,9 +112,9 @@ void upscale_256x240_to_320x240_bilinearish(uint32_t* restrict dst, uint32_t* re
}
}
-void upscale_256xXXX_to_320x240(uint32_t* restrict dst, uint32_t* restrict src, uint_fast16_t width, uint_fast16_t height)
+
+void upscale_256xXXX_to_320x240(uint32_t* restrict dst, uint32_t* restrict src, uint_fast16_t width, uint_fast16_t height, uint32_t midh)
{
- uint32_t midh = 240 / 2;
uint32_t Eh = 0;
uint32_t source;
uint32_t dh = 0;
diff --git a/shell/scalers/scaler.h b/shell/scalers/scaler.h
index f220800..a3ae4c0 100644
--- a/shell/scalers/scaler.h
+++ b/shell/scalers/scaler.h
@@ -5,7 +5,8 @@
/* Generic */
extern void bitmap_scale(uint32_t startx, uint32_t starty, uint32_t viswidth, uint32_t visheight, uint32_t newwidth, uint32_t newheight,uint32_t pitchsrc,uint32_t pitchdest, uint16_t* restrict src, uint16_t* restrict dst);
-extern void upscale_256xXXX_to_320x240(uint32_t* restrict dst, uint32_t* restrict src, uint_fast16_t width, uint_fast16_t height);
+extern void upscale_256xXXX_to_320x240(uint32_t* restrict dst, uint32_t* restrict src, uint_fast16_t width, uint_fast16_t height, uint32_t midh);
extern void upscale_256x240_to_320x240_bilinearish(uint32_t* restrict dst, uint32_t* restrict src, uint_fast16_t width, uint_fast16_t height);
+extern void upscale_240x208_to_320x240(uint16_t *dst, uint16_t *src);
#endif
diff --git a/shell/video/sdl/video_blit.c b/shell/video/sdl/video_blit.c
index 08aadcd..bf790bb 100644
--- a/shell/video/sdl/video_blit.c
+++ b/shell/video/sdl/video_blit.c
@@ -86,23 +86,30 @@ void Update_Video_Ingame(int width, int height)
uint16_t *s, *d;
uint32_t h, w;
uint8_t PAL = !!(Memory.FillRAM[0x2133] & 4);
+ if (height == SNES_HEIGHT_EXTENDED) height++; // 239 to 240
SDL_LockSurface(sdl_screen);
switch(option.fullscreen)
{
- case 0:
+ case 0: // Native
s = (uint16_t*) GFX.Screen;
d = (uint16_t*) sdl_screen->pixels + ((sdl_screen->w - width)/2 + (sdl_screen->h - height) * 160) - (PAL ? 0 : 2*320);
for(uint8_t y = 0; y < height; y++, s += GFX_PITCH / 2, d += sdl_screen->w) memmove(d, s, width * 2);
break;
- case 1:
- upscale_256xXXX_to_320x240((uint32_t*) sdl_screen->pixels, (uint32_t*) GFX.Screen, GFX_PITCH / 2, PAL ? 240 : 224);
+ case 1: // FS Sharp
+ upscale_256xXXX_to_320x240((uint32_t*) sdl_screen->pixels, (uint32_t*) GFX.Screen, GFX_PITCH / 2, height, height);
break;
- case 2:
+ case 2: // FS Smooth
+ upscale_256xXXX_to_320x240((uint32_t*) sdl_screen->pixels, (uint32_t*) GFX.Screen, GFX_PITCH / 2, height, 240/2);
+ break;
+ case 3: // Bilinear
if (height == 240) upscale_256x240_to_320x240_bilinearish((uint32_t*) sdl_screen->pixels, (uint32_t*) GFX.Screen, GFX_PITCH / 2, 239);
else upscale_256x240_to_320x240_bilinearish((uint32_t*) sdl_screen->pixels + (160*8), (uint32_t*) GFX.Screen, GFX_PITCH / 2, 224);
break;
+ case 4: // Overscan
+ upscale_240x208_to_320x240((uint16_t*) sdl_screen->pixels, (uint16_t*) GFX.Screen);
+ break;
}
//bitmap_scale(0, 0, IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, sdl_screen->w, sdl_screen->h, SNES_WIDTH*2, 0, GFX.Screen, sdl_screen->pixels);
diff --git a/src/gfx16.c b/src/gfx16.c
index 0c17f34..02ece3c 100644
--- a/src/gfx16.c
+++ b/src/gfx16.c
@@ -2534,11 +2534,16 @@ void DisplayChar(uint8* Screen, uint8 c)
}
}
+#ifdef TRIMUI
+#include "config.h"
+#endif
void S9xDisplayFrameRate()
{
char string[16];
uint8 *Screen = GFX.Screen;
-
+#ifdef TRIMUI
+ if (option.fullscreen == 4) Screen += GFX_PITCH *8 +16; // for Overscan
+#endif
sprintf(string, "%02d/%02d", IPPU.DisplayedRenderedFrameCount, (int)Memory.ROMFramesPerSecond);
for (int i = 0; i < 5; i++) {