added random function; global variable fix

actorid
Marc Zinnschlag 15 years ago
parent df8f8a315c
commit 185f8bd56d

@ -18,7 +18,16 @@ namespace MWScript
char CompilerContext::getGlobalType (const std::string& name) const
{
if (const ESM::Global *global = mEnvironment.mWorld->getStore().globals.find (name))
return global->type;
{
switch (global->type)
{
case ESM::VT_Short: return 's';
case ESM::VT_Int: return 'l';
case ESM::VT_Float: return 'f';
default: return ' ';
}
}
return ' ';
}

@ -304,6 +304,17 @@ namespace Compiler
mNextOperand = false;
return true;
}
else if (keyword==Scanner::K_random)
{
mTokenLoc = loc;
parseArguments ("l", scanner);
Generator::random (mCode);
mOperands.push_back ('l');
mNextOperand = false;
return true;
}
else
{
// check for custom extensions

@ -254,6 +254,11 @@ namespace
{
code.push_back (Compiler::Generator::segment5 (44));
}
void opRandom (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (45));
}
}
namespace Compiler
@ -625,6 +630,11 @@ namespace Compiler
assert (0);
}
}
void random (CodeContainer& code)
{
opRandom (code);
}
}
}

@ -98,6 +98,8 @@ namespace Compiler
void fetchGlobal (CodeContainer& code, Literals& literals, char localType,
const std::string& name);
void random (CodeContainer& code);
}
}

@ -243,6 +243,7 @@ namespace Compiler
"set", "to",
"getsquareroot",
"menumode",
"random",
0
};

@ -49,7 +49,8 @@ namespace Compiler
K_messagebox,
K_set, K_to,
K_getsquareroot,
K_menumode
K_menumode,
K_random
};
enum special

@ -103,6 +103,7 @@ op 41: store stack[0] in global float stack[1] and pop twice
op 42: replace stack[0] with global short stack[0]
op 43: replace stack[0] with global long stack[0]
op 44: replace stack[0] with global float stack[0]
opcodes 45-33554431 unused
op 45: replace stack[0] with a random integer value in the range [0, stack[0]-1]
opcodes 46-33554431 unused
opcodes 33554432-67108863 reserved for extensions

@ -85,6 +85,7 @@ namespace Interpreter
// misc
interpreter.installSegment3 (0, new OpMessageBox);
interpreter.installSegment5 (38, new OpMenuMode);
interpreter.installSegment5 (45, new OpRandom);
}
}

@ -1,6 +1,7 @@
#ifndef INTERPRETER_MISCOPCODES_H_INCLUDED
#define INTERPRETER_MISCOPCODES_H_INCLUDED
#include <cstdlib>
#include <stdexcept>
#include <vector>
#include <string>
@ -97,6 +98,26 @@ namespace Interpreter
runtime.push (runtime.getContext().menuMode());
}
};
class OpRandom : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
double r = static_cast<double> (std::rand()) / RAND_MAX; // [0, 1)
Type_Integer limit = *reinterpret_cast<Type_Integer *> (&runtime[0]);
if (limit<0)
throw std::runtime_error (
"random: argument out of range (Don't be so negative!)");
Type_Integer value = static_cast<Type_Integer> (r*limit); // [o, limit)
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
}
};
}
#endif

Loading…
Cancel
Save