mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 15:15:31 +00:00
Implement TestCells (feature #5219)
This commit is contained in:
parent
31c5c6d993
commit
24ce242941
14 changed files with 247 additions and 43 deletions
|
@ -235,6 +235,7 @@
|
|||
Feature #5147: Show spell magicka cost in spell buying window
|
||||
Feature #5170: Editor: Land shape editing, land selection
|
||||
Feature #5193: Weapon sheathing
|
||||
Feature #5219: Impelement TestCells console command
|
||||
Feature #5224: Handle NiKeyframeController for NiTriShape
|
||||
Task #4686: Upgrade media decoder to a more current FFmpeg API
|
||||
Task #4695: Optimize Distant Terrain memory consumption
|
||||
|
|
|
@ -118,6 +118,9 @@ namespace MWBase
|
|||
|
||||
virtual MWWorld::CellStore *getCell (const ESM::CellId& id) = 0;
|
||||
|
||||
virtual void testExteriorCells() = 0;
|
||||
virtual void testInteriorCells() = 0;
|
||||
|
||||
virtual void useDeathCamera() = 0;
|
||||
|
||||
virtual void setWaterHeight(const float height) = 0;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <osg/TextureCubeMap>
|
||||
|
||||
#include <osgUtil/LineSegmentIntersector>
|
||||
#include <osgUtil/IncrementalCompileOperation>
|
||||
|
||||
#include <osg/ImageUtils>
|
||||
|
||||
|
@ -391,6 +390,11 @@ namespace MWRender
|
|||
mWorkQueue = nullptr;
|
||||
}
|
||||
|
||||
osgUtil::IncrementalCompileOperation* RenderingManager::getIncrementalCompileOperation()
|
||||
{
|
||||
return mViewer->getIncrementalCompileOperation();
|
||||
}
|
||||
|
||||
MWRender::Objects& RenderingManager::getObjects()
|
||||
{
|
||||
return *mObjects.get();
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include <components/settings/settings.hpp>
|
||||
|
||||
#include <osgUtil/IncrementalCompileOperation>
|
||||
|
||||
#include "objects.hpp"
|
||||
|
||||
#include "renderinginterface.hpp"
|
||||
|
@ -89,6 +91,8 @@ namespace MWRender
|
|||
const std::string& resourcePath, DetourNavigator::Navigator& navigator);
|
||||
~RenderingManager();
|
||||
|
||||
osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation();
|
||||
|
||||
MWRender::Objects& getObjects();
|
||||
|
||||
Resource::ResourceSystem* getResourceSystem();
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
#include <components/interpreter/runtime.hpp>
|
||||
#include <components/interpreter/opcodes.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/actionteleport.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
#include "../mwbase/statemanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
|
@ -34,6 +36,52 @@ namespace MWScript
|
|||
}
|
||||
};
|
||||
|
||||
class OpTestCells : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
runtime.getContext().report("Use TestCells from the main menu, when there is no active game session.");
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode();
|
||||
if (wasConsole)
|
||||
MWBase::Environment::get().getWindowManager()->toggleConsole();
|
||||
|
||||
MWBase::Environment::get().getWorld()->testExteriorCells();
|
||||
|
||||
if (wasConsole)
|
||||
MWBase::Environment::get().getWindowManager()->toggleConsole();
|
||||
}
|
||||
};
|
||||
|
||||
class OpTestInteriorCells : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
runtime.getContext().report("Use TestInteriorCells from the main menu, when there is no active game session.");
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasConsole = MWBase::Environment::get().getWindowManager()->isConsoleMode();
|
||||
if (wasConsole)
|
||||
MWBase::Environment::get().getWindowManager()->toggleConsole();
|
||||
|
||||
MWBase::Environment::get().getWorld()->testInteriorCells();
|
||||
|
||||
if (wasConsole)
|
||||
MWBase::Environment::get().getWindowManager()->toggleConsole();
|
||||
}
|
||||
};
|
||||
|
||||
class OpCOC : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
@ -204,6 +252,8 @@ namespace MWScript
|
|||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
{
|
||||
interpreter.installSegment5 (Compiler::Cell::opcodeCellChanged, new OpCellChanged);
|
||||
interpreter.installSegment5 (Compiler::Cell::opcodeTestCells, new OpTestCells);
|
||||
interpreter.installSegment5 (Compiler::Cell::opcodeTestInteriorCells, new OpTestInteriorCells);
|
||||
interpreter.installSegment5 (Compiler::Cell::opcodeCOC, new OpCOC);
|
||||
interpreter.installSegment5 (Compiler::Cell::opcodeCOE, new OpCOE);
|
||||
interpreter.installSegment5 (Compiler::Cell::opcodeGetInterior, new OpGetInterior);
|
||||
|
|
|
@ -461,5 +461,7 @@ op 0x200030a: SetNavMeshNumber
|
|||
op 0x200030b: Journal, explicit
|
||||
op 0x200030c: RepairedOnMe
|
||||
op 0x200030d: RepairedOnMe, explicit
|
||||
op 0x200030e: TestCells
|
||||
op 0x200030f: TestInteriorCells
|
||||
|
||||
opcodes 0x200030c-0x3ffffff unused
|
||||
opcodes 0x2000310-0x3ffffff unused
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/resource/bulletshape.hpp>
|
||||
#include <components/sceneutil/unrefqueue.hpp>
|
||||
#include <components/detournavigator/navigator.hpp>
|
||||
#include <components/detournavigator/debug.hpp>
|
||||
#include <components/misc/convert.hpp>
|
||||
|
@ -22,6 +23,8 @@
|
|||
#include "../mwbase/mechanicsmanager.hpp"
|
||||
#include "../mwbase/windowmanager.hpp"
|
||||
|
||||
#include "../mwmechanics/actorutil.hpp"
|
||||
|
||||
#include "../mwrender/renderingmanager.hpp"
|
||||
#include "../mwrender/landmanager.hpp"
|
||||
|
||||
|
@ -205,10 +208,11 @@ namespace
|
|||
{
|
||||
MWWorld::CellStore& mCell;
|
||||
Loading::Listener& mLoadingListener;
|
||||
bool mTest;
|
||||
|
||||
std::vector<MWWorld::Ptr> mToInsert;
|
||||
|
||||
InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener);
|
||||
InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool test);
|
||||
|
||||
bool operator() (const MWWorld::Ptr& ptr);
|
||||
|
||||
|
@ -216,8 +220,8 @@ namespace
|
|||
void insert(AddObject&& addObject);
|
||||
};
|
||||
|
||||
InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener)
|
||||
: mCell (cell), mLoadingListener (loadingListener)
|
||||
InsertVisitor::InsertVisitor (MWWorld::CellStore& cell, Loading::Listener& loadingListener, bool test)
|
||||
: mCell (cell), mLoadingListener (loadingListener), mTest(test)
|
||||
{}
|
||||
|
||||
bool InsertVisitor::operator() (const MWWorld::Ptr& ptr)
|
||||
|
@ -246,7 +250,8 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
mLoadingListener.increaseProgress (1);
|
||||
if (!mTest)
|
||||
mLoadingListener.increaseProgress (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,9 +322,10 @@ namespace MWWorld
|
|||
mPreloader->updateCache(mRendering.getReferenceTime());
|
||||
}
|
||||
|
||||
void Scene::unloadCell (CellStoreCollection::iterator iter)
|
||||
void Scene::unloadCell (CellStoreCollection::iterator iter, bool test)
|
||||
{
|
||||
Log(Debug::Info) << "Unloading cell " << (*iter)->getCell()->getDescription();
|
||||
if (!test)
|
||||
Log(Debug::Info) << "Unloading cell " << (*iter)->getCell()->getDescription();
|
||||
|
||||
const auto navigator = MWBase::Environment::get().getWorld()->getNavigator();
|
||||
ListAndResetObjectsVisitor visitor;
|
||||
|
@ -373,13 +379,16 @@ namespace MWWorld
|
|||
mActiveCells.erase(*iter);
|
||||
}
|
||||
|
||||
void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn)
|
||||
void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test)
|
||||
{
|
||||
std::pair<CellStoreCollection::iterator, bool> result = mActiveCells.insert(cell);
|
||||
|
||||
if(result.second)
|
||||
{
|
||||
Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription();
|
||||
if (test)
|
||||
Log(Debug::Info) << "Testing cell " << cell->getCell()->getDescription();
|
||||
else
|
||||
Log(Debug::Info) << "Loading cell " << cell->getCell()->getDescription();
|
||||
|
||||
float verts = ESM::Land::LAND_SIZE;
|
||||
float worldsize = ESM::Land::REAL_SIZE;
|
||||
|
@ -390,7 +399,7 @@ namespace MWWorld
|
|||
const int cellY = cell->getCell()->getGridY();
|
||||
|
||||
// Load terrain physics first...
|
||||
if (cell->getCell()->isExterior())
|
||||
if (!test && cell->getCell()->isExterior())
|
||||
{
|
||||
osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY);
|
||||
const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : 0;
|
||||
|
@ -418,38 +427,44 @@ namespace MWWorld
|
|||
cell->respawn();
|
||||
|
||||
// ... then references. This is important for adjustPosition to work correctly.
|
||||
insertCell (*cell, loadingListener);
|
||||
insertCell (*cell, loadingListener, test);
|
||||
|
||||
mRendering.addCell(cell);
|
||||
MWBase::Environment::get().getWindowManager()->addCell(cell);
|
||||
bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior();
|
||||
float waterLevel = cell->getWaterLevel();
|
||||
mRendering.setWaterEnabled(waterEnabled);
|
||||
if (waterEnabled)
|
||||
if (!test)
|
||||
{
|
||||
mPhysics->enableWater(waterLevel);
|
||||
mRendering.setWaterHeight(waterLevel);
|
||||
|
||||
if (cell->getCell()->isExterior())
|
||||
MWBase::Environment::get().getWindowManager()->addCell(cell);
|
||||
bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior();
|
||||
float waterLevel = cell->getWaterLevel();
|
||||
mRendering.setWaterEnabled(waterEnabled);
|
||||
if (waterEnabled)
|
||||
{
|
||||
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
|
||||
navigator->addWater(osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE,
|
||||
cell->getWaterLevel(), heightField->getCollisionObject()->getWorldTransform());
|
||||
mPhysics->enableWater(waterLevel);
|
||||
mRendering.setWaterHeight(waterLevel);
|
||||
|
||||
if (cell->getCell()->isExterior())
|
||||
{
|
||||
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
|
||||
navigator->addWater(osg::Vec2i(cellX, cellY), ESM::Land::REAL_SIZE,
|
||||
cell->getWaterLevel(), heightField->getCollisionObject()->getWorldTransform());
|
||||
}
|
||||
else
|
||||
{
|
||||
navigator->addWater(osg::Vec2i(cellX, cellY), std::numeric_limits<int>::max(),
|
||||
cell->getWaterLevel(), btTransform::getIdentity());
|
||||
}
|
||||
}
|
||||
else
|
||||
mPhysics->disableWater();
|
||||
|
||||
const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
navigator->update(player.getRefData().getPosition().asVec3());
|
||||
|
||||
if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))
|
||||
{
|
||||
navigator->addWater(osg::Vec2i(cellX, cellY), std::numeric_limits<int>::max(),
|
||||
cell->getWaterLevel(), btTransform::getIdentity());
|
||||
|
||||
mRendering.configureAmbient(cell->getCell());
|
||||
}
|
||||
}
|
||||
else
|
||||
mPhysics->disableWater();
|
||||
|
||||
const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
navigator->update(player.getRefData().getPosition().asVec3());
|
||||
|
||||
if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx))
|
||||
mRendering.configureAmbient(cell->getCell());
|
||||
}
|
||||
|
||||
mPreloader->notifyLoaded(cell);
|
||||
|
@ -594,6 +609,101 @@ namespace MWWorld
|
|||
mCellChanged = true;
|
||||
}
|
||||
|
||||
void Scene::testExteriorCells()
|
||||
{
|
||||
// Note: temporary disable ICO to decrease memory usage
|
||||
mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(nullptr);
|
||||
|
||||
mRendering.getResourceSystem()->setExpiryDelay(1.f);
|
||||
|
||||
const MWWorld::Store<ESM::Cell> &cells = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>();
|
||||
|
||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||
Loading::ScopedLoad load(loadingListener);
|
||||
loadingListener->setProgressRange(cells.getExtSize());
|
||||
|
||||
MWWorld::Store<ESM::Cell>::iterator it = cells.extBegin();
|
||||
int i = 1;
|
||||
for (; it != cells.extEnd(); ++it)
|
||||
{
|
||||
loadingListener->setLabel("Testing exterior cells ("+std::to_string(i)+"/"+std::to_string(cells.getExtSize())+")...");
|
||||
|
||||
CellStoreCollection::iterator iter = mActiveCells.begin();
|
||||
|
||||
CellStore *cell = MWBase::Environment::get().getWorld()->getExterior(it->mData.mX, it->mData.mY);
|
||||
loadCell (cell, loadingListener, false, true);
|
||||
|
||||
iter = mActiveCells.begin();
|
||||
while (iter != mActiveCells.end())
|
||||
{
|
||||
if (it->isExterior() && it->mData.mX == (*iter)->getCell()->getGridX() &&
|
||||
it->mData.mY == (*iter)->getCell()->getGridY())
|
||||
{
|
||||
unloadCell(iter, true);
|
||||
break;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
mRendering.getResourceSystem()->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.getUnrefQueue()->flush(mRendering.getWorkQueue());
|
||||
|
||||
loadingListener->increaseProgress (1);
|
||||
i++;
|
||||
}
|
||||
|
||||
mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(mRendering.getIncrementalCompileOperation());
|
||||
mRendering.getResourceSystem()->setExpiryDelay(Settings::Manager::getFloat("cache expiry delay", "Cells"));
|
||||
}
|
||||
|
||||
void Scene::testInteriorCells()
|
||||
{
|
||||
// Note: temporary disable ICO to decrease memory usage
|
||||
mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(nullptr);
|
||||
|
||||
mRendering.getResourceSystem()->setExpiryDelay(1.f);
|
||||
|
||||
const MWWorld::Store<ESM::Cell> &cells = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>();
|
||||
|
||||
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
|
||||
Loading::ScopedLoad load(loadingListener);
|
||||
loadingListener->setProgressRange(cells.getIntSize());
|
||||
|
||||
int i = 1;
|
||||
MWWorld::Store<ESM::Cell>::iterator it = cells.intBegin();
|
||||
for (; it != cells.intEnd(); ++it)
|
||||
{
|
||||
loadingListener->setLabel("Testing interior cells ("+std::to_string(i)+"/"+std::to_string(cells.getIntSize())+")...");
|
||||
|
||||
CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(it->mName);
|
||||
loadCell (cell, loadingListener, false, true);
|
||||
|
||||
CellStoreCollection::iterator iter = mActiveCells.begin();
|
||||
while (iter != mActiveCells.end())
|
||||
{
|
||||
assert (!(*iter)->getCell()->isExterior());
|
||||
|
||||
if (it->mName == (*iter)->getCell()->mName)
|
||||
{
|
||||
unloadCell(iter, true);
|
||||
break;
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
mRendering.getResourceSystem()->updateCache(mRendering.getReferenceTime());
|
||||
mRendering.getUnrefQueue()->flush(mRendering.getWorkQueue());
|
||||
|
||||
loadingListener->increaseProgress (1);
|
||||
i++;
|
||||
}
|
||||
|
||||
mRendering.getResourceSystem()->getSceneManager()->setIncrementalCompileOperation(mRendering.getIncrementalCompileOperation());
|
||||
mRendering.getResourceSystem()->setExpiryDelay(Settings::Manager::getFloat("cache expiry delay", "Cells"));
|
||||
}
|
||||
|
||||
void Scene::changePlayerCell(CellStore *cell, const ESM::Position &pos, bool adjustPlayerPos)
|
||||
{
|
||||
mCurrentCell = cell;
|
||||
|
@ -759,9 +869,9 @@ namespace MWWorld
|
|||
mCellChanged = false;
|
||||
}
|
||||
|
||||
void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener)
|
||||
void Scene::insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test)
|
||||
{
|
||||
InsertVisitor insertVisitor (cell, *loadingListener);
|
||||
InsertVisitor insertVisitor (cell, *loadingListener, test);
|
||||
cell.forEach (insertVisitor);
|
||||
insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mRendering); });
|
||||
insertVisitor.insert([&] (const MWWorld::Ptr& ptr) { addObject(ptr, *mPhysics, mNavigator); });
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace MWWorld
|
|||
|
||||
osg::Vec3f mLastPlayerPos;
|
||||
|
||||
void insertCell (CellStore &cell, Loading::Listener* loadingListener);
|
||||
void insertCell (CellStore &cell, Loading::Listener* loadingListener, bool test = false);
|
||||
|
||||
// Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center
|
||||
void changeCellGrid (int playerCellX, int playerCellY, bool changeEvent = true);
|
||||
|
@ -107,9 +107,9 @@ namespace MWWorld
|
|||
void preloadCell(MWWorld::CellStore* cell, bool preloadSurrounding=false);
|
||||
void preloadTerrain(const osg::Vec3f& pos);
|
||||
|
||||
void unloadCell (CellStoreCollection::iterator iter);
|
||||
void unloadCell (CellStoreCollection::iterator iter, bool test = false);
|
||||
|
||||
void loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn);
|
||||
void loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn, bool test = false);
|
||||
|
||||
void playerMoved (const osg::Vec3f& pos);
|
||||
|
||||
|
@ -151,6 +151,9 @@ namespace MWWorld
|
|||
Ptr searchPtrViaActorId (int actorId);
|
||||
|
||||
void preload(const std::string& mesh, bool useAnim=false);
|
||||
|
||||
void testExteriorCells();
|
||||
void testInteriorCells();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -792,6 +792,14 @@ namespace MWWorld
|
|||
{
|
||||
return mSharedInt.size() + mSharedExt.size();
|
||||
}
|
||||
size_t Store<ESM::Cell>::getExtSize() const
|
||||
{
|
||||
return mSharedExt.size();
|
||||
}
|
||||
size_t Store<ESM::Cell>::getIntSize() const
|
||||
{
|
||||
return mSharedInt.size();
|
||||
}
|
||||
void Store<ESM::Cell>::listIdentifier(std::vector<std::string> &list) const
|
||||
{
|
||||
list.reserve(list.size() + mSharedInt.size());
|
||||
|
|
|
@ -314,6 +314,8 @@ namespace MWWorld
|
|||
const ESM::Cell *searchExtByRegion(const std::string &id) const;
|
||||
|
||||
size_t getSize() const;
|
||||
size_t getExtSize() const;
|
||||
size_t getIntSize() const;
|
||||
|
||||
void listIdentifier(std::vector<std::string> &list) const;
|
||||
|
||||
|
|
|
@ -586,6 +586,16 @@ namespace MWWorld
|
|||
return getInterior (id.mWorldspace);
|
||||
}
|
||||
|
||||
void World::testExteriorCells()
|
||||
{
|
||||
mWorldScene->testExteriorCells();
|
||||
}
|
||||
|
||||
void World::testInteriorCells()
|
||||
{
|
||||
mWorldScene->testInteriorCells();
|
||||
}
|
||||
|
||||
void World::useDeathCamera()
|
||||
{
|
||||
if(mRendering->getCamera()->isVanityOrPreviewModeEnabled() )
|
||||
|
|
|
@ -223,6 +223,9 @@ namespace MWWorld
|
|||
|
||||
CellStore *getCell (const ESM::CellId& id) override;
|
||||
|
||||
void testExteriorCells() override;
|
||||
void testInteriorCells() override;
|
||||
|
||||
//switch to POV before showing player's death animation
|
||||
void useDeathCamera() override;
|
||||
|
||||
|
|
|
@ -89,6 +89,8 @@ namespace Compiler
|
|||
void registerExtensions (Extensions& extensions)
|
||||
{
|
||||
extensions.registerFunction ("cellchanged", 'l', "", opcodeCellChanged);
|
||||
extensions.registerInstruction("testcells", "", opcodeTestCells);
|
||||
extensions.registerInstruction("testinteriorcells", "", opcodeTestInteriorCells);
|
||||
extensions.registerInstruction ("coc", "S", opcodeCOC);
|
||||
extensions.registerInstruction ("centeroncell", "S", opcodeCOC);
|
||||
extensions.registerInstruction ("coe", "ll", opcodeCOE);
|
||||
|
|
|
@ -75,6 +75,8 @@ namespace Compiler
|
|||
namespace Cell
|
||||
{
|
||||
const int opcodeCellChanged = 0x2000000;
|
||||
const int opcodeTestCells = 0x200030e;
|
||||
const int opcodeTestInteriorCells = 0x200030f;
|
||||
const int opcodeCOC = 0x2000026;
|
||||
const int opcodeCOE = 0x2000226;
|
||||
const int opcodeGetInterior = 0x2000131;
|
||||
|
|
Loading…
Reference in a new issue