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 char CompilerContext::getGlobalType (const std::string& name) const
{ {
if (const ESM::Global *global = mEnvironment.mWorld->getStore().globals.find (name)) 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 ' '; return ' ';
} }

@ -304,6 +304,17 @@ namespace Compiler
mNextOperand = false; mNextOperand = false;
return true; 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 else
{ {
// check for custom extensions // check for custom extensions

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

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

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

@ -49,7 +49,8 @@ namespace Compiler
K_messagebox, K_messagebox,
K_set, K_to, K_set, K_to,
K_getsquareroot, K_getsquareroot,
K_menumode K_menumode,
K_random
}; };
enum special 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 42: replace stack[0] with global short stack[0]
op 43: replace stack[0] with global long stack[0] op 43: replace stack[0] with global long stack[0]
op 44: replace stack[0] with global float 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 opcodes 33554432-67108863 reserved for extensions

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

@ -1,6 +1,7 @@
#ifndef INTERPRETER_MISCOPCODES_H_INCLUDED #ifndef INTERPRETER_MISCOPCODES_H_INCLUDED
#define INTERPRETER_MISCOPCODES_H_INCLUDED #define INTERPRETER_MISCOPCODES_H_INCLUDED
#include <cstdlib>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
#include <string> #include <string>
@ -97,6 +98,26 @@ namespace Interpreter
runtime.push (runtime.getContext().menuMode()); 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 #endif

Loading…
Cancel
Save