Random number generator

The random number generator is pretty simple. A 16-bit seed is stored which for convenience in code is split into two 8-bit values. The routine is at 0xdd4 in the sf2ua ROM. Here’s the equivalent C code:

short sf2rand(void) {
    int x = (g.randSeed1 << 8) + g.randSeed2;
    x *= 3;
    x = x >> 8;
    g.randSeed2 += x;
    g.randSeed1  = x;
    return g.randSeed2;

As far as PRNGs go it’s pretty poor, but good enough for our purpose here. The output of it is often bitmasked to limit its values (e.g. masked with 0xf to get a number from 0-15, masked with 0xe to get an even number from 0-14, and so on), and also used as a bit index with the BTST instruction to get a 1-in-N chance.

For example, to get a 1-in-4 chance:

if( 0x88888888 & (1 << (sf2rand() & 0x1f)))

The RNG is seeded with exactly the same value every time the machine starts (there’s nothing else to seed it with, no RTC, nothing), so it always produces the same string of random numbers.

If you start the machine, wait for the player invite screen to start, insert a coin and play with Ryu, you will face Dhalsim on your first fight. If you insert your coin while the copyright warning is still printing, you’ll face Blanka instead.

One of these days I should analyse it to see when the seed returns to its initial value, i.e. when the sequence starts repeating.

Random number generator