Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace all calls to rand() by calls to a custom randomizer #788

Open
dirkwhoffmann opened this issue Mar 5, 2024 · 1 comment
Open
Labels

Comments

@dirkwhoffmann
Copy link
Owner

VirtualC64 calls rand() at multiple places. Although the returned sequences are deterministic, this causes issues in run-ahead mode, since both instances would query different numbers and diverge.

TODO: Implement a new Randomizer class that returns a deterministic pseudo-random sequence and instantiate this class in both the main instance and the run-ahead instance.

Fun fact: Bugs related to run-ahead mode result in funny behavior due to diverging emulator instances. In Barry McGuigan World Championship Boxing, I've thought to have knocked out my opponent.

Bildschirmfoto 2024-03-05 um 17 38 20

However, this only happened in the run-ahead instance. After the next resync, I've been lying on the ground and lost the fight.

@dirkwhoffmann
Copy link
Owner Author

An easy solution is to derive the pseudo-number directly from the current CPU cycle:

u32
C64::random()
{
    return random(u32(cpu.clock));
}

u32
C64::random(u32 seed)
{
    // Parameters for the Linear Congruential Generator (LCG)
    u64 a = 1664525;
    u64 c = 1013904223;
    u64 m = 1LL << 32;

    // Apply the LCG formula
    return u32((a * seed + c) % m);
}

random() can be used as long as there is only one call per cycle. Otherwise, the same value would be returned twice.

Arrays such as colorRam can be initialized as follows:

        // Initialize color RAM with random numbers
        u32 seed = 0;
        for (isize i = 0; i < isizeof(colorRam); i++) {
            
            seed = c64.random(seed);
            colorRam[i] = u8(seed);
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant