mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-18 16:32:32 +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/SCMFile.hpp>
|
||||||
#include <script/ScriptDisassembly.hpp>
|
#include <script/ScriptDisassembly.hpp>
|
||||||
#include <script/ScriptMachine.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) {
|
: codes(_codes), scm(_scm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
ScriptDisassembly(SCMOpcodes* codes, SCMFile* scm);
|
ScriptDisassembly(ScriptModule* codes, SCMFile* scm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the disassembly routine.
|
* Execute the disassembly routine.
|
||||||
@ -42,7 +42,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SCMOpcodes* codes;
|
ScriptModule* codes;
|
||||||
SCMFile* scm;
|
SCMFile* scm;
|
||||||
|
|
||||||
std::map<SCMAddress, InstructionInfo> instructions;
|
std::map<SCMAddress, InstructionInfo> instructions;
|
||||||
|
@ -6,22 +6,6 @@
|
|||||||
#include <script/ScriptMachine.hpp>
|
#include <script/ScriptMachine.hpp>
|
||||||
#include <script/ScriptModule.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) {
|
void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
|
||||||
if (t.wakeCounter > 0) {
|
if (t.wakeCounter > 0) {
|
||||||
t.wakeCounter = std::max(t.wakeCounter - msPassed, 0);
|
t.wakeCounter = std::max(t.wakeCounter - msPassed, 0);
|
||||||
@ -30,14 +14,14 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
|
|||||||
|
|
||||||
while (t.wakeCounter == 0) {
|
while (t.wakeCounter == 0) {
|
||||||
auto pc = t.programCounter;
|
auto pc = t.programCounter;
|
||||||
auto opcode = _file->read<SCMOpcode>(pc);
|
auto opcode = file->read<SCMOpcode>(pc);
|
||||||
|
|
||||||
bool isNegatedConditional = ((opcode & SCM_NEGATE_CONDITIONAL_MASK) ==
|
bool isNegatedConditional = ((opcode & SCM_NEGATE_CONDITIONAL_MASK) ==
|
||||||
SCM_NEGATE_CONDITIONAL_MASK);
|
SCM_NEGATE_CONDITIONAL_MASK);
|
||||||
opcode = opcode & ~SCM_NEGATE_CONDITIONAL_MASK;
|
opcode = opcode & ~SCM_NEGATE_CONDITIONAL_MASK;
|
||||||
|
|
||||||
ScriptFunctionMeta* foundcode;
|
ScriptFunctionMeta* foundcode;
|
||||||
if (!_ops->findOpcode(opcode, &foundcode)) {
|
if (!module->findOpcode(opcode, &foundcode)) {
|
||||||
throw IllegalInstruction(opcode, pc, t.name);
|
throw IllegalInstruction(opcode, pc, t.name);
|
||||||
}
|
}
|
||||||
ScriptFunctionMeta& code = *foundcode;
|
ScriptFunctionMeta& code = *foundcode;
|
||||||
@ -50,7 +34,7 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
|
|||||||
auto requiredParams = std::abs(code.arguments);
|
auto requiredParams = std::abs(code.arguments);
|
||||||
|
|
||||||
for (int p = 0; p < requiredParams || hasExtraParameters; ++p) {
|
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);
|
auto type = static_cast<SCMType>(type_r);
|
||||||
|
|
||||||
if (type_r > 42) {
|
if (type_r > 42) {
|
||||||
@ -66,27 +50,27 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
|
|||||||
hasExtraParameters = false;
|
hasExtraParameters = false;
|
||||||
break;
|
break;
|
||||||
case TInt8:
|
case TInt8:
|
||||||
parameters.back().integer = _file->read<std::int8_t>(pc);
|
parameters.back().integer = file->read<std::int8_t>(pc);
|
||||||
pc += sizeof(SCMByte);
|
pc += sizeof(SCMByte);
|
||||||
break;
|
break;
|
||||||
case TInt16:
|
case TInt16:
|
||||||
parameters.back().integer = _file->read<std::int16_t>(pc);
|
parameters.back().integer = file->read<std::int16_t>(pc);
|
||||||
pc += sizeof(SCMByte) * 2;
|
pc += sizeof(SCMByte) * 2;
|
||||||
break;
|
break;
|
||||||
case TGlobal: {
|
case TGlobal: {
|
||||||
auto v = _file->read<std::uint16_t>(pc);
|
auto v = file->read<std::uint16_t>(pc);
|
||||||
parameters.back().globalPtr =
|
parameters.back().globalPtr =
|
||||||
globalData.data() + v; //* SCM_VARIABLE_SIZE;
|
globalData.data() + v; //* SCM_VARIABLE_SIZE;
|
||||||
if (v >= _file->getGlobalsSize()) {
|
if (v >= file->getGlobalsSize()) {
|
||||||
state->world->logger->error(
|
state->world->logger->error(
|
||||||
"SCM", "Global Out of bounds! " +
|
"SCM", "Global Out of bounds! " +
|
||||||
std::to_string(v) + " " +
|
std::to_string(v) + " " +
|
||||||
std::to_string(_file->getGlobalsSize()));
|
std::to_string(file->getGlobalsSize()));
|
||||||
}
|
}
|
||||||
pc += sizeof(SCMByte) * 2;
|
pc += sizeof(SCMByte) * 2;
|
||||||
} break;
|
} break;
|
||||||
case TLocal: {
|
case TLocal: {
|
||||||
auto v = _file->read<std::uint16_t>(pc);
|
auto v = file->read<std::uint16_t>(pc);
|
||||||
parameters.back().globalPtr =
|
parameters.back().globalPtr =
|
||||||
t.locals.data() + v * SCM_VARIABLE_SIZE;
|
t.locals.data() + v * SCM_VARIABLE_SIZE;
|
||||||
if (v >= SCM_THREAD_LOCAL_SIZE) {
|
if (v >= SCM_THREAD_LOCAL_SIZE) {
|
||||||
@ -96,17 +80,17 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
|
|||||||
pc += sizeof(SCMByte) * 2;
|
pc += sizeof(SCMByte) * 2;
|
||||||
} break;
|
} break;
|
||||||
case TInt32:
|
case TInt32:
|
||||||
parameters.back().integer = _file->read<std::int32_t>(pc);
|
parameters.back().integer = file->read<std::int32_t>(pc);
|
||||||
pc += sizeof(SCMByte) * 4;
|
pc += sizeof(SCMByte) * 4;
|
||||||
break;
|
break;
|
||||||
case TString:
|
case TString:
|
||||||
std::copy(_file->data() + pc, _file->data() + pc + 8,
|
std::copy(file->data() + pc, file->data() + pc + 8,
|
||||||
parameters.back().string);
|
parameters.back().string);
|
||||||
pc += sizeof(SCMByte) * 8;
|
pc += sizeof(SCMByte) * 8;
|
||||||
break;
|
break;
|
||||||
case TFloat16:
|
case TFloat16:
|
||||||
parameters.back().real =
|
parameters.back().real =
|
||||||
_file->read<std::int16_t>(pc) / 16.f;
|
file->read<std::int16_t>(pc) / 16.f;
|
||||||
pc += sizeof(SCMByte) * 2;
|
pc += sizeof(SCMByte) * 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -179,21 +163,17 @@ void ScriptMachine::executeThread(SCMThread& t, int msPassed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptMachine::ScriptMachine(GameState* _state, SCMFile* file, SCMOpcodes* ops)
|
ScriptMachine::ScriptMachine(GameState* _state, SCMFile* file,
|
||||||
: _file(file), _ops(ops), state(_state) {
|
ScriptModule* ops)
|
||||||
|
: file(file), module(ops), state(_state) {
|
||||||
// Copy globals
|
// Copy globals
|
||||||
auto size = _file->getGlobalsSize();
|
auto size = file->getGlobalsSize();
|
||||||
globalData.resize(size);
|
globalData.resize(size);
|
||||||
auto offset = _file->getGlobalSection();
|
auto offset = file->getGlobalSection();
|
||||||
std::copy(_file->data() + offset, _file->data() + offset + size,
|
std::copy(file->data() + offset, file->data() + offset + size,
|
||||||
globalData.begin());
|
globalData.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptMachine::~ScriptMachine() {
|
|
||||||
delete _file;
|
|
||||||
delete _ops;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptMachine::startThread(SCMThread::pc_t start, bool mission) {
|
void ScriptMachine::startThread(SCMThread::pc_t start, bool mission) {
|
||||||
SCMThread t;
|
SCMThread t;
|
||||||
for (int i = 0; i < SCM_THREAD_LOCAL_SIZE * SCM_VARIABLE_SIZE; ++i) {
|
for (int i = 0; i < SCM_THREAD_LOCAL_SIZE * SCM_VARIABLE_SIZE; ++i) {
|
||||||
|
@ -120,15 +120,11 @@ struct SCMThread {
|
|||||||
*/
|
*/
|
||||||
class ScriptMachine {
|
class ScriptMachine {
|
||||||
public:
|
public:
|
||||||
ScriptMachine(GameState* state, SCMFile* file, SCMOpcodes* ops);
|
ScriptMachine(GameState* state, SCMFile* file, ScriptModule* ops);
|
||||||
~ScriptMachine();
|
~ScriptMachine() { }
|
||||||
|
|
||||||
SCMFile* getFile() const {
|
SCMFile* getFile() const {
|
||||||
return _file;
|
return file;
|
||||||
}
|
|
||||||
|
|
||||||
SCMOpcodes* getOpcodes() const {
|
|
||||||
return _ops;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void startThread(SCMThread::pc_t start, bool mission = false);
|
void startThread(SCMThread::pc_t start, bool mission = false);
|
||||||
@ -152,8 +148,8 @@ public:
|
|||||||
void execute(float dt);
|
void execute(float dt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SCMFile* _file;
|
SCMFile* file;
|
||||||
SCMOpcodes* _ops;
|
ScriptModule* module;
|
||||||
GameState* state;
|
GameState* state;
|
||||||
|
|
||||||
std::list<SCMThread> _activeThreads;
|
std::list<SCMThread> _activeThreads;
|
||||||
|
@ -376,12 +376,4 @@ struct SCMMicrocode {
|
|||||||
|
|
||||||
typedef std::map<SCMOpcode, SCMMicrocode> SCMMicrocodeTable;
|
typedef std::map<SCMOpcode, SCMMicrocode> SCMMicrocodeTable;
|
||||||
|
|
||||||
struct SCMOpcodes {
|
|
||||||
std::vector<ScriptModule*> modules;
|
|
||||||
|
|
||||||
~SCMOpcodes();
|
|
||||||
|
|
||||||
bool findOpcode(ScriptFunctionID id, ScriptFunctionMeta** out);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,8 +11,7 @@
|
|||||||
#include <engine/SaveGame.hpp>
|
#include <engine/SaveGame.hpp>
|
||||||
#include <objects/GameObject.hpp>
|
#include <objects/GameObject.hpp>
|
||||||
|
|
||||||
#include <script/ScriptMachine.hpp>
|
#include <script/SCMFile.hpp>
|
||||||
#include <script/modules/GTA3Module.hpp>
|
|
||||||
|
|
||||||
#include <ai/PlayerController.hpp>
|
#include <ai/PlayerController.hpp>
|
||||||
#include <data/CutsceneData.hpp>
|
#include <data/CutsceneData.hpp>
|
||||||
@ -100,9 +99,6 @@ RWGame::~RWGame() {
|
|||||||
|
|
||||||
log.info("Game", "Stopping work queue");
|
log.info("Game", "Stopping work queue");
|
||||||
work.stop();
|
work.stop();
|
||||||
|
|
||||||
log.info("Game", "Cleaning up scripts");
|
|
||||||
delete script;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RWGame::newGame() {
|
void RWGame::newGame() {
|
||||||
@ -142,16 +138,11 @@ void RWGame::loadGame(const std::string& savename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RWGame::startScript(const std::string& name) {
|
void RWGame::startScript(const std::string& name) {
|
||||||
SCMFile* f = data.loadSCM(name);
|
script.reset(data.loadSCM(name));
|
||||||
if (f) {
|
if (script) {
|
||||||
if (script) delete script;
|
vm = std::make_unique<ScriptMachine>(&state, script.get(), &opcodes);
|
||||||
|
|
||||||
SCMOpcodes* opcodes = new SCMOpcodes;
|
state.script = vm.get();
|
||||||
opcodes->modules.push_back(new GTA3Module);
|
|
||||||
|
|
||||||
script = new ScriptMachine(&state, f, opcodes);
|
|
||||||
|
|
||||||
state.script = script;
|
|
||||||
} else {
|
} else {
|
||||||
log.error("Game", "Failed to load SCM: " + name);
|
log.error("Game", "Failed to load SCM: " + name);
|
||||||
}
|
}
|
||||||
@ -520,9 +511,9 @@ void RWGame::tick(float dt) {
|
|||||||
|
|
||||||
world->dynamicsWorld->stepSimulation(dt, 2, dt);
|
world->dynamicsWorld->stepSimulation(dt, 2, dt);
|
||||||
|
|
||||||
if (script) {
|
if (vm) {
|
||||||
try {
|
try {
|
||||||
script->execute(dt);
|
vm->execute(dt);
|
||||||
} catch (SCMException& ex) {
|
} catch (SCMException& ex) {
|
||||||
std::cerr << ex.what() << std::endl;
|
std::cerr << ex.what() << std::endl;
|
||||||
log.error("Script", ex.what());
|
log.error("Script", ex.what());
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <render/DebugDraw.hpp>
|
#include <render/DebugDraw.hpp>
|
||||||
#include <render/GameRenderer.hpp>
|
#include <render/GameRenderer.hpp>
|
||||||
#include <script/ScriptMachine.hpp>
|
#include <script/ScriptMachine.hpp>
|
||||||
|
#include <script/modules/GTA3Module.hpp>
|
||||||
#include "game.hpp"
|
#include "game.hpp"
|
||||||
|
|
||||||
#include "GameBase.hpp"
|
#include "GameBase.hpp"
|
||||||
@ -22,7 +23,11 @@ class RWGame : public GameBase {
|
|||||||
GameState state;
|
GameState state;
|
||||||
|
|
||||||
std::unique_ptr<GameWorld> world;
|
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 clock;
|
||||||
std::chrono::steady_clock::time_point last_clock_time;
|
std::chrono::steady_clock::time_point last_clock_time;
|
||||||
|
|
||||||
@ -72,8 +77,8 @@ public:
|
|||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptMachine* getScript() const {
|
ScriptMachine *getScriptVM() const {
|
||||||
return script;
|
return vm.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hitWorldRay(glm::vec3& hit, glm::vec3& normal,
|
bool hitWorldRay(glm::vec3& hit, glm::vec3& normal,
|
||||||
|
@ -124,7 +124,7 @@ void IngameState::startTest() {
|
|||||||
|
|
||||||
void IngameState::startGame() {
|
void IngameState::startGame() {
|
||||||
game->startScript("data/main.scm");
|
game->startScript("data/main.scm");
|
||||||
game->getScript()->startThread(0);
|
game->getScriptVM()->startThread(0);
|
||||||
getWorld()->sound.playBackground(getWorld()->data->getDataPath() +
|
getWorld()->sound.playBackground(getWorld()->data->getDataPath() +
|
||||||
"/audio/City.wav");
|
"/audio/City.wav");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user