Language: c
const int A = <some>; // no entropy
const int B = <some>; // no entropy
int seed = 0; // no entropy
int rand()
{
seed = A*seed + B; // A, B, seed - no entropy -> new seed - no entropy
return seed;
} // so this func deterministic
void main ()
{
seed = time(0); // time(0) - source of entropy, so seed isn't deterministic.
for (int i=0; i<10; ++i)
printf("rand() = %d\n", rand()); // there will be 10 random numbers but! if you know first, you can easily determine all 9 after.
}
// so if you set seed to some certain value in main, you'll get deterministic program. it will run always same.
List of some sources of entropy:
1) Time, timers, delays, elapsed time between some two points in program.
2) Threads execution order, it can't be same, unless if you syncronize all with appropriate methods (mutexes, events etc.)
3) Program base address (where it was loaded), current stack pointer :D, addresses of memory allocated in heap...
4) User input: keys down, keys up, mouse movements...
5) OS events: WM_MESSAGES, hmmm something else :)
6) Polling stuff: socket recieve packets, socket send packet, sound in poll mode (is there space for next sound samples?)...
7) Special random devices that produces
REAL RANDOM!
You can expand this list forever.
But when it comes to emulators, you may restrict your emulator core from accessing to all this stuff except user input.
So your emulator must have only two methods:
1) advance time (emulate frame / emulate miliseconds ...)
2) change current user input (for rerecording)
and restrict from any other external input that may have entropy :), also restrict frontend from changing any data used by core. Use "encapsulation" method :).
Question: how then I'll show image and play sound if it produce entropy?
Answer: yes it produce entropy, but as far as you don't access it from core: (advance time method) you can use it, because while you didn't call time advance methods, state does not change.