mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-15 15:02:34 +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:
parent
fb4d9ea8c3
commit
684e32f4a9
@ -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) {
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user