예제 #1
0
파일: i_video.c 프로젝트: CaptainHIT/prboom
// 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;
  }
}
예제 #2
0
// 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;
  }
}
예제 #3
0
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;
}
예제 #4
0
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);
  }
}