[Scummvm-git-logs] scummvm master -> 1c394fb7fc49c9a894fb0091bcf1fb29573800b9
sev-
sev at scummvm.org
Sat Jul 11 21:22:54 UTC 2020
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
1c394fb7fc DIRECTOR: Implement Director-specific PRNG and hook it to Lingo
Commit: 1c394fb7fc49c9a894fb0091bcf1fb29573800b9
https://github.com/scummvm/scummvm/commit/1c394fb7fc49c9a894fb0091bcf1fb29573800b9
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2020-07-11T23:22:12+02:00
Commit Message:
DIRECTOR: Implement Director-specific PRNG and hook it to Lingo
Changed paths:
engines/director/director.cpp
engines/director/director.h
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-the.cpp
engines/director/util.cpp
engines/director/util.h
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 6a2f51ea1c..58340a5eb9 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -45,8 +45,7 @@ uint32 wmMode = 0;
DirectorEngine *g_director;
-DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc),
- _rnd("director") {
+DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
DebugMan.addDebugChannel(kDebugLingoExec, "lingoexec", "Lingo Execution");
DebugMan.addDebugChannel(kDebugCompile, "compile", "Lingo Compilation");
DebugMan.addDebugChannel(kDebugParse, "parse", "Lingo code parsing");
diff --git a/engines/director/director.h b/engines/director/director.h
index e0d4035838..244179d613 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -23,7 +23,6 @@
#ifndef DIRECTOR_DIRECTOR_H
#define DIRECTOR_DIRECTOR_H
-#include "common/random.h"
#include "common/rect.h"
#include "common/str-array.h"
@@ -31,6 +30,7 @@
#include "engines/engine.h"
#include "director/types.h"
+#include "director/util.h"
namespace Common {
class MacResManager;
@@ -191,7 +191,7 @@ public:
void waitForClick();
public:
- Common::RandomSource _rnd;
+ RandomState _rnd;
Graphics::ManagedSurface *_surface;
Graphics::MacWindowManager *_wm;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index fd9930ee1a..5118b0350d 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -396,7 +396,7 @@ void LB::b_power(int nargs) {
void LB::b_random(int nargs) {
Datum max = g_lingo->pop();
- Datum res((int)(g_lingo->_vm->_rnd.getRandomNumber(max.asInt() - 1) + 1));
+ Datum res((int)(g_director->_rnd.getRandom(max.asInt()) + 1));
g_lingo->push(res);
}
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 0663dba1ac..274f79899b 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -656,7 +656,8 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
d.u.i = 1;
break;
case kTheRandomSeed:
- getTheEntitySTUB(kTheRandomSeed);
+ d.type = INT;
+ d.u.i = g_director->_rnd.getSeed();
break;
case kTheResult:
getTheEntitySTUB(kTheResult);
@@ -904,7 +905,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
setTheEntitySTUB(kThePreLoadRAM);
break;
case kTheRandomSeed:
- setTheEntitySTUB(kTheRandomSeed);
+ g_director->_rnd.setSeed(d.asInt());
break;
case kTheRomanLingo:
setTheEntitySTUB(kTheRomanLingo);
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index adda30cd47..84b28d79ca 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -537,5 +537,61 @@ Common::String dumpScriptName(const char *prefix, int type, int id, const char *
return Common::String::format("./dumps/%s-%s-%d.%s", prefix, typeName.c_str(), id, ext);
}
+void RandomState::setSeed(int seed) {
+ init(32);
+
+ _seed = seed ? seed : 1;
+}
+
+int32 RandomState::getRandom(int32 range) {
+ int32 res;
+
+ if (_seed == 0)
+ init(32);
+
+ res = perlin(genNextRandom() * 71);
+
+ if (range > 0)
+ res = ((res & 0x7fffffff) % range);
+
+ return res;
+}
+
+static const uint32 masks[31] = {
+ 0x00000003, 0x00000006, 0x0000000c, 0x00000014, 0x00000030, 0x00000060, 0x000000b8, 0x00000110,
+ 0x00000240, 0x00000500, 0x00000ca0, 0x00001b00, 0x00003500, 0x00006000, 0x0000b400, 0x00012000,
+ 0x00020400, 0x00072000, 0x00090000, 0x00140000, 0x00300000, 0x00400000, 0x00d80000, 0x01200000,
+ 0x03880000, 0x07200000, 0x09000000, 0x14000000, 0x32800000, 0x48000000, 0xa3000000
+};
+
+void RandomState::init(int len) {
+ if (len < 2 || len > 32)
+ len = 32;
+
+ _seed = 1;
+ _len = (1 << len) - 1;
+ _mask = masks[len - 2];
+}
+
+int32 RandomState::genNextRandom() {
+ if (_seed & 1)
+ _seed = (_seed >> 1) ^ _mask;
+ else
+ _seed >>= 1;
+
+ return _seed;
+}
+
+int32 RandomState::perlin(int32 val) {
+ int32 res;
+
+ val = ((val << 13) ^ val) - (val >> 21);
+
+ res = (val * (val * val * 15731 + 789221) + 1376312589) & 0x7fffffff;
+ res += val;
+ res = ((res << 13) ^ res) - (res >> 21);
+
+ return res;
+}
} // End of namespace Director
diff --git a/engines/director/util.h b/engines/director/util.h
index 9baacd3c15..038533d17c 100644
--- a/engines/director/util.h
+++ b/engines/director/util.h
@@ -48,6 +48,26 @@ Common::String dumpScriptName(const char *prefix, int type, int id, const char *
bool processQuitEvent(bool click = false); // events.cpp
+class RandomState {
+public:
+ uint32 _seed;
+ uint32 _mask;
+ uint32 _len;
+
+ RandomState() {
+ _seed = _mask = _len = 0;
+ }
+
+ void setSeed(int seed);
+ uint32 getSeed() { return _seed; }
+ int32 getRandom(int32 range);
+
+private:
+ void init(int len);
+ int32 genNextRandom();
+ int32 perlin(int32 val);
+};
+
} // End of namespace Director
#endif
More information about the Scummvm-git-logs
mailing list