Forum

Setgamma: Engine crash restore gamma?

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

Setgamma: Engine crash restore gamma?

Postby Baker » Wed Jul 07, 2010 7:39 pm

After most engines crash, I have to run setgamma.exe with no params to restore the gamma.

Someone said some engine (like Q4? It's been a while and I am guessing) automatically restored the gamma the way the setgamma does upon *starting* the engine.

What is setgamma doing to restore the desktop gamma?

If anyone knows. I am kind of tired of running the setgamma utility after crashes and would rather the startup of my engine take care of that nuisance.

Any ideas or suggestions?
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby revelator » Wed Jul 07, 2010 8:09 pm

hmm i think i seen the code somewhere on lh's site ? might be possible to integrate it somewhere in the video code.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby mh » Wed Jul 07, 2010 8:53 pm

Code: Select all
LONG WINAPI TildeDirectQ (LPEXCEPTION_POINTERS toast)
{
   MessageBox (NULL, "Something bad happened and DirectQ is now toast.\n"
      "Please visit http://mhquake.blogspot.com and report this crash.",
      "An error has occurred",
      MB_OK | MB_ICONSTOP);

   // restore monitor gamma
   VID_DefaultMonitorGamma_f ();

   // restore default timer
   timeEndPeriod (sys_time_period);

   // down she goes
   return EXCEPTION_EXECUTE_HANDLER;
}


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
   InitCommonControls ();
   SetUnhandledExceptionFilter (TildeDirectQ);


You may recognise some of that. ;)

Of course it's OS-specific but gamma-handling stuff is going to be OS-specific anyway. VID_DefaultMonitorGamma_f just constructs a linear gamma ramp and applies it. It may not restore it exactly if the user had customized it, but at least the end result doesn't sear your eyes out, and anyway restoring it exactly may not be possible if the crash resulted in the memory used to store the original ramps being corrupted.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby metlslime » Thu Jul 08, 2010 1:34 am

setgamma basically does the same thing that the engines themselves do when changing gamma.

The problem is, when the engine truly crashes, it can't execute any more code. (When it pops up a dialog box saying "Quake Error"that is different, because Quake found the error and is shutting down gracefully -- and should already restore the gamma.)

However, see mh's comment... that's new territory for me.
metlslime
 
Posts: 316
Joined: Tue Feb 05, 2008 11:03 pm

Postby r00k » Thu Jul 08, 2010 9:19 am

Thank's MH!
I just tested this in Qrack and it works like a champ!
Code: Select all
LONG WINAPI ABANDONSHIP (LPEXCEPTION_POINTERS toast)//MH
{
   MessageBox (NULL, "Whoops! That's not suppose to happen!\n"
      "Please contact ************ to report this crash.",
     "!@#$%^&*",
      MB_OK | MB_ICONSTOP);

   Host_Shutdown();

   // down she goes
   return EXCEPTION_EXECUTE_HANDLER;
}


then in WinMain
Code: Select all
   SetUnhandledExceptionFilter(ABANDONSHIP);
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby mh » Tue Jul 13, 2010 6:02 pm

It may also be an idea to do something useful with those exception pointers. :D

Code: Select all
#ifdef _DEBUG

#include <windows.h>
#include <assert.h>
#include <Dbghelp.h>
#include <stdio.h>

#pragma comment (lib, "Dbghelp.lib")


bool symbolsinit = false;


void InitSymbols (void)
{
   if (!symbolsinit)
   {
      // get the current symbols options
      DWORD dwOptions = SymGetOptions ();

      // load lines
      SymSetOptions (dwOptions | SYMOPT_LOAD_LINES);

      BOOL blah = SymInitialize (GetCurrentProcess (), NULL, TRUE);
        assert (blah);

      symbolsinit = true;
   }
}


void KillSymbols (void)
{
   if (symbolsinit)
   {
      SymCleanup (GetCurrentProcess ());
      symbolsinit = false;
   }
}


void GetCrashReason (LPEXCEPTION_POINTERS ep)
{
   // ensure that the exception pointers weren't stomped
   if (!ep) return;
   if (IsBadReadPtr (ep, sizeof (EXCEPTION_POINTERS))) return;

   // turn on the symbols engine
   InitSymbols ();

   DWORD dwLineDisp = 0;
   IMAGEHLP_LINE64 crashline = {sizeof (IMAGEHLP_LINE64), NULL, 0, NULL, 0};

   if (SymGetLineFromAddr64 (GetCurrentProcess (), (DWORD64) ep->ExceptionRecord->ExceptionAddress, &dwLineDisp, &crashline))
   {
      char msg[2048];

      sprintf (msg, "file: %s  line: %i", crashline.FileName, (int) crashline.LineNumber);
      MessageBox (NULL, msg, "An error has occurred", MB_OK | MB_ICONSTOP);
   }
   else MessageBox (NULL, "Unknown error", "An error has occurred", MB_OK | MB_ICONSTOP);

   // and turn it off again
   KillSymbols ();
}
#else
void GetCrashReason (LPEXCEPTION_POINTERS ep)
{
   // if we're not using a debug build all that we can do is display an error
   MessageBox (NULL, "Something bad happened and DirectQ is now toast.\n"
      "Please visit http://mhquake.blogspot.com and report this crash.",
      "An error has occurred",
      MB_OK | MB_ICONSTOP);
}
#endif


Handy if you're distributing debug versions to beta testers.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Chip » Tue Jul 13, 2010 8:39 pm

I noticed that Darkplaces has the option to turn off hardware gamma and lets you play with its own (software, I guess) gamma options.

I noticed that while playing Quake windowed, and the screen behind it was brightened. As I clicked outside Quake, and it lost focus, the desktop gamma reverted to normal. It behaved as expected.

As soon as I turned hardware gamma off, the screen became normal, even with focus on Quake.

Isn't it better to use software/internal gamma, rather than hardware?
Last edited by Chip on Tue Jul 13, 2010 11:08 pm, edited 1 time in total.
QuakeWiki
getButterfly - WordPress Support Services
Roo Holidays

Fear not the dark, but what the dark hides.
User avatar
Chip
 
Posts: 575
Joined: Wed Jan 21, 2009 9:12 am
Location: Dublin, Ireland

Postby Baker » Tue Jul 13, 2010 9:21 pm

Very nice, MH ;)
Last edited by Baker on Tue Jul 13, 2010 9:22 pm, edited 1 time in total.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby mh » Tue Jul 13, 2010 9:22 pm

It depends on how the software/internal gamma is implemented. Drawing Quads over the screen to brighten/darken it can really really HURT your fillrate; you only need to compare a timedemo demo1 with gl_polyblend 0 versus one with gl_polyblend 1 to see what I mean.

In most cases that won't matter, as Quake is going to be running fast enough anyway, but it does become a serious problem when you start running big maps/complex scenes that stress the renderer.

An alternative approach is to render the entire scene to texture then 2x or 4x modulate it by a colour to the framebuffer. If you're already rendering everything to texture anyway this may be viable and will give you gamma (or at least brightness) for free; if not then you've got added complexity, lost performance and a reliance on hardware that supports render to texture and 2x or 4x modulate blends.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Spike » Tue Jul 13, 2010 9:43 pm

I wonder if you can just change the brightness of your lightmaps.
if you always brighten the screen, damage/pickup/powerup flashes won't be quite as annoying when they halve your framerate (if you're fillrate bound, anyway). It would actually be smoother to always blend, even if it gives a lower framerate...

Actually, that's a good point, with windows 2000 upwards, microsoft added lots of extra checks with hardware gamma ramps. You can really notice your framerate dropping any and every time the brightness changes. bonus flashes are the worst! polyblends don't have that issue.
as a result, FTE uses hardware gamma for gamma/contrast, and polyblends for damage/bonuses. it just feels better, and most modern cards have ample fillrate.
Your average quake engine will actually struggle more on cpu usage in complex scenes than fillrate, so polyblend isn't actually all that bad. Its still noticable though.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Tue Jul 13, 2010 10:13 pm

I use the blended render to texture idea for bonus flashes these days, with the texture resolution set to a power of 2 below the screen size. Rendering at the lower resolution for a fraction of a second is hardly even noticeable and it eliminates the (admittedly quite small) fillrate hit that polyblends give. (It's also good for emulating the software Quake underwater warp and you get the colour blend for free with that.)

Changing lightmap brightness is a nice idea, but I'm thinking that it wouldn't help if your sbar or menu graphics were too bright or too dark, and also reduces the dynamic range available for lights. May even be considered a form of cheating by some. Still a nice idea though.

I had OpenGL code for doing brightness via a single polyblend and a 2x or 4x modulate years ago, but I don't know what happened to it. Multiple polyblends would definitely stack up the fillrate damage until it starts to become unacceptable though.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Spike » Tue Jul 13, 2010 10:31 pm

does your underwater warp also warp the hud?
if not, then how does it affect the gamma there, and if so, why?!?! :P

glsl can be quite godly though. :)
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Tue Jul 13, 2010 10:38 pm

Spike wrote:does your underwater warp also warp the hud?
if not, then how does it affect the gamma there, and if so, why?!?! :P

glsl can be quite godly though. :)

It doesn't; I use SetDeviceGammaRamp for standard gamma. Just spitting out ideas here really. :D

(It doesn't even use a shader - preventing it from warping the edges of the texture in a reasonable manner is a bitch. 20x20 tesselation of the viewport rect is good enough (you'd get away with 16x16 or even 8x8); add in an indexed triangle list and overhead is utterly minimised.)

(Edit: aaah, I've just seen FTE's underwater warp. I can see that I don't need to tell you about these things. :D )
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Baker » Thu May 26, 2011 8:41 pm

I am so glad I asked this question way back when :D

This for me will solve the gamma shutdown issue. I can just have the crash detection do it.

[Maybe a recursive calling check to make sure the gamma shutdown isn't making the crash. Like "Double Quake Error" ... which I have never seen, but it recursively checks to make sure Sys_Error wasn't from Sys_Error ... creating an infinitely loop.]
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Baker » Wed Jun 15, 2011 5:28 pm

I'm someone has a more efficient way to do this, but what good is crash detection if you don't have an easy way to crash the engine during testing.

Code: Select all
void Sys_Crash_f (void)
{
   void (*Crash_Me_Now) (void);
   
   if (!developer.value)
   {
      Con_Printf ("Only available in developer mode\n");
      return;
   }

   Crash_Me_Now = NULL;
   Crash_Me_Now ();   // CRASH!!  To test crash protection.
   
}


Code: Select all
   Cmd_AddCommand ("crash", Sys_Crash_f);


The crash protection stuff is awesome, but I had to do a bit of playing around to get it to work how I wanted. I was having the issue of the popup appearing behind the window in fullscreen mode so I needed to do some experiments and follow some code to restore the display settings (and then gamma obviously) first.

Note to self: Make sure -dedicated doesn't get this. That could be highly freaking annoying on a hosted server. (I mean the crash protection, the crash command could prove useful making sure a remote server is setup properly to restart itself, etc. But obviously that should only be conditionally available.)
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest