You have to make sure you take time into account when doing your object movement. For example, if you had the following:

SomeObject.x := SomeObject.x + 2; // move it to the right

Now, that's all fine and dandy, with your object continually moving to the right 2 pixels each frame. However, if your frame rate isn't constant then you have to adjust the movement -- if a frame takes twice as long, say, you'd want to add 4 instead of 2 to object.

Thus, accounting for the frame rate is simply a multiplication (the longer the frame takes, the more you want to move the object) based on the elapsed time.

First, calculate how much time has passed since the last frame -- this is easy enough if you simply note the current ticks using GetTickCount, timeGetTime (with appropriate init/deinit code if under NT/2000/XP, ask if interested), or QueryPerformanceFrequency/QueryPerformanceCounter each frame (keeping the old one handy, of course, for comparison). You simply grab a value each frame, compare it to the previously grabbed value, and do a subtraction. You might want to adjust the value to be in seconds rather than ticks -- if so, divide by 1000 for GetTickCount or timeGetTime, or by the QueryPerformanceFrequency value (store this in a variable rather than calling it every frame) for QueryPerformanceCounter.

If you do this then you simply have to think of your object speeds in terms of "pixels per second" rather than "pixels per frame". Collision detection might become a bit more annoying, mind you, so you might think about limiting the maximum allowed time-since-last-frame in case of really bad glitches (e.g. hard disc thrashing causing bad jumps). You can also consider keeping lots of old values handy (maybe about 8 or so) and taking the average of them, rather than the immediate time for the last frame. This would possibly make things smoother, or maybe not (experiment a little).

I don't know whether DelphiX's timer lets you get how long has elapsed since the last timer update (I'd assume it would). If not, here's the unit that I use (let me know if you find bugs). It's easy to use: just create a TGameTimer, call Update once per frame, then multiply all your object's movement values by the ElapsedTime property to get movement based on time.

The net result of time-based movement should be that all computers give correct results, but slower ones give jerky movement (which will still be correct, just a little ugly). But that's not something you can account for, really, if the frame rate drops like that. All computers, though, should calculate their objects to be at the same position at a given time.