static void sdldisplay_find_best_fullscreen_scaler( void ) { static int windowed_scaler = -1; /* Make sure we have at least more than half of the screen covered in fullscreen to avoid the "postage stamp" on machines that don't support 320x240 anymore e.g. Mac notebooks */ if( settings_current.full_screen ) { int i = 0; while( i < SCALER_NUM && ( image_height*sdldisplay_current_size <= min_fullscreen_height/2 || image_height*sdldisplay_current_size > max_fullscreen_height ) ) { if( windowed_scaler == -1) windowed_scaler = current_scaler; while( !scaler_is_supported(i) ) i++; scaler_select_scaler( i++ ); sdldisplay_current_size = scaler_get_scaling_factor( current_scaler ); /* if we failed to find a suitable size scaler, just use normal (what the user had originally may be too big) */ if( image_height * sdldisplay_current_size <= min_fullscreen_height/2 || image_height * sdldisplay_current_size > max_fullscreen_height ) { scaler_select_scaler( SCALER_NORMAL ); sdldisplay_current_size = scaler_get_scaling_factor( current_scaler ); } } } else { if( windowed_scaler != -1 ) { scaler_select_scaler( windowed_scaler ); windowed_scaler = -1; sdldisplay_current_size = scaler_get_scaling_factor( current_scaler ); } } }
static int sdldisplay_load_gfx_mode( void ) { Uint16 *tmp_screen_pixels; sdldisplay_force_full_refresh = 1; tmp_screen = NULL; tmp_screen_width = (image_width + 3); sdldisplay_current_size = scaler_get_scaling_factor( current_scaler ); sdldisplay_find_best_fullscreen_scaler(); /* Create the surface that contains the scaled graphics in 16 bit mode */ sdldisplay_gc = SDL_SetVideoMode( image_width * sdldisplay_current_size, image_height * sdldisplay_current_size, 16, settings_current.full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE ); if( !sdldisplay_gc ) { fprintf( stderr, "%s: couldn't create SDL graphics context\n", fuse_progname ); fuse_abort(); } sdldisplay_is_full_screen = settings_current.full_screen = !!(sdldisplay_gc->flags & SDL_FULLSCREEN); /* Distinguish 555 and 565 mode */ if( sdldisplay_gc->format->Gmask >> sdldisplay_gc->format->Gshift == 0x1f ) scaler_select_bitformat( 555 ); else
int screenshot_write( const char *filename, scaler_type scaler ) { FILE *f; png_structp png_ptr; png_infop info_ptr; libspectrum_byte *row_pointers[ MAX_SIZE * DISPLAY_SCREEN_HEIGHT ]; size_t rgb_stride = MAX_SIZE * DISPLAY_ASPECT_WIDTH * 4, png_stride = MAX_SIZE * DISPLAY_ASPECT_WIDTH * 3; size_t y, base_height, base_width, height, width; int error; if( machine_current->timex ) { base_height = 2 * DISPLAY_SCREEN_HEIGHT; base_width = DISPLAY_SCREEN_WIDTH; } else { base_height = DISPLAY_SCREEN_HEIGHT; base_width = DISPLAY_ASPECT_WIDTH; } /* Change from paletted data to RGB data */ error = get_rgb32_data( rgb_data1, rgb_stride, base_height, base_width ); if( error ) return error; /* Actually scale the data here */ scaler_get_proc32( scaler )( rgb_data1, rgb_stride, rgb_data2, rgb_stride, base_width, base_height ); height = base_height * scaler_get_scaling_factor( scaler ); width = base_width * scaler_get_scaling_factor( scaler ); /* Reduce from RGB(padding byte) to just RGB */ error = rgb32_to_rgb24( png_data, png_stride, rgb_data2, rgb_stride, height, width ); if( error ) return error; for( y = 0; y < height; y++ ) row_pointers[y] = &png_data[ y * png_stride ]; f = fopen( filename, "wb" ); if( !f ) { ui_error( UI_ERROR_ERROR, "Couldn't open `%s': %s", filename, strerror( errno ) ); return 1; } png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if( !png_ptr ) { ui_error( UI_ERROR_ERROR, "Couldn't allocate png_ptr" ); fclose( f ); return 1; } info_ptr = png_create_info_struct( png_ptr ); if( !info_ptr ) { ui_error( UI_ERROR_ERROR, "Couldn't allocate info_ptr" ); png_destroy_write_struct( &png_ptr, NULL ); fclose( f ); return 1; } /* Set up the error handling; libpng will return to here if it encounters an error */ if( setjmp( png_jmpbuf( png_ptr ) ) ) { ui_error( UI_ERROR_ERROR, "Error from libpng" ); png_destroy_write_struct( &png_ptr, &info_ptr ); fclose( f ); return 1; } png_init_io( png_ptr, f ); /* Make files as small as possible */ png_set_compression_level( png_ptr, Z_BEST_COMPRESSION ); png_set_IHDR( png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT ); png_set_rows( png_ptr, info_ptr, row_pointers ); png_write_png( png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); png_destroy_write_struct( &png_ptr, &info_ptr ); if( fclose( f ) ) { ui_error( UI_ERROR_ERROR, "Couldn't close `%s': %s", filename, strerror( errno ) ); return 1; } return 0; }