diff --git a/bin/default.gcw0.desktop b/bin/default.gcw0.desktop index 7bbfd32..bcd40f6 100644 --- a/bin/default.gcw0.desktop +++ b/bin/default.gcw0.desktop @@ -5,5 +5,8 @@ Exec=fbasdl.dge Terminal=false Type=Application StartupNotify=true -Icon=skin/fba_icon +Icon=fbasdl +X-OD-Manual=readme.txt +X-OD-NeedsDownscaling=true Categories=emulators; + diff --git a/src/sdl-dingux/burner.h b/src/sdl-dingux/burner.h index 104fad1..c2ecf58 100644 --- a/src/sdl-dingux/burner.h +++ b/src/sdl-dingux/burner.h @@ -140,6 +140,7 @@ typedef struct int vsync; int rescale; int rotate; + int hwscaling; int showfps; int frameskip; int m68kcore; diff --git a/src/sdl-dingux/config.cpp b/src/sdl-dingux/config.cpp index 3b379f1..0637381 100644 --- a/src/sdl-dingux/config.cpp +++ b/src/sdl-dingux/config.cpp @@ -162,6 +162,7 @@ void ConfigGameDefault() options.vsync = 0; options.rescale = 0; // no scaling by default options.rotate = 0; + options.hwscaling = 0; // no HW scaling by default options.showfps = 0; options.frameskip = -1; // auto frameskip by default options.create_lists = 0; @@ -215,6 +216,7 @@ int ConfigGameLoad(FILE * f) if(strcmp(arg1, "FBA_VSYNC") == 0) options.vsync = argd; if(strcmp(arg1, "FBA_RESCALE") == 0) options.rescale = argd; if(strcmp(arg1, "FBA_ROTATE") == 0) options.rotate = argd; + if(strcmp(arg1, "FBA_HWSCALING") == 0) options.hwscaling = argd; if(strcmp(arg1, "FBA_SHOWFPS") == 0) options.showfps = argd; if(strcmp(arg1, "FBA_FRAMESKIP") == 0) options.frameskip = argd; if(strcmp(arg1, "FBA_M68KCORE") == 0) options.m68kcore = argd; @@ -301,6 +303,7 @@ int ConfigGameSave(FILE * fp) fprintf(fp, "FBA_VSYNC %d\n", options.vsync); fprintf(fp, "FBA_RESCALE %d\n", options.rescale); fprintf(fp, "FBA_ROTATE %d\n", options.rotate); + fprintf(fp, "FBA_HWSCALING %d\n", options.hwscaling); fprintf(fp, "FBA_SHOWFPS %d\n", options.showfps); fprintf(fp, "FBA_FRAMESKIP %d\n", options.frameskip); fprintf(fp, "FBA_M68KCORE %d\n", options.m68kcore); diff --git a/src/sdl-dingux/gui_main.cpp b/src/sdl-dingux/gui_main.cpp index 209bb1a..68df559 100644 --- a/src/sdl-dingux/gui_main.cpp +++ b/src/sdl-dingux/gui_main.cpp @@ -75,7 +75,7 @@ SELECTOR sel; unsigned char joy_speed[4]={0,1,3,7}; -static char *abreviation_cf[10][7]={ +static char *abreviation_cf[11][7]={ {"Disable","Enable","","","","",""}, {"Original","Fullscreen","","","","",""}, {"Off","Auto","Manual","","","",""}, @@ -85,7 +85,8 @@ static char *abreviation_cf[10][7]={ {"Off","LIBAO","SDL","SDL old","","",""}, {"11025", "16000", "22050", "32000", "44100", "", ""}, {"No","Yes","","","","",""}, - {"No","Yes","","","","",""} + {"No","Yes","","","","",""}, + {"Off","Aspect","Fullscr","","","",""} }; void load_lastsel(); @@ -805,6 +806,10 @@ void put_option_line(int first, unsigned char num, unsigned char y) sprintf((char*)g_string, "Rotate vertical game: %s", abreviation_cf[9][options.rotate]); put_string( g_string , OPTIONS_START_X , y , BLANC , gui_screen ); break; + case OPTION_GUI_DEF_RUN_HWSCALING: + sprintf((char*)g_string, "Hardware scaling: %s", abreviation_cf[10][options.hwscaling]); + put_string( g_string , OPTIONS_START_X , y , BLANC , gui_screen ); + break; case OPTION_GUI_DEF_RUN_VSYNC: sprintf((char*)g_string, "Vertical sync: %s", abreviation_cf[5][options.vsync]); put_string( g_string , OPTIONS_START_X , y , BLANC , gui_screen ); @@ -1015,6 +1020,10 @@ void ss_prg_options(int first, int last) case OPTION_GUI_DEF_RUN_ROTATE: options.rotate ^= 1; break; + case OPTION_GUI_DEF_RUN_HWSCALING: + options.hwscaling--; + if(options.hwscaling < 0) options.hwscaling = 2; + break; case OPTION_GUI_DEF_RUN_VSYNC: options.vsync ^= 1; break; @@ -1114,6 +1123,10 @@ void ss_prg_options(int first, int last) case OPTION_GUI_DEF_RUN_ROTATE: options.rotate ^= 1; break; + case OPTION_GUI_DEF_RUN_HWSCALING: + options.hwscaling++; + if(options.hwscaling > 2) options.hwscaling = 0; + break; case OPTION_GUI_DEF_RUN_VSYNC: options.vsync ^= 1; break; @@ -1215,6 +1228,9 @@ static int run_options_static[] = { OPTION_FBA_SOUND, OPTION_FBA_SAMPLERATE, OPTION_FBA_ROTATE, +#ifdef OPTIONS_FOR_GCW0 + OPTION_FBA_HWSCALING, +#endif OPTION_FBA_VSYNC, OPTION_FBA_SHOWFPS, OPTION_FBA_68K, @@ -1250,6 +1266,10 @@ void put_run_option_line(unsigned char num, unsigned char y) put_string("Rotate vertical game", OPTIONS_START_X, y, BLANC, gui_screen); put_string(abreviation_cf[9][options.rotate], CONF_START_X, y, VERT, gui_screen); break; + case OPTION_FBA_HWSCALING: + put_string("Hardware scaling", OPTIONS_START_X, y, BLANC, gui_screen); + put_string(abreviation_cf[10][options.hwscaling], CONF_START_X, y, VERT, gui_screen); + break; case OPTION_FBA_VSYNC: put_string("Vertical sync", OPTIONS_START_X, y, BLANC, gui_screen); put_string(abreviation_cf[5][options.vsync], CONF_START_X, y, VERT, gui_screen); @@ -1367,6 +1387,10 @@ void ss_prog_run(void) case OPTION_FBA_ROTATE: options.rotate ^= 1; break; + case OPTION_FBA_HWSCALING: + options.hwscaling--; + if(options.hwscaling < 0) options.hwscaling = 2; + break; case OPTION_FBA_VSYNC: options.vsync ^= 1; break; @@ -1404,6 +1428,10 @@ void ss_prog_run(void) case OPTION_FBA_ROTATE: options.rotate ^= 1; break; + case OPTION_FBA_HWSCALING: + options.hwscaling++; + if(options.hwscaling > 2) options.hwscaling = 0; + break; case OPTION_FBA_VSYNC: options.vsync ^= 1; break; diff --git a/src/sdl-dingux/gui_main.h b/src/sdl-dingux/gui_main.h index 4d7d8c0..2ea9a13 100644 --- a/src/sdl-dingux/gui_main.h +++ b/src/sdl-dingux/gui_main.h @@ -43,12 +43,13 @@ #define OPTION_FBA_SOUND 2 #define OPTION_FBA_SAMPLERATE 3 #define OPTION_FBA_ROTATE 4 -#define OPTION_FBA_VSYNC 5 -#define OPTION_FBA_SHOWFPS 6 -#define OPTION_FBA_68K 7 -#define OPTION_FBA_Z80 8 -#define OPTION_FBA_ANALOG 9 -#define OPTION_FBA_FAVORITE 10 +#define OPTION_FBA_HWSCALING 5 +#define OPTION_FBA_VSYNC 6 +#define OPTION_FBA_SHOWFPS 7 +#define OPTION_FBA_68K 8 +#define OPTION_FBA_Z80 9 +#define OPTION_FBA_ANALOG 10 +#define OPTION_FBA_FAVORITE 11 #define OPTION_FBA_FIRST OPTION_FBA_RUN #define OPTION_FBA_LAST OPTION_FBA_FAVORITE @@ -141,11 +142,12 @@ #define OPTION_GUI_DEF_RUN_SOUND 600 #define OPTION_GUI_DEF_RUN_SAMPLERATE 601 #define OPTION_GUI_DEF_RUN_ROTATE 602 -#define OPTION_GUI_DEF_RUN_VSYNC 603 -#define OPTION_GUI_DEF_RUN_SHOWFPS 604 -#define OPTION_GUI_DEF_RUN_CORE 605 -#define OPTION_GUI_DEF_RUN_ANALOG 606 -#define OPTION_GUI_DEF_RUN_RETURN 607 +#define OPTION_GUI_DEF_RUN_HWSCALING 603 +#define OPTION_GUI_DEF_RUN_VSYNC 604 +#define OPTION_GUI_DEF_RUN_SHOWFPS 605 +#define OPTION_GUI_DEF_RUN_CORE 606 +#define OPTION_GUI_DEF_RUN_ANALOG 607 +#define OPTION_GUI_DEF_RUN_RETURN 608 #define OPTION_DEF_RUN_FIRST OPTION_GUI_DEF_RUN_SOUND #define OPTION_DEF_RUN_LAST OPTION_GUI_DEF_RUN_RETURN diff --git a/src/sdl-dingux/main.cpp b/src/sdl-dingux/main.cpp index bf7ef6f..c19739a 100644 --- a/src/sdl-dingux/main.cpp +++ b/src/sdl-dingux/main.cpp @@ -146,6 +146,7 @@ void parse_cmd(int argc, char *argv[], char *path) {"vsync", 0, &options.vsync, 1}, {"scaling", required_argument, 0, 'a'}, {"rotate", required_argument, 0, 'o'}, + {"hwscaling", required_argument, 0, 'h'}, {"sense", required_argument, 0, 'd'}, {"showfps", 0, &options.showfps, 1}, {"no-showfps", 0, &options.showfps, 0}, @@ -206,6 +207,13 @@ void parse_cmd(int argc, char *argv[], char *path) if ((z2>2) || (z2<0)) z2=0; options.rotate = z2; break; + case 'h': + if(!optarg) continue; + z2=0; + sscanf(optarg,"%d",&z2); + if ((z2>2) || (z2<0)) z2=0; + options.hwscaling = z2; + break; case 'd': if(!optarg) continue; z2=0; diff --git a/src/sdl-dingux/sdl_menu.cpp b/src/sdl-dingux/sdl_menu.cpp index 689d7f6..58dfd1a 100644 --- a/src/sdl-dingux/sdl_menu.cpp +++ b/src/sdl-dingux/sdl_menu.cpp @@ -366,12 +366,19 @@ void gui_Run() { struct timeval s, e; extern struct timeval start; +#ifdef DEVICE_GCW0 + int hwscale = options.hwscaling; +#endif #ifdef FBA_DEBUG debug = 1; #endif gettimeofday(&s, NULL); - +#ifdef DEVICE_GCW0 + if (hwscale > 0 && (screen->w != 320 || screen->h != 240)) { + VideoInitForce320x240(); // sets video mode to 320x240 so the menu screen looks right when a game uses a resolution different than 320x240 + } +#endif VideoClear(); SDL_EnableKeyRepeat(/*SDL_DEFAULT_REPEAT_DELAY*/ 150, /*SDL_DEFAULT_REPEAT_INTERVAL*/30); gui_MainMenu.itemCur = 0; @@ -379,7 +386,12 @@ void gui_Run() SDL_EnableKeyRepeat(0, 0); ConfigGameSave(); VideoClear(); - +#ifdef DEVICE_GCW0 + if (hwscale > 0) { + VideoInit(); // when menu is closed to return to the game, video mode is set to the appropiate resolution for the game + VideoClear(); + } +#endif gettimeofday(&e, NULL); start.tv_sec += e.tv_sec - s.tv_sec; start.tv_usec += e.tv_usec - s.tv_usec; diff --git a/src/sdl-dingux/sdl_menu.h b/src/sdl-dingux/sdl_menu.h index 7386fac..4f5667f 100644 --- a/src/sdl-dingux/sdl_menu.h +++ b/src/sdl-dingux/sdl_menu.h @@ -17,6 +17,8 @@ * */ +#define DEVICE_GCW0 + #ifndef _SDL_MENU_H_ #define _SDL_MENU_H_ diff --git a/src/sdl-dingux/sdl_run.cpp b/src/sdl-dingux/sdl_run.cpp index 6c60054..1ec188d 100644 --- a/src/sdl-dingux/sdl_run.cpp +++ b/src/sdl-dingux/sdl_run.cpp @@ -75,10 +75,21 @@ void RunEmulator(int drvnum) if(options.sense < 100) { nAnalogSpeed = 0x100 / 100 * options.sense; } +#ifdef DEVICE_GCW0 + int hwscale = options.hwscaling; +#endif gui_Init(); - VideoInit(); +#ifdef DEVICE_GCW0 + if (hwscale > 0) { + VideoInitForce320x240(); // sets video mode to 320x240 so the loading screen looks right when a game uses a resolution different than 320x240 + } else { +#endif + VideoInit(); +#ifdef DEVICE_GCW0 + } +#endif printf("Attempt to initialise '%s'\n", BurnDrvGetTextA(DRV_FULLNAME)); @@ -94,6 +105,12 @@ void RunEmulator(int drvnum) goto finish; } +#ifdef DEVICE_GCW0 + if (hwscale > 0) { + VideoInit(); // after loading screen ends, video mode is set to the appropiate resolution for the game + } +#endif + RunReset(); GameLooping = true; diff --git a/src/sdl-dingux/sdl_run.h b/src/sdl-dingux/sdl_run.h index e9363e0..642f5be 100644 --- a/src/sdl-dingux/sdl_run.h +++ b/src/sdl-dingux/sdl_run.h @@ -17,6 +17,8 @@ * */ +#define DEVICE_GCW0 + #ifndef _SDL_RUN_H_ #define _SDL_RUN_H_ diff --git a/src/sdl-dingux/sdl_video.cpp b/src/sdl-dingux/sdl_video.cpp index 602c48a..0c16f3c 100644 --- a/src/sdl-dingux/sdl_video.cpp +++ b/src/sdl-dingux/sdl_video.cpp @@ -927,7 +927,6 @@ static void Blitrf_320x240_to_320x240() } } - static void Blitr_320x224_to_320x240() { // 320x224 rotate to 192x240 @@ -1257,6 +1256,7 @@ static void Blitrf_280x224_to_320x240() p += 128; } } + static void Blitr_272x236_to_320x240() { // 272x236 rotate to 208x240 @@ -1761,6 +1761,7 @@ static void Blitrf() p += r_offset; } } + typedef struct { int dst_w; @@ -1831,7 +1832,36 @@ int VideoInit() SDL_InitSubSystem(SDL_INIT_VIDEO); } - screen = SDL_SetVideoMode(320, 240, 16, flags); +#ifdef DEVICE_GCW0 + int hwscale = options.hwscaling; + bool bRotated = options.rotate; + BurnDrvGetFullSize(&VideoBufferWidth, &VideoBufferHeight); + printf("w=%d h=%d\n",VideoBufferWidth, VideoBufferHeight); + + if (hwscale > 0) { + + FILE* aspect_ratio_file = fopen("/sys/devices/platform/jz-lcd.0/keep_aspect_ratio", "w"); + if (aspect_ratio_file) { + if (hwscale == 1) { //Aspect + fwrite("1", 1, 1, aspect_ratio_file); + } else if (hwscale == 2) { //Fullscreen + fwrite("0", 1, 1, aspect_ratio_file); + } + fclose(aspect_ratio_file); + } + + if (bRotated) { + screen = SDL_SetVideoMode(VideoBufferHeight, VideoBufferWidth, 16, SDL_HWSURFACE | SDL_TRIPLEBUF); + } else { + screen = SDL_SetVideoMode(VideoBufferWidth, VideoBufferHeight, 16, SDL_HWSURFACE | SDL_TRIPLEBUF); + } + + } else { +#endif + screen = SDL_SetVideoMode(320, 240, 16, flags); +#ifdef DEVICE_GCW0 + } +#endif /*{ int i = 0; // 0 - 320x240, 1 - 400x240, 2 - 480x272 int surfacewidth, surfaceheight; @@ -1867,60 +1897,86 @@ int VideoInit() SDL_ShowCursor(SDL_DISABLE); SDL_WM_SetCaption("Final Burn SDL", 0); - BurnDrvGetFullSize(&VideoBufferWidth, &VideoBufferHeight); - printf("w=%d h=%d\n",VideoBufferWidth, VideoBufferHeight); - nBurnBpp = 2; BurnHighCol = myHighCol16; BurnRecalcPal(); + nBurnPitch = VideoBufferWidth * 2; + PhysicalBufferWidth = screen->w; BurnVideoBuffer = (unsigned short *)malloc(VideoBufferWidth * VideoBufferHeight * 2); memset(BurnVideoBuffer, 0, VideoBufferWidth * VideoBufferHeight * 2); - BurnerVideoTrans = Blit_320x240_to_320x240; // default blit bool bVertical = options.rotate && (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL); - // if source buffer < screen buffer then set general blitting routine with centering if needed - if(!bVertical && VideoBufferWidth <= screen->w && VideoBufferHeight <= screen->h) { - if(BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) - BurnerVideoTrans = Blitf; - else - BurnerVideoTrans = Blit; - } else if(bVertical && VideoBufferWidth <= screen->h && VideoBufferHeight <= screen->w) { - if(BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) - BurnerVideoTrans = Blitrf; - else - BurnerVideoTrans = Blitr; - } else { - // if source buffer is bigger than screen buffer then find an appropriate downscaler - for(int i = 0; blit_table[i].dst_w != 0; i++) { - if(blit_table[i].dst_w == screen->w && blit_table[i].dst_h == screen->h && - blit_table[i].src_w == VideoBufferWidth && blit_table[i].src_h == VideoBufferHeight) { - if (bVertical && (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED)) - BurnerVideoTrans = blit_table[i].blitrf; - else if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) - BurnerVideoTrans = blit_table[i].blitf; - else if (bVertical) - BurnerVideoTrans = blit_table[i].blitr; - else - BurnerVideoTrans = blit_table[i].blit; - break; - } - } - } - - if (BurnerVideoTrans == Blit || BurnerVideoTrans == Blitf || BurnerVideoTrans == Blitr || BurnerVideoTrans == Blitrf) { +#ifdef DEVICE_GCW0 + if (hwscale > 0) { if (bVertical) { - p_offset = ((screen->h - VideoBufferWidth)/2)*screen->w; - r_offset = screen->w - VideoBufferHeight; + if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) { + BurnerVideoTrans = Blitrf; + } else { + BurnerVideoTrans = Blitr; + } + p_offset = 0; + r_offset = 0; + } else { + if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) { + BurnerVideoTrans = Blitf; + } else { + BurnerVideoTrans = Blit; + } + p_offset = 0; + q_offset = VideoBufferWidth * VideoBufferHeight - 1; } - else { - p_offset = (screen->w - VideoBufferWidth)/2 + (screen->h - VideoBufferHeight)/2*screen->w; - q_offset = VideoBufferWidth*VideoBufferHeight-1; + } else { +#endif + BurnerVideoTrans = Blit_320x240_to_320x240; // default blit + + //bool bVertical = options.rotate && (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL); + + // if source buffer < screen buffer then set general blitting routine with centering if needed + if(!bVertical && VideoBufferWidth <= screen->w && VideoBufferHeight <= screen->h) { + if(BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) + BurnerVideoTrans = Blitf; + else + BurnerVideoTrans = Blit; + } else if(bVertical && VideoBufferWidth <= screen->h && VideoBufferHeight <= screen->w) { + if(BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) + BurnerVideoTrans = Blitrf; + else + BurnerVideoTrans = Blitr; + } else { + // if source buffer is bigger than screen buffer then find an appropriate downscaler + for(int i = 0; blit_table[i].dst_w != 0; i++) { + if(blit_table[i].dst_w == screen->w && blit_table[i].dst_h == screen->h && + blit_table[i].src_w == VideoBufferWidth && blit_table[i].src_h == VideoBufferHeight) { + if (bVertical && (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED)) + BurnerVideoTrans = blit_table[i].blitrf; + else if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) + BurnerVideoTrans = blit_table[i].blitf; + else if (bVertical) + BurnerVideoTrans = blit_table[i].blitr; + else + BurnerVideoTrans = blit_table[i].blit; + break; + } + } + } + + if (BurnerVideoTrans == Blit || BurnerVideoTrans == Blitf || BurnerVideoTrans == Blitr || BurnerVideoTrans == Blitrf) { + if (bVertical) { + p_offset = ((screen->h - VideoBufferWidth)/2)*screen->w; + r_offset = screen->w - VideoBufferHeight; + } + else { + p_offset = (screen->w - VideoBufferWidth)/2 + (screen->h - VideoBufferHeight)/2*screen->w; + q_offset = VideoBufferWidth*VideoBufferHeight-1; + } } +#ifdef DEVICE_GCW0 } +#endif return 0; } @@ -1946,3 +2002,22 @@ void VideoFlip() { SDL_Flip(screen); } + +int VideoInitForce320x240() +{ + // Initialize SDL + if(!(SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO)) { + SDL_InitSubSystem(SDL_INIT_VIDEO); + } + + screen = SDL_SetVideoMode(320, 240, 16, SDL_SWSURFACE); + SDL_ShowCursor(SDL_DISABLE); + + if(!screen) { + printf("SDL_SetVideoMode screen not initialised.\n"); + } else { + printf("SDL_SetVideoMode successful.\n"); + } + + return 0; +} diff --git a/src/sdl-dingux/sdl_video.h b/src/sdl-dingux/sdl_video.h index d994033..890a018 100644 --- a/src/sdl-dingux/sdl_video.h +++ b/src/sdl-dingux/sdl_video.h @@ -17,6 +17,8 @@ * */ +#define DEVICE_GCW0 + #ifndef _SDL_VIDEO_H_ #define _SDL_VIDEO_H_ @@ -33,4 +35,6 @@ void VideoExit(); void VideoFlip(void); void VideoClear(); +int VideoInitForce320x240(); + #endif // _SDL_VIDEO_H_