/* render the console on a surface/texture SDL12 : vbitmap = SDL_Surface SDL2 : vbitmap = SDL_Texture */ static void render(void *vbitmap, int console_width, int console_height, char_t *console_buffer, char_t *prev_console_buffer) { char_t *prev_console_buffer_ptr = prev_console_buffer; if ( TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { TCOD_sys_console_to_bitmap(vbitmap, console_width, console_height, console_buffer, prev_console_buffer_ptr); if ( TCOD_ctx.sdl_cbk ) { TCOD_ctx.sdl_cbk((void *)screen); } SDL_Flip(screen); } #ifndef NO_OPENGL else { TCOD_opengl_render(oldFade, ascii_updated, console_buffer, prev_console_buffer); TCOD_opengl_swap(); } #endif oldFade=(int)TCOD_console_get_fade(); if ( any_ascii_updated ) { memset(ascii_updated,0,sizeof(bool)*TCOD_ctx.max_font_chars); any_ascii_updated=false; } }
/* In order to avoid rendering race conditions and the ensuing segmentation * faults, this should only be called when it would normally be and not * specifically to force screen refreshes. To this end, and to avoid * threading complications it takes care of special cases internally. */ static void render(void *vbitmap, int console_width, int console_height, char_t *console_buffer, char_t *prev_console_buffer) { char_t *prev_console_buffer_ptr = prev_console_buffer; if ( TCOD_ctx.renderer == TCOD_RENDERER_SDL ) { int console_width_p = console_width*TCOD_ctx.font_width; int console_height_p = console_height*TCOD_ctx.font_height; /* Make a bitmap of exact rendering size and correct format. */ if (scale_screen == NULL) { int bpp; Uint32 rmask, gmask, bmask, amask; if (SDL_PixelFormatEnumToMasks(SDL_GetWindowPixelFormat(window), &bpp, &rmask, &gmask, &bmask, &amask) == SDL_FALSE) { TCOD_fatal("SDL : failed to create scaling surface : indeterminate window pixel format"); return; } scale_screen=SDL_CreateRGBSurface(SDL_SWSURFACE,console_width_p,console_height_p,bpp,rmask,gmask,bmask,amask); if (scale_screen == NULL) { TCOD_fatal("SDL : failed to create scaling surface"); return; } } else if (clear_screen) { clear_screen=false; SDL_FillRect(scale_screen,0,0); /* Implicitly do complete console redraw, not just tracked changes. */ prev_console_buffer_ptr = NULL; } TCOD_sys_console_to_bitmap(scale_screen, console_width, console_height, console_buffer, prev_console_buffer_ptr); /* Scale the rendered bitmap to the screen, preserving aspect ratio, and blit it. * This data is also used for console coordinate resolution.. */ if (scale_data.last_scale_factor != scale_factor || scale_data.last_scale_xc != scale_xc || scale_data.last_scale_yc != scale_yc || scale_data.last_fullscreen != TCOD_ctx.fullscreen || scale_data.force_recalc) { /* Preserve old value of input variables, to enable recalculation if they change. */ scale_data.last_scale_factor = scale_factor; scale_data.last_scale_xc = scale_xc; scale_data.last_scale_yc = scale_yc; scale_data.last_fullscreen = TCOD_ctx.fullscreen; scale_data.force_recalc = 0; if (scale_data.last_fullscreen) { scale_data.surface_width = TCOD_ctx.actual_fullscreen_width; scale_data.surface_height = TCOD_ctx.actual_fullscreen_height; } else { scale_data.surface_width = console_width_p; scale_data.surface_height = console_height_p; } scale_data.min_scale_factor = MAX((float)console_width_p/scale_data.surface_width, (float)console_height_p/scale_data.surface_height); if (scale_data.min_scale_factor > 1.0f) scale_data.min_scale_factor = 1.0f; /*printf("min_scale_factor %0.3f = MAX(%d/%d, %d/%d)", scale_data.min_scale_factor, console_width_p, scale_data.surface_width, console_height_p, scale_data.surface_height);*/ scale_data.dst_height_width_ratio = (float)scale_data.surface_height/scale_data.surface_width; scale_data.src_proportionate_width = (int)(console_width_p / scale_factor); scale_data.src_proportionate_height = (int)((console_width_p * scale_data.dst_height_width_ratio) / scale_factor); /* Work out how much of the console to copy. */ scale_data.src_x0 = (scale_xc * console_width_p) - (0.5f * scale_data.src_proportionate_width); if (scale_data.src_x0 + scale_data.src_proportionate_width > console_width_p) scale_data.src_x0 = console_width_p - scale_data.src_proportionate_width; if (scale_data.src_x0 < 0) scale_data.src_x0 = 0; scale_data.src_copy_width = scale_data.src_proportionate_width; if (scale_data.src_x0 + scale_data.src_copy_width > console_width_p) scale_data.src_copy_width = console_width_p - scale_data.src_x0; scale_data.src_y0 = (scale_yc * console_height_p) - (0.5f * scale_data.src_proportionate_height); if (scale_data.src_y0 + scale_data.src_proportionate_height > console_height_p) scale_data.src_y0 = console_height_p - scale_data.src_proportionate_height; if (scale_data.src_y0 < 0) scale_data.src_y0 = 0; scale_data.src_copy_height = scale_data.src_proportionate_height; if (scale_data.src_y0 + scale_data.src_copy_height > console_height_p) scale_data.src_copy_height = console_height_p - scale_data.src_y0; scale_data.dst_display_width = (scale_data.src_copy_width * scale_data.surface_width) / scale_data.src_proportionate_width; scale_data.dst_display_height = (scale_data.src_copy_height * scale_data.surface_height) / scale_data.src_proportionate_height; scale_data.dst_offset_x = (scale_data.surface_width - scale_data.dst_display_width)/2; scale_data.dst_offset_y = (scale_data.surface_height - scale_data.dst_display_height)/2; } SDL_RenderClear(renderer); actual_rendering(); SDL_RenderPresent(renderer); } #ifndef NO_OPENGL else { TCOD_opengl_render(oldFade, ascii_updated, console_buffer, prev_console_buffer); TCOD_opengl_swap(); } #endif oldFade=(int)TCOD_console_get_fade(); if ( any_ascii_updated ) { memset(ascii_updated,0,sizeof(bool)*TCOD_ctx.max_font_chars); any_ascii_updated=false; } }