This page is a mirror of Tepples' nesdev forum mirror (URL TBD).

# Adjusting speeds and accelerations from PAL to NTSC

I've timed a game for PAL, and I want to adjust the values so it runs at the same speed (well, rephrase: "the objects move at the same relative speed") in NTSC.

If I have a speed of VPAL, VNTSC = VPAL * 5 / 6

I'm having problems with A. I know the ratio is different, but my maths are rusty. I know I have to use derivatives and nice differential equations. Years ago this would be easy to solve, but now I'm struggling.

Any help? I've done some bad math but the results are, urm, acceptable.

Take 1 second,
APAL=VPAL/50
ANTSC=VNTSC/60

And we know that
VNTSC=VPAL*5/6

So
ANTSC=(VPAL*5/6)/60
ANTSC=VPAL/72
ANTSC=VPAL/50 * 50/72

And
ANTSC=APAL * 50/72

A bit sloppy, but seems to work. Example:

PAL:
A = 10; after 1 second (50 frames), V = 10 * 50 = 500.
A sprite would have moved S = 1/2A*T^2 = 5*50^2 = 12500 units.

NTSC:
A = 10 * 50 / 72 ~= 6.95; after 1 second (60 frames), V = 6.95 * 60 = 417.
A sprite would have moved S = 1/2A*T^2 = 6.95/2 * 60^2 = 12510 units.

Which is pretty close.

Problem is, you need good precission to achieve good results. In my engine, I am using just 4 bits of fixed point. But I'll manage.
Easiest way is to skip logic updates once every 6 frames (=> render the same frame twice). I did that in STREEMERZ because the original game ran at 50 FPS and I didn't want to risk breaking the game by introducing fixed point variables. I think it's an acceptable solution, albeit not perfect.
I've done such a thing in fixed screen games (I use neslib, and neslib allows for it via a compile time option), but I'm afraid that would introduce a noticeable glitch in my current game, as it is a side scroller. I'll try, though.

I've currently adjusted the values PAL->NTSC and the NTSC doesn't fly like before, but the movement is different as the lack of precission has forced me to get things going using several subterfuges.

I'll try what you suggest nevertheless.
I'm having some difficulty following the math, especially at this part
na_th_an wrote:
So
ANTSC=(VPAL*5/6)/60
ANTSC=VPAL/72
ANTSC=VPAL/50 * 50/72

When I tried this 2 years ago, I found that for acceleration the time factor was always squared.

As = 12500 * (1)^2 = 12500 units per second
APAL = 12500 * (1/50)^2 = 5 units per PAL frame
ANTSC = 12500 * (1/60)^2 ~= 3.472 units per NTSC frame

Rounding ANTSC to 4 bits of fractional precision will result in 3.5 units per frame, which ends being 100 units off over a whole second. 4 bits fractional precision is a little corse for this, maybe add 1 byte of fractional precision just for the player character?
You're both right: 50/72 = (5/6)^2 = 0.69444

But no adjustment is perfect. Perhaps 3 and 4 units of acceleration in alternate frames would be close enough.
JRoatch wrote:
When I tried this 2 years ago, I found that for acceleration the time factor was always squared.

Velocity affects position over time, so it's scaled by time. Acceleration affects velocity over time, so its affect on velocity is scaled by time, but its affect on position is scaled by time squared. How to adjust depends where you're applying the scaling.

The other thing is that's an ideal model. The model of the jump might be a parabolic curve, but in practice you're probably doing an Euler Integration, approximating it in discrete steps. The problem with this is that the approximation compounds at every step (frame), and the result can be pretty far off the ideal model, and very sensitive to small changes.

Instead of trying to do your adjustments based on the ideal model, you might just write a simple program (not on the NES) to iterate the calculation frame by frame, and just tweak the parameters by hand until you have a new arc that has the properties that you want. This lets you make all sorts of adjustments, like figuring out precisely how many pixels high the jump will be, the timing of how many frames you're above a certain level, etc. and you can also add things like releasing the jump button early to the simulation.
Well, I've tried both.

First the calculated adjustments + manual adjustments, then the don't update objects every 6th frame. So far (I haven't tried on real hardware), I've opted for the latter, as I can't find a noticeable glitch and the game plays almost exactly in NTSC and PAL. With the former method, the game just doesn't feel the same.

I will try in real hardware as soon as possible and will make a final decision.

As for the precision issue, I am using 4 bits just because I've made my engine so a single unsigned int is used for the X coordinates (16 bits), and the level is 16 screens (4096 bytes) long. 4096*16 = 65536. The engine is fairly simple and everything depends on that. I'll try different approaches for bigger levels in the future.
I'd forgotten about this, and as such have been scaling acceleration incorrectly. Thanks for bringing this up - my Genesis game is fixed!