// CPhipps - // I_CalculateRes // Calculates the screen resolution, possibly using the supplied guide void I_CalculateRes(unsigned int width, unsigned int height) { // e6y: how about 1680x1050? /* SCREENWIDTH = (width+3) & ~3; SCREENHEIGHT = (height+3) & ~3; */ // e6y // GLBoom will try to set the closest supported resolution // if the requested mode can't be set correctly. // For example glboom.exe -geom 1025x768 -nowindow will set 1024x768. // It affects only fullscreen modes. if (V_GetMode() == VID_MODEGL) { if ( desired_fullscreen ) { I_ClosestResolution(&width, &height, SDL_OPENGL|SDL_FULLSCREEN); } SCREENWIDTH = width; SCREENHEIGHT = height; SCREENPITCH = SCREENWIDTH; } else { SCREENWIDTH = width; SCREENHEIGHT = height; SCREENPITCH = (width * V_GetPixelDepth() + 3) & ~3; if (!(SCREENPITCH % 1024)) SCREENPITCH += 32; } }
// CPhipps - // I_CalculateRes // Calculates the screen resolution, possibly using the supplied guide void I_CalculateRes(int width, int height) { // e6y // GLBoom will try to set the closest supported resolution // if the requested mode can't be set correctly. // For example glboom.exe -geom 1025x768 -nowindow will set 1024x768. // It affects only fullscreen modes. if (V_GetMode() == VID_MODEGL) { if ( desired_fullscreen ) { I_ClosestResolution(&width, &height, SDL_OPENGL|SDL_FULLSCREEN); } SCREENWIDTH = width; SCREENHEIGHT = height; SCREENPITCH = SCREENWIDTH; } else { unsigned int count1, count2; int pitch1, pitch2; SCREENWIDTH = width;//(width+15) & ~15; SCREENHEIGHT = height; // e6y // Trying to optimise screen pitch for reducing of CPU cache misses. // It is extremally important for wiping in software. // I have ~20x improvement in speed with using 1056 instead of 1024 on Pentium4 // and only ~10% for Core2Duo if (try_to_reduce_cpu_cache_misses) { unsigned int mintime = 100; int w = (width+15) & ~15; pitch1 = w * V_GetPixelDepth(); pitch2 = w * V_GetPixelDepth() + 32; count1 = I_TestCPUCacheMisses(pitch1, SCREENHEIGHT, mintime); count2 = I_TestCPUCacheMisses(pitch2, SCREENHEIGHT, mintime); lprintf(LO_INFO, "I_CalculateRes: trying to optimize screen pitch\n"); lprintf(LO_INFO, " test case for pitch=%d is processed %d times for %d msec\n", pitch1, count1, mintime); lprintf(LO_INFO, " test case for pitch=%d is processed %d times for %d msec\n", pitch2, count2, mintime); SCREENPITCH = (count2 > count1 ? pitch2 : pitch1); lprintf(LO_INFO, " optimized screen pitch is %d\n", SCREENPITCH); } else { SCREENPITCH = SCREENWIDTH * V_GetPixelDepth(); } } // e6y: processing of screen_multiply { int factor = ((V_GetMode() == VID_MODEGL) ? 1 : render_screen_multiply); REAL_SCREENWIDTH = SCREENWIDTH * factor; REAL_SCREENHEIGHT = SCREENHEIGHT * factor; REAL_SCREENPITCH = SCREENPITCH * factor; } }
DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscreen, DFrameBuffer *old) { static int retry = 0; static int owidth, oheight; BaseWinFB *fb; PalEntry flashColor; int flashAmount; LOG4 ("CreateFB %d %d %d %p\n", width, height, fullscreen, old); if (old != NULL) { // Reuse the old framebuffer if its attributes are the same BaseWinFB *fb = static_cast<BaseWinFB *> (old); if (fb->Width == width && fb->Height == height && fb->Windowed == !fullscreen) { return old; } old->GetFlash (flashColor, flashAmount); old->ObjectFlags |= OF_YesReallyDelete; if (old == screen) screen = NULL; delete old; } else { flashColor = 0; flashAmount = 0; } if (D3D != NULL) { fb = new D3DFB (width, height, fullscreen); } else { fb = new DDrawFB (width, height, fullscreen); } LOG1 ("New fb created @ %p\n", fb); // If we could not create the framebuffer, try again with slightly // different parameters in this order: // 1. Try with the closest size // 2. Try in the opposite screen mode with the original size // 3. Try in the opposite screen mode with the closest size // This is a somewhat confusing mass of recursion here. while (fb == NULL || !fb->IsValid ()) { static HRESULT hr; if (fb != NULL) { if (retry == 0) { hr = fb->GetHR (); } delete fb; LOG1 ("fb is bad: %08lx\n", hr); } else { LOG ("Could not create fb at all\n"); } screen = NULL; LOG1 ("Retry number %d\n", retry); switch (retry) { case 0: owidth = width; oheight = height; case 2: // Try a different resolution. Hopefully that will work. I_ClosestResolution (&width, &height, 8); LOG2 ("Retry with size %d,%d\n", width, height); break; case 1: // Try changing fullscreen mode. Maybe that will work. width = owidth; height = oheight; fullscreen = !fullscreen; LOG1 ("Retry with fullscreen %d\n", fullscreen); break; default: // I give up! LOG3 ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr); I_FatalError ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr); } ++retry; fb = static_cast<DDrawFB *>(CreateFrameBuffer (width, height, fullscreen, NULL)); } retry = 0; fb->SetFlash (flashColor, flashAmount); return fb; }
static void ApplyWindowResize(SDL_Event *resize_event) { int i, k; char mode[80]; int w = MAX(320, resize_event->resize.w); int h = MAX(200, resize_event->resize.h); if (screen_resolution) { if (!(SDL_GetModState() & KMOD_SHIFT)) { // Find the biggest screen mode that will fall within these // dimensions, falling back to the smallest mode possible if // none is found. Uint32 flags = SDL_FULLSCREEN; if (V_GetMode() == VID_MODEGL) flags |= SDL_OPENGL; I_ClosestResolution(&w, &h, flags); } w = MAX(320, w); h = MAX(200, h); sprintf(mode, "%dx%d", w, h); screen_resolution = screen_resolutions_list[0]; for (i = 0; i < MAX_RESOLUTIONS_COUNT; i++) { if (screen_resolutions_list[i]) { if (!strcmp(mode, screen_resolutions_list[i])) { screen_resolution = screen_resolutions_list[i]; break; } } } // custom resolution if (screen_resolution == screen_resolutions_list[0]) { if (screen_resolution_lowest && !strcmp(screen_resolution_lowest, screen_resolutions_list[0])) { // there is no "custom resolution" entry in the list for(k = MAX_RESOLUTIONS_COUNT - 1; k > 0; k--) { screen_resolutions_list[k] = screen_resolutions_list[k - 1]; } // add it screen_resolutions_list[0] = strdup(mode); screen_resolution = screen_resolutions_list[0]; } else { union { const char *c; char *s; } u; // type punning via unions u.c = screen_resolutions_list[0]; free(u.s); screen_resolutions_list[0] = strdup(mode); screen_resolution = screen_resolutions_list[0]; } } V_ChangeScreenResolution(); doom_printf("%dx%d", w, h); } }