mirror of https://github.com/bsnes-emu/bsnes.git
Update to v104r04 release.
byuu says: Changelog: - higan/emulator: added new Random class with three entropy settings: none, low, and high - md/vdp: corrected Vcounter readout in interlace mode [MoD] - sfc: updated core to use the new Random class; defaults to high entropy No entropy essentially returns 0, unless the random.bias(n) function is called, in which case, it returns n. In this case, n is meant to be the "logical/ideal" default value that maximizes compatibility with games. Low entropy is a very simple entropy modeled after RAM initialization striping patterns (eg 32 0x00s, followed by 32 0xFFs, repeating throughout.) It doesn't "glitch" like real hardware does on rare occasions (parts of the pattern being broken from time to time.) It also only really returns 0 or ~0. So the entropy is indeed extremely low, and not very useful at all for detecting bugs. Over time, we can try to improve this, of course. High entropy is PCG. This replaces the older, lower-entropy and more predictable, LFSR. PCG should be more than enough for emulator randomness, while still being quite fast. Unfortunately, the bad news ... both no entropy and low entropy fix the Konami logo popping sound in Prince of Persia, but all three entropy settings still cause the distortion in-game, especially evident at the title screen. So ... this may be a more serious bug than first suspected.
This commit is contained in:
parent
c0934b826c
commit
d621136d69
|
@ -12,7 +12,7 @@ using namespace nall;
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const string Name = "higan";
|
static const string Name = "higan";
|
||||||
static const string Version = "104.03";
|
static const string Version = "104.04";
|
||||||
static const string Author = "byuu";
|
static const string Author = "byuu";
|
||||||
static const string License = "GPLv3";
|
static const string License = "GPLv3";
|
||||||
static const string Website = "http://byuu.org/";
|
static const string Website = "http://byuu.org/";
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Emulator {
|
||||||
|
|
||||||
|
struct Random {
|
||||||
|
enum class Entropy : uint { None, Low, High };
|
||||||
|
|
||||||
|
auto entropy(Entropy entropy) -> void {
|
||||||
|
settings.entropy = entropy;
|
||||||
|
seed();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto seed(maybe<uint32> seed = nothing, maybe<uint32> sequence = nothing) -> void {
|
||||||
|
if(!seed) seed = (uint32)clock();
|
||||||
|
if(!sequence) sequence = 0;
|
||||||
|
seed32(seed(), sequence());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto operator()() -> uint64 {
|
||||||
|
return iterate64();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bias(uint64 bias) -> uint64 {
|
||||||
|
if(settings.entropy == Entropy::None) return bias;
|
||||||
|
return operator()();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bound(uint64 bound) -> uint64 {
|
||||||
|
uint64 threshold = -bound % bound;
|
||||||
|
while(true) {
|
||||||
|
uint64 result = iterate64();
|
||||||
|
if(result >= threshold) return result % bound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto serialize(serializer& s) -> void {
|
||||||
|
s.integer((uint&)settings.entropy);
|
||||||
|
s.integer(ram.state);
|
||||||
|
s.integer(ram.increment);
|
||||||
|
s.integer(pcg.state);
|
||||||
|
s.integer(pcg.increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto seed32(uint32 seed, uint32 sequence) -> void {
|
||||||
|
switch(settings.entropy) {
|
||||||
|
|
||||||
|
case Entropy::None: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Entropy::Low: {
|
||||||
|
ram.state = seed;
|
||||||
|
ram.increment = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Entropy::High: {
|
||||||
|
pcg.state = 0;
|
||||||
|
pcg.increment = sequence << 1 | 1;
|
||||||
|
iterate32();
|
||||||
|
pcg.state += seed;
|
||||||
|
iterate32();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iterate32() -> uint32 {
|
||||||
|
switch(settings.entropy) {
|
||||||
|
|
||||||
|
case Entropy::None: {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Entropy::Low: {
|
||||||
|
uint64 result = 0;
|
||||||
|
if(ram.increment.bit(4 + ram.state.bits(0,1))) result = ~0;
|
||||||
|
ram.increment++;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Entropy::High: {
|
||||||
|
uint64 state = pcg.state;
|
||||||
|
pcg.state = state * 6364136223846793005ull + pcg.increment;
|
||||||
|
uint32 xorshift = (state >> 18 ^ state) >> 27;
|
||||||
|
uint32 rotate = state >> 59;
|
||||||
|
return xorshift >> rotate | xorshift << (-rotate & 31);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto iterate64() -> uint64 {
|
||||||
|
return (uint64)iterate32() << 32 | (uint64)iterate32() << 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Settings {
|
||||||
|
Entropy entropy = Entropy::High;
|
||||||
|
} settings;
|
||||||
|
|
||||||
|
struct RAM { //Entropy::Low
|
||||||
|
uint64 state;
|
||||||
|
uint64 increment;
|
||||||
|
} ram;
|
||||||
|
|
||||||
|
struct PCG { //Entropy::High
|
||||||
|
uint64 state;
|
||||||
|
uint64 increment;
|
||||||
|
} pcg;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -14,8 +14,8 @@ auto VDP::read(uint24 addr) -> uint16 {
|
||||||
//counter
|
//counter
|
||||||
case 0xc00008: case 0xc0000a: case 0xc0000c: case 0xc0000e: {
|
case 0xc00008: case 0xc0000a: case 0xc0000c: case 0xc0000e: {
|
||||||
auto vcounter = state.vcounter;
|
auto vcounter = state.vcounter;
|
||||||
if(io.interlaceMode == 3) {
|
if(io.interlaceMode.bit(0)) {
|
||||||
vcounter = vcounter << 1 | state.field; //todo: unverified
|
if(io.interlaceMode.bit(1)) vcounter <<= 1;
|
||||||
vcounter.bit(0) = vcounter.bit(8);
|
vcounter.bit(0) = vcounter.bit(8);
|
||||||
}
|
}
|
||||||
return vcounter << 8 | (state.hdot >> 1) << 0;
|
return vcounter << 8 | (state.hdot >> 1) << 0;
|
||||||
|
|
|
@ -103,7 +103,8 @@ auto ArmDSP::unload() -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ArmDSP::power() -> void {
|
auto ArmDSP::power() -> void {
|
||||||
for(auto n : range(16 * 1024)) programRAM[n] = random(0x00);
|
random.seed();
|
||||||
|
for(auto n : range(16 * 1024)) programRAM[n] = random();
|
||||||
bridge.reset = false;
|
bridge.reset = false;
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,8 @@ auto CPU::power() -> void {
|
||||||
bus.map(reader, writer, "00-3f,80-bf:0000-1fff", 0x2000);
|
bus.map(reader, writer, "00-3f,80-bf:0000-1fff", 0x2000);
|
||||||
bus.map(reader, writer, "7e-7f:0000-ffff", 0x20000);
|
bus.map(reader, writer, "7e-7f:0000-ffff", 0x20000);
|
||||||
|
|
||||||
for(auto& byte : wram) byte = random(0x55);
|
random.seed();
|
||||||
|
for(auto& byte : wram) byte = random.bias(0x55);
|
||||||
|
|
||||||
//DMA
|
//DMA
|
||||||
for(auto& channel : this->channel) {
|
for(auto& channel : this->channel) {
|
||||||
|
|
|
@ -232,7 +232,8 @@ auto DSP::power() -> void {
|
||||||
create(Enter, system.apuFrequency());
|
create(Enter, system.apuFrequency());
|
||||||
stream = Emulator::audio.createStream(2, frequency() / 768.0);
|
stream = Emulator::audio.createStream(2, frequency() / 768.0);
|
||||||
|
|
||||||
for(auto& byte : apuram) byte = random(0x00);
|
random.seed();
|
||||||
|
for(auto& byte : apuram) byte = random();
|
||||||
|
|
||||||
memory::fill(&state, sizeof(State));
|
memory::fill(&state, sizeof(State));
|
||||||
state.noise = 0x4000;
|
state.noise = 0x4000;
|
||||||
|
|
|
@ -207,17 +207,17 @@ auto PPU::Background::getTileColor() -> uint {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::Background::power() -> void {
|
auto PPU::Background::power() -> void {
|
||||||
io.tiledataAddress = (random(0x0000) & 0x0f) << 12;
|
io.tiledataAddress = (random() & 0x0f) << 12;
|
||||||
io.screenAddress = (random(0x0000) & 0xfc) << 8;
|
io.screenAddress = (random() & 0xfc) << 8;
|
||||||
io.screenSize = random(0);
|
io.screenSize = random();
|
||||||
io.mosaic = random(0);
|
io.mosaic = random();
|
||||||
io.tileSize = random(0);
|
io.tileSize = random();
|
||||||
io.mode = 0;
|
io.mode = 0;
|
||||||
for(auto& p : io.priority) p = 0;
|
for(auto& p : io.priority) p = 0;
|
||||||
io.aboveEnable = random(0);
|
io.aboveEnable = random();
|
||||||
io.belowEnable = random(0);
|
io.belowEnable = random();
|
||||||
io.hoffset = random(0x0000);
|
io.hoffset = random();
|
||||||
io.voffset = random(0x0000);
|
io.voffset = random();
|
||||||
|
|
||||||
latch.hoffset = 0;
|
latch.hoffset = 0;
|
||||||
latch.voffset = 0;
|
latch.voffset = 0;
|
||||||
|
|
|
@ -189,13 +189,13 @@ auto PPU::Object::power() -> void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io.aboveEnable = random(false);
|
io.aboveEnable = random();
|
||||||
io.belowEnable = random(false);
|
io.belowEnable = random();
|
||||||
io.interlace = random(false);
|
io.interlace = random();
|
||||||
|
|
||||||
io.baseSize = random(0);
|
io.baseSize = random();
|
||||||
io.nameselect = random(0);
|
io.nameselect = random();
|
||||||
io.tiledataAddress = (random(0x0000) & 7) << 13;
|
io.tiledataAddress = (random() & 7) << 13;
|
||||||
io.firstSprite = 0;
|
io.firstSprite = 0;
|
||||||
|
|
||||||
for(auto& p : io.priority) p = 0;
|
for(auto& p : io.priority) p = 0;
|
||||||
|
|
|
@ -95,17 +95,18 @@ auto PPU::power() -> void {
|
||||||
function<auto (uint24, uint8) -> void> writer{&PPU::writeIO, this};
|
function<auto (uint24, uint8) -> void> writer{&PPU::writeIO, this};
|
||||||
bus.map(reader, writer, "00-3f,80-bf:2100-213f");
|
bus.map(reader, writer, "00-3f,80-bf:2100-213f");
|
||||||
|
|
||||||
for(auto& n : vram.data) n = random(0x0000);
|
random.seed();
|
||||||
|
for(auto& n : vram.data) n = random();
|
||||||
|
|
||||||
ppu1.mdr = random(0xff);
|
ppu1.mdr = random.bias(0xff);
|
||||||
ppu2.mdr = random(0xff);
|
ppu2.mdr = random.bias(0xff);
|
||||||
|
|
||||||
latch.vram = random(0x0000);
|
latch.vram = random();
|
||||||
latch.oam = random(0x00);
|
latch.oam = random();
|
||||||
latch.cgram = random(0x00);
|
latch.cgram = random();
|
||||||
latch.bgofsPPU1 = random(0x00);
|
latch.bgofsPPU1 = random();
|
||||||
latch.bgofsPPU2 = random(0x00);
|
latch.bgofsPPU2 = random();
|
||||||
latch.mode7 = random(0x00);
|
latch.mode7 = random();
|
||||||
latch.counters = false;
|
latch.counters = false;
|
||||||
latch.hcounter = 0;
|
latch.hcounter = 0;
|
||||||
latch.vcounter = 0;
|
latch.vcounter = 0;
|
||||||
|
@ -119,59 +120,59 @@ auto PPU::power() -> void {
|
||||||
|
|
||||||
//$2102 OAMADDL
|
//$2102 OAMADDL
|
||||||
//$2103 OAMADDH
|
//$2103 OAMADDH
|
||||||
io.oamBaseAddress = random(0x0000);
|
io.oamBaseAddress = random();
|
||||||
io.oamAddress = random(0x0000);
|
io.oamAddress = random();
|
||||||
io.oamPriority = random(false);
|
io.oamPriority = random();
|
||||||
|
|
||||||
//$2105 BGMODE
|
//$2105 BGMODE
|
||||||
io.bgPriority = false;
|
io.bgPriority = false;
|
||||||
io.bgMode = 0;
|
io.bgMode = 0;
|
||||||
|
|
||||||
//$210d BG1HOFS
|
//$210d BG1HOFS
|
||||||
io.hoffsetMode7 = random(0x0000);
|
io.hoffsetMode7 = random();
|
||||||
|
|
||||||
//$210e BG1VOFS
|
//$210e BG1VOFS
|
||||||
io.voffsetMode7 = random(0x0000);
|
io.voffsetMode7 = random();
|
||||||
|
|
||||||
//$2115 VMAIN
|
//$2115 VMAIN
|
||||||
io.vramIncrementMode = random(1);
|
io.vramIncrementMode = random.bias(1);
|
||||||
io.vramMapping = random(0);
|
io.vramMapping = random();
|
||||||
io.vramIncrementSize = 1;
|
io.vramIncrementSize = 1;
|
||||||
|
|
||||||
//$2116 VMADDL
|
//$2116 VMADDL
|
||||||
//$2117 VMADDH
|
//$2117 VMADDH
|
||||||
io.vramAddress = random(0x0000);
|
io.vramAddress = random();
|
||||||
|
|
||||||
//$211a M7SEL
|
//$211a M7SEL
|
||||||
io.repeatMode7 = random(0);
|
io.repeatMode7 = random();
|
||||||
io.vflipMode7 = random(false);
|
io.vflipMode7 = random();
|
||||||
io.hflipMode7 = random(false);
|
io.hflipMode7 = random();
|
||||||
|
|
||||||
//$211b M7A
|
//$211b M7A
|
||||||
io.m7a = random(0x0000);
|
io.m7a = random();
|
||||||
|
|
||||||
//$211c M7B
|
//$211c M7B
|
||||||
io.m7b = random(0x0000);
|
io.m7b = random();
|
||||||
|
|
||||||
//$211d M7C
|
//$211d M7C
|
||||||
io.m7c = random(0x0000);
|
io.m7c = random();
|
||||||
|
|
||||||
//$211e M7D
|
//$211e M7D
|
||||||
io.m7d = random(0x0000);
|
io.m7d = random();
|
||||||
|
|
||||||
//$211f M7X
|
//$211f M7X
|
||||||
io.m7x = random(0x0000);
|
io.m7x = random();
|
||||||
|
|
||||||
//$2120 M7Y
|
//$2120 M7Y
|
||||||
io.m7y = random(0x0000);
|
io.m7y = random();
|
||||||
|
|
||||||
//$2121 CGADD
|
//$2121 CGADD
|
||||||
io.cgramAddress = random(0x00);
|
io.cgramAddress = random();
|
||||||
io.cgramAddressLatch = random(0);
|
io.cgramAddressLatch = random();
|
||||||
|
|
||||||
//$2133 SETINI
|
//$2133 SETINI
|
||||||
io.extbg = random(false);
|
io.extbg = random();
|
||||||
io.pseudoHires = random(false);
|
io.pseudoHires = random();
|
||||||
io.overscan = false;
|
io.overscan = false;
|
||||||
io.interlace = false;
|
io.interlace = false;
|
||||||
|
|
||||||
|
|
|
@ -161,19 +161,20 @@ auto PPU::Screen::fixedColor() const -> uint15 {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::Screen::power() -> void {
|
auto PPU::Screen::power() -> void {
|
||||||
for(auto& n : cgram) n = random(0x0000);
|
random.seed();
|
||||||
|
for(auto& n : cgram) n = random();
|
||||||
|
|
||||||
io.blendMode = random(false);
|
io.blendMode = random();
|
||||||
io.directColor = random(false);
|
io.directColor = random();
|
||||||
io.colorMode = random(false);
|
io.colorMode = random();
|
||||||
io.colorHalve = random(false);
|
io.colorHalve = random();
|
||||||
io.bg1.colorEnable = random(false);
|
io.bg1.colorEnable = random();
|
||||||
io.bg2.colorEnable = random(false);
|
io.bg2.colorEnable = random();
|
||||||
io.bg3.colorEnable = random(false);
|
io.bg3.colorEnable = random();
|
||||||
io.bg4.colorEnable = random(false);
|
io.bg4.colorEnable = random();
|
||||||
io.obj.colorEnable = random(false);
|
io.obj.colorEnable = random();
|
||||||
io.back.colorEnable = random(false);
|
io.back.colorEnable = random();
|
||||||
io.colorBlue = random(0);
|
io.colorBlue = random();
|
||||||
io.colorGreen = random(0);
|
io.colorGreen = random();
|
||||||
io.colorRed = random(0);
|
io.colorRed = random();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,58 +47,58 @@ auto PPU::Window::test(bool oneEnable, bool one, bool twoEnable, bool two, uint
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PPU::Window::power() -> void {
|
auto PPU::Window::power() -> void {
|
||||||
io.bg1.oneEnable = random(false);
|
io.bg1.oneEnable = random();
|
||||||
io.bg1.oneInvert = random(false);
|
io.bg1.oneInvert = random();
|
||||||
io.bg1.twoEnable = random(false);
|
io.bg1.twoEnable = random();
|
||||||
io.bg1.twoInvert = random(false);
|
io.bg1.twoInvert = random();
|
||||||
io.bg1.mask = random(0);
|
io.bg1.mask = random();
|
||||||
io.bg1.aboveEnable = random(false);
|
io.bg1.aboveEnable = random();
|
||||||
io.bg1.belowEnable = random(false);
|
io.bg1.belowEnable = random();
|
||||||
|
|
||||||
io.bg2.oneEnable = random(false);
|
io.bg2.oneEnable = random();
|
||||||
io.bg2.oneInvert = random(false);
|
io.bg2.oneInvert = random();
|
||||||
io.bg2.twoEnable = random(false);
|
io.bg2.twoEnable = random();
|
||||||
io.bg2.twoInvert = random(false);
|
io.bg2.twoInvert = random();
|
||||||
io.bg2.mask = random(0);
|
io.bg2.mask = random();
|
||||||
io.bg2.aboveEnable = random(false);
|
io.bg2.aboveEnable = random();
|
||||||
io.bg2.belowEnable = random(false);
|
io.bg2.belowEnable = random();
|
||||||
|
|
||||||
io.bg3.oneEnable = random(false);
|
io.bg3.oneEnable = random();
|
||||||
io.bg3.oneInvert = random(false);
|
io.bg3.oneInvert = random();
|
||||||
io.bg3.twoEnable = random(false);
|
io.bg3.twoEnable = random();
|
||||||
io.bg3.twoInvert = random(false);
|
io.bg3.twoInvert = random();
|
||||||
io.bg3.mask = random(0);
|
io.bg3.mask = random();
|
||||||
io.bg3.aboveEnable = random(false);
|
io.bg3.aboveEnable = random();
|
||||||
io.bg3.belowEnable = random(false);
|
io.bg3.belowEnable = random();
|
||||||
|
|
||||||
io.bg4.oneEnable = random(false);
|
io.bg4.oneEnable = random();
|
||||||
io.bg4.oneInvert = random(false);
|
io.bg4.oneInvert = random();
|
||||||
io.bg4.twoEnable = random(false);
|
io.bg4.twoEnable = random();
|
||||||
io.bg4.twoInvert = random(false);
|
io.bg4.twoInvert = random();
|
||||||
io.bg4.mask = random(0);
|
io.bg4.mask = random();
|
||||||
io.bg4.aboveEnable = random(false);
|
io.bg4.aboveEnable = random();
|
||||||
io.bg4.belowEnable = random(false);
|
io.bg4.belowEnable = random();
|
||||||
|
|
||||||
io.obj.oneEnable = random(false);
|
io.obj.oneEnable = random();
|
||||||
io.obj.oneInvert = random(false);
|
io.obj.oneInvert = random();
|
||||||
io.obj.twoEnable = random(false);
|
io.obj.twoEnable = random();
|
||||||
io.obj.twoInvert = random(false);
|
io.obj.twoInvert = random();
|
||||||
io.obj.mask = random(0);
|
io.obj.mask = random();
|
||||||
io.obj.aboveEnable = random(false);
|
io.obj.aboveEnable = random();
|
||||||
io.obj.belowEnable = random(false);
|
io.obj.belowEnable = random();
|
||||||
|
|
||||||
io.col.oneEnable = random(false);
|
io.col.oneEnable = random();
|
||||||
io.col.oneInvert = random(false);
|
io.col.oneInvert = random();
|
||||||
io.col.twoEnable = random(false);
|
io.col.twoEnable = random();
|
||||||
io.col.twoInvert = random(false);
|
io.col.twoInvert = random();
|
||||||
io.col.mask = random(0);
|
io.col.mask = random();
|
||||||
io.col.aboveMask = random(0);
|
io.col.aboveMask = random();
|
||||||
io.col.belowMask = random(0);
|
io.col.belowMask = random();
|
||||||
|
|
||||||
io.oneLeft = random(0x00);
|
io.oneLeft = random();
|
||||||
io.oneRight = random(0x00);
|
io.oneRight = random();
|
||||||
io.twoLeft = random(0x00);
|
io.twoLeft = random();
|
||||||
io.twoRight = random(0x00);
|
io.twoRight = random();
|
||||||
|
|
||||||
output.above.colorEnable = 0;
|
output.above.colorEnable = 0;
|
||||||
output.below.colorEnable = 0;
|
output.below.colorEnable = 0;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <emulator/emulator.hpp>
|
#include <emulator/emulator.hpp>
|
||||||
#include <emulator/thread.hpp>
|
#include <emulator/thread.hpp>
|
||||||
#include <emulator/scheduler.hpp>
|
#include <emulator/scheduler.hpp>
|
||||||
|
#include <emulator/random.hpp>
|
||||||
#include <emulator/cheat.hpp>
|
#include <emulator/cheat.hpp>
|
||||||
|
|
||||||
#include <processor/arm7tdmi/arm7tdmi.hpp>
|
#include <processor/arm7tdmi/arm7tdmi.hpp>
|
||||||
|
@ -23,8 +24,10 @@ namespace SuperFamicom {
|
||||||
#define platform Emulator::platform
|
#define platform Emulator::platform
|
||||||
namespace File = Emulator::File;
|
namespace File = Emulator::File;
|
||||||
using Scheduler = Emulator::Scheduler;
|
using Scheduler = Emulator::Scheduler;
|
||||||
|
using Random = Emulator::Random;
|
||||||
using Cheat = Emulator::Cheat;
|
using Cheat = Emulator::Cheat;
|
||||||
extern Scheduler scheduler;
|
extern Scheduler scheduler;
|
||||||
|
extern Random random;
|
||||||
extern Cheat cheat;
|
extern Cheat cheat;
|
||||||
|
|
||||||
struct Thread : Emulator::Thread {
|
struct Thread : Emulator::Thread {
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
Random random;
|
|
||||||
|
|
||||||
auto Random::seed(uint seed) -> void {
|
|
||||||
iter = seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Random::operator()(uint result) -> uint {
|
|
||||||
if(!settings.random) return result;
|
|
||||||
return iter = (iter >> 1) ^ (((iter & 1) - 1) & 0xedb88320);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Random::serialize(serializer& s) -> void {
|
|
||||||
s.integer(iter);
|
|
||||||
}
|
|
|
@ -42,9 +42,9 @@ auto System::serialize(serializer& s) -> void {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto System::serializeAll(serializer& s) -> void {
|
auto System::serializeAll(serializer& s) -> void {
|
||||||
|
random.serialize(s);
|
||||||
cartridge.serialize(s);
|
cartridge.serialize(s);
|
||||||
system.serialize(s);
|
system.serialize(s);
|
||||||
random.serialize(s);
|
|
||||||
cpu.serialize(s);
|
cpu.serialize(s);
|
||||||
smp.serialize(s);
|
smp.serialize(s);
|
||||||
ppu.serialize(s);
|
ppu.serialize(s);
|
||||||
|
|
|
@ -4,9 +4,9 @@ namespace SuperFamicom {
|
||||||
|
|
||||||
System system;
|
System system;
|
||||||
Scheduler scheduler;
|
Scheduler scheduler;
|
||||||
|
Random random;
|
||||||
Cheat cheat;
|
Cheat cheat;
|
||||||
#include "video.cpp"
|
#include "video.cpp"
|
||||||
#include "random.cpp"
|
|
||||||
#include "serialization.cpp"
|
#include "serialization.cpp"
|
||||||
|
|
||||||
auto System::run() -> void {
|
auto System::run() -> void {
|
||||||
|
@ -141,7 +141,7 @@ auto System::power() -> void {
|
||||||
Emulator::audio.reset();
|
Emulator::audio.reset();
|
||||||
Emulator::audio.setInterface(interface);
|
Emulator::audio.setInterface(interface);
|
||||||
|
|
||||||
random.seed((uint)time(0));
|
random.entropy(Random::Entropy::High);
|
||||||
|
|
||||||
scheduler.reset();
|
scheduler.reset();
|
||||||
cpu.power();
|
cpu.power();
|
||||||
|
|
|
@ -44,17 +44,7 @@ private:
|
||||||
friend class Cartridge;
|
friend class Cartridge;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Random {
|
|
||||||
auto seed(uint seed) -> void;
|
|
||||||
auto operator()(uint result) -> uint;
|
|
||||||
auto serialize(serializer& s) -> void;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint iter = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern System system;
|
extern System system;
|
||||||
extern Random random;
|
|
||||||
|
|
||||||
auto Region::NTSC() -> bool { return system.region() == System::Region::NTSC; }
|
auto Region::NTSC() -> bool { return system.region() == System::Region::NTSC; }
|
||||||
auto Region::PAL() -> bool { return system.region() == System::Region::PAL; }
|
auto Region::PAL() -> bool { return system.region() == System::Region::PAL; }
|
||||||
|
|
Loading…
Reference in New Issue