diff --git a/cpu/cyclone b/cpu/cyclone index 1f03ed6a..94a9d9a8 160000 --- a/cpu/cyclone +++ b/cpu/cyclone @@ -1 +1 @@ -Subproject commit 1f03ed6a49252bfb900c4d3932094308e1c5b375 +Subproject commit 94a9d9a888e72cbfa4db12113cd113cf5e154f7f diff --git a/pico/cd/libchdr b/pico/cd/libchdr index 929a8d65..ff3175dd 160000 --- a/pico/cd/libchdr +++ b/pico/cd/libchdr @@ -1 +1 @@ -Subproject commit 929a8d6523a7d21ea9e035f43211cd759e072053 +Subproject commit ff3175ddb040b1a967c665a28868b16bf5aa97dd diff --git a/pico/media.c b/pico/media.c index c944f989..fca66153 100644 --- a/pico/media.c +++ b/pico/media.c @@ -298,8 +298,9 @@ enum media_type_e PicoLoadMedia(const char *filename, // simple test for GG. Do this here since m.hardware is nulled in Insert if (PicoIn.AHW & PAHW_SMS) { - if (!strcmp(rom->ext,"gg") && !PicoIn.hwSelect) { - Pico.m.hardware |= 0x1; + if ( (!strcmp(rom->ext,"gg") || !strcmp(rom->ext,"GG")) && + !PicoIn.hwSelect) { + Pico.m.hardware |= 0x01; lprintf("detected GG ROM\n"); } else lprintf("detected SMS ROM\n"); diff --git a/pico/sound/emu2413 b/pico/sound/emu2413 index 4062e93e..9f253489 160000 --- a/pico/sound/emu2413 +++ b/pico/sound/emu2413 @@ -1 +1 @@ -Subproject commit 4062e93e9316ee5c488167ade5a83753e5f07ae3 +Subproject commit 9f25348936e691252afcfc992069c5a4810bf3f2 diff --git a/platform/common/configfile_fk.c b/platform/common/configfile_fk.c index 5cffe32a..e663efe3 100644 --- a/platform/common/configfile_fk.c +++ b/platform/common/configfile_fk.c @@ -1,4 +1,4 @@ -// configfile.c - handles loading and saving the configuration options +// configfile_fk.c - handles loading and saving the configuration options #include #include #include diff --git a/platform/common/dr_libs b/platform/common/dr_libs index 49de65c5..b20f7512 160000 --- a/platform/common/dr_libs +++ b/platform/common/dr_libs @@ -1 +1 @@ -Subproject commit 49de65c5204cb055afc1a14b11753e17d52a1d1b +Subproject commit b20f7512a69b732ab4082c05e01fc29d42333fae diff --git a/platform/common/minimp3 b/platform/common/minimp3 index afb604c0..ef9e212f 160000 --- a/platform/common/minimp3 +++ b/platform/common/minimp3 @@ -1 +1 @@ -Subproject commit afb604c06bc8beb145fecd42c0ceb5bda8795144 +Subproject commit ef9e212fa29bb72d23558da21bb5694fd2d01768 diff --git a/platform/common/plat_sdl.c b/platform/common/plat_sdl.c index 9f067f48..a2afc2d3 100644 --- a/platform/common/plat_sdl.c +++ b/platform/common/plat_sdl.c @@ -81,7 +81,8 @@ static struct uyvy { uint32_t y:8; uint32_t vyu:24; } yuv_uyvy[65536]; SDL_Surface * hw_screen = NULL; SDL_Surface * virtual_hw_screen = NULL; -SDL_Surface * sms_game_screen = NULL; +static SDL_Surface * sms_game_screen = NULL; +static SDL_Surface * gg_game_screen = NULL; void clear_screen(SDL_Surface *surface, uint16_t color) { @@ -1473,6 +1474,169 @@ void flip_Downscale_OptimizedWidth320_mergeUpDown(SDL_Surface *src_surface, SDL_ } } +void upscale_160x144_to_240x240_bilinearish(SDL_Surface *src_surface, SDL_Surface *dst_surface) +{ + if (src_surface->w != 160) + { + printf("src_surface->w (%d) != 160 \n", src_surface->w); + return; + } + if (src_surface->h != 144) + { + printf("src_surface->h (%d) != 144 \n", src_surface->h); + return; + } + + uint16_t *Src16 = (uint16_t *) src_surface->pixels; + uint16_t *Dst16 = (uint16_t *) dst_surface->pixels; + + // There are 80 blocks of 2 pixels horizontally, and 48 of 3 horizontally. + // Horizontally: 240=80*3 160=80*2 + // Vertically: 240=48*5 144=48*3 + // Each block of 2*3 becomes 3x5. + uint32_t BlockX, BlockY; + uint16_t *BlockSrc; + uint16_t *BlockDst; + uint16_t _a, _b, _ab, __a, __b, __ab; + for (BlockY = 0; BlockY < 48; BlockY++) + { + BlockSrc = Src16 + BlockY * 160 * 3; + BlockDst = Dst16 + BlockY * 240 * 5; + for (BlockX = 0; BlockX < 80; BlockX++) + { + /* Horizontaly: + * Before(2): + * (a)(b) + * After(3): + * (a)(ab)(b) + */ + + /* Verticaly: + * Before(3): + * (1)(2)(3) + * After(5): + * (1)(12)(2)(23)(3) + */ + + // -- Line 1 -- + _a = *(BlockSrc ); + _b = *(BlockSrc + 1); + _ab = Weight1_1( _a, _b); + *(BlockDst ) = _a; + *(BlockDst + 1) = _ab; + *(BlockDst + 2) = _b; + + // -- Line 2 -- + __a = *(BlockSrc + 160 * 1 ); + __b = *(BlockSrc + 160 * 1 + 1); + __ab = Weight1_1( __a, __b); + *(BlockDst + 240 * 1 ) = Weight1_1(_a, __a); + *(BlockDst + 240 * 1 + 1) = Weight1_1(_ab, __ab); + *(BlockDst + 240 * 1 + 2) = Weight1_1(_b, __b); + + // -- Line 3 -- + *(BlockDst + 240 * 2 ) = __a; + *(BlockDst + 240 * 2 + 1) = __ab; + *(BlockDst + 240 * 2 + 2) = __b; + + // -- Line 4 -- + _a = __a; + _b = __b; + _ab = __ab; + __a = *(BlockSrc + 160 * 2 ); + __b = *(BlockSrc + 160 * 2 + 1); + __ab = Weight1_1( __a, __b); + *(BlockDst + 240 * 3 ) = Weight1_1(_a, __a); + *(BlockDst + 240 * 3 + 1) = Weight1_1(_ab, __ab); + *(BlockDst + 240 * 3 + 2) = Weight1_1(_b, __b); + + // -- Line 5 -- + *(BlockDst + 240 * 4 ) = __a; + *(BlockDst + 240 * 4 + 1) = __ab; + *(BlockDst + 240 * 4 + 2) = __b; + + BlockSrc += 2; + BlockDst += 3; + } + } +} + + +void upscale_160x144_to_240x216_bilinearish(SDL_Surface *src_surface, SDL_Surface *dst_surface) +{ + if (src_surface->w != 160) + { + printf("src_surface->w (%d) != 160 \n", src_surface->w); + return; + } + if (src_surface->h != 144) + { + printf("src_surface->h (%d) != 144 \n", src_surface->h); + return; + } + + /* Y padding for centering */ + uint32_t y_padding = (240 - 216) / 2 + 1; + + uint16_t *Src16 = (uint16_t *) src_surface->pixels; + uint16_t *Dst16 = ((uint16_t *) dst_surface->pixels) + y_padding * 240; + + // There are 80 blocks of 2 pixels horizontally, and 72 of 2 horizontally. + // Horizontally: 240=80*3 160=80*2 + // Vertically: 216=72*3 144=72*2 + // Each block of 2*3 becomes 3x5. + uint32_t BlockX, BlockY; + uint16_t *BlockSrc; + uint16_t *BlockDst; + volatile uint16_t _a, _b, _ab, __a, __b, __ab; + for (BlockY = 0; BlockY < 72; BlockY++) + { + + BlockSrc = Src16 + BlockY * 160 * 2; + BlockDst = Dst16 + BlockY * 240 * 3; + for (BlockX = 0; BlockX < 80; BlockX++) + { + /* Horizontaly: + * Before(2): + * (a)(b) + * After(3): + * (a)(ab)(b) + */ + + /* Verticaly: + * Before(2): + * (1)(2) + * After(3): + * (1)(12)(2) + */ + + // -- Line 1 -- + _a = *(BlockSrc ); + _b = *(BlockSrc + 1); + _ab = Weight1_1( _a, _b); + *(BlockDst ) = _a; + *(BlockDst + 1) = _ab; + *(BlockDst + 2) = _b; + + // -- Line 2 -- + __a = *(BlockSrc + 160 * 1 ); + __b = *(BlockSrc + 160 * 1 + 1); + __ab = Weight1_1( __a, __b); + *(BlockDst + 240 * 1 ) = Weight1_1(_a, __a); + *(BlockDst + 240 * 1 + 1) = Weight1_1(_ab, __ab); + *(BlockDst + 240 * 1 + 2) = Weight1_1(_b, __b); + + // -- Line 3 -- + *(BlockDst + 240 * 2 ) = __a; + *(BlockDst + 240 * 2 + 1) = __ab; + *(BlockDst + 240 * 2 + 2) = __b; + + BlockSrc += 2; + BlockDst += 3; + } + } +} + void SDL_Rotate_270(SDL_Surface * hw_surface, SDL_Surface * virtual_hw_surface){ int i, j; uint16_t *source_pixels = (uint16_t*) virtual_hw_surface->pixels; @@ -1512,6 +1676,147 @@ void SDL_Rotate_270(SDL_Surface * hw_surface, SDL_Surface * virtual_hw_surface){ +void scale_for_gg(SDL_Surface *src_surface, + SDL_Surface *dst_surface, + ENUM_ASPECT_RATIOS_TYPES aspect_ratio){ + //printf("In %s\n", __func__); + + switch(aspect_ratio){ + case ASPECT_RATIOS_TYPE_STRETCHED: + upscale_160x144_to_240x240_bilinearish(src_surface, dst_surface); + break; + + case ASPECT_RATIOS_TYPE_MANUAL: + ;uint32_t h_scaled = src_surface->h*RES_HW_SCREEN_HORIZONTAL/src_surface->w; + ;uint32_t h_zoomed = h_scaled + aspect_ratio_factor_percent*(RES_HW_SCREEN_VERTICAL - h_scaled)/100; + flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + MAX(src_surface->w*h_zoomed/src_surface->h, RES_HW_SCREEN_HORIZONTAL), + MIN(h_zoomed, RES_HW_SCREEN_VERTICAL)); + break; + + case ASPECT_RATIOS_TYPE_CROPPED: + flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + src_surface->w*RES_HW_SCREEN_VERTICAL/src_surface->h, + RES_HW_SCREEN_VERTICAL); + break; + + case ASPECT_RATIOS_TYPE_SCALED: + upscale_160x144_to_240x216_bilinearish(src_surface, dst_surface); + break; + + default: + printf("Wrong aspect ratio value: %d\n", aspect_ratio); + aspect_ratio = ASPECT_RATIOS_TYPE_STRETCHED; + break; + } +} + + +void scale_for_SMS(SDL_Surface *src_surface, + SDL_Surface *dst_surface, + ENUM_ASPECT_RATIOS_TYPES aspect_ratio){ + //printf("In %s\n", __func__); + + switch(aspect_ratio){ + case ASPECT_RATIOS_TYPE_STRETCHED: + flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + RES_HW_SCREEN_HORIZONTAL, + RES_HW_SCREEN_VERTICAL); + break; + + case ASPECT_RATIOS_TYPE_MANUAL: + ;uint32_t h_scaled = MIN(src_surface->h*RES_HW_SCREEN_HORIZONTAL/src_surface->w, + RES_HW_SCREEN_VERTICAL); + uint32_t h_zoomed = MIN(h_scaled + aspect_ratio_factor_percent*(RES_HW_SCREEN_VERTICAL - h_scaled)/100, + RES_HW_SCREEN_VERTICAL); + flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + MAX(src_surface->w*h_zoomed/src_surface->h, RES_HW_SCREEN_HORIZONTAL), + MIN(h_zoomed, RES_HW_SCREEN_VERTICAL)); + break; + + case ASPECT_RATIOS_TYPE_CROPPED: + flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + src_surface->w*RES_HW_SCREEN_VERTICAL/src_surface->h, + RES_HW_SCREEN_VERTICAL); + break; + + case ASPECT_RATIOS_TYPE_SCALED: + flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + RES_HW_SCREEN_HORIZONTAL, + src_surface->h*RES_HW_SCREEN_HORIZONTAL/src_surface->w); + break; + + default: + printf("Wrong aspect ratio value: %d\n", aspect_ratio); + aspect_ratio = ASPECT_RATIOS_TYPE_STRETCHED; + break; + } +} + + +void scale_for_genesis(SDL_Surface *src_surface, + SDL_Surface *dst_surface, + ENUM_ASPECT_RATIOS_TYPES aspect_ratio){ + //printf("In %s\n", __func__); + uint16_t hres_max; + + switch(aspect_ratio){ + case ASPECT_RATIOS_TYPE_STRETCHED: + if(src_surface->w == 320 && src_surface->h < RES_HW_SCREEN_VERTICAL){ + flip_Downscale_OptimizedWidth320_mergeUpDown(src_surface, dst_surface, + RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); + } + else if(src_surface->w == 320){ + flip_Downscale_LeftRightGaussianFilter_OptimizedWidth320(src_surface, dst_surface, + RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); + } + else{ + flip_Downscale_LeftRightGaussianFilter_Optimized(src_surface, dst_surface, + RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); + /*flip_Downscale_LeftRightGaussianFilter(src_surface, hw_screen, + RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL);*/ + } + break; + + case ASPECT_RATIOS_TYPE_MANUAL: + hres_max= MIN(RES_HW_SCREEN_VERTICAL, src_surface->h); + ;uint32_t h_scaled = MIN(src_surface->h*RES_HW_SCREEN_HORIZONTAL/src_surface->w, + RES_HW_SCREEN_VERTICAL); + uint32_t h_zoomed = MIN(h_scaled + aspect_ratio_factor_percent*(hres_max - h_scaled)/100, + RES_HW_SCREEN_VERTICAL); + flip_NNOptimized_LeftRightUpDownBilinear_Optimized8(src_surface, dst_surface, + MAX(src_surface->w*h_zoomed/src_surface->h, RES_HW_SCREEN_HORIZONTAL), + MIN(h_zoomed, RES_HW_SCREEN_VERTICAL)); + break; + + case ASPECT_RATIOS_TYPE_CROPPED: + /*flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + MAX(src_surface->w*RES_HW_SCREEN_VERTICAL/src_surface->h, RES_HW_SCREEN_HORIZONTAL), + RES_HW_SCREEN_VERTICAL);*/ + hres_max= MIN(RES_HW_SCREEN_VERTICAL, src_surface->h); + flip_NNOptimized_AllowOutOfScreen(src_surface, dst_surface, + MAX(src_surface->w*hres_max/src_surface->h, RES_HW_SCREEN_HORIZONTAL), + hres_max); + break; + + case ASPECT_RATIOS_TYPE_SCALED: + flip_NNOptimized_LeftRightUpDownBilinear_Optimized8(src_surface, dst_surface, + RES_HW_SCREEN_HORIZONTAL, + MIN(src_surface->h*RES_HW_SCREEN_HORIZONTAL/src_surface->w, RES_HW_SCREEN_VERTICAL)); + break; + + default: + printf("Wrong aspect ratio value: %d\n", aspect_ratio); + aspect_ratio = ASPECT_RATIOS_TYPE_STRETCHED; + flip_NNOptimized_LeftRightUpDownBilinear_Optimized8(src_surface, dst_surface, + RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); + break; + } +} + + + + @@ -1573,19 +1878,20 @@ void plat_video_flip(void) SDL_Surface *game_surface; /* Sega Game Gear -> 160*144 res in 320*240 surface */ - if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & 0x3) == 0x3){ + //if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & 0x3) == 0x3){ + if ((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & 0x01)){ - /* Copy sms game pixels */ - int offset_y = (plat_sdl_screen->h - sms_game_screen->h)/2; - int offset_x = (plat_sdl_screen->w - sms_game_screen->w)/2 - 1; + /* Copy Game Gear game pixels */ + int offset_y = (plat_sdl_screen->h - gg_game_screen->h)/2; + int offset_x = (plat_sdl_screen->w - gg_game_screen->w)/2 - 1; int y; - for(y=0; y<192; y++){ - memcpy((uint16_t*)sms_game_screen->pixels + sms_game_screen->w*y, + for(y=0; yh; y++){ + memcpy((uint16_t*)gg_game_screen->pixels + gg_game_screen->w*y, (uint16_t*)plat_sdl_screen->pixels + plat_sdl_screen->w*(y+offset_y) + offset_x, - sms_game_screen->w*sizeof(uint16_t)); + gg_game_screen->w*sizeof(uint16_t)); } - game_surface = sms_game_screen; + game_surface = gg_game_screen; } /* Sega Master System -> 256*192 res in 320*240 surface */ else if (PicoIn.AHW & PAHW_SMS){ @@ -1594,7 +1900,7 @@ void plat_video_flip(void) int offset_y = (plat_sdl_screen->h - sms_game_screen->h)/2; int offset_x = (plat_sdl_screen->w - sms_game_screen->w)/2 + 1; int y; - for(y=0; y<192; y++){ + for(y=0; yh; y++){ memcpy((uint16_t*)sms_game_screen->pixels + sms_game_screen->w*y, (uint16_t*)plat_sdl_screen->pixels + plat_sdl_screen->w*(y+offset_y) + offset_x, sms_game_screen->w*sizeof(uint16_t)); @@ -1610,62 +1916,26 @@ void plat_video_flip(void) /// --------------Optimized Flip depending on aspect ratio ------------- static int prev_aspect_ratio; if(prev_aspect_ratio != aspect_ratio || need_screen_cleared){ - //printf("aspect ratio changed: %d\n", aspect_ratio); + /*printf("aspect ratio changed: %s\n", aspect_ratio_name[aspect_ratio]); + printf("game_surface res = %dx%d\n", game_surface->w, game_surface->h);*/ clear_screen(virtual_hw_screen, 0); prev_aspect_ratio = aspect_ratio; need_screen_cleared = 0; } - uint16_t hres_max; - - switch(aspect_ratio){ - case ASPECT_RATIOS_TYPE_STRETCHED: - if(game_surface->w == 320 && game_surface->h < RES_HW_SCREEN_VERTICAL){ - flip_Downscale_OptimizedWidth320_mergeUpDown(game_surface, virtual_hw_screen, - RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); - } - else if(game_surface->w == 320){ - flip_Downscale_LeftRightGaussianFilter_OptimizedWidth320(game_surface, virtual_hw_screen, - RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); - } - else{ - flip_Downscale_LeftRightGaussianFilter_Optimized(game_surface, virtual_hw_screen, - RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); - /*flip_Downscale_LeftRightGaussianFilter(game_surface, hw_screen, - RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL);*/ - } - break; - case ASPECT_RATIOS_TYPE_MANUAL: - hres_max= MIN(RES_HW_SCREEN_VERTICAL, game_surface->h); - ;uint32_t h_scaled = MIN(game_surface->h*RES_HW_SCREEN_HORIZONTAL/game_surface->w, - RES_HW_SCREEN_VERTICAL); - uint32_t h_zoomed = MIN(h_scaled + aspect_ratio_factor_percent*(hres_max - h_scaled)/100, - RES_HW_SCREEN_VERTICAL); - flip_NNOptimized_LeftRightUpDownBilinear_Optimized8(game_surface, virtual_hw_screen, - MAX(game_surface->w*h_zoomed/game_surface->h, RES_HW_SCREEN_HORIZONTAL), - MIN(h_zoomed, RES_HW_SCREEN_VERTICAL)); - break; - case ASPECT_RATIOS_TYPE_CROPPED: - /*flip_NNOptimized_AllowOutOfScreen(game_surface, virtual_hw_screen, - MAX(game_surface->w*RES_HW_SCREEN_VERTICAL/game_surface->h, RES_HW_SCREEN_HORIZONTAL), - RES_HW_SCREEN_VERTICAL);*/ - hres_max= MIN(RES_HW_SCREEN_VERTICAL, game_surface->h); - flip_NNOptimized_AllowOutOfScreen(game_surface, virtual_hw_screen, - MAX(game_surface->w*hres_max/game_surface->h, RES_HW_SCREEN_HORIZONTAL), - hres_max); - break; - case ASPECT_RATIOS_TYPE_SCALED: - flip_NNOptimized_LeftRightUpDownBilinear_Optimized8(game_surface, virtual_hw_screen, - RES_HW_SCREEN_HORIZONTAL, - MIN(game_surface->h*RES_HW_SCREEN_HORIZONTAL/game_surface->w, RES_HW_SCREEN_VERTICAL)); - break; - default: - printf("Wrong aspect ratio value: %d\n", aspect_ratio); - aspect_ratio = ASPECT_RATIOS_TYPE_STRETCHED; - flip_NNOptimized_LeftRightUpDownBilinear_Optimized8(game_surface, virtual_hw_screen, - RES_HW_SCREEN_HORIZONTAL, RES_HW_SCREEN_VERTICAL); - break; - } + /** Rescale for console */ + /** Game Gear */ + if((PicoIn.AHW & PAHW_SMS) && (Pico.m.hardware & 0x01)){ + scale_for_gg(game_surface, virtual_hw_screen, aspect_ratio); + } + /** SMS */ + else if(PicoIn.AHW & PAHW_SMS){ + scale_for_SMS(game_surface, virtual_hw_screen, aspect_ratio); + } + /** Genesis */ + else{ + scale_for_genesis(game_surface, virtual_hw_screen, aspect_ratio); + } // Rotate //SDL_Rotate_270(hw_screen, virtual_hw_screen); @@ -1838,6 +2108,12 @@ void plat_init(void) fprintf(stderr, "sms_game_screen failed: %s\n", SDL_GetError()); } + gg_game_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, + 160, 144, 16, 0xFFFF, 0xFFFF, 0xFFFF, 0); + if (gg_game_screen == NULL) { + fprintf(stderr, "gg_game_screen failed: %s\n", SDL_GetError()); + } + g_menuscreen_w = plat_sdl_screen->w; g_menuscreen_h = plat_sdl_screen->h; g_menuscreen_pp = g_menuscreen_w; @@ -1884,6 +2160,7 @@ void plat_finish(void) { SDL_FreeSurface(virtual_hw_screen); SDL_FreeSurface(sms_game_screen); + SDL_FreeSurface(gg_game_screen); deinit_menu_SDL(); free(shadow_fb); shadow_fb = NULL; diff --git a/platform/libpicofe b/platform/libpicofe index e87e15f1..aa471f7f 160000 --- a/platform/libpicofe +++ b/platform/libpicofe @@ -1 +1 @@ -Subproject commit e87e15f1702e4182ebabb1ab9df1fb9ff13a2e95 +Subproject commit aa471f7f59f3dcc3cf0b6efc6213e53ea0453c9c