1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-03 17:19:46 +02:00

Simplify Script system by removing SCMOpcodes

This was just a useless container for a set of modules. We only have
one module now so don't bother with it. This means we can remove some
more raw new & deletes from RWGame too.
This commit is contained in:
Daniel Evans 2016-10-20 23:10:52 +01:00
parent fb4d9ea8c3
commit 684e32f4a9
8 changed files with 43 additions and 78 deletions

View File

@ -1,8 +1,9 @@
#include <script/SCMFile.hpp>
#include <script/ScriptDisassembly.hpp>
#include <script/ScriptMachine.hpp>
#include <script/ScriptModule.hpp>
ScriptDisassembly::ScriptDisassembly(SCMOpcodes* _codes, SCMFile* _scm)
ScriptDisassembly::ScriptDisassembly(ScriptModule* _codes, SCMFile* _scm)
: codes(_codes), scm(_scm) {
}

View File

@ -27,7 +27,7 @@ public:
uint8_t flags;
};
ScriptDisassembly(SCMOpcodes* codes, SCMFile* scm);
ScriptDisassembly(ScriptModule* codes, SCMFile* scm);
/**
* Execute the disassembly routine.
@ -42,7 +42,7 @@ public:
}
private:
SCMOpcodes* codes;
ScriptModule* codes;
SCMFile* scm;
std::map<SCMAddress, InstructionInfo> instructions;

View File

@ -6,22 +6,6 @@
#include <script/ScriptMachine.hpp>
#include <script/ScriptModule.hpp>
SCMOpcodes::~SCMOpcodes() {
for (auto m : modules) {
delete m;
}
}
bool SCMOpcodes::findOpcode(ScriptFunctionID id, ScriptFunctionMeta** out) {
for (ScriptModule* module : modules) {
if (module->findOpcode(id, out)) {
return true;
}
}
return false;
}
void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
if (t.wakeCounter > 0) {
t.wakeCounter = std::max(t.wakeCounter - msPassed, 0);
@ -30,14 +14,14 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
while (t.wakeCounter == 0) {
auto pc = t.programCounter;
auto opcode = _file->read<SCMOpcode>(pc);
auto opcode = file->read<SCMOpcode>(pc);
bool isNegatedConditional = ((opcode & SCM_NEGATE_CONDITIONAL_MASK) ==
SCM_NEGATE_CONDITIONAL_MASK);
opcode = opcode & ~SCM_NEGATE_CONDITIONAL_MASK;
ScriptFunctionMeta* foundcode;
if (!_ops->findOpcode(opcode, &foundcode)) {
if (!module->findOpcode(opcode, &foundcode)) {
throw IllegalInstruction(opcode, pc, t.name);
}
ScriptFunctionMeta& code = *foundcode;
@ -50,7 +34,7 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
auto requiredParams = std::abs(code.arguments);
for (int p = 0; p < requiredParams || hasExtraParameters; ++p) {
auto type_r = _file->read<SCMByte>(pc);
auto type_r = file->read<SCMByte>(pc);
auto type = static_cast<SCMType>(type_r);
if (type_r > 42) {
@ -66,27 +50,27 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
hasExtraParameters = false;
break;
case TInt8:
parameters.back().integer = _file->read<std::int8_t>(pc);
parameters.back().integer = file->read<std::int8_t>(pc);
pc += sizeof(SCMByte);
break;
case TInt16:
parameters.back().integer = _file->read<std::int16_t>(pc);
parameters.back().integer = file->read<std::int16_t>(pc);
pc += sizeof(SCMByte) * 2;
break;
case TGlobal: {
auto v = _file->read<std::uint16_t>(pc);
auto v = file->read<std::uint16_t>(pc);
parameters.back().globalPtr =
globalData.data() + v; //* SCM_VARIABLE_SIZE;
if (v >= _file->getGlobalsSize()) {
if (v >= file->getGlobalsSize()) {
state->world->logger->error(
"SCM", "Global Out of bounds! " +
std::to_string(v) + " " +
std::to_string(_file->getGlobalsSize()));
std::to_string(file->getGlobalsSize()));
}
pc += sizeof(SCMByte) * 2;
} break;
case TLocal: {
auto v = _file->read<std::uint16_t>(pc);
auto v = file->read<std::uint16_t>(pc);
parameters.back().globalPtr =
t.locals.data() + v * SCM_VARIABLE_SIZE;
if (v >= SCM_THREAD_LOCAL_SIZE) {
@ -96,17 +80,17 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
pc += sizeof(SCMByte) * 2;
} break;
case TInt32:
parameters.back().integer = _file->read<std::int32_t>(pc);
parameters.back().integer = file->read<std::int32_t>(pc);
pc += sizeof(SCMByte) * 4;
break;
case TString:
std::copy(_file->data() + pc, _file->data() + pc + 8,
std::copy(file->data() + pc, file->data() + pc + 8,
parameters.back().string);
pc += sizeof(SCMByte) * 8;
break;
case TFloat16:
parameters.back().real =
_file->read<std::int16_t>(pc) / 16.f;
file->read<std::int16_t>(pc) / 16.f;
pc += sizeof(SCMByte) * 2;
break;
default:
@ -179,21 +163,17 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
}
}
ScriptMachine::ScriptMachine(GameState* _state, SCMFile* file, SCMOpcodes* ops)
: _file(file), _ops(ops), state(_state) {
ScriptMachine::ScriptMachine(GameState* _state, SCMFile* file,
ScriptModule* ops)
: file(file), module(ops), state(_state) {
// Copy globals
auto size = _file->getGlobalsSize();
auto size = file->getGlobalsSize();
globalData.resize(size);
auto offset = _file->getGlobalSection();
std::copy(_file->data() + offset, _file->data() + offset + size,
auto offset = file->getGlobalSection();
std::copy(file->data() + offset, file->data() + offset + size,
globalData.begin());
}
ScriptMachine::~ScriptMachine() {
delete _file;
delete _ops;
}
void ScriptMachine::startThread(SCMThread::pc_t start, bool mission) {
SCMThread t;
for (int i = 0; i < SCM_THREAD_LOCAL_SIZE * SCM_VARIABLE_SIZE; ++i) {

View File

@ -120,15 +120,11 @@ struct SCMThread {
*/
class ScriptMachine {
public:
ScriptMachine(GameState* state, SCMFile* file, SCMOpcodes* ops);
~ScriptMachine();
ScriptMachine(GameState* state, SCMFile* file, ScriptModule* ops);
~ScriptMachine() { }
SCMFile* getFile() const {
return _file;
}
SCMOpcodes* getOpcodes() const {
return _ops;
return file;
}
void startThread(SCMThread::pc_t start, bool mission = false);
@ -152,8 +148,8 @@ public:
void execute(float dt);
private:
SCMFile* _file;
SCMOpcodes* _ops;
SCMFile* file;
ScriptModule* module;
GameState* state;
std::list<SCMThread> _activeThreads;

View File

@ -376,12 +376,4 @@ struct SCMMicrocode {
typedef std::map<SCMOpcode, SCMMicrocode> SCMMicrocodeTable;
struct SCMOpcodes {
std::vector<ScriptModule*> modules;
~SCMOpcodes();
bool findOpcode(ScriptFunctionID id, ScriptFunctionMeta** out);
};
#endif

View File

@ -11,8 +11,7 @@
#include <engine/SaveGame.hpp>
#include <objects/GameObject.hpp>
#include <script/ScriptMachine.hpp>
#include <script/modules/GTA3Module.hpp>
#include <script/SCMFile.hpp>
#include <ai/PlayerController.hpp>
#include <data/CutsceneData.hpp>
@ -100,9 +99,6 @@ RWGame::~RWGame() {
log.info("Game", "Stopping work queue");
work.stop();
log.info("Game", "Cleaning up scripts");
delete script;
}
void RWGame::newGame() {
@ -142,16 +138,11 @@ void RWGame::loadGame(const std::string& savename) {
}
void RWGame::startScript(const std::string& name) {
SCMFile* f = data.loadSCM(name);
if (f) {
if (script) delete script;
script.reset(data.loadSCM(name));
if (script) {
vm = std::make_unique<ScriptMachine>(&state, script.get(), &opcodes);
SCMOpcodes* opcodes = new SCMOpcodes;
opcodes->modules.push_back(new GTA3Module);
script = new ScriptMachine(&state, f, opcodes);
state.script = script;
state.script = vm.get();
} else {
log.error("Game", "Failed to load SCM: " + name);
}
@ -520,9 +511,9 @@ void RWGame::tick(float dt) {
world->dynamicsWorld->stepSimulation(dt, 2, dt);
if (script) {
if (vm) {
try {
script->execute(dt);
vm->execute(dt);
} catch (SCMException& ex) {
std::cerr << ex.what() << std::endl;
log.error("Script", ex.what());

View File

@ -8,6 +8,7 @@
#include <render/DebugDraw.hpp>
#include <render/GameRenderer.hpp>
#include <script/ScriptMachine.hpp>
#include <script/modules/GTA3Module.hpp>
#include "game.hpp"
#include "GameBase.hpp"
@ -22,7 +23,11 @@ class RWGame : public GameBase {
GameState state;
std::unique_ptr<GameWorld> world;
ScriptMachine* script = nullptr;
GTA3Module opcodes;
std::unique_ptr<ScriptMachine> vm;
std::unique_ptr<SCMFile> script;
std::chrono::steady_clock clock;
std::chrono::steady_clock::time_point last_clock_time;
@ -72,8 +77,8 @@ public:
return renderer;
}
ScriptMachine* getScript() const {
return script;
ScriptMachine *getScriptVM() const {
return vm.get();
}
bool hitWorldRay(glm::vec3& hit, glm::vec3& normal,

View File

@ -124,7 +124,7 @@ void IngameState::startTest() {
void IngameState::startGame() {
game->startScript("data/main.scm");
game->getScript()->startThread(0);
game->getScriptVM()->startThread(0);
getWorld()->sound.playBackground(getWorld()->data->getDataPath() +
"/audio/City.wav");
}