I just have a few comments. Firstly, you do not have enough comments. There are places where itโs not clear what you are trying to do, so itโs hard to say if there is a better way to do this, but I will point to them when I come to them. Firstly though:
#define MSECS_PER_STEP 20 int stepCount, stepSize;
They are not initialized by anything. They will probably appear as 0, but you should initialize them. In addition, instead of declaring them as static, you might want to put them in a structure that you pass to the loop by reference.
int deltatime = msec() - lastMsec;
Since lastMsec not (initialized and probably 0), it probably starts as a big delta.
lastMsec = msec();
This line, like the last line, calls msec . This probably means "current time" and these calls are close enough that the return value is probably the same for both calls, which is probably also what you expected, but still you call this function twice. You should change these lines to int now = msec(); int deltatime = now - lastMsec; lastMsec = now; to avoid calling this function twice. At the moment, getting functions is often much higher than you think.
if (deltatime != 0) { iterations = deltatime/MSECS_PER_STEP; accumulator += deltatime%MSECS_PER_STEP; }
You should have a comment here that says it does, as well as the comment above which means what the variables mean.
while (accumulator >= MSECS_PER_STEP) { iterations++; accumulator -= MSECS_PER_STEP; }
This loop requires comment. It also should not be. It looks like it could be replaced with iterations += accumulator/MSECS_PER_STEP; accumulator %= MSECS_PER_STEP; . Separation and module must be performed at shorter and more sequential times than a cycle on any machine with hardware separation (which many do).
handleInput(); // gathers user input from an event queue for (j=0; j<iterations; j++) { for (i=0; i<stepCount; i++) { doStep(stepSize/(float) stepCount); // forwards the sim } }
Performing steps in a loop regardless of input will result in the game not responding if it does slow work and is lagging. It seems, at least, if the game is behind, all the input data will begin to be added and executed together, and all the game time will pass in one piece. This is a less graceful way to fail.
Also, I can guess what j (external loop) means, but the inner loop is less clear to me. also, the value passed to the doStep function is what it means.
}
This is the last brace. I think it looks lonely.
I donโt know what happens if you name your loop function, which may be out of your control, and this may dictate what this function does and how it looks, but if not, I hope that you will review the structure. I believe that the best way to do this is to have a function that is called repeatedly, but with only one event at a time (regularly released in a relatively short period). These events can be either user input events or timer events. User input events have just been configured to respond to the next timer event. (when you do not have any events for sleep processing)
You should always assume that every timer event is processed in the same period, although there may be some drift if the processing is behind. The main oddity that you can notice here is that if the game lags behind the processing of timer events and then gets caught again, the time in the game may slow down (below real time), then accelerate (to real time) and then slowly back off ( in real time).
Ways to solve this problem include only one timer event, which will be in the event queue at a time, which will slow down time (below real time) and then speed up backups (up to real time) without an ultra-fast interval.
Another way to do this, functionally similar to what you have, would be the last step in processing each timer event in the queue of the next timer event (note that no one should send timer events (except for the first) if thatโs how you decide to implement the game). This would mean getting rid of the regular time intervals between timer events, as well as limiting the ability to sleep in the program, because at least every time the event queue was checked, the timer processing should be processed.