Thread: Having only one function run at higher priority

  1. #31
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    probably - read this thread from the beginning trying to pay attention this time to what is being said?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  2. #32
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by ulillillia View Post
    What I meant by "it takes 20 seconds for 1 second to show in the timer" is that, if the CPU usage for all other tasks is 95%, the effect is that of processing at 3 fps instead of 60. 20 seconds would pass in the real world when, ignoring the adjusting for dropped frames (which doesn't take much to get), only 1 second of the actual game's time would pass. I get a somewhat similar case with Virtual Dub and this is not my program. If Norton begins running its automatic updates (which is at normal priority), the video plays back very jerky even though VD hardly uses any CPU, unlike my game. If I bump up the thread priority to "above normal", the jerkiness vanishes entirely.

    When a frame is lost, the distance traveled is multiplied by "FramesToAdvance", which is normally 1. That was the only change made. Even then, I don't see what's wrong....
    Ok, I give in. AdvanceClock will kinda actually work. It's a little different from what I do, but it in itself isn't the problem.
    From your decription of the fact that you get a slowing down of time proportional to the slowing down of the frame rate says only one thing - You have locked the frame rate into the logic update rate.

    What you probably have is that MoveObects is actually drawing them as well, as I asked about earlier. You need to change that! Moving them is fast, but drawing them is slow. You need to seperate these out into seperate functions. MoveObjects should ONLY move them. DrawObjects should only draw them. That is the key.
    Then what you do is put the call to DrawObjects at the very end of AdvanceClock, not inside the loop either. Leave MoveObjects where it is.
    Then if you have a stall you can still update the game logic as per the number of times you need to to catch up, but you only draw one frame and skip the rest, so you stay in real-time.

    Now as for the sleep, it isn't ideal, but in practicality it is usable. At least I'm getting away with it, and I know plenty of others that are as well. However, instead of doing a Sleep(1) multiple times until enough time has passed, simply calculate how long to sleep for and just make 1 call to sleep - no loop around it.

    Here is some actual code I use:
    Code:
    	DWORD elapsedTicks = GetTickCount() - startTicks;
    #ifdef DEBUG
    	if (elapsedTicks > 2000) {
    		// This is a safety mechanism... If you debug for too long, the
    		// process effectively locks up afterwards, so we pretend time stopped!
    		startTicks += elapsedTicks;
    		elapsedTicks = 0;
    	}
    #endif
    	while (elapsedTicks > LOGICSTEP) {
    		startTicks += LOGICSTEP;
    		elapsedTicks -= LOGICSTEP;
    		HandleKeys();
    		LogicTick();
    	}
    	fractionalLogicStep = elapsedTicks;
    None of that does any drawing.
    Just after that, I draw a frame, and then calculate how long I should sleep for.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #33
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    Once again, you've misunderstood something. My program, whether it uses 40% of the CPU or 90% has no effect on the frame rate, until it would otherwise go above 100% where it logically would drop (and I would expect the jerky motion). I was referring to other processes in the background (and I've stated this too). To rule out my program as the culprit, I just set the ground resolution to an unusually high quality setting to have an extremely high number of position calculations and drawing (even though I've optimized my drawing function) and the frame rate really drops (the maximum quality, 1, has barely 4 fps, but even something like 30 still looks quite good, though I typically use 14 which has only 4 percentage units more CPU usage than 30. MoveObjects has no drawing functions in it at all and is no longer used in "AdvanceClock" (it used to be, but is no longer present, the optimization I made to it (if you didn't notice the lack of these in that function)). It mostly consists of stuff like this (and lots of it (highly repetitive - copy paste used)):

    Code:
    		PrelakeHills04.x -= (AverageXSpeed/PrelakeHills04.Scaling/6.0);
    		while (PrelakeHills04.x > 0.0) { PrelakeHills04.x -= 1536.0; }
    		while (PrelakeHills04.x < -1536.0) { PrelakeHills04.x += 1536.0; }
    		PrelakeHills04.XMain = (int)PrelakeHills04.x;
    		PrelakeHills04.y = (height/PrelakeHills04.Scaling)+(240-PrelakeHills04Info.biHeight);
    		PrelakeHills04.YMain = (int)PrelakeHills04.y;
    All (100%) of the drawing stuff is done entirely in the "DrawScenery" function, immediately after the function to find positions. This is the main loop:

    Code:
    	while(GameRunning == 1) // this is the main loop
    	{
    		PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE);
    		if (msg.message == WM_QUIT) // check for a quit message
    		{
    			GameRunning = 0; // if found, quit app
    			break;
    		}
    		
    		else
    		{
    			FramesProcessed++;
    			SecondsFrames = (float)FramesProcessed/60.0f;
    			// At the start of each frame, the clock is advanced as close as possible to 1/60 of a second.
    			AdvanceClock();
    			
    			// Next, keyboard input should be processed so I know to move the objects
    			ProcessInput();
    			
    			// After that, the positions of the objects are processed to find out where things should be drawn to
    			MoveObjects();
    			
    			// Then, the scene must be drawn based on those calculated positions
    			DrawScenery();
    			
    			/*
    			DebugPointerTest[1] = PrelakeHills01MainDataPointer;
    			DebugTest[1] = (double)DebugPointerTest[1]; // zero, invalid
    			DebugPointerTest[2] = PrelakeHills02MainDataPointer;
    			DebugTest[2] = (double)DebugPointerTest[2]; // nonzero, valid
    			*/
    			
    			// Finally, translate and dispatch any messages into event queue so other programs can run
    			Sleep(1); // wait some milliseconds
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    The drawing is only done once per object per frame and at the very end. If I don't lock the frame rate to a constant value, jitter or ripping occurs due to monitor synchronization (I've got a temporary one-time-needed fix for this - tapping Z a few times to slightly adjust the "actual" variable).

    I proposed the idea of setting just the "AdvanceClock" function to a higher priority since, by increasing the priority of any program, any jerkiness it has practically disappears all together. I always do this with GameBridge's software since it really gets jerky when Norton runs its automatic updates and using "Above Normal" for GameBridge's software causes all jerkiness to disappear. GameBridge's software also has the same issue as my own program with the case of other programs using the CPU causing lost frames (and this program uses 30 or 29.97 fps (not sure which, though the latter is more likely knowing NTSC TV)).
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

  4. #34
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Do you really use Norton crap? You know their software is poor, right? Just seeing as how their update causes other programs to jerk speaks volumes about their quality.
    And the "jerkiness" due to monitor synchronization... I don't know, but is that kind of like V-Sync?
    I also notice your loop is kind of average. I made up my own fixed-rate function that locks FPS if you're interested to see it.
    It kind of works on the principle to call back X times per specified time interval via a callback function, either via a global function or a class.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #35
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You're doing nothing but lieing to me, or contradicting yourself. You're not answering my questions.
    And now you've finally posted what I asked for originally. Talk about squeezing blood from a stone.
    Don't you try and tell me one more time that I'VE misunderstood something. What you mean is that YOU just cannot explain yourself properly.

    It sound to me like you're now saying that your ONLY problem is that you're getting tearing due to not vsyncing. Fine, do vsyncing then.

    The Windows message handling function you posted may have a bug. You shouldn't call TranslateMessage, or DispatchMessage when PeekMessage returns zero. This may cause the last message to be processed multiple times, unless PeekMessage clears out the message lpMsg points to in this case, which msdn doesn't say. Why the extra sleep at the end?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  6. #36
    Math wizard
    Join Date
    Dec 2006
    Location
    USA
    Posts
    582
    It's not vsyncing that I'm concerned over and that's not what I was after. I'm not lying either. I'll just leave it as I've got it for now; it's getting too far out of hand....
    High elevation is the best elevation. The higher, the better the view!
    My computer: XP Pro SP3, 3.4 GHz i7-2600K CPU (OC'd to 4 GHz), 4 GB DDR3 RAM, X-Fi Platinum sound, GeForce 460, 1920x1440 resolution, 1250 GB HDD space, Visual C++ 2008 Express

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  2. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM
  3. Run function from text file
    By hendraiskandar in forum C Programming
    Replies: 1
    Last Post: 06-20-2005, 01:36 AM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM