From 3a2dccad4b046f850481155682133c4b4f29bf83 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 27 Feb 2016 13:40:53 +0100 Subject: [PATCH] Implement 'Show' script instruction --- apps/openmw/mwscript/docs/vmformat.txt | 2 + apps/openmw/mwscript/locals.cpp | 26 ++++++++++ apps/openmw/mwscript/locals.hpp | 6 +++ apps/openmw/mwscript/miscextensions.cpp | 66 +++++++++++++++++++++++++ components/compiler/extensions0.cpp | 1 + components/compiler/opcodes.hpp | 2 + 6 files changed, 103 insertions(+) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 93219c649..d3070c79b 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -449,5 +449,7 @@ op 0x2000300: EnableLevelupMenu op 0x2000301: ToggleScripts op 0x2000302: Fixme op 0x2000303: Fixme, explicit +op 0x2000304: Show +op 0x2000305: Show, explicit opcodes 0x2000304-0x3ffffff unused diff --git a/apps/openmw/mwscript/locals.cpp b/apps/openmw/mwscript/locals.cpp index ee93ea2e7..5c9ffa07a 100644 --- a/apps/openmw/mwscript/locals.cpp +++ b/apps/openmw/mwscript/locals.cpp @@ -97,6 +97,32 @@ namespace MWScript return 0; } + float Locals::getFloatVar(const std::string &script, const std::string &var) + { + ensure (script); + + const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); + int index = locals.getIndex(var); + char type = locals.getType(var); + if(index != -1) + { + switch(type) + { + case 's': + return mShorts.at (index); + + case 'l': + return mLongs.at (index); + + case 'f': + return mFloats.at(index); + default: + return 0; + } + } + return 0; + } + bool Locals::setVarByInt(const std::string& script, const std::string& var, int val) { ensure (script); diff --git a/apps/openmw/mwscript/locals.hpp b/apps/openmw/mwscript/locals.hpp index bb4df42bf..d63411a94 100644 --- a/apps/openmw/mwscript/locals.hpp +++ b/apps/openmw/mwscript/locals.hpp @@ -51,6 +51,12 @@ namespace MWScript /// \note Locals will be automatically configured first, if necessary int getIntVar (const std::string& script, const std::string& var); + /// if var does not exist, returns 0 + /// @note var needs to be in lowercase + /// + /// \note Locals will be automatically configured first, if necessary + float getFloatVar (const std::string& script, const std::string& var); + /// \note If locals have not been configured yet, no data is written. /// /// \return Locals written? diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 9e415faaa..1830be693 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -849,6 +849,70 @@ namespace MWScript } }; + template + class OpShow : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime, false); + std::string var = runtime.getStringLiteral(runtime[0].mInteger); + runtime.pop(); + + std::stringstream output; + + if (!ptr.isEmpty()) + { + const std::string& script = ptr.getClass().getScript(ptr); + if (script.empty()) + { + output << ptr.getCellRef().getRefId() << " has no script " << std::endl; + } + else + { + const Compiler::Locals& locals = + MWBase::Environment::get().getScriptManager()->getLocals(script); + char type = locals.getType(var); + switch (type) + { + case 'l': + case 's': + output << ptr.getCellRef().getRefId() << "." << var << ": " << ptr.getRefData().getLocals().getIntVar(script, var); + break; + case 'f': + output << ptr.getCellRef().getRefId() << "." << var << ": " << ptr.getRefData().getLocals().getFloatVar(script, var); + break; + default: + output << "unknown local '" << var << "' for '" << ptr.getCellRef().getRefId() << "'"; + break; + } + } + } + else + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + char type = world->getGlobalVariableType (var); + + switch (type) + { + case 's': + output << runtime.getContext().getGlobalShort (var); + break; + case 'l': + output << runtime.getContext().getGlobalLong (var); + break; + case 'f': + output << runtime.getContext().getGlobalFloat (var); + break; + default: + output << "unknown global variable"; + } + } + runtime.getContext().report(output.str()); + } + }; + template class OpShowVars : public Interpreter::Opcode0 { @@ -1266,6 +1330,8 @@ namespace MWScript interpreter.installSegment5 (Compiler::Misc::opcodeEnableTeleporting, new OpEnableTeleporting); interpreter.installSegment5 (Compiler::Misc::opcodeShowVars, new OpShowVars); interpreter.installSegment5 (Compiler::Misc::opcodeShowVarsExplicit, new OpShowVars); + interpreter.installSegment5 (Compiler::Misc::opcodeShow, new OpShow); + interpreter.installSegment5 (Compiler::Misc::opcodeShowExplicit, new OpShow); interpreter.installSegment5 (Compiler::Misc::opcodeToggleGodMode, new OpToggleGodMode); interpreter.installSegment5 (Compiler::Misc::opcodeToggleScripts, new OpToggleScripts); interpreter.installSegment5 (Compiler::Misc::opcodeDisableLevitation, new OpEnableLevitation); diff --git a/components/compiler/extensions0.cpp b/components/compiler/extensions0.cpp index 6916945f9..161d8adb4 100644 --- a/components/compiler/extensions0.cpp +++ b/components/compiler/extensions0.cpp @@ -300,6 +300,7 @@ namespace Compiler extensions.registerInstruction ("disableteleporting", "", opcodeDisableTeleporting); extensions.registerInstruction ("enableteleporting", "", opcodeEnableTeleporting); extensions.registerInstruction ("showvars", "", opcodeShowVars, opcodeShowVarsExplicit); + extensions.registerInstruction ("show", "c", opcodeShow, opcodeShowExplicit); extensions.registerInstruction ("sv", "", opcodeShowVars, opcodeShowVarsExplicit); extensions.registerInstruction("tgm", "", opcodeToggleGodMode); extensions.registerInstruction("togglegodmode", "", opcodeToggleGodMode); diff --git a/components/compiler/opcodes.hpp b/components/compiler/opcodes.hpp index feed5513e..430b88484 100644 --- a/components/compiler/opcodes.hpp +++ b/components/compiler/opcodes.hpp @@ -277,6 +277,8 @@ namespace Compiler const int opcodeEnableTeleporting = 0x2000216; const int opcodeShowVars = 0x200021d; const int opcodeShowVarsExplicit = 0x200021e; + const int opcodeShow = 0x2000304; + const int opcodeShowExplicit = 0x2000305; const int opcodeToggleGodMode = 0x200021f; const int opcodeToggleScripts = 0x2000301; const int opcodeDisableLevitation = 0x2000220;