Merge branch 'development' of https://github.com/GarageGames/Torque3D into PBR_ProbeArrayGLWIP

# Conflicts:
#	Engine/source/gfx/D3D11/gfxD3D11Device.cpp
#	Engine/source/lighting/lightManager.cpp
#	Templates/Full/game/levels/Empty Room.mis
#	Templates/Full/game/levels/Empty Terrain.mis
This commit is contained in:
AzaezelX 2019-05-01 23:18:31 -05:00
commit dd1470202d
218 changed files with 7060 additions and 2938 deletions

236
Engine/source/T3D/Scene.cpp Normal file
View file

@ -0,0 +1,236 @@
#include "Scene.h"
Scene * Scene::smRootScene = nullptr;
Vector<Scene*> Scene::smSceneList;
IMPLEMENT_CO_NETOBJECT_V1(Scene);
Scene::Scene() :
mIsSubScene(false),
mParentScene(nullptr),
mSceneId(-1),
mIsEditing(false),
mIsDirty(false)
{
}
Scene::~Scene()
{
}
void Scene::initPersistFields()
{
Parent::initPersistFields();
addGroup("Internal");
addField("isSubscene", TypeBool, Offset(mIsSubScene, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
addField("isEditing", TypeBool, Offset(mIsEditing, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
addField("isDirty", TypeBool, Offset(mIsDirty, Scene), "", AbstractClassRep::FIELD_HideInInspectors);
endGroup("Internal");
}
bool Scene::onAdd()
{
if (!Parent::onAdd())
return false;
smSceneList.push_back(this);
mSceneId = smSceneList.size() - 1;
/*if (smRootScene == nullptr)
{
//we're the first scene, so we're the root. woo!
smRootScene = this;
}
else
{
mIsSubScene = true;
smRootScene->mSubScenes.push_back(this);
}*/
return true;
}
void Scene::onRemove()
{
Parent::onRemove();
smSceneList.remove(this);
mSceneId = -1;
/*if (smRootScene == this)
{
for (U32 i = 0; i < mSubScenes.size(); i++)
{
mSubScenes[i]->deleteObject();
}
}
else if (smRootScene != nullptr)
{
for (U32 i = 0; i < mSubScenes.size(); i++)
{
if(mSubScenes[i]->getId() == getId())
smRootScene->mSubScenes.erase(i);
}
}*/
}
void Scene::addObject(SimObject* object)
{
//Child scene
Scene* scene = dynamic_cast<Scene*>(object);
if (scene)
{
//We'll keep these principly separate so they don't get saved into each other
mSubScenes.push_back(scene);
return;
}
SceneObject* sceneObj = dynamic_cast<SceneObject*>(object);
if (sceneObj)
{
//We'll operate on the presumption that if it's being added via regular parantage means, it's considered permanent
mPermanentObjects.push_back(sceneObj);
Parent::addObject(object);
return;
}
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
Parent::addObject(object);
}
void Scene::removeObject(SimObject* object)
{
//Child scene
Scene* scene = dynamic_cast<Scene*>(object);
if (scene)
{
//We'll keep these principly separate so they don't get saved into each other
mSubScenes.remove(scene);
return;
}
SceneObject* sceneObj = dynamic_cast<SceneObject*>(object);
if (sceneObj)
{
//We'll operate on the presumption that if it's being added via regular parantage means, it's considered permanent
mPermanentObjects.remove(sceneObj);
Parent::removeObject(object);
return;
}
Parent::removeObject(object);
}
void Scene::addDynamicObject(SceneObject* object)
{
mDynamicObjects.push_back(object);
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
Parent::addObject(object);
}
void Scene::removeDynamicObject(SceneObject* object)
{
mDynamicObjects.remove(object);
//Do it like regular, though we should probably bail if we're trying to add non-scene objects to the scene?
Parent::removeObject(object);
}
void Scene::interpolateTick(F32 delta)
{
}
void Scene::processTick()
{
}
void Scene::advanceTime(F32 timeDelta)
{
}
U32 Scene::packUpdate(NetConnection *conn, U32 mask, BitStream *stream)
{
bool ret = Parent::packUpdate(conn, mask, stream);
return ret;
}
void Scene::unpackUpdate(NetConnection *conn, BitStream *stream)
{
}
//
Vector<SceneObject*> Scene::getObjectsByClass(String className)
{
return Vector<SceneObject*>();
}
DefineEngineFunction(getScene, Scene*, (U32 sceneId), (0),
"Get the root Scene object that is loaded.\n"
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
{
if (Scene::smSceneList.empty() || sceneId >= Scene::smSceneList.size())
return nullptr;
return Scene::smSceneList[sceneId];
}
DefineEngineFunction(getRootScene, S32, (), ,
"Get the root Scene object that is loaded.\n"
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
{
Scene* root = Scene::getRootScene();
if (root)
return root->getId();
return 0;
}
DefineEngineMethod(Scene, getRootScene, S32, (),,
"Get the root Scene object that is loaded.\n"
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
{
Scene* root = Scene::getRootScene();
if (root)
return root->getId();
return 0;
}
DefineEngineMethod(Scene, addDynamicObject, void, (SceneObject* sceneObj), (nullAsType<SceneObject*>()),
"Get the root Scene object that is loaded.\n"
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
{
object->addDynamicObject(sceneObj);
}
DefineEngineMethod(Scene, removeDynamicObject, void, (SceneObject* sceneObj), (nullAsType<SceneObject*>()),
"Get the root Scene object that is loaded.\n"
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
{
object->removeDynamicObject(sceneObj);
}
DefineEngineMethod(Scene, getObjectsByClass, String, (String className), (""),
"Get the root Scene object that is loaded.\n"
"@return The id of the Root Scene. Will be 0 if no root scene is loaded")
{
if (className == String::EmptyString)
return "";
//return object->getObjectsByClass(className);
return "";
}

79
Engine/source/T3D/Scene.h Normal file
View file

@ -0,0 +1,79 @@
#pragma once
#include "console/engineAPI.h"
#ifndef _NETOBJECT_H_
#include "sim/netObject.h"
#endif
#ifndef _ITICKABLE_H_
#include "core/iTickable.h"
#endif
#include "scene/sceneObject.h"
/// Scene
/// This object is effectively a smart container to hold and manage any relevent scene objects and data
/// used to run things.
class Scene : public NetObject, public virtual ITickable
{
typedef NetObject Parent;
bool mIsSubScene;
Scene* mParentScene;
Vector<Scene*> mSubScenes;
Vector<SceneObject*> mPermanentObjects;
Vector<SceneObject*> mDynamicObjects;
S32 mSceneId;
bool mIsEditing;
bool mIsDirty;
protected:
static Scene * smRootScene;
DECLARE_CONOBJECT(Scene);
public:
Scene();
~Scene();
static void initPersistFields();
virtual bool onAdd();
virtual void onRemove();
virtual void interpolateTick(F32 delta);
virtual void processTick();
virtual void advanceTime(F32 timeDelta);
virtual void addObject(SimObject* object);
virtual void removeObject(SimObject* object);
void addDynamicObject(SceneObject* object);
void removeDynamicObject(SceneObject* object);
//
//Networking
U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
void unpackUpdate(NetConnection *conn, BitStream *stream);
//
Vector<SceneObject*> getObjectsByClass(String className);
static Scene *getRootScene()
{
if (Scene::smSceneList.empty())
return nullptr;
return Scene::smSceneList[0];
}
static Vector<Scene*> smSceneList;
};

View file

@ -621,8 +621,6 @@ void AnimationComponent::advanceThreads(F32 dt)
Thread& st = mAnimationThreads[i];
if (st.thread && st.sequence != -1)
{
bool cyclic = getShape()->sequences[st.sequence].isCyclic();
if (!getShape()->sequences[st.sequence].isCyclic() &&
!st.atEnd &&
((st.timescale > 0.f) ? mOwnerShapeInstance->getPos(st.thread) >= 1.0 : mOwnerShapeInstance->getPos(st.thread) <= 0))

View file

@ -237,8 +237,6 @@ bool CameraComponent::getCameraTransform(F32* pos,MatrixF* mat)
{
// Returns camera to world space transform
// Handles first person / third person camera position
bool isServer = isServerObject();
if (mTargetNodeIdx == -1)
{
if (mUseParentTransform)
@ -479,7 +477,6 @@ void CameraComponent::setRotation(RotationF newRot)
Frustum CameraComponent::getFrustum()
{
Frustum visFrustum;
F32 left, right, top, bottom;
F32 aspectRatio = mClientScreen.x / mClientScreen.y;
visFrustum.set(false, mDegToRad(mCameraFov), aspectRatio, 0.1f, 1000, mOwner->getTransform());

View file

@ -538,7 +538,6 @@ PhysicsCollision* CollisionComponent::buildColShapes()
for (S32 o = start; o < end; o++)
{
const TSShape::Object &object = shape->objects[o];
const String &meshName = shape->names[object.nameIndex];
if (object.numMeshes <= detail.objectDetailNum)
continue;

View file

@ -152,7 +152,6 @@ void StateMachine::readConditions(StateTransition &currentTransition)
//get our first state
StateTransition::Condition firstCondition;
StateField firstField;
bool fieldRead = false;
readFieldName(&firstField, reader);
firstCondition.field = firstField;

View file

@ -239,8 +239,6 @@ bool TriggerComponent::testObject(SceneObject* enter)
myList.setObject(mOwner);
myCI->buildPolyList(PLC_Collision, &myList, enterBox, sphere);
bool test = true;
}
}
}

View file

@ -330,9 +330,6 @@ void PlayerControllerComponent::updateMove()
}
// Update current orientation
bool doStandardMove = true;
GameConnection* con = mOwner->getControllingClient();
MatrixF zRot;
zRot.set(EulerF(0.0f, 0.0f, mOwner->getRotation().asEulerF().z));
@ -355,7 +352,6 @@ void PlayerControllerComponent::updateMove()
mContactInfo.jump = false;
mContactInfo.run = false;
bool jumpSurface = false, runSurface = false;
if (!mOwner->isMounted())
findContact(&mContactInfo.run, &mContactInfo.jump, &mContactInfo.contactNormal);
if (mContactInfo.jump)
@ -577,7 +573,6 @@ void PlayerControllerComponent::updatePos(const F32 travelTime)
newPos = mPhysicsRep->move(mVelocity * travelTime, collisionList);
bool haveCollisions = false;
bool wasFalling = mFalling;
if (collisionList.getCount() > 0)
{
mFalling = false;

View file

@ -719,8 +719,6 @@ bool ConvexShape::buildExportPolyList(ColladaUtils::ExportData* exportData, cons
//Convex shapes only have the one 'level', so we'll just rely on the export post-process to back-fill
if (isServerObject() && getClientObject())
{
ConvexShape* clientShape = dynamic_cast<ConvexShape*>(getClientObject());
exportData->meshData.increment();
//Prep a meshData for this shape in particular

View file

@ -306,8 +306,6 @@ void Entity::onPostAdd()
bool Entity::_setGameObject(void *object, const char *index, const char *data)
{
Entity *e = static_cast<Entity*>(object);
// Sanity!
AssertFatal(data != NULL, "Cannot use a NULL asset Id.");
@ -513,8 +511,6 @@ U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
for (U32 i = 0; i < mNetworkedComponents.size(); i++)
{
NetworkedComponent::UpdateState state = mNetworkedComponents[i].updateState;
if (mNetworkedComponents[i].updateState == NetworkedComponent::Adding)
{
const char* className = mComponents[mNetworkedComponents[i].componentIndex]->getClassName();
@ -1381,7 +1377,6 @@ bool Entity::removeComponent(Component *comp, bool deleteComponent)
//to re-add them. Need to implement a clean clear function that will clear the local list, and only delete unused behaviors during an update.
void Entity::clearComponents(bool deleteComponents)
{
bool srv = isServerObject();
if (!deleteComponents)
{
while (mComponents.size() > 0)
@ -1399,8 +1394,6 @@ void Entity::clearComponents(bool deleteComponents)
{
comp->onComponentRemove(); //in case the behavior needs to do cleanup on the owner
bool removed = mComponents.remove(comp);
//we only need to delete them on the server side. they'll be cleaned up on the client side
//via the ghosting system for us
if (isServerObject())
@ -1663,7 +1656,6 @@ void Entity::notifyComponents(String signalFunction, String argA, String argB, S
void Entity::setComponentsDirty()
{
bool tmp = true;
/*if (mToLoadComponents.empty())
mStartComponentUpdate = true;
@ -1694,7 +1686,6 @@ void Entity::setComponentsDirty()
void Entity::setComponentDirty(Component *comp, bool forceUpdate)
{
bool found = false;
for (U32 i = 0; i < mComponents.size(); i++)
{
if (mComponents[i]->getId() == comp->getId())

View file

@ -309,7 +309,6 @@ Vector<T*> Entity::getComponents()
Vector<T*> foundObjects;
T *curObj;
Component* comp;
// Loop through our child objects.
for (U32 i = 0; i < mComponents.size(); i++)

View file

@ -490,7 +490,7 @@ void ParticleEmitterData::unpackData(BitStream* stream)
#if defined(AFX_CAP_PARTICLE_POOLS)
if (stream->readFlag())
{
pool_datablock = (afxParticlePoolData*)stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
pool_datablock = (afxParticlePoolData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
stream->read(&pool_index);
pool_depth_fade = stream->readFlag();
pool_radial_fade = stream->readFlag();

View file

@ -553,7 +553,6 @@ void renderFrame(GFXTextureTargetRef* target, MatrixF transform, Frustum frustum
GFX->setStateBlock(mDefaultGuiSB);
GFXTargetRef origTarget = GFX->getActiveRenderTarget();
U32 origStyle = GFX->getCurrentRenderStyle();
// Clear the zBuffer so GUI doesn't hose object rendering accidentally
GFX->clear(GFXClearZBuffer, ColorI(20, 20, 20), 1.0f, 0);

View file

@ -6150,8 +6150,22 @@ void Player::updateWorkingCollisionSet()
mWorkingQueryBox.maxExtents += twolPoint;
disableCollision();
//We temporarily disable the collisions of anything mounted to us so we don't accidentally walk into things we've attached to us
for (SceneObject *ptr = mMount.list; ptr; ptr = ptr->getMountLink())
{
ptr->disableCollision();
}
mConvex.updateWorkingList(mWorkingQueryBox,
isGhost() ? sClientCollisionContactMask : sServerCollisionContactMask);
//And now re-enable the collisions of the mounted things
for (SceneObject *ptr = mMount.list; ptr; ptr = ptr->getMountLink())
{
ptr->enableCollision();
}
enableCollision();
}
}
@ -6345,6 +6359,14 @@ U32 Player::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
if(len > 8191)
len = 8191;
stream->writeInt((S32)len, 13);
// constrain the range of mRot.z
while (mRot.z < 0.0f)
mRot.z += M_2PI_F;
while (mRot.z > M_2PI_F)
mRot.z -= M_2PI_F;
}
stream->writeFloat(mRot.z / M_2PI_F, 7);
stream->writeSignedFloat(mHead.x / (mDataBlock->maxLookAngle - mDataBlock->minLookAngle), 6);

View file

@ -34,6 +34,8 @@
#include "T3D/physics/physicsShape.h"
#include "core/util/path.h"
#include "T3D/Scene.h"
// We use this locally ( within this file ) to prevent infinite recursion
// while loading prefab files that contain other prefabs.
static Vector<String> sPrefabFileStack;
@ -269,11 +271,11 @@ void Prefab::setFile( String file )
SimGroup* Prefab::explode()
{
SimGroup *missionGroup;
Scene* scene = Scene::getRootScene();
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
if ( !scene)
{
Con::errorf( "Prefab::explode, MissionGroup was not found." );
Con::errorf( "Prefab::explode, Scene was not found." );
return NULL;
}
@ -295,7 +297,7 @@ SimGroup* Prefab::explode()
smChildToPrefabMap.erase( child->getId() );
}
missionGroup->addObject(group);
scene->addObject(group);
mChildGroup = NULL;
mChildMap.clear();
@ -468,10 +470,10 @@ Prefab* Prefab::getPrefabByChild( SimObject *child )
bool Prefab::isValidChild( SimObject *simobj, bool logWarnings )
{
if ( simobj->getName() && dStricmp(simobj->getName(),"MissionGroup") == 0 )
if ( simobj->getName() && simobj == Scene::getRootScene() )
{
if ( logWarnings )
Con::warnf( "MissionGroup is not valid within a Prefab." );
Con::warnf( "root Scene is not valid within a Prefab." );
return false;
}

View file

@ -93,7 +93,7 @@ public:
void setFile( String file );
/// Removes all children from this Prefab and puts them into a SimGroup
/// which is added to the MissionGroup and returned to the caller.
/// which is added to the Scene and returned to the caller.
SimGroup* explode();
bool buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF& sphere);

View file

@ -72,8 +72,7 @@ class ProximityMine: public Item
protected:
enum MaskBits {
DeployedMask = Parent::NextFreeMask,
ExplosionMask = Parent::NextFreeMask << 1,
NextFreeMask = Parent::NextFreeMask << 2
ExplosionMask = Parent::NextFreeMask << 1
};
enum State

View file

@ -3266,7 +3266,7 @@ void ShapeBase::unpackUpdate(NetConnection *con, BitStream *stream)
st.play = stream->readFlag();
if ( st.play )
{
st.profile = (SFXTrack*) stream->readRangedU32( DataBlockObjectIdFirst,
st.profile = (SFXTrack*)(uintptr_t)stream->readRangedU32( DataBlockObjectIdFirst,
DataBlockObjectIdLast );
}

View file

@ -189,7 +189,7 @@ ShapeBaseImageData::ShapeBaseImageData()
lightRadius = 10.f;
lightBrightness = 1.0f;
shapeName = "core/art/shapes/noshape.dts";
shapeName = "core/shapes/noshape.dts";
shapeNameFP = "";
imageAnimPrefix = "";
imageAnimPrefixFP = "";
@ -1202,7 +1202,7 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
}
projectile = (stream->readFlag() ?
(ProjectileData*)stream->readRangedU32(DataBlockObjectIdFirst,
(ProjectileData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast) : 0);
cloakable = stream->readFlag();
@ -1340,7 +1340,7 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
if (stream->readFlag())
{
s.emitter = (ParticleEmitterData*) stream->readRangedU32(DataBlockObjectIdFirst,
s.emitter = (ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast);
stream->read(&s.emitterTime);

View file

@ -21,11 +21,9 @@ void MeshRenderSystem::render(SceneManager *sceneManager, SceneRenderState* stat
for (U32 i = 0; i < count; i++)
{
//Server side items exist for data, but we don't actually render them
bool isClient = MeshRenderSystemInterface::all[i]->mIsClient;
if (!MeshRenderSystemInterface::all[i]->mIsClient)
continue;
bool isStatic = MeshRenderSystemInterface::all[i]->mStatic;
if (MeshRenderSystemInterface::all[i]->mStatic)
continue;

View file

@ -1135,7 +1135,6 @@ bool TSStatic::buildExportPolyList(ColladaUtils::ExportData* exportData, const B
if (isServerObject() && getClientObject())
{
TSStatic* clientShape = dynamic_cast<TSStatic*>(getClientObject());
U32 numDetails = clientShape->mShapeInstance->getNumDetails() - 1;
exportData->meshData.increment();

View file

@ -282,14 +282,14 @@ void FlyingVehicleData::unpackData(BitStream* stream)
for (S32 i = 0; i < MaxSounds; i++) {
sound[i] = NULL;
if (stream->readFlag())
sound[i] = (SFXProfile*)stream->readRangedU32(DataBlockObjectIdFirst,
sound[i] = (SFXProfile*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast);
}
for (S32 j = 0; j < MaxJetEmitters; j++) {
jetEmitter[j] = NULL;
if (stream->readFlag())
jetEmitter[j] = (ParticleEmitterData*)stream->readRangedU32(DataBlockObjectIdFirst,
jetEmitter[j] = (ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast);
}

View file

@ -411,13 +411,13 @@ void HoverVehicleData::unpackData(BitStream* stream)
for (S32 i = 0; i < MaxSounds; i++)
sound[i] = stream->readFlag()?
(SFXProfile*) stream->readRangedU32(DataBlockObjectIdFirst,
(SFXProfile*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast): 0;
for (S32 j = 0; j < MaxJetEmitters; j++) {
jetEmitter[j] = NULL;
if (stream->readFlag())
jetEmitter[j] = (ParticleEmitterData*)stream->readRangedU32(DataBlockObjectIdFirst,
jetEmitter[j] = (ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast);
}

View file

@ -374,7 +374,7 @@ void VehicleData::unpackData(BitStream* stream)
for (i = 0; i < Body::MaxSounds; i++) {
body.sound[i] = NULL;
if (stream->readFlag())
body.sound[i] = (SFXProfile*)stream->readRangedU32(DataBlockObjectIdFirst,
body.sound[i] = (SFXProfile*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast);
}

View file

@ -494,7 +494,7 @@ void WheeledVehicleData::unpackData(BitStream* stream)
Parent::unpackData(stream);
tireEmitter = stream->readFlag()?
(ParticleEmitterData*) stream->readRangedU32(DataBlockObjectIdFirst,
(ParticleEmitterData*)(uintptr_t)stream->readRangedU32(DataBlockObjectIdFirst,
DataBlockObjectIdLast): 0;
for (S32 i = 0; i < MaxSounds; i++)

View file

@ -133,7 +133,7 @@ void afxEffectGroupData::unpack_fx(BitStream* stream, afxEffectList& fx)
fx.clear();
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
for (int i = 0; i < n_fx; i++)
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
}
#define myOffset(field) Offset(field, afxEffectGroupData)

View file

@ -608,7 +608,7 @@ void afxEffectWrapperData::unpack_mods(BitStream* stream, afxXM_BaseData* mods[]
{
S32 n_mods = stream->readInt(6);
for (int i = 0; i < n_mods; i++)
mods[i] = (afxXM_BaseData*) readDatablockID(stream);
mods[i] = (afxXM_BaseData*)(uintptr_t)readDatablockID(stream);
}
bool afxEffectWrapperData::preload(bool server, String &errorStr)

View file

@ -147,7 +147,7 @@ void afxEffectronData::unpack_fx(BitStream* stream, afxEffectList& fx)
fx.clear();
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
for (int i = 0; i < n_fx; i++)
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
}
void afxEffectronData::packData(BitStream* stream)

View file

@ -304,7 +304,7 @@ void afxMagicSpellData::unpack_fx(BitStream* stream, afxEffectList& fx)
fx.clear();
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
for (int i = 0; i < n_fx; i++)
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
}
void afxMagicSpellData::packData(BitStream* stream)
@ -356,7 +356,7 @@ void afxMagicSpellData::unpackData(BitStream* stream)
mDo_move_interrupts = stream->readFlag();
stream->read(&mMove_interrupt_speed);
mMissile_db = (afxMagicMissileData*) readDatablockID(stream);
mMissile_db = (afxMagicMissileData*)(uintptr_t)readDatablockID(stream);
stream->read(&mLaunch_on_server_signal);
stream->read(&mPrimary_target_types);

View file

@ -151,6 +151,12 @@ void afxRenderHighlightMgr::render( SceneRenderState *state )
matrixSet.setProjection(*passRI->projection);
mat->setTransforms(matrixSet, state);
// Setup HW skinning transforms if applicable
if (mat->usesHardwareSkinning())
{
mat->setNodeTransforms(passRI->mNodeTransforms, passRI->mNodeTransformCount);
}
mat->setSceneInfo(state, sgData);
mat->setBuffers(passRI->vertBuff, passRI->primBuff);
@ -173,4 +179,4 @@ void afxRenderHighlightMgr::render( SceneRenderState *state )
// Make sure the effect is gonna render.
getSelectionEffect()->setSkip( false );
}
}

View file

@ -214,7 +214,7 @@ void afxSelectronData::unpack_fx(BitStream* stream, afxEffectList& fx)
fx.clear();
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
for (int i = 0; i < n_fx; i++)
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
}
void afxSelectronData::packData(BitStream* stream)

View file

@ -128,7 +128,7 @@ void afxSpellBookData::unpackData(BitStream* stream)
do_id_convert = true;
for (S32 i = 0; i < pages_per_book*spells_per_page; i++)
rpg_spells[i] = (afxRPGMagicSpellData*) readDatablockID(stream);
rpg_spells[i] = (afxRPGMagicSpellData*)(uintptr_t)readDatablockID(stream);
}
DefineEngineMethod(afxSpellBookData, getPageSlotIndex, S32, (Point2I bookSlot),,

View file

@ -195,8 +195,8 @@ void afxT3DLightBaseData::unpackData(BitStream* stream)
stream->read( &mAnimState.animationPhase );
stream->read( &mFlareScale );
mAnimationData = (LightAnimData*) readDatablockID(stream);
mFlareData = (LightFlareData*) readDatablockID(stream);
mAnimationData = (LightAnimData*)(uintptr_t)readDatablockID(stream);
mFlareData = (LightFlareData*)(uintptr_t)readDatablockID(stream);
do_id_convert = true;
}

View file

@ -215,7 +215,7 @@ void afxPhraseEffectData::unpack_fx(BitStream* stream, afxEffectList& fx)
fx.clear();
S32 n_fx = stream->readInt(EFFECTS_PER_PHRASE_BITS);
for (int i = 0; i < n_fx; i++)
fx.push_back((afxEffectWrapperData*)readDatablockID(stream));
fx.push_back((afxEffectWrapperData*)(uintptr_t)readDatablockID(stream));
}
void afxPhraseEffectData::packData(BitStream* stream)

View file

@ -1611,9 +1611,7 @@ static void handleExtendedMasterServerListResponse(BitStream* stream, U32 key, U
{
U16 packetIndex, packetTotal;
U32 i;
U16 serverCount, port;
U8 netNum[16];
char addressBuffer[256];
U16 serverCount;
NetAddress addr;
stream->read(&packetIndex);

View file

@ -130,8 +130,8 @@ void AssetManager::initPersistFields()
// Call parent.
Parent::initPersistFields();
addField( "EchoInfo", TypeBool, Offset(mEchoInfo, AssetManager), "Whether the asset manager echos extra information to the console or not." );
addField( "IgnoreAutoUnload", TypeBool, Offset(mIgnoreAutoUnload, AssetManager), "Whether the asset manager should ignore unloading of auto-unload assets or not." );
addField( "EchoInfo", TypeBool, false, Offset(mEchoInfo, AssetManager), "Whether the asset manager echos extra information to the console or not." );
addField( "IgnoreAutoUnload", TypeBool, true, Offset(mIgnoreAutoUnload, AssetManager), "Whether the asset manager should ignore unloading of auto-unload assets or not." );
}
//-----------------------------------------------------------------------------
@ -228,7 +228,7 @@ bool AssetManager::loadModuleAutoLoadAssets(ModuleDefinition* pModuleDefinition)
AssertFatal(pModuleDefinition != NULL, "Cannot auto load assets using a NULL module definition");
// Does the module have any assets associated with it?
if (pModuleDefinition->getModuleAssets().empty())
if (pModuleDefinition->getModuleAssets().empty() && mEchoInfo)
{
// Yes, so warn.
Con::warnf("Asset Manager: Cannot auto load assets to module '%s' as it has no existing assets.", pModuleDefinition->getSignature());

View file

@ -836,7 +836,7 @@ public:
/// Define a call-in point for calling into the engine. Unlike with DefineEngineFunction, the statically
/// callable function will be confined to the namespace of the given class.
///
/// @param name The name of the C++ class (or a registered export scope).
/// @param classname The name of the C++ class (or a registered export scope).
/// @param name The name of the method as it should be seen by the control layer.
/// @param returnType The value type returned to the control layer.
/// @param args The argument list as it would appear on the function definition

View file

@ -2834,13 +2834,16 @@ DefineEngineMethod( SimObject, getFieldValue, const char*, ( const char* fieldNa
"@param index Optional parameter to specify the index of an array field separately.\n"
"@return The value of the given field or \"\" if undefined." )
{
const U32 nameLen = dStrlen( fieldName );
if (nameLen == 0)
return "";
char fieldNameBuffer[ 1024 ];
char arrayIndexBuffer[ 64 ];
// Parse out index if the field is given in the form of 'name[index]'.
const char* arrayIndex = NULL;
const U32 nameLen = dStrlen( fieldName );
if( fieldName[ nameLen - 1 ] == ']' )
{
const char* leftBracket = dStrchr( fieldName, '[' );

View file

@ -398,10 +398,10 @@ void CloudLayer::_initTexture()
}
if ( mTextureName.isNotEmpty() )
mTexture.set( mTextureName, &GFXStaticTextureSRGBProfile, "CloudLayer" );
mTexture.set( mTextureName, &GFXNormalMapProfile, "CloudLayer" );
if ( mTexture.isNull() )
mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "CloudLayer" );
mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXNormalMapProfile, "CloudLayer" );
}
void CloudLayer::_initBuffers()
@ -501,4 +501,4 @@ void CloudLayer::_initBuffers()
}
mPB.unlock();
}
}

View file

@ -45,6 +45,8 @@
#include "materials/materialDefinition.h"
#include "T3D/prefab.h"
#include "T3D/Scene.h"
IMPLEMENT_CONOBJECT(GuiMeshRoadEditorCtrl);
ConsoleDocClass( GuiMeshRoadEditorCtrl,
@ -420,12 +422,14 @@ void GuiMeshRoadEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
newRoad->registerObject();
// Add to MissionGroup
SimGroup *missionGroup;
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
Con::errorf( "GuiMeshRoadEditorCtrl - could not find MissionGroup to add new MeshRoad" );
// Add to scene
Scene *scene;
scene = Scene::getRootScene();
if ( !scene)
Con::errorf( "GuiMeshRoadEditorCtrl - could not find Scene to add new MeshRoad" );
else
missionGroup->addObject( newRoad );
scene->addObject( newRoad );
Point3F pos( endPnt );
pos.z += mDefaultDepth * 0.5f;

View file

@ -43,6 +43,8 @@
#include "T3D/gameBase/gameConnection.h"
#include "T3D/prefab.h"
#include "T3D/Scene.h"
IMPLEMENT_CONOBJECT(GuiRiverEditorCtrl);
ConsoleDocClass( GuiRiverEditorCtrl,
@ -444,12 +446,12 @@ void GuiRiverEditorCtrl::_process3DMouseDown( const Gui3DMouseEvent& event )
return;
}
// Add to MissionGroup
SimGroup *missionGroup;
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
Con::errorf( "GuiRiverEditorCtrl - could not find MissionGroup to add new River" );
// Add to Scene
Scene* scene = Scene::getRootScene();
if ( !scene )
Con::errorf( "GuiRiverEditorCtrl - could not find root Scene to add new River" );
else
missionGroup->addObject( newRiver );
scene->addObject( newRiver );
Point3F pos( endPnt );
pos.z += mDefaultDepth * 0.5f;

View file

@ -39,6 +39,8 @@
#include "gui/worldEditor/undoActions.h"
#include "materials/materialDefinition.h"
#include "T3D/Scene.h"
IMPLEMENT_CONOBJECT(GuiRoadEditorCtrl);
ConsoleDocClass( GuiRoadEditorCtrl,
@ -407,12 +409,12 @@ void GuiRoadEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event)
newRoad->registerObject();
// Add to MissionGroup
SimGroup *missionGroup;
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
Con::errorf( "GuiDecalRoadEditorCtrl - could not find MissionGroup to add new DecalRoad" );
// Add to scene
Scene* scene = Scene::getRootScene();
if ( !scene )
Con::errorf( "GuiDecalRoadEditorCtrl - could not find scene to add new DecalRoad" );
else
missionGroup->addObject( newRoad );
scene->addObject( newRoad );
newRoad->insertNode( tPos, mDefaultWidth, 0 );
U32 newNode = newRoad->insertNode( tPos, mDefaultWidth, 1 );
@ -722,7 +724,7 @@ void GuiRoadEditorCtrl::renderScene(const RectI & updateRect)
// Draw the spline based from the client-side road
// because the serverside spline is not actually reliable...
// Can be incorrect if the DecalRoad is before the TerrainBlock
// in the MissionGroup.
// in the scene.
if ( mHoverRoad && mHoverRoad != mSelRoad )
{

View file

@ -55,7 +55,7 @@ void ForestCreateUndoAction::addItem( ForestItemData *data,
// We store the datablock ID rather than the actual pointer
// since the pointer could go bad.
SimObjectId dataId = item.getData()->getId();
mItems.last().setData( (ForestItemData*)dataId );
mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
}
void ForestCreateUndoAction::redo()
@ -110,7 +110,7 @@ void ForestDeleteUndoAction::removeItem( const ForestItem &item )
SimObjectId dataId = item.getData()->getId();
mItems.push_back( item );
mItems.last().setData( (ForestItemData*)dataId );
mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
mData->removeItem( item.getKey(), item.getPosition() );
}
@ -171,7 +171,7 @@ void ForestUpdateAction::saveItem( const ForestItem &item )
// We store the datablock ID rather than the actual pointer
// since the pointer could go bad.
SimObjectId dataId = item.getData()->getId();
mItems.last().setData( (ForestItemData*)dataId );
mItems.last().setData( (ForestItemData*)(uintptr_t)dataId );
}
void ForestUpdateAction::_swapState()
@ -215,7 +215,7 @@ void ForestUpdateAction::_swapState()
item.getScale() );
// Save the state before this swap for the next swap.
newItem.setData( (ForestItemData*)data->getId() );
newItem.setData( (ForestItemData*)(uintptr_t)data->getId() );
mItems.push_back( newItem );
}

View file

@ -233,7 +233,7 @@ DXGI_SWAP_CHAIN_DESC GFXD3D11Device::setupPresentParams(const GFXVideoMode &mode
if (mode.fullScreen)
{
d3dpp.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
d3dpp.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
d3dpp.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
d3dpp.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
}
@ -1893,4 +1893,4 @@ void GFXD3D11Device::setDebugMarker(ColorI color, const char *name)
D3DPERF_SetMarker(D3DCOLOR_ARGB(color.alpha, color.red, color.green, color.blue),
(LPCWSTR)&eventName);
}
}

View file

@ -77,11 +77,11 @@ _STRING_VALUE_LOOKUP_FXN(GFXStringBlendOp);
#define INIT_LOOKUPTABLE( tablearray, enumprefix, type ) \
for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
tablearray[i] = (type)GFX_UNINIT_VAL;
tablearray[i] = (type)(uintptr_t)GFX_UNINIT_VAL;
#define INIT_LOOKUPTABLE_EX( tablearray, enumprefix, type, typeTable ) \
for( S32 i = enumprefix##_FIRST; i < enumprefix##_COUNT; i++ ) \
{\
tablearray[i] = (type)GFX_UNINIT_VAL;\
tablearray[i] = (type)(uintptr_t)GFX_UNINIT_VAL;\
typeTable[i] = &defaultStringValueLookup;\
}

View file

@ -131,7 +131,7 @@ void GFXGLPrimitiveBuffer::finish()
GLvoid* GFXGLPrimitiveBuffer::getBuffer()
{
// NULL specifies no offset into the hardware buffer
return (GLvoid*)mBufferOffset;
return (GLvoid*)(uintptr_t)mBufferOffset;
}
void GFXGLPrimitiveBuffer::zombify()

View file

@ -130,7 +130,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -141,7 +141,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -152,7 +152,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -163,7 +163,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -174,7 +174,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -185,7 +185,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = true;
glElement.type = GL_UNSIGNED_BYTE;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -196,7 +196,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -207,7 +207,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_UNSIGNED_BYTE;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
}
@ -221,7 +221,7 @@ void GFXGLVertexDecl::_initVerticesFormat(U32 stream)
glElement.normalized = false;
glElement.type = GL_FLOAT;
glElement.stride = vertexSize;
glElement.pointerFirst = (void*)buffer;
glElement.pointerFirst = (void*)(uintptr_t)buffer;
buffer += element.getSizeInBytes();
++texCoordIndex;

View file

@ -72,7 +72,7 @@ GuiSwatchButtonCtrl::GuiSwatchButtonCtrl()
void GuiSwatchButtonCtrl::initPersistFields()
{
addField("color", TypeColorF, Offset(mSwatchColor, GuiSwatchButtonCtrl), "The foreground color of GuiSwatchButtonCtrl");
addField( "gridBitmap", TypeString, Offset( mGridBitmap, GuiSwatchButtonCtrl ), "The bitmap used for the transparent grid" );
addField( "gridBitmap", TypeRealString, Offset( mGridBitmap, GuiSwatchButtonCtrl ), "The bitmap used for the transparent grid" );
Parent::initPersistFields();
}

View file

@ -613,3 +613,25 @@ void GuiSplitContainer::onMouseDragged( const GuiEvent &event )
solvePanelConstraints(newDragPos, firstPanel, secondPanel, clientRect);
}
}
void GuiSplitContainer::setSplitPoint(Point2I splitPoint)
{
GuiContainer *firstPanel = dynamic_cast<GuiContainer*>(at(0));
GuiContainer *secondPanel = dynamic_cast<GuiContainer*>(at(1));
// This function will constrain the panels to their minExtents and update the mSplitPoint
if (firstPanel && secondPanel)
{
RectI clientRect = getClientRect();
solvePanelConstraints(splitPoint, firstPanel, secondPanel, clientRect);
layoutControls(clientRect);
}
}
DefineEngineMethod(GuiSplitContainer, setSplitPoint, void, (Point2I splitPoint), ,
"Set the position of the split handle.")
{
object->setSplitPoint(splitPoint);
}

View file

@ -87,6 +87,9 @@ public:
virtual void solvePanelConstraints(Point2I newDragPos, GuiContainer * firstPanel, GuiContainer * secondPanel, const RectI& clientRect);
virtual Point2I getMinExtent() const;
//Set the positin of the split handler
void setSplitPoint(Point2I splitPoint);
protected:
S32 mFixedPanel;

View file

@ -0,0 +1,298 @@
//-----------------------------------------------------------------------------
// Gui3DProjectionCtrl
// Doppelganger Inc
// Orion Elenzil 200701
//
// This control is meant to be merely a container for other controls.
// What's neat is that it's easy to 'attach' this control to a point in world-space
// or, more interestingly, to an object such as a player.
//
// Usage:
// * Create the Gui3DProjectionControl - by default it will be at 0, 0, 0.
// * You can change where it's located by setting the field "offsetWorld".
// - note you can specify that right in the .gui file
// * You can attach it to any SceneObject by calling "setAttachedTo()".
//
// Behaviour:
// * If you're attaching it to a player, by default it will center on the player's head.
// * If you attach it to an object, by default it will delete itself if the object is deleted.
// * Doesn't occlude w/r/t 3D objects.
//
// Console Methods:
// * SetAttachedTo(SceneObject)
// * GetAttachedTo()
//
// Params:
// * pointWorld - read/write point in worldspace. read-only if attached to an object.
// * offsetObject - an offset in objectspace. default 0, 0, 0.
// * offsetWorld - an offset in worldspace. default 0, 0, 0.
// * offsetScreen - an offset in screenspace. default 0, 0.
// * hAlign - horizontal alignment. 0 = left, 1 = center, 2 = right. default center.
// * vAlign - vertical alignment. 0 = top, 1 = center, 2 = bottomt. default center.
// * useEyePoint - H & V usage of the eyePoint, if player object. default 0, 1. (ie - use only the vertical component)
// * autoDelete - self-delete when attachedTo object is deleted. default true.
//
// Todo:
// * occlusion - hide the control when its anchor point is occluded.
// * integrate w/ zbuffer - this would actually be a change to the whole GuiControl system.
// * allow attaching to arbitrary nodes in a skeleton.
// * avoid projection when the object is out of the frustum.
//
// oxe 20070111
//-----------------------------------------------------------------------------
#include "console/console.h"
#include "console/consoleTypes.h"
#include "scene/sceneObject.h"
#include "T3D/player.h"
#include "gui/controls/gui3DProjectionCtrl.h"
IMPLEMENT_CONOBJECT(Gui3DProjectionCtrl);
//-----------------------------------------------------------------------------
Gui3DProjectionCtrl::Gui3DProjectionCtrl()
{
mTSCtrl = NULL;
mAttachedTo = NULL;
mAttachedToPlayer = NULL;
mAutoDelete = true;
mHAlign = center;
mVAlign = center;
mUseEyePoint.x = 0;
mUseEyePoint.y = 1;
mPtWorld .set(0, 0, 0);
mPtProj .set(0, 0);
mOffsetObject.set(0, 0, 0);
mOffsetWorld .set(0, 0, 0);
mOffsetScreen.set(0, 0);
}
void Gui3DProjectionCtrl::initPersistFields()
{
Parent::initPersistFields();
addGroup("3DProjection");
addField("pointWorld" , TypePoint3F , Offset(mPtWorld , Gui3DProjectionCtrl));
addField("offsetObject" , TypePoint3F , Offset(mOffsetObject , Gui3DProjectionCtrl));
addField("offsetWorld" , TypePoint3F , Offset(mOffsetWorld , Gui3DProjectionCtrl));
addField("offsetScreen" , TypePoint2I , Offset(mOffsetScreen , Gui3DProjectionCtrl));
addField("hAlign" , TypeS32 , Offset(mHAlign , Gui3DProjectionCtrl));
addField("vAlign" , TypeS32 , Offset(mVAlign , Gui3DProjectionCtrl));
addField("useEyePoint" , TypePoint2I , Offset(mUseEyePoint , Gui3DProjectionCtrl));
addField("autoDelete" , TypeBool , Offset(mAutoDelete , Gui3DProjectionCtrl));
endGroup("3DProjection");
}
void Gui3DProjectionCtrl::onRender(Point2I offset, const RectI &updateRect)
{
doPositioning();
doProjection();
doAlignment();
Parent::onRender(offset, updateRect);
}
void Gui3DProjectionCtrl::resizeDuringRender()
{
doPositioning();
doProjection ();
doAlignment ();
}
bool Gui3DProjectionCtrl::onWake()
{
// walk up the GUI tree until we find a GuiTSCtrl.
mTSCtrl = NULL;
GuiControl* walkCtrl = getParent();
AssertFatal(walkCtrl != NULL, "Gui3DProjectionCtrl::onWake() - NULL parent");
bool doMore = true;
while (doMore)
{
mTSCtrl = dynamic_cast<GuiTSCtrl*>(walkCtrl);
walkCtrl = walkCtrl->getParent();
doMore = (mTSCtrl == NULL) && (walkCtrl != NULL);
}
if (!mTSCtrl)
Con::errorf("Gui3DProjectionCtrl::onWake() - no TSCtrl parent");
return Parent::onWake();
}
void Gui3DProjectionCtrl::onSleep()
{
mTSCtrl = NULL;
return Parent::onSleep();
}
void Gui3DProjectionCtrl::onDeleteNotify(SimObject* obj)
{
// - SimSet assumes that obj is a member of THIS, which in our case ain't true.
// oxe 20070116 - the following doesn't compile on GCC.
// SimSet::Parent::onDeleteNotify(obj);
if (!obj)
{
Con::warnf("Gui3DProjectionCtrl::onDeleteNotify - got NULL");
return;
}
if (obj != mAttachedTo)
{
if (mAttachedTo != NULL)
Con::warnf("Gui3DProjectionCtrl::onDeleteNotify - got unexpected object: %d vs. %d", obj->getId(), mAttachedTo->getId());
return;
}
if (mAutoDelete)
this->deleteObject();
}
//-----------------------------------------------------------------------------
void Gui3DProjectionCtrl::doPositioning()
{
if (mAttachedTo == NULL)
return;
Point3F ptBase; // the regular position of the object.
Point3F ptEye; // the render position of the eye node, if a player object.
Point3F pt; // combination of ptBase and ptEye.
MatrixF mat; // utility
mAttachedTo->getRenderTransform().getColumn(3, &ptBase);
if (mAttachedToPlayer != NULL)
{
mAttachedToPlayer->getRenderEyeTransform(&mat);
mat.getColumn(3, &ptEye);
}
else
{
ptEye = ptBase;
}
// use some components from ptEye but other position from ptBase
pt = ptBase;
if (mUseEyePoint.x != 0)
{
pt.x = ptEye.x;
pt.y = ptEye.y;
}
if (mUseEyePoint.y != 0)
{
pt.z = ptEye.z;
}
// object-space offset
Point3F offsetObj;
QuatF quat(mAttachedTo->getRenderTransform());
quat.mulP(mOffsetObject, &offsetObj);
pt += offsetObj;
// world-space offset
pt += mOffsetWorld;
mPtWorld = pt;
}
void Gui3DProjectionCtrl::doProjection()
{
if (!mTSCtrl)
return;
Point3F pt;
if (!mTSCtrl->project(mPtWorld, &pt))
return;
mPtProj.x = (S32)(pt.x + 0.5f);
mPtProj.y = (S32)(pt.y + 0.5f);
}
void Gui3DProjectionCtrl::doAlignment()
{
// alignment
Point2I offsetAlign;
switch(mHAlign)
{
default:
case center:
offsetAlign.x = -getBounds().extent.x / 2;
break;
case min:
offsetAlign.x = 0;
break;
case max:
offsetAlign.x = -getBounds().extent.x;
break;
}
switch(mVAlign)
{
default:
case center:
offsetAlign.y = -getBounds().extent.y / 2;
break;
case min:
offsetAlign.y = 0;
break;
case max:
offsetAlign.y = -getBounds().extent.y;
break;
}
// projected point
mPtScreen = mPtProj;
// alignment offset
mPtScreen += offsetAlign;
// screen offset
mPtScreen += mOffsetScreen;
// setTrgPosition(mPtScreen);
RectI bounds = getBounds();
bounds.point = mPtScreen;
setBounds(bounds);
}
//-----------------------------------------------------------------------------
void Gui3DProjectionCtrl::setAttachedTo(SceneObject* obj)
{
if (obj == mAttachedTo)
return;
if (mAttachedTo)
clearNotify(mAttachedTo);
mAttachedTo = obj;
mAttachedToPlayer = dynamic_cast<Player*>(obj);
if (mAttachedTo)
deleteNotify(mAttachedTo);
}
DefineEngineMethod(Gui3DProjectionCtrl, setAttachedTo, void, (SceneObject* target), (nullAsType<SceneObject*>()), "(object)")
{
if(target)
object->setAttachedTo(target);
}
DefineEngineMethod(Gui3DProjectionCtrl, getAttachedTo, S32, (),, "()")
{
SceneObject* obj = object->getAttachedTo();
if (!obj)
return 0;
else
return obj->getId();
}

View file

@ -0,0 +1,77 @@
//-----------------------------------------------------------------------------
// Gui3DProjectionCtrl
// Doppelganger Inc
// Orion Elenzil 200701
//
//
//-----------------------------------------------------------------------------
#ifndef _GUI3DPROJECTIONCTRL_H_
#define _GUI3DPROJECTIONCTRL_H_
#include "gui/core/guiTypes.h"
#include "gui/core/guiControl.h"
#include "gui/3d/guiTSControl.h"
#include "scene/sceneObject.h"
#include "T3D/player.h"
class Gui3DProjectionCtrl : public GuiControl
{
//-----------------------------------------------------------------------------
// stock stuff
public:
Gui3DProjectionCtrl();
typedef GuiControl Parent;
DECLARE_CONOBJECT(Gui3DProjectionCtrl);
static void initPersistFields ();
//-----------------------------------------------------------------------------
// more interesting stuff
GuiTSCtrl* mTSCtrl; /// must be a child of one of these.
SimObjectPtr<SceneObject> mAttachedTo; /// optional object we're attached to.
SimObjectPtr<Player> mAttachedToPlayer; /// same pointer as mAttachedTo, but conveniently casted to player.
Point3F mPtWorld; /// the worldspace point which we're projecting
Point2I mPtProj; /// the screenspace projected point. - note there are further modifiers before
Point2I mPtScreen;
Point3F mOffsetObject; /// object-space offset applied first to the attached point to obtain mPtWorld.
Point3F mOffsetWorld; /// world-space offset applied second to the attached point to obtain mPtWorld.
Point2I mOffsetScreen; /// screen-space offset applied to mPtProj. note we still have centering, etc.
enum alignment
{
min = 0,
center = 1,
max = 2
};
alignment mHAlign; /// horizontal alignment
alignment mVAlign; /// horizontal alignment
bool mAutoDelete; /// optionally self-delete when mAttachedTo is deleted.
Point2I mUseEyePoint; /// optionally use the eye point. x != 0 -> horiz. y != 0 -> vert.
virtual void onRender (Point2I offset, const RectI &updateRect);
virtual void resizeDuringRender ();
virtual bool onWake ();
virtual void onSleep ();
virtual void onDeleteNotify (SimObject *object);
void doPositioning ();
void doProjection ();
void doAlignment ();
void setAttachedTo (SceneObject* obj);
SceneObject* getAttachedTo () { return mAttachedTo; }
void setWorldPt (Point3F& pt) { mPtWorld = pt; }
Point3F getWorldPt () { return mPtWorld; }
};
#endif //_GUI3DPROJECTIONCTRL_H_

View file

@ -89,9 +89,6 @@ bool GuiConsole::onWake()
S32 GuiConsole::getMaxWidth(S32 startIndex, S32 endIndex)
{
//sanity check
U32 size;
ConsoleLogEntry *log;
if (startIndex < 0 || (U32)endIndex >= mFilteredLog.size() || startIndex > endIndex)
return 0;
@ -190,9 +187,6 @@ void GuiConsole::onPreRender()
void GuiConsole::onRenderCell(Point2I offset, Point2I cell, bool /*selected*/, bool /*mouseOver*/)
{
U32 size;
ConsoleLogEntry *log;
ConsoleLogEntry &entry = mFilteredLog[cell.y];
switch (entry.mLevel)
{
@ -210,9 +204,6 @@ void GuiConsole::onCellSelected( Point2I cell )
{
Parent::onCellSelected( cell );
U32 size;
ConsoleLogEntry* log;
ConsoleLogEntry& entry = mFilteredLog[cell.y];
onMessageSelected_callback( entry.mLevel, entry.mString );
}

View file

@ -631,7 +631,7 @@ DefineEngineMethod( GuiListBoxCtrl, addItem, S32, (const char* newItem, const ch
else if(elementCount == 1)
{
U32 objId = dAtoi( color );
return object->addItem( newItem, (void*)objId );
return object->addItem( newItem, (void*)(uintptr_t)objId );
}
else
{
@ -1523,7 +1523,7 @@ void GuiListBoxCtrl::_mirror()
if ( !found )
{
addItem( _makeMirrorItemName( curObj ), (void*)curId );
addItem( _makeMirrorItemName( curObj ), (void*)(uintptr_t)curId );
}
}
}

View file

@ -1241,6 +1241,9 @@ void GuiTextEditCtrl::onLoseFirstResponder()
root->disableKeyboardTranslation();
}
updateHistory(&mTextBuffer, true);
mHistoryDirty = false;
//execute the validate command
if( mValidateCommand.isNotEmpty() )
evaluate( mValidateCommand );

View file

@ -33,6 +33,7 @@
#include "gfx/gfxDrawUtil.h"
#include "gfx/primBuilder.h"
#include "console/engineAPI.h"
#include "gui/editor/guiPopupMenuCtrl.h"
// menu bar:
// basic idea - fixed height control bar at the top of a window, placed and sized in gui editor
@ -1113,6 +1114,13 @@ GuiMenuBar::GuiMenuBar()
void GuiMenuBar::onRemove()
{
GuiPopupMenuBackgroundCtrl* backgroundCtrl;
if (Sim::findObject("PopUpMenuControl", backgroundCtrl))
{
if (backgroundCtrl->mMenuBarCtrl == this)
backgroundCtrl->mMenuBarCtrl = nullptr;
}
Parent::onRemove();
}
@ -1472,11 +1480,11 @@ PopupMenu* GuiMenuBar::getMenu(U32 index)
return mMenuList[index].popupMenu;
}
PopupMenu* GuiMenuBar::findMenu(StringTableEntry barTitle)
PopupMenu* GuiMenuBar::findMenu(String barTitle)
{
for (U32 i = 0; i < mMenuList.size(); i++)
{
if (mMenuList[i].text == barTitle)
if (String::ToLower(mMenuList[i].text) == String::ToLower(barTitle))
return mMenuList[i].popupMenu;
}
@ -1521,8 +1529,7 @@ DefineEngineMethod(GuiMenuBar, insert, void, (SimObject* pObject, S32 pos), (nul
DefineEngineMethod(GuiMenuBar, findMenu, S32, (const char* barTitle), (""), "(barTitle)")
{
StringTableEntry barTitleStr = StringTable->insert(barTitle);
PopupMenu* menu = object->findMenu(barTitleStr);
PopupMenu* menu = object->findMenu(barTitle);
if (menu)
return menu->getId();

View file

@ -116,7 +116,7 @@ public:
U32 getMenuListCount() { return mMenuList.size(); }
PopupMenu* getMenu(U32 index);
PopupMenu* findMenu(StringTableEntry barTitle);
PopupMenu* findMenu(String barTitle);
DECLARE_CONOBJECT(GuiMenuBar);
DECLARE_CALLBACK( void, onMouseInMenu, ( bool hasLeftMenu ));

View file

@ -50,7 +50,9 @@ GuiInspectorField::GuiInspectorField( GuiInspector* inspector,
mField( field ),
mFieldArrayIndex( NULL ),
mEdit( NULL ),
mTargetObject(NULL)
mTargetObject(NULL),
mUseHeightOverride(false),
mHeightOverride(18)
{
if( field != NULL )
mCaption = field->pFieldname;
@ -77,7 +79,9 @@ GuiInspectorField::GuiInspectorField()
mTargetObject(NULL),
mVariableName(StringTable->EmptyString()),
mCallbackName(StringTable->EmptyString()),
mSpecialEditField(false)
mSpecialEditField(false),
mUseHeightOverride(false),
mHeightOverride(18)
{
setCanSave( false );
}
@ -112,7 +116,12 @@ bool GuiInspectorField::onAdd()
if ( mEdit == NULL )
return false;
setBounds(0,0,100,18);
S32 fieldHeight = 18;
if (mUseHeightOverride)
fieldHeight = mHeightOverride;
setBounds(0,0,100, fieldHeight);
// Add our edit as a child
addObject( mEdit );

View file

@ -84,6 +84,10 @@ class GuiInspectorField : public GuiControl
///
bool mHighlighted;
//These are so we can special-case our height for additional room on certain field-types
bool mUseHeightOverride;
U32 mHeightOverride;
//An override that lets us bypass inspector-dependent logic for setting/getting variables/fields
bool mSpecialEditField;
//An override to make sure this field is associated to an object that isn't expressly

View file

@ -133,9 +133,6 @@ bool GuiInspectorMountingGroup::inspectGroup()
clearFields();
bool bNewItems = false;
bool bMakingArray = false;
GuiStackControl *pArrayStack = NULL;
GuiRolloutCtrl *pArrayRollout = NULL;
bool bGrabItems = false;
AbstractClassRep* commonAncestorClass = findCommonAncestorClass();
@ -240,7 +237,6 @@ void GuiInspectorMountingGroup::updateAllFields()
void GuiInspectorMountingGroup::onMouseMove(const GuiEvent &event)
{
//mParent->mOverDivider = false;
bool test = false;
}
DefineEngineMethod(GuiInspectorMountingGroup, inspectGroup, bool, (),, "Refreshes the dynamic fields in the inspector.")

View file

@ -282,156 +282,159 @@ void PopupMenu::showPopup(GuiCanvas *owner, S32 x /* = -1 */, S32 y /* = -1 */)
if (owner == NULL)
return;
GuiControl* editorGui;
Sim::findObject("EditorGui", editorGui);
GuiPopupMenuBackgroundCtrl* backgroundCtrl;
Sim::findObject("PopUpMenuControl", backgroundCtrl);
if (editorGui)
GuiControlProfile* profile;
Sim::findObject("GuiMenubarProfile", profile);
if (!profile)
return;
if (mTextList == nullptr)
{
GuiPopupMenuBackgroundCtrl* backgroundCtrl;
Sim::findObject("PopUpMenuControl", backgroundCtrl);
mTextList = new GuiPopupMenuTextListCtrl();
mTextList->registerObject();
mTextList->setControlProfile(profile);
GuiControlProfile* profile;
Sim::findObject("GuiMenubarProfile", profile);
if (!profile)
return;
if (mTextList == nullptr)
{
mTextList = new GuiPopupMenuTextListCtrl();
mTextList->registerObject();
mTextList->setControlProfile(profile);
mTextList->mPopup = this;
mTextList->mMenuBar = getMenuBarCtrl();
}
if (!backgroundCtrl)
{
backgroundCtrl = new GuiPopupMenuBackgroundCtrl();
backgroundCtrl->registerObject("PopUpMenuControl");
}
if (!backgroundCtrl || !mTextList)
return;
if (!mIsSubmenu)
{
//if we're a 'parent' menu, then tell the background to clear out all existing other popups
backgroundCtrl->clearPopups();
}
//find out if we're doing a first-time add
S32 popupIndex = backgroundCtrl->findPopupMenu(this);
if (popupIndex == -1)
{
backgroundCtrl->addObject(mTextList);
backgroundCtrl->mPopups.push_back(this);
}
mTextList->mBackground = backgroundCtrl;
owner->pushDialogControl(backgroundCtrl, 10);
//Set the background control's menubar, if any, and if it's not already set
if(backgroundCtrl->mMenuBarCtrl == nullptr)
backgroundCtrl->mMenuBarCtrl = getMenuBarCtrl();
backgroundCtrl->setExtent(editorGui->getExtent());
mTextList->clear();
S32 textWidth = 0, width = 0;
S32 acceleratorWidth = 0;
GFont *font = profile->mFont;
Point2I maxBitmapSize = Point2I(0, 0);
S32 numBitmaps = profile->mBitmapArrayRects.size();
if (numBitmaps)
{
RectI *bitmapBounds = profile->mBitmapArrayRects.address();
for (S32 i = 0; i < numBitmaps; i++)
{
if (bitmapBounds[i].extent.x > maxBitmapSize.x)
maxBitmapSize.x = bitmapBounds[i].extent.x;
if (bitmapBounds[i].extent.y > maxBitmapSize.y)
maxBitmapSize.y = bitmapBounds[i].extent.y;
}
}
for (U32 i = 0; i < mMenuItems.size(); i++)
{
if (!mMenuItems[i].mVisible)
continue;
S32 iTextWidth = font->getStrWidth(mMenuItems[i].mText.c_str());
S32 iAcceleratorWidth = mMenuItems[i].mAccelerator ? font->getStrWidth(mMenuItems[i].mAccelerator) : 0;
if (iTextWidth > textWidth)
textWidth = iTextWidth;
if (iAcceleratorWidth > acceleratorWidth)
acceleratorWidth = iAcceleratorWidth;
}
width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4;
mTextList->setCellSize(Point2I(width, font->getHeight() + 2));
mTextList->clearColumnOffsets();
mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index.
mTextList->addColumnOffset(maxBitmapSize.x + 1);
mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4);
U32 entryCount = 0;
for (U32 i = 0; i < mMenuItems.size(); i++)
{
if (!mMenuItems[i].mVisible)
continue;
char buf[512];
// If this menu item is a submenu, then set the isSubmenu to 2 to indicate
// an arrow should be drawn. Otherwise set the isSubmenu normally.
char isSubmenu = 1;
if (mMenuItems[i].mIsSubmenu)
isSubmenu = 2;
char bitmapIndex = 1;
if (mMenuItems[i].mBitmapIndex >= 0 && (mMenuItems[i].mBitmapIndex * 3 <= profile->mBitmapArrayRects.size()))
bitmapIndex = mMenuItems[i].mBitmapIndex + 2;
dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, mMenuItems[i].mText.c_str(), mMenuItems[i].mAccelerator ? mMenuItems[i].mAccelerator : "");
mTextList->addEntry(entryCount, buf);
if (!mMenuItems[i].mEnabled)
mTextList->setEntryActive(entryCount, false);
entryCount++;
}
Point2I pos = Point2I::Zero;
if (x == -1 && y == -1)
pos = owner->getCursorPos();
else
pos = Point2I(x, y);
mTextList->setPosition(pos);
//nudge in if we'd overshoot the screen
S32 widthDiff = (mTextList->getPosition().x + mTextList->getExtent().x) - backgroundCtrl->getWidth();
if (widthDiff > 0)
{
Point2I popupPos = mTextList->getPosition();
mTextList->setPosition(popupPos.x - widthDiff, popupPos.y);
}
mTextList->setHidden(false);
mTextList->mPopup = this;
mTextList->mMenuBar = getMenuBarCtrl();
}
if (!backgroundCtrl)
{
backgroundCtrl = new GuiPopupMenuBackgroundCtrl();
backgroundCtrl->registerObject("PopUpMenuControl");
}
if (!backgroundCtrl || !mTextList)
return;
if (!mIsSubmenu)
{
//if we're a 'parent' menu, then tell the background to clear out all existing other popups
backgroundCtrl->clearPopups();
}
//find out if we're doing a first-time add
S32 popupIndex = backgroundCtrl->findPopupMenu(this);
if (popupIndex == -1)
{
backgroundCtrl->addObject(mTextList);
backgroundCtrl->mPopups.push_back(this);
}
mTextList->mBackground = backgroundCtrl;
owner->pushDialogControl(backgroundCtrl, 10);
//Set the background control's menubar, if any, and if it's not already set
if(backgroundCtrl->mMenuBarCtrl == nullptr)
backgroundCtrl->mMenuBarCtrl = getMenuBarCtrl();
backgroundCtrl->setExtent(owner->getExtent());
mTextList->clear();
S32 textWidth = 0, width = 0;
S32 acceleratorWidth = 0;
GFont *font = profile->mFont;
Point2I maxBitmapSize = Point2I(0, 0);
S32 numBitmaps = profile->mBitmapArrayRects.size();
if (numBitmaps)
{
RectI *bitmapBounds = profile->mBitmapArrayRects.address();
for (S32 i = 0; i < numBitmaps; i++)
{
if (bitmapBounds[i].extent.x > maxBitmapSize.x)
maxBitmapSize.x = bitmapBounds[i].extent.x;
if (bitmapBounds[i].extent.y > maxBitmapSize.y)
maxBitmapSize.y = bitmapBounds[i].extent.y;
}
}
for (U32 i = 0; i < mMenuItems.size(); i++)
{
if (!mMenuItems[i].mVisible)
continue;
S32 iTextWidth = font->getStrWidth(mMenuItems[i].mText.c_str());
S32 iAcceleratorWidth = mMenuItems[i].mAccelerator ? font->getStrWidth(mMenuItems[i].mAccelerator) : 0;
if (iTextWidth > textWidth)
textWidth = iTextWidth;
if (iAcceleratorWidth > acceleratorWidth)
acceleratorWidth = iAcceleratorWidth;
}
width = textWidth + acceleratorWidth + maxBitmapSize.x * 2 + 2 + 4;
mTextList->setCellSize(Point2I(width, font->getHeight() + 2));
mTextList->clearColumnOffsets();
mTextList->addColumnOffset(-1); // add an empty column in for the bitmap index.
mTextList->addColumnOffset(maxBitmapSize.x + 1);
mTextList->addColumnOffset(maxBitmapSize.x + 1 + textWidth + 4);
U32 entryCount = 0;
for (U32 i = 0; i < mMenuItems.size(); i++)
{
if (!mMenuItems[i].mVisible)
continue;
char buf[512];
// If this menu item is a submenu, then set the isSubmenu to 2 to indicate
// an arrow should be drawn. Otherwise set the isSubmenu normally.
char isSubmenu = 1;
if (mMenuItems[i].mIsSubmenu)
isSubmenu = 2;
char bitmapIndex = 1;
if (mMenuItems[i].mBitmapIndex >= 0 && (mMenuItems[i].mBitmapIndex * 3 <= profile->mBitmapArrayRects.size()))
bitmapIndex = mMenuItems[i].mBitmapIndex + 2;
dSprintf(buf, sizeof(buf), "%c%c\t%s\t%s", bitmapIndex, isSubmenu, mMenuItems[i].mText.c_str(), mMenuItems[i].mAccelerator ? mMenuItems[i].mAccelerator : "");
mTextList->addEntry(entryCount, buf);
if (!mMenuItems[i].mEnabled)
mTextList->setEntryActive(entryCount, false);
entryCount++;
}
Point2I pos = Point2I::Zero;
if (x == -1 && y == -1)
pos = owner->getCursorPos();
else
pos = Point2I(x, y);
mTextList->setPosition(pos);
//nudge in if we'd overshoot the screen
S32 widthDiff = (mTextList->getPosition().x + mTextList->getExtent().x) - backgroundCtrl->getWidth();
if (widthDiff > 0)
{
Point2I popupPos = mTextList->getPosition();
mTextList->setPosition(popupPos.x - widthDiff, popupPos.y);
}
//If we'd overshoot the screen vertically, just mirror the axis so we're above the mouse
S32 heightDiff = (mTextList->getPosition().y + mTextList->getExtent().y) - backgroundCtrl->getHeight();
if (heightDiff > 0)
{
Point2I popupPos = mTextList->getPosition();
mTextList->setPosition(popupPos.x, popupPos.y - mTextList->getExtent().y);
}
mTextList->setHidden(false);
}
void PopupMenu::hidePopup()

View file

@ -58,9 +58,25 @@ ConsoleDocClass( GuiInputCtrl,
//------------------------------------------------------------------------------
GuiInputCtrl::GuiInputCtrl()
: mSendAxisEvents(false),
mSendBreakEvents(false),
mSendModifierEvents(false)
{
}
//------------------------------------------------------------------------------
void GuiInputCtrl::initPersistFields()
{
addGroup("GuiInputCtrl");
addField("sendAxisEvents", TypeBool, Offset(mSendAxisEvents, GuiInputCtrl),
"If true, onAxisEvent callbacks will be sent for SI_AXIS Move events (Default false).");
addField("sendBreakEvents", TypeBool, Offset(mSendBreakEvents, GuiInputCtrl),
"If true, break events for all devices will generate callbacks (Default false).");
addField("sendModifierEvents", TypeBool, Offset(mSendModifierEvents, GuiInputCtrl),
"If true, Make events will be sent for modifier keys (Default false).");
endGroup("GuiInputCtrl");
Parent::initPersistFields();
}
@ -110,6 +126,8 @@ static bool isModifierKey( U16 keyCode )
case KEY_RALT:
case KEY_LSHIFT:
case KEY_RSHIFT:
case KEY_MAC_LOPT:
case KEY_MAC_ROPT:
return( true );
}
@ -117,33 +135,49 @@ static bool isModifierKey( U16 keyCode )
}
IMPLEMENT_CALLBACK( GuiInputCtrl, onInputEvent, void, (const char* device, const char* action, bool state ),
( device, action, state),
"@brief Callback that occurs when an input is triggered on this control\n\n"
"@param device The device type triggering the input, such as keyboard, mouse, etc\n"
"@param action The actual event occuring, such as a key or button\n"
"@param state True if the action is being pressed, false if it is being release\n\n"
);
( device, action, state),
"@brief Callback that occurs when an input is triggered on this control\n\n"
"@param device The device type triggering the input, such as keyboard, mouse, etc\n"
"@param action The actual event occuring, such as a key or button\n"
"@param state True if the action is being pressed, false if it is being release\n\n");
IMPLEMENT_CALLBACK(GuiInputCtrl, onAxisEvent, void, (const char* device, const char* action, F32 axisValue),
(device, action, axisValue),
"@brief Callback that occurs when an axis event is triggered on this control\n\n"
"@param device The device type triggering the input, such as mouse, joystick, gamepad, etc\n"
"@param action The ActionMap code for the axis\n"
"@param axisValue The current value of the axis\n\n");
//------------------------------------------------------------------------------
bool GuiInputCtrl::onInputEvent( const InputEventInfo &event )
{
// TODO - add POV support...
char deviceString[32];
if ( event.action == SI_MAKE )
{
if ( event.objType == SI_BUTTON
|| event.objType == SI_POV
|| ( ( event.objType == SI_KEY ) && !isModifierKey( event.objInst ) ) )
|| event.objType == SI_KEY )
{
char deviceString[32];
if ( !ActionMap::getDeviceName( event.deviceType, event.deviceInst, deviceString ) )
return( false );
return false;
const char* actionString = ActionMap::buildActionString( &event );
if ((event.objType == SI_KEY) && isModifierKey(event.objInst))
{
if (!mSendModifierEvents)
return false;
//Con::executef( this, "onInputEvent", deviceString, actionString, "1" );
onInputEvent_callback(deviceString, actionString, 1);
char keyString[32];
if (!ActionMap::getKeyString(event.objInst, keyString))
return false;
return( true );
onInputEvent_callback(deviceString, keyString, 1);
}
else
{
const char* actionString = ActionMap::buildActionString(&event);
onInputEvent_callback(deviceString, actionString, 1);
}
return true;
}
}
else if ( event.action == SI_BREAK )
@ -152,14 +186,36 @@ bool GuiInputCtrl::onInputEvent( const InputEventInfo &event )
{
char keyString[32];
if ( !ActionMap::getKeyString( event.objInst, keyString ) )
return( false );
return false;
//Con::executef( this, "onInputEvent", "keyboard", keyString, "0" );
onInputEvent_callback("keyboard", keyString, 0);
onInputEvent_callback("keyboard", keyString, 0);
return true;
}
else if (mSendBreakEvents)
{
if (!ActionMap::getDeviceName(event.deviceType, event.deviceInst, deviceString))
return false;
return( true );
const char* actionString = ActionMap::buildActionString(&event);
onInputEvent_callback(deviceString, actionString, 0);
return true;
}
}
else if (mSendAxisEvents && ((event.objType == SI_AXIS) || (event.objType == SI_INT) || (event.objType == SI_FLOAT)))
{
F32 fValue = event.fValue;
if (event.objType == SI_INT)
fValue = (F32)event.iValue;
return( false );
if (!ActionMap::getDeviceName(event.deviceType, event.deviceInst, deviceString))
return false;
const char* actionString = ActionMap::buildActionString(&event);
onAxisEvent_callback(deviceString, actionString, fValue);
return (event.deviceType != MouseDeviceType); // Don't consume mouse move events
}
return false;
}

View file

@ -32,23 +32,31 @@
/// to script. This is useful for implementing custom keyboard handling code.
class GuiInputCtrl : public GuiMouseEventCtrl
{
public:
protected:
bool mSendAxisEvents;
bool mSendBreakEvents;
bool mSendModifierEvents;
typedef GuiMouseEventCtrl Parent;
// GuiControl.
virtual bool onWake();
virtual void onSleep();
public:
virtual bool onInputEvent( const InputEventInfo &event );
static void initPersistFields();
typedef GuiMouseEventCtrl Parent;
DECLARE_CONOBJECT(GuiInputCtrl);
DECLARE_CATEGORY( "Gui Other Script" );
DECLARE_DESCRIPTION( "A control that locks the mouse and reports all keyboard input events to script." );
GuiInputCtrl();
DECLARE_CALLBACK( void, onInputEvent, ( const char* device, const char* action, bool state ));
// GuiControl.
virtual bool onWake();
virtual void onSleep();
virtual bool onInputEvent( const InputEventInfo &event );
static void initPersistFields();
DECLARE_CONOBJECT(GuiInputCtrl);
DECLARE_CATEGORY( "Gui Other Script" );
DECLARE_DESCRIPTION( "A control that locks the mouse and reports all input events to script." );
DECLARE_CALLBACK( void, onInputEvent, ( const char* device, const char* action, bool state ));
DECLARE_CALLBACK(void, onAxisEvent, (const char* device, const char* action, F32 axisValue));
};
#endif // _GUI_INPUTCTRL_H

View file

@ -38,6 +38,7 @@
#include "scene/sceneRenderState.h"
#include "renderInstance/renderBinManager.h"
#include "T3D/Scene.h"
IMPLEMENT_CONOBJECT(EditTSCtrl);
ConsoleDocClass( EditTSCtrl,
@ -795,15 +796,15 @@ void EditTSCtrl::_renderScene( ObjectRenderInst*, SceneRenderState *state, BaseM
GFXTransformSaver saver;
// render through console callbacks
SimSet * missionGroup = static_cast<SimSet*>(Sim::findObject("MissionGroup"));
if(missionGroup)
Scene* scene = Scene::getRootScene();
if(scene)
{
mConsoleRendering = true;
// [ rene, 27-Jan-10 ] This calls onEditorRender on the server objects instead
// of on the client objects which seems a bit questionable to me.
for(SimSetIterator itr(missionGroup); *itr; ++itr)
for(SimSetIterator itr(scene); *itr; ++itr)
{
SceneObject* object = dynamic_cast< SceneObject* >( *itr );
if( object && object->isRenderEnabled() && !object->isHidden() )

View file

@ -51,6 +51,8 @@
#include "T3D/portal.h"
#include "math/mPolyhedron.impl.h"
#include "T3D/Scene.h"
IMPLEMENT_CONOBJECT( GuiConvexEditorCtrl );
ConsoleDocClass( GuiConvexEditorCtrl,
@ -121,12 +123,12 @@ bool GuiConvexEditorCtrl::onWake()
if ( !Parent::onWake() )
return false;
SimGroup *missionGroup;
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
Scene* scene = Scene::getRootScene();
if ( !scene )
return true;
SimGroup::iterator itr = missionGroup->begin();
for ( ; itr != missionGroup->end(); itr++ )
SimGroup::iterator itr = scene->begin();
for ( ; itr != scene->end(); itr++ )
{
if ( dStrcmp( (*itr)->getClassName(), "ConvexShape" ) == 0 )
{
@ -166,8 +168,8 @@ void GuiConvexEditorCtrl::setVisible( bool val )
mSavedGizmoFlags = -1;
}
SimGroup* misGroup;
if (Sim::findObject("MissionGroup", misGroup))
Scene* scene = Scene::getRootScene();
if (scene != nullptr)
{
//Make our proxy objects "real" again
for (U32 i = 0; i < mProxyObjects.size(); ++i)
@ -178,13 +180,13 @@ void GuiConvexEditorCtrl::setVisible( bool val )
AbstractClassRep* classRep = AbstractClassRep::findClassRep(mProxyObjects[i].targetObjectClass);
if (!classRep)
{
Con::errorf("WorldEditor::createPolyhedralObject - No such class: %s", mProxyObjects[i].targetObjectClass);
Con::errorf("WorldEditor::createPolyhedralObject - No such class: %s", mProxyObjects[i].targetObjectClass.c_str());
continue;
}
SceneObject* polyObj = createPolyhedralObject(mProxyObjects[i].targetObjectClass.c_str(), mProxyObjects[i].shapeProxy);
misGroup->addObject(polyObj);
scene->addObject(polyObj);
//Now, remove the convex proxy
mProxyObjects[i].shapeProxy->deleteObject();
@ -222,19 +224,19 @@ void GuiConvexEditorCtrl::setVisible( bool val )
updateGizmoPos();
mSavedGizmoFlags = mGizmoProfile->flags;
SimGroup* misGroup;
if (Sim::findObject("MissionGroup", misGroup))
Scene* scene = Scene::getRootScene();
if (scene != nullptr)
{
for (U32 c = 0; c < misGroup->size(); ++c)
for (U32 c = 0; c < scene->size(); ++c)
{
bool isTrigger = (misGroup->at(c)->getClassName() == StringTable->insert("Trigger"));
bool isZone = (misGroup->at(c)->getClassName() == StringTable->insert("Zone"));
bool isPortal = (misGroup->at(c)->getClassName() == StringTable->insert("Portal"));
bool isOccluder = (misGroup->at(c)->getClassName() == StringTable->insert("OcclusionVolume"));
bool isTrigger = (scene->at(c)->getClassName() == StringTable->insert("Trigger"));
bool isZone = (scene->at(c)->getClassName() == StringTable->insert("Zone"));
bool isPortal = (scene->at(c)->getClassName() == StringTable->insert("Portal"));
bool isOccluder = (scene->at(c)->getClassName() == StringTable->insert("OcclusionVolume"));
if (isZone || isPortal || isOccluder)
{
SceneObject* sceneObj = static_cast<SceneObject*>(misGroup->at(c));
SceneObject* sceneObj = static_cast<SceneObject*>(scene->at(c));
if (!sceneObj)
{
Con::errorf("WorldEditor::createConvexShapeFrom - Invalid object");
@ -1350,9 +1352,9 @@ void GuiConvexEditorCtrl::setupShape( ConvexShape *shape )
shape->registerObject();
updateShape( shape );
SimGroup *group;
if ( Sim::findObject( "missionGroup", group ) )
group->addObject( shape );
Scene* scene = Scene::getRootScene();
if ( scene )
scene->addObject( shape );
}
void GuiConvexEditorCtrl::updateShape( ConvexShape *shape, S32 offsetFace )
@ -1929,10 +1931,8 @@ ConvexEditorTool::EventResult ConvexEditorCreateTool::on3DMouseUp( const Gui3DMo
}
else if ( mStage == 0 )
{
SimGroup *mg;
Sim::findObject( "MissionGroup", mg );
mg->addObject( mNewConvex );
SimGroup *scene = Scene::getRootScene();
scene->addObject( mNewConvex );
mStage = -1;
@ -2128,9 +2128,9 @@ ConvexShape* ConvexEditorCreateTool::extrudeShapeFromFace( ConvexShape *inShape,
newShape->registerObject();
mEditor->updateShape( newShape );
SimGroup *group;
if ( Sim::findObject( "missionGroup", group ) )
group->addObject( newShape );
Scene* scene = Scene::getRootScene();
if ( scene )
scene->addObject( newShape );
return newShape;
}
@ -2513,4 +2513,4 @@ if (convex)
DefineEngineMethod( GuiConvexEditorCtrl, splitSelectedFace, void, (), , "" )
{
object->splitSelectedFace();
}
}

View file

@ -36,7 +36,7 @@
#include "gui/worldEditor/terrainActions.h"
#include "terrain/terrMaterial.h"
#include "T3D/Scene.h"
IMPLEMENT_CONOBJECT(TerrainEditor);
@ -2405,10 +2405,10 @@ void TerrainEditor::reorderMaterial( S32 index, S32 orderPos )
DefineEngineMethod( TerrainEditor, attachTerrain, void, (const char * terrain), (""), "(TerrainBlock terrain)")
{
SimSet * missionGroup = dynamic_cast<SimSet*>(Sim::findObject("MissionGroup"));
if (!missionGroup)
Scene* scene = Scene::getRootScene();
if (!scene)
{
Con::errorf(ConsoleLogEntry::Script, "TerrainEditor::attach: no mission group found");
Con::errorf(ConsoleLogEntry::Script, "TerrainEditor::attach: no scene found");
return;
}
@ -2417,7 +2417,7 @@ DefineEngineMethod( TerrainEditor, attachTerrain, void, (const char * terrain),
// attach to first found terrainBlock
if (dStrcmp (terrain,"")==0)
{
for(SimSetIterator itr(missionGroup); *itr; ++itr)
for(SimSetIterator itr(scene); *itr; ++itr)
{
TerrainBlock* terrBlock = dynamic_cast<TerrainBlock*>(*itr);

View file

@ -51,6 +51,8 @@
#include "tools/editorTool.h"
#include "T3D/Scene.h"
IMPLEMENT_CONOBJECT( WorldEditor );
ConsoleDocClass( WorldEditor,
@ -455,19 +457,20 @@ bool WorldEditor::pasteSelection( bool dropSel )
return false;
}
SimGroup *missionGroup = NULL;
SimGroup *targetGroup = NULL;
if( isMethod( "getNewObjectGroup" ) )
{
const char* targetGroupName = Con::executef( this, "getNewObjectGroup" );
if( targetGroupName && targetGroupName[ 0 ] && !Sim::findObject( targetGroupName, missionGroup ) )
if( targetGroupName && targetGroupName[ 0 ] && !Sim::findObject( targetGroupName, targetGroup) )
Con::errorf( "WorldEditor::pasteSelection() - no SimGroup called '%s'", targetGroupName );
}
if( !missionGroup )
if( !targetGroup)
{
if( !Sim::findObject( "MissionGroup", missionGroup ) )
targetGroup = Scene::getRootScene();
if( !targetGroup)
{
Con::errorf( "WorldEditor::pasteSelection() - MissionGroup not found" );
Con::errorf( "WorldEditor::pasteSelection() - Scene not found" );
return false;
}
}
@ -481,8 +484,8 @@ bool WorldEditor::pasteSelection( bool dropSel )
if ( !obj )
continue;
if ( missionGroup )
missionGroup->addObject( obj );
if (targetGroup)
targetGroup->addObject( obj );
action->addObject( obj );
@ -594,7 +597,7 @@ void WorldEditor::hideObject(SceneObject* serverObj, bool hide)
void WorldEditor::hideSelection(bool hide)
{
SimGroup* pGroup = dynamic_cast<SimGroup*>(Sim::findObject("MissionGroup"));
Scene* scene = Scene::getRootScene();
// set server/client objects hide field
for(U32 i = 0; i < mSelected->size(); i++)
@ -605,7 +608,7 @@ void WorldEditor::hideSelection(bool hide)
// Prevent non-mission group objects (i.e. Player) from being hidden.
// Otherwise it is difficult to show them again.
if(!serverObj->isChildOfGroup(pGroup))
if(!serverObj->isChildOfGroup(scene))
continue;
hideObject(serverObj, hide);
@ -2437,7 +2440,7 @@ void WorldEditor::renderScene( const RectI &updateRect )
}
// Render the paths
renderPaths(Sim::findObject("MissionGroup"));
renderPaths(Scene::getRootScene());
// walk selected
Selection* selection = getActiveSelectionSet();
@ -3653,10 +3656,10 @@ void WorldEditor::makeSelectionPrefab( const char *filename )
return;
}
SimGroup *missionGroup;
if ( !Sim::findObject( "MissionGroup", missionGroup ) )
Scene* scene = Scene::getRootScene();
if ( !scene)
{
Con::errorf( "WorldEditor::makeSelectionPrefab - Could not find MissionGroup." );
Con::errorf( "WorldEditor::makeSelectionPrefab - Could not find root Scene." );
return;
}
@ -3746,7 +3749,7 @@ void WorldEditor::makeSelectionPrefab( const char *filename )
fabMat.inverse();
fab->setTransform( fabMat );
fab->registerObject();
missionGroup->addObject( fab );
scene->addObject( fab );
// Select it, mark level as dirty.
clearSelection();
@ -3812,10 +3815,10 @@ void WorldEditor::makeSelectionAMesh(const char *filename)
return;
}
SimGroup *missionGroup;
if (!Sim::findObject("MissionGroup", missionGroup))
Scene* scene = Scene::getRootScene();
if (!scene)
{
Con::errorf("WorldEditor::makeSelectionAMesh - Could not find MissionGroup.");
Con::errorf("WorldEditor::makeSelectionAMesh - Could not find root Scene.");
return;
}
@ -3877,8 +3880,6 @@ void WorldEditor::makeSelectionAMesh(const char *filename)
fabMat.inverse();
MatrixF objMat;
SimObject *obj = NULL;
SceneObject *sObj = NULL;
Vector< SceneObject* > objectList;
@ -3967,7 +3968,7 @@ void WorldEditor::makeSelectionAMesh(const char *filename)
fabMat.inverse();
ts->setTransform(fabMat);
ts->registerObject();
missionGroup->addObject(ts);
scene->addObject(ts);
// Select it, mark level as dirty.
clearSelection();

View file

@ -226,8 +226,8 @@ void LightManager::registerGlobalLights( const Frustum *frustum, bool staticLigh
{
// Cull the lights using the frustum.
getSceneManager()->getContainer()->findObjectList(*frustum, lightMask, &activeLights);
if (enableZoneLightCulling)
/*
for (U32 i = 0; i < activeLights.size(); ++i)
{
for (U32 i = 0; i < activeLights.size(); ++i)
{
@ -238,7 +238,7 @@ void LightManager::registerGlobalLights( const Frustum *frustum, bool staticLigh
}
}
}
*/
// Store the culling position for sun placement
// later... see setSpecialLight.
mCullPos = frustum->getPosition();

View file

@ -44,7 +44,7 @@
#define M_CONST_E_F 2.7182818284590452353602874f
#define POINT_EPSILON (1e-4) ///< Epsilon for point types.
#define POINT_EPSILON (0.0001f) ///< Epsilon for point types.
/// Result of an overlap test.

View file

@ -216,7 +216,7 @@ void Frustum::setNearFarDist( F32 nearDist, F32 farDist )
// Recalculate the frustum.
MatrixF xfm( mTransform );
const F32 CENTER_EPSILON = 0.001;
const F32 CENTER_EPSILON = 0.001f;
F32 centerX = mNearLeft + (mNearRight - mNearLeft) * 0.5;
F32 centerY = mNearBottom + (mNearTop - mNearBottom) * 0.5;
if ((centerX > CENTER_EPSILON || centerX < -CENTER_EPSILON) || (centerY > CENTER_EPSILON || centerY < -CENTER_EPSILON) )

View file

@ -69,7 +69,7 @@ S32 QSORT_CALLBACK moduleDefinitionVersionIdSort( const void* a, const void* b )
ModuleManager::ModuleManager() :
mEnforceDependencies(true),
mEchoInfo(true),
mEchoInfo(false),
mDatabaseLocks( 0 ),
mIgnoreLoadedGroups(false)
{

View file

@ -107,8 +107,7 @@ DefineEngineFunction(NavMeshUpdateAll, void, (S32 objid, bool remove), (0, false
SceneObject *obj;
if(!Sim::findObject(objid, obj))
return;
if(remove)
obj->disableCollision();
obj->mPathfindingIgnore = remove;
SimSet *set = NavMesh::getServerSet();
for(U32 i = 0; i < set->size(); i++)
{
@ -119,8 +118,6 @@ DefineEngineFunction(NavMeshUpdateAll, void, (S32 objid, bool remove), (0, false
m->buildTiles(obj->getWorldBox());
}
}
if(remove)
obj->enableCollision();
}
DefineEngineFunction(NavMeshUpdateAroundObject, void, (S32 objid, bool remove), (0, false),
@ -129,8 +126,7 @@ DefineEngineFunction(NavMeshUpdateAroundObject, void, (S32 objid, bool remove),
SceneObject *obj;
if (!Sim::findObject(objid, obj))
return;
if (remove)
obj->disableCollision();
obj->mPathfindingIgnore = remove;
SimSet *set = NavMesh::getServerSet();
for (U32 i = 0; i < set->size(); i++)
{
@ -141,8 +137,6 @@ DefineEngineFunction(NavMeshUpdateAroundObject, void, (S32 objid, bool remove),
m->buildTiles(obj->getWorldBox());
}
}
if (remove)
obj->enableCollision();
}

View file

@ -281,9 +281,22 @@ void AsyncPacketBufferedInputStream< Stream, Packet >::_requestNext()
IResettable* resettable = dynamic_cast< IResettable* >( s );
if( resettable )
{
IPositionable< U32 >* positionable = dynamic_cast< IPositionable< U32 >* >( &Deref( stream ) );
U32 pos;
if(positionable)
pos = positionable->getPosition();
resettable->reset();
isEOS = false;
this->mNumRemainingSourceElements = mNumTotalSourceElements;
if( positionable )
{
positionable->setPosition(pos);
U32 dur = stream->getDuration();
if(dur != 0) //avoiding division by zero? not needed, probably
this->mNumRemainingSourceElements -= (U32)(mNumTotalSourceElements*(F32)pos/dur);
}
}
}
else if( isEOS )

View file

@ -249,6 +249,14 @@ enum InputObjectInstancesEnum
SI_DPOV2 = 0x215,
SI_LPOV2 = 0x216,
SI_RPOV2 = 0x217,
SI_POVMASK = 0x218,
SI_POVMASK2 = 0x219,
/// Trackball event codes.
SI_XBALL = 0x21A,
SI_YBALL = 0x21B,
SI_XBALL2 = 0x21C,
SI_YBALL2 = 0x21D,
XI_CONNECT = 0x300,
XI_THUMBLX = 0x301,
@ -262,7 +270,7 @@ enum InputObjectInstancesEnum
XI_DPAD_DOWN = 0x308,
XI_DPAD_LEFT = 0x309,
XI_DPAD_RIGHT = 0x310,*/
XI_START = 0x311,
XI_BACK = 0x312,
XI_LEFT_THUMB = 0x313,
@ -273,7 +281,8 @@ enum InputObjectInstancesEnum
XI_A = 0x317,
XI_B = 0x318,
XI_X = 0x319,
XI_Y = 0x320,
XI_Y = 0x31A,
XI_GUIDE = 0x31B,
INPUT_DEVICE_PLUGIN_CODES_START = 0x400,
};

View file

@ -285,9 +285,9 @@ bool FileDialog::Execute()
{
// Single file selection, do it the easy way
if(mForceRelativePath)
mData.mFile = Platform::makeRelativePathName(resultPath.c_str(), NULL);
mData.mFile = Con::getReturnBuffer(Platform::makeRelativePathName(resultPath.c_str(), NULL));
else
mData.mFile = resultPath.c_str();
mData.mFile = Con::getReturnBuffer(resultPath.c_str());
}
else if (mData.mStyle & FileDialogData::FDS_MULTIPLEFILES)
{

View file

@ -230,7 +230,6 @@ namespace PlatformNetState
// which are required for LAN queries (PC->Xbox connectivity). The wire protocol still
// uses the VDP packet structure, though.
S32 protocol = IPPROTO_UDP;
bool useVDP = false;
#ifdef TORQUE_DISABLE_PC_CONNECTIVITY
// Xbox uses a VDP (voice/data protocol) socket for networking
protocol = IPPROTO_VDP;
@ -1956,7 +1955,6 @@ void Net::enableMulticast()
if (error == NoError)
{
NetAddress listenAddress;
char listenAddressStr[256];
Net::addressToString(&multicastAddress, listenAddressStr);
Con::printf("Multicast initialized on %s", listenAddressStr);

View file

@ -39,7 +39,7 @@
#import "platform/profiler.h"
#import "cinterface/c_controlInterface.h"
#import "core/volume.h"
#include "console/engineAPI.h"
//TODO: file io still needs some work...
#define MAX_MAC_PATH_LONG 2048
@ -992,25 +992,22 @@ bool Platform::fileTimeToString(FileTime * time, char * string, U32 strLen) { re
//-----------------------------------------------------------------------------
#if defined(TORQUE_DEBUG)
ConsoleFunction(testHasSubdir,void,2,2,"tests platform::hasSubDirectory") {
Con::printf("testing %s",(const char*)argv[1]);
DefineEngineFunction(testHasSubdir,void, (String _dir),,"tests platform::hasSubDirectory") {
Platform::addExcludedDirectory(".svn");
if(Platform::hasSubDirectory(argv[1]))
if(Platform::hasSubDirectory(_dir.c_str()))
Con::printf(" has subdir");
else
Con::printf(" does not have subdir");
}
ConsoleFunction(testDumpDirectories,void,4,4,"testDumpDirectories('path', int depth, bool noBasePath)") {
DefineEngineFunction(testDumpDirectories,void,(String _path, S32 _depth, bool _noBasePath),,"testDumpDirectories('path', int depth, bool noBasePath)") {
Vector<StringTableEntry> paths;
const S32 depth = dAtoi(argv[2]);
const bool noBasePath = dAtob(argv[3]);
Platform::addExcludedDirectory(".svn");
Platform::dumpDirectories(argv[1], paths, depth, noBasePath);
Platform::dumpDirectories(_path.c_str(), paths, _depth, _noBasePath);
Con::printf("Dumping directories starting from %s with depth %i", (const char*)argv[1],depth);
Con::printf("Dumping directories starting from %s with depth %i", _path.c_str(), _depth);
for(Vector<StringTableEntry>::iterator itr = paths.begin(); itr != paths.end(); itr++) {
Con::printf(*itr);
@ -1018,14 +1015,13 @@ ConsoleFunction(testDumpDirectories,void,4,4,"testDumpDirectories('path', int de
}
ConsoleFunction(testDumpPaths, void, 3, 3, "testDumpPaths('path', int depth)")
DefineEngineFunction(testDumpPaths, void, (String _path, S32 _depth),, "testDumpPaths('path', int depth)")
{
Vector<Platform::FileInfo> files;
S32 depth = dAtoi(argv[2]);
Platform::addExcludedDirectory(".svn");
Platform::dumpPath(argv[1], files, depth);
Platform::dumpPath(_path.c_str(), files, _depth);
for(Vector<Platform::FileInfo>::iterator itr = files.begin(); itr != files.end(); itr++) {
Con::printf("%s/%s",itr->pFullPath, itr->pFileName);
@ -1033,15 +1029,15 @@ ConsoleFunction(testDumpPaths, void, 3, 3, "testDumpPaths('path', int depth)")
}
//-----------------------------------------------------------------------------
ConsoleFunction(testFileTouch, bool , 2,2, "testFileTouch('path')")
DefineEngineFunction(testFileTouch, bool , (String _path),, "testFileTouch('path')")
{
return dFileTouch(argv[1]);
return dFileTouch(_path.c_str());
}
ConsoleFunction(testGetFileTimes, bool, 2,2, "testGetFileTimes('path')")
DefineEngineFunction(testGetFileTimes, bool, (String _path),, "testGetFileTimes('path')")
{
FileTime create, modify;
bool ok = Platform::getFileTimes(argv[1], &create, &modify);
bool ok = Platform::getFileTimes(_path.c_str(), &create, &modify);
Con::printf("%s Platform::getFileTimes %i, %i", ok ? "+OK" : "-FAIL", create, modify);
return ok;
}

View file

@ -24,6 +24,7 @@
#import "console/console.h"
#import "math/mMath.h"
#import "core/strings/stringFunctions.h"
#include "console/engineAPI.h"
extern void mInstallLibrary_C();
extern void mInstallLibrary_Vec();
@ -51,7 +52,13 @@ void Platform::setMathControlStateKnown()
}
//--------------------------------------
ConsoleFunction( MathInit, void, 1, 10, "(DETECT|C|SSE)")
DefineEngineStringlyVariadicFunction( mathInit, void, 1, 10, "( ... )"
"@brief Install the math library with specified extensions.\n\n"
"Possible parameters are:\n\n"
" - 'DETECT' Autodetect math lib settings.\n\n"
" - 'C' Enable the C math routines. C routines are always enabled.\n\n"
" - 'SSE' Enable SSE math routines.\n\n"
"@ingroup Math")
{
U32 properties = CPU_PROP_C; // C entensions are always used

View file

@ -27,15 +27,11 @@
#include "sdlInput.h"
#include "platform/platformInput.h"
#include "sdlInputManager.h"
#include "SDL.h"
#ifdef LOG_INPUT
#include <time.h>
#include <stdarg.h>
#endif
// Static class variables:
InputManager* Input::smManager;
InputManager* Input::smManager = NULL;
bool Input::smActive;
U8 Input::smModifierKeys;
bool Input::smLastKeyboardActivated;
@ -43,10 +39,6 @@ bool Input::smLastMouseActivated;
bool Input::smLastJoystickActivated;
InputEvent Input::smInputEvent;
#ifdef LOG_INPUT
static HANDLE gInputLog;
#endif
static void fillAsciiTable() {}
//------------------------------------------------------------------------------
@ -91,24 +83,17 @@ void Input::init()
fillAsciiTable();
Con::printf( "" );
smManager = new SDLInputManager;
if (smManager)
{
SDLInputManager::init();
}
// Set ourselves to participate in per-frame processing.
Process::notify(Input::process, PROCESS_INPUT_ORDER);
}
//------------------------------------------------------------------------------
DefineEngineFunction(isJoystickDetected, bool, (),, "")
{
return(SDL_NumJoysticks() > 0);
}
//------------------------------------------------------------------------------
DefineEngineFunction(getJoystickAxes, const char*, (const char* instance), , "")
{
// TODO SDL
return("");
}
//------------------------------------------------------------------------------
U16 Input::getKeyCode( U16 asciiCode )
{
@ -118,7 +103,7 @@ U16 Input::getKeyCode( U16 asciiCode )
char c[2];
c[0]= asciiCode;
c[1] = NULL;
return KeyMapSDL::getTorqueScanCodeFromSDL( SDL_GetScancodeFromName( c ) );
return KeyMapSDL::getTorqueScanCodeFromSDL( SDL_GetScancodeFromKey( SDL_GetKeyFromName(c) ) );
}
//------------------------------------------------------------------------------
@ -159,6 +144,13 @@ void Input::destroy()
SDL_QuitSubSystem( SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER );
if (smManager)
{
if (smManager->isEnabled())
smManager->disable();
delete smManager;
smManager = NULL;
}
}
//------------------------------------------------------------------------------
@ -186,8 +178,8 @@ void Input::activate()
//ImmReleaseContext( getWin32WindowHandle(), winState.imeHandle );
#endif
if ( !Con::getBoolVariable( "$enableDirectInput" ) )
return;
if (smManager && !smManager->isEnabled())
smManager->enable();
if ( smManager && smManager->isEnabled() && !smActive )
{
@ -199,7 +191,10 @@ void Input::activate()
//------------------------------------------------------------------------------
void Input::deactivate()
{
if ( smManager && smManager->isEnabled() && smActive )
if (smManager && smManager->isEnabled())
smManager->disable();
if (smActive)
{
smActive = false;
Con::printf( "Input deactivated." );
@ -435,4 +430,4 @@ U32 KeyMapSDL::getSDLScanCodeFromTorque(U32 torque)
buildScanCodeArray();
return T3D_SDL[torque];
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,114 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _SDLINPUTMANAGER_H_
#define _SDLINPUTMANAGER_H_
#ifndef _PLATFORMINPUT_H_
#include "platform/platformInput.h"
#endif
#include "SDL.h"
//------------------------------------------------------------------------------
class SDLInputManager : public InputManager
{
enum Constants {
MaxJoysticks = 4, // Up to 4 simultaneous joysticks
MaxControllers = 4, // Up to 4 simultaneous controllers
MaxHats = 2, // Maximum 2 hats per device
MaxBalls = 2, // Maximum 2 trackballs per device
MaxControllerAxes = 7, // From map_StringForControllerAxis[] in SDL_gamecontroller.c
MaxControllerButtons = 16 // From map_StringForControllerButton[] in SDL_gamecontroller.c
};
struct controllerState
{
S32 sdlInstID; // SDL device instance id
U32 torqueInstID; // Torque device instance id
SDL_GameController *inputDevice;
};
struct joystickState
{
S32 sdlInstID; // SDL device instance id
U32 torqueInstID; // Torque device instance id
SDL_Joystick *inputDevice;
U32 numAxes;
U8 lastHatState[MaxHats];
void reset();
};
private:
typedef InputManager Parent;
static S32 map_EventForControllerAxis[MaxControllerAxes];
static S32 map_EventForControllerButton[MaxControllerButtons];
static bool smJoystickEnabled;
static bool smJoystickSplitAxesLR;
static bool smControllerEnabled;
static bool smPOVButtonEvents;
static bool smPOVMaskEvents;
joystickState mJoysticks[MaxJoysticks];
controllerState mControllers[MaxControllers];
// Used to look up a torque instance based on a device inst
HashTable<S32, joystickState*> mJoystickMap;
HashTable<S32, controllerState*> mControllerMap;
bool mJoystickActive;
void deviceConnectedCallback(S32 index);
bool closeControllerByIndex(S32 index);
void closeController(SDL_JoystickID sdlId);
bool closeJoystickByIndex(S32 index);
void closeJoystick(SDL_JoystickID sdlId);
void buildInputEvent(U32 deviceType, U32 deviceInst, InputEventType objType, InputObjectInstances objInst, InputActionType action, S32 iValue);
void buildInputEvent(U32 deviceType, U32 deviceInst, InputEventType objType, InputObjectInstances objInst, InputActionType action, F32 fValue);
void buildHatEvents(U32 deviceType, U32 deviceInst, U8 lastState, U8 currentState, S32 hatIndex);
public:
DECLARE_STATIC_CLASS(SDLInputManager);
public:
SDLInputManager();
bool enable();
void disable();
void process();
void processEvent(SDL_Event &evt);
static void init();
// Console interface:
S32 openJoystick(S32 sdlIndex, S32 requestedTID);
S32 openController(S32 sdlIndex, S32 requestedTID);
void closeDevice(S32 sdlIndex);
S32 getJoystickOpenState(S32 sdlIndex);
void getJoystickTorqueInst(S32 sdlIndex, char* instBuffer);
};
#endif // _SDLINPUTMANAGER_H_

View file

@ -34,13 +34,14 @@
#include <stdarg.h>
#include <fcntl.h>
#include "console/engineAPI.h"
StdConsole *stdConsole = NULL;
ConsoleFunction(enableWinConsole, void, 2, 2, "enableWinConsole(bool);")
DefineEngineFunction(enableWinConsole, void, (bool _enable),, "enableWinConsole(bool);")
{
argc;
if (stdConsole)
stdConsole->enable(dAtob(argv[1]));
stdConsole->enable(_enable);
}
void StdConsole::create()

View file

@ -55,7 +55,7 @@
#include "console/console.h"
#include "core/strings/stringFunctions.h"
#include "util/tempAlloc.h"
#include "cinterface/cinterface.h"
#include "cinterface/c_controlInterface.h"
#include "core/volume.h"
#if defined(__FreeBSD__)

View file

@ -24,7 +24,7 @@
#include "console/console.h"
#include "math/mMath.h"
#include "core/strings/stringFunctions.h"
#include "console/engineAPI.h"
extern void mInstallLibrary_C();
extern void mInstallLibrary_ASM();
@ -35,7 +35,13 @@ extern void mInstall_Library_SSE();
//--------------------------------------
ConsoleFunction( MathInit, void, 1, 10, "(detect|C|FPU|MMX|3DNOW|SSE|...)")
DefineEngineStringlyVariadicFunction( mathInit, void, 1, 10, "( ... )"
"@brief Install the math library with specified extensions.\n\n"
"Possible parameters are:\n\n"
" - 'DETECT' Autodetect math lib settings.\n\n"
" - 'C' Enable the C math routines. C routines are always enabled.\n\n"
" - 'SSE' Enable SSE math routines.\n\n"
"@ingroup Math")
{
U32 properties = CPU_PROP_C; // C entensions are always used

View file

@ -29,7 +29,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "console/engineAPI.h"
#ifndef TORQUE_DEDICATED
#include <SDL.h>
#endif
@ -203,10 +203,7 @@ void Platform::outputDebugString(const char *string, ...)
//-----------------------------------------------------------------------------
// testing function
ConsoleFunction(debug_debugbreak, void, 1, 1, "debug_debugbreak()")
{
Platform::debugBreak();
}
//DefineEngineFunction(debug_debugbreak, void, () , , "debug_debugbreak();");
//-----------------------------------------------------------------------------
void Platform::restartInstance()

View file

@ -1392,7 +1392,7 @@ void SceneContainer::getBinRange( const F32 min, const F32 max, U32& minBin, U32
// This is truly lame, but it can happen. There must be a better way to
// deal with this.
if (minCoord == SceneContainer::csmTotalBinSize)
minCoord = SceneContainer::csmTotalBinSize - 0.01;
minCoord = SceneContainer::csmTotalBinSize - 0.01f;
}
AssertFatal(minCoord >= 0.0 && minCoord < SceneContainer::csmTotalBinSize, "Bad minCoord");
@ -1415,7 +1415,7 @@ void SceneContainer::getBinRange( const F32 min, const F32 max, U32& minBin, U32
// This is truly lame, but it can happen. There must be a better way to
// deal with this.
if (minCoord == SceneContainer::csmTotalBinSize)
minCoord = SceneContainer::csmTotalBinSize - 0.01;
minCoord = SceneContainer::csmTotalBinSize - 0.01f;
}
AssertFatal(minCoord >= 0.0 && minCoord < SceneContainer::csmTotalBinSize, "Bad minCoord");
@ -1426,7 +1426,7 @@ void SceneContainer::getBinRange( const F32 min, const F32 max, U32& minBin, U32
// This is truly lame, but it can happen. There must be a better way to
// deal with this.
if (maxCoord == SceneContainer::csmTotalBinSize)
maxCoord = SceneContainer::csmTotalBinSize - 0.01;
maxCoord = SceneContainer::csmTotalBinSize - 0.01f;
}
AssertFatal(maxCoord >= 0.0 && maxCoord < SceneContainer::csmTotalBinSize, "Bad maxCoord");

View file

@ -93,6 +93,9 @@ ConsoleDocClass( SceneObject,
"@ingroup gameObjects\n"
);
#ifdef TORQUE_TOOLS
extern bool gEditingMission;
#endif
Signal< void( SceneObject* ) > SceneObject::smSceneObjectAdd;
Signal< void( SceneObject* ) > SceneObject::smSceneObjectRemove;
@ -763,8 +766,14 @@ void SceneObject::onCameraScopeQuery( NetConnection* connection, CameraScopeQuer
bool SceneObject::isRenderEnabled() const
{
AbstractClassRep *classRep = getClassRep();
return ( mObjectFlags.test( RenderEnabledFlag ) && classRep->isRenderEnabled() );
#ifdef TORQUE_TOOLS
if (gEditingMission)
{
AbstractClassRep *classRep = getClassRep();
return (mObjectFlags.test(RenderEnabledFlag) && classRep->isRenderEnabled());
}
#endif
return (mObjectFlags.test(RenderEnabledFlag));
}
//-----------------------------------------------------------------------------

View file

@ -35,6 +35,8 @@
#include "renderInstance/renderPassManager.h"
#include "console/engineAPI.h"
#include "T3D/Scene.h"
extern bool gEditingMission;
//--------------------------------------------------------------------------
@ -59,13 +61,13 @@ DefineEngineFunction(pathOnMissionLoadDone, void, (),,
"@ingroup Networking")
{
// Need to load subobjects for all loaded interiors...
SimGroup* pMissionGroup = dynamic_cast<SimGroup*>(Sim::findObject("MissionGroup"));
AssertFatal(pMissionGroup != NULL, "Error, mission done loading and no mission group?");
Scene* scene = Scene::getRootScene();
AssertFatal(scene != NULL, "Error, mission done loading and no scene?");
U32 currStart = 0;
U32 currEnd = 1;
Vector<SimGroup*> groups;
groups.push_back(pMissionGroup);
groups.push_back(scene);
while (true) {
for (U32 i = currStart; i < currEnd; i++) {

View file

@ -36,6 +36,8 @@
#else
# include <al/al.h>
# include <al/alc.h>
# include <AL/alext.h>
# include <AL/efx-presets.h>
#endif
#ifndef ALAPIENTRY
@ -134,6 +136,31 @@ typedef void * (ALCAPIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, con
typedef ALCenum (ALCAPIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
typedef const ALCchar* (ALCAPIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
typedef void (ALCAPIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
///Changes for effects
typedef void (ALAPIENTRY *LPALGENEFFECTS)(ALsizei n, ALuint *effects);
typedef void (ALAPIENTRY *LPALDELETEEFFECTS)(ALsizei n, const ALuint *effects);
typedef ALboolean (ALAPIENTRY *LPALISEFFECT)(ALuint effect);
typedef void (ALAPIENTRY *LPALEFFECTI)(ALuint effect, ALenum param, ALint value);
typedef void (ALAPIENTRY *LPALEFFECTIV)(ALuint effect, ALenum param, const ALint *values);
typedef void (ALAPIENTRY *LPALEFFECTF)(ALuint effect, ALenum param, ALfloat value);
typedef void (ALAPIENTRY *LPALEFFECTFV)(ALuint effect, ALenum param, const ALfloat *values);
typedef void (ALAPIENTRY *LPALGETEFFECTI)(ALuint effect, ALenum param, ALint *value);
typedef void (ALAPIENTRY *LPALGETEFFECTIV)(ALuint effect, ALenum param, ALint *values);
typedef void (ALAPIENTRY *LPALGETEFFECTF)(ALuint effect, ALenum param, ALfloat *value);
typedef void (ALAPIENTRY *LPALGETEFFECTFV)(ALuint effect, ALenum param, ALfloat *values);
typedef void (ALAPIENTRY *LPALRELEASEALEFFECTS)(ALCdevice *device);
typedef void (ALAPIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei n, ALuint *effectslots);
typedef void (ALAPIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei n, const ALuint *effectslots);
typedef ALboolean (ALAPIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint effectslot);
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint effectslot, ALenum param, ALint value);
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint effectslot, ALenum param, const ALint *values);
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint effectslot, ALenum param, ALfloat value);
typedef void (ALAPIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint effectslot, ALenum param, const ALfloat *values);
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint effectslot, ALenum param, ALint *value);
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint effectslot, ALenum param, ALint *values);
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint effectslot, ALenum param, ALfloat *value);
typedef void (ALAPIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint effectslot, ALenum param, ALfloat *values);
typedef void (ALAPIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3);
typedef struct
{
@ -166,6 +193,7 @@ typedef struct
LPALISSOURCE alIsSource;
LPALSOURCEI alSourcei;
LPALSOURCEF alSourcef;
LPALSOURCE3I alSource3i;
LPALSOURCE3F alSource3f;
LPALSOURCEFV alSourcefv;
LPALGETSOURCEI alGetSourcei;
@ -203,6 +231,29 @@ typedef struct
LPALCISEXTENSIONPRESENT alcIsExtensionPresent;
LPALCGETPROCADDRESS alcGetProcAddress;
LPALCGETENUMVALUE alcGetEnumValue;
LPALGENEFFECTS alGenEffects;
LPALDELETEEFFECTS alDeleteEffects;
LPALISEFFECT alIsEffect;
LPALEFFECTI alEffecti;
LPALEFFECTIV alEffectiv;
LPALEFFECTF alEffectf;
LPALEFFECTFV alEffectfv;
LPALGETEFFECTI alGetEffecti;
LPALGETEFFECTIV alGetEffectiv;
LPALGETEFFECTF alGetEffectf;
LPALGETEFFECTFV alGetEffectfv;
LPALRELEASEALEFFECTS alReleaseEffects;
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
} OPENALFNTABLE, *LPOPENALFNTABLE;
#endif

View file

@ -42,16 +42,21 @@ SFXALDevice::SFXALDevice( SFXProvider *provider,
// TODO: The OpenAL device doesn't set the primary buffer
// $pref::SFX::frequency or $pref::SFX::bitrate!
//check auxiliary device sends 4 and add them to the device
ALint attribs[4] = { 0 };
ALCint iSends = 0;
attribs[0] = ALC_MAX_AUXILIARY_SENDS;
attribs[1] = 4;
mDevice = mOpenAL.alcOpenDevice( name );
mOpenAL.alcGetError( mDevice );
if( mDevice )
{
mContext = mOpenAL.alcCreateContext( mDevice, NULL );
mContext = mOpenAL.alcCreateContext( mDevice, attribs );
if( mContext )
mOpenAL.alcMakeContextCurrent( mContext );
mOpenAL.alcGetIntegerv(mDevice, ALC_MAX_AUXILIARY_SENDS, 1, &iSends);
U32 err = mOpenAL.alcGetError( mDevice );
if( err != ALC_NO_ERROR )
@ -78,7 +83,10 @@ SFXALDevice::SFXALDevice( SFXProvider *provider,
SFXALDevice::~SFXALDevice()
{
_releaseAllResources();
///cleanup our effects
mOpenAL.alDeleteAuxiliaryEffectSlots(4, effectSlot);
mOpenAL.alDeleteEffects(2, effect);
///cleanup of effects ends
mOpenAL.alcMakeContextCurrent( NULL );
mOpenAL.alcDestroyContext( mContext );
mOpenAL.alcCloseDevice( mDevice );
@ -145,6 +153,9 @@ void SFXALDevice::setListener( U32 index, const SFXListenerProperties& listener
mOpenAL.alListenerfv( AL_POSITION, pos );
mOpenAL.alListenerfv( AL_VELOCITY, velocity );
mOpenAL.alListenerfv( AL_ORIENTATION, (const F32 *)&tupple[0] );
///Pass a unit size to openal, 1.0 assumes 1 meter to 1 game unit.
///Crucial for air absorbtion calculations.
mOpenAL.alListenerf(AL_METERS_PER_UNIT, 1.0f);
}
//-----------------------------------------------------------------------------
@ -164,7 +175,13 @@ void SFXALDevice::setDistanceModel( SFXDistanceModel model )
if( mUserRolloffFactor != mRolloffFactor )
_setRolloffFactor( mUserRolloffFactor );
break;
/// create a case for our exponential distance model
case SFXDistanceModelExponent:
mOpenAL.alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
if (mUserRolloffFactor != mRolloffFactor)
_setRolloffFactor(mUserRolloffFactor);
break;
default:
AssertWarn( false, "SFXALDevice::setDistanceModel - distance model not implemented" );
}
@ -200,3 +217,109 @@ void SFXALDevice::setRolloffFactor( F32 factor )
mUserRolloffFactor = factor;
}
void SFXALDevice::openSlots()
{
for (uLoop = 0; uLoop < 4; uLoop++)
{
mOpenAL.alGenAuxiliaryEffectSlots(1, &effectSlot[uLoop]);
}
for (uLoop = 0; uLoop < 2; uLoop++)
{
mOpenAL.alGenEffects(1, &effect[uLoop]);
}
///debug string output so we know our slots are open
Platform::outputDebugString("Slots Open");
}
///create reverb effect
void SFXALDevice::setReverb(const SFXReverbProperties& reverb)
{
///output a debug string so we know each time the reverb changes
Platform::outputDebugString("Updated");
///load an efxeaxreverb default and add our values from
///sfxreverbproperties to it
EFXEAXREVERBPROPERTIES prop = EFX_REVERB_PRESET_GENERIC;
prop.flDensity = reverb.flDensity;
prop.flDiffusion = reverb.flDiffusion;
prop.flGain = reverb.flGain;
prop.flGainHF = reverb.flGainHF;
prop.flGainLF = reverb.flGainLF;
prop.flDecayTime = reverb.flDecayTime;
prop.flDecayHFRatio = reverb.flDecayHFRatio;
prop.flDecayLFRatio = reverb.flDecayLFRatio;
prop.flReflectionsGain = reverb.flReflectionsGain;
prop.flReflectionsDelay = reverb.flReflectionsDelay;
prop.flLateReverbGain = reverb.flLateReverbGain;
prop.flLateReverbDelay = reverb.flLateReverbDelay;
prop.flEchoTime = reverb.flEchoTime;
prop.flEchoDepth = reverb.flEchoDepth;
prop.flModulationTime = reverb.flModulationTime;
prop.flModulationDepth = reverb.flModulationDepth;
prop.flAirAbsorptionGainHF = reverb.flAirAbsorptionGainHF;
prop.flHFReference = reverb.flHFReference;
prop.flLFReference = reverb.flLFReference;
prop.flRoomRolloffFactor = reverb.flRoomRolloffFactor;
prop.iDecayHFLimit = reverb.iDecayHFLimit;
if (mOpenAL.alGetEnumValue("AL_EFFECT_EAXREVERB") != 0)
{
/// EAX Reverb is available. Set the EAX effect type
mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
///add our values to the setup of the reverb
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DENSITY, prop.flDensity);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DIFFUSION, prop.flDiffusion);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAIN, prop.flGain);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINHF, prop.flGainHF);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINLF, prop.flGainLF);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_TIME, prop.flDecayTime);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_HFRATIO, prop.flDecayHFRatio);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_LFRATIO, prop.flDecayLFRatio);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_GAIN, prop.flReflectionsGain);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_GAIN, prop.flLateReverbGain);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_TIME, prop.flEchoTime);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_DEPTH, prop.flEchoDepth);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_TIME, prop.flModulationTime);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_DEPTH, prop.flModulationDepth);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_HFREFERENCE, prop.flHFReference);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LFREFERENCE, prop.flLFReference);
mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor);
mOpenAL.alEffecti(effect[0], AL_EAXREVERB_DECAY_HFLIMIT, prop.iDecayHFLimit);
mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]);
Platform::outputDebugString("eax reverb properties set");
}
else
{
/// No EAX Reverb. Set the standard reverb effect
mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_REVERB);
mOpenAL.alEffectf(effect[0], AL_REVERB_DENSITY, prop.flDensity);
mOpenAL.alEffectf(effect[0], AL_REVERB_DIFFUSION, prop.flDiffusion);
mOpenAL.alEffectf(effect[0], AL_REVERB_GAIN, prop.flGain);
mOpenAL.alEffectf(effect[0], AL_REVERB_GAINHF, prop.flGainHF);
mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_TIME, prop.flDecayTime);
mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_HFRATIO, prop.flDecayHFRatio);
mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_GAIN, prop.flReflectionsGain);
mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay);
mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_GAIN, prop.flLateReverbGain);
mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay);
mOpenAL.alEffectf(effect[0], AL_REVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF);
mOpenAL.alEffectf(effect[0], AL_REVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor);
mOpenAL.alEffecti(effect[0], AL_REVERB_DECAY_HFLIMIT, prop.iDecayHFLimit);
mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]);
}
}

View file

@ -85,6 +85,15 @@ class SFXALDevice : public SFXDevice
virtual void setDistanceModel( SFXDistanceModel model );
virtual void setDopplerFactor( F32 factor );
virtual void setRolloffFactor( F32 factor );
//function for openAL to open slots
virtual void openSlots();
//slots
ALuint effectSlot[4] = { 0 };
ALuint effect[2] = { 0 };
ALuint uLoop;
//get values from sfxreverbproperties and pass it to openal device
virtual void setReverb(const SFXReverbProperties& reverb);
virtual void resetReverb() {}
};
#endif // _SFXALDEVICE_H_

View file

@ -118,7 +118,8 @@ void SFXALVoice::_play()
#ifdef DEBUG_SPEW
Platform::outputDebugString( "[SFXALVoice] Starting playback" );
#endif
//send every voice that plays to the alauxiliary slot that has the reverb
mOpenAL.alSource3i(mSourceName, AL_AUXILIARY_SEND_FILTER, 1, 0, AL_FILTER_NULL);
mOpenAL.alSourcePlay( mSourceName );
//WORKAROUND: Adjust play cursor for buggy OAL when resuming playback. Do this after alSourcePlay

View file

@ -439,7 +439,118 @@ ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable
OutputDebugStringA("Failed to retrieve 'alcGetEnumValue' function address\n");
return AL_FALSE;
}
lpOALFnTable->alGenEffects = (LPALGENEFFECTS)GetProcAddress(g_hOpenALDLL, "alGenEffects");
if (lpOALFnTable->alGenEffects == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGenEffects' function address\n");
}
lpOALFnTable->alEffecti = (LPALEFFECTI)GetProcAddress(g_hOpenALDLL, "alEffecti");
if (lpOALFnTable->alEffecti == NULL)
{
OutputDebugStringA("Failed to retrieve 'alEffecti' function address\n");
}
lpOALFnTable->alEffectiv = (LPALEFFECTIV)GetProcAddress(g_hOpenALDLL, "alEffectiv");
if (lpOALFnTable->alEffectiv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alEffectiv' function address\n");
}
lpOALFnTable->alEffectf = (LPALEFFECTF)GetProcAddress(g_hOpenALDLL, "alEffectf");
if (lpOALFnTable->alEffectf == NULL)
{
OutputDebugStringA("Failed to retrieve 'alEffectf' function address\n");
}
lpOALFnTable->alEffectfv = (LPALEFFECTFV)GetProcAddress(g_hOpenALDLL, "alEffectfv");
if (lpOALFnTable->alEffectfv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alEffectfv' function address\n");
}
lpOALFnTable->alGetEffecti = (LPALGETEFFECTI)GetProcAddress(g_hOpenALDLL, "alGetEffecti");
if (lpOALFnTable->alGetEffecti == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetEffecti' function address\n");
}
lpOALFnTable->alGetEffectiv = (LPALGETEFFECTIV)GetProcAddress(g_hOpenALDLL, "alGetEffectiv");
if (lpOALFnTable->alGetEffectiv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetEffectiv' function address\n");
}
lpOALFnTable->alGetEffectf = (LPALGETEFFECTF)GetProcAddress(g_hOpenALDLL, "alGetEffectf");
if (lpOALFnTable->alGetEffectf == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetEffectf' function address\n");
}
lpOALFnTable->alGetEffectfv = (LPALGETEFFECTFV)GetProcAddress(g_hOpenALDLL, "alGetEffectfv");
if (lpOALFnTable->alGetEffectfv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetEffectfv' function address\n");
}
lpOALFnTable->alDeleteEffects = (LPALDELETEEFFECTS)GetProcAddress(g_hOpenALDLL, "alDeleteEffects");
if (lpOALFnTable->alDeleteEffects == NULL)
{
OutputDebugStringA("Failed to retrieve 'alDeleteEffects' function address\n");
}
lpOALFnTable->alIsEffect = (LPALISEFFECT)GetProcAddress(g_hOpenALDLL, "alIsEffect");
if (lpOALFnTable->alIsEffect == NULL)
{
OutputDebugStringA("Failed to retrieve 'alIsEffect' function address\n");
}
lpOALFnTable->alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSlotf");
if (lpOALFnTable->alAuxiliaryEffectSlotf == NULL)
{
OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSlotf' function address\n");
}
lpOALFnTable->alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSlotfv");
if (lpOALFnTable->alAuxiliaryEffectSlotfv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSlotfv' function address\n");
}
lpOALFnTable->alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSloti");
if (lpOALFnTable->alAuxiliaryEffectSloti == NULL)
{
OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSloti' function address\n");
}
lpOALFnTable->alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSlotiv");
if (lpOALFnTable->alAuxiliaryEffectSlotiv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSlotiv' function address\n");
}
lpOALFnTable->alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)GetProcAddress(g_hOpenALDLL, "alIsAuxiliaryEffectSlot");
if (lpOALFnTable->alIsAuxiliaryEffectSlot == NULL)
{
OutputDebugStringA("Failed to retrieve 'alIsAuxiliaryEffectSlot' function address\n");
}
lpOALFnTable->alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)GetProcAddress(g_hOpenALDLL, "alGenAuxiliaryEffectSlots");
if (lpOALFnTable->alGenAuxiliaryEffectSlots == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGenAuxiliaryEffectSlots' function address\n");
}
lpOALFnTable->alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)GetProcAddress(g_hOpenALDLL, "alDeleteAuxiliaryEffectSlots");
if (lpOALFnTable->alDeleteAuxiliaryEffectSlots == NULL)
{
OutputDebugStringA("Failed to retrieve 'alDeleteAuxiliaryEffectSlots' function address\n");
}
lpOALFnTable->alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSlotf");
if (lpOALFnTable->alGetAuxiliaryEffectSlotf == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSlotf' function address\n");
}
lpOALFnTable->alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSlotfv");
if (lpOALFnTable->alGetAuxiliaryEffectSlotfv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSlotfv' function address\n");
}
lpOALFnTable->alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSloti");
if (lpOALFnTable->alGetAuxiliaryEffectSloti == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSloti' function address\n");
}
lpOALFnTable->alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSlotiv");
if (lpOALFnTable->alGetAuxiliaryEffectSlotiv == NULL)
{
OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSlotiv' function address\n");
}
lpOALFnTable->alSource3i = (LPALSOURCE3I)GetProcAddress(g_hOpenALDLL, "alSource3i");
return AL_TRUE;
}

View file

@ -153,6 +153,7 @@ enum SFXDistanceModel
{
SFXDistanceModelLinear, ///< Volume decreases linearly from min to max where it reaches zero.
SFXDistanceModelLogarithmic, ///< Volume halves every min distance steps starting from min distance; attenuation stops at max distance.
SFXDistanceModelExponent, /// exponential falloff for distance attenuation.
};
DefineEnumType( SFXDistanceModel );
@ -187,6 +188,14 @@ inline F32 SFXDistanceAttenuation( SFXDistanceModel model, F32 minDistance, F32
gain = minDistance / ( minDistance + rolloffFactor * ( distance - minDistance ) );
break;
///create exponential distance model
case SFXDistanceModelExponent:
distance = getMax(distance, minDistance);
distance = getMin(distance, maxDistance);
gain = pow((distance / minDistance), (-rolloffFactor));
break;
}
@ -313,97 +322,97 @@ class SFXFormat
/// Reverb environment properties.
///
/// @note A given device may not implement all properties.
///restructure our reverbproperties to match openal
class SFXReverbProperties
{
public:
typedef void Parent;
F32 mEnvSize;
F32 mEnvDiffusion;
S32 mRoom;
S32 mRoomHF;
S32 mRoomLF;
F32 mDecayTime;
F32 mDecayHFRatio;
F32 mDecayLFRatio;
S32 mReflections;
F32 mReflectionsDelay;
F32 mReflectionsPan[ 3 ];
S32 mReverb;
F32 mReverbDelay;
F32 mReverbPan[ 3 ];
F32 mEchoTime;
F32 mEchoDepth;
F32 mModulationTime;
F32 mModulationDepth;
F32 mAirAbsorptionHF;
F32 mHFReference;
F32 mLFReference;
F32 mRoomRolloffFactor;
F32 mDiffusion;
F32 mDensity;
S32 mFlags;
SFXReverbProperties()
: mEnvSize( 7.5f ),
mEnvDiffusion( 1.0f ),
mRoom( -1000 ),
mRoomHF( -100 ),
mRoomLF( 0 ),
mDecayTime( 1.49f ),
mDecayHFRatio( 0.83f ),
mDecayLFRatio( 1.0f ),
mReflections( -2602 ),
mReflectionsDelay( 0.007f ),
mReverb( 200 ),
mReverbDelay( 0.011f ),
mEchoTime( 0.25f ),
mEchoDepth( 0.0f ),
mModulationTime( 0.25f ),
mModulationDepth( 0.0f ),
mAirAbsorptionHF( -5.0f ),
mHFReference( 5000.0f ),
mLFReference( 250.0f ),
mRoomRolloffFactor( 0.0f ),
mDiffusion( 100.0f ),
mDensity( 100.0f ),
mFlags( 0 )
{
mReflectionsPan[ 0 ] = 0.0f;
mReflectionsPan[ 1 ] = 0.0f;
mReflectionsPan[ 2 ] = 0.0f;
mReverbPan[ 0 ] = 0.0f;
mReverbPan[ 1 ] = 0.0f;
mReverbPan[ 2 ] = 0.0f;
}
void validate()
{
mEnvSize = mClampF( mEnvSize, 1.0f, 100.0f );
mEnvDiffusion = mClampF( mEnvDiffusion, 0.0f, 1.0f );
mRoom = mClamp( mRoom, -10000, 0 );
mRoomHF = mClamp( mRoomHF, -10000, 0 );
mRoomLF = mClamp( mRoomLF, -10000, 0 );
mDecayTime = mClampF( mDecayTime, 0.1f, 20.0f );
mDecayHFRatio = mClampF( mDecayHFRatio, 0.1f, 2.0f );
mDecayLFRatio = mClampF( mDecayLFRatio, 0.1f, 2.0f );
mReflections = mClamp( mReflections, -10000, 1000 );
mReflectionsDelay = mClampF( mReflectionsDelay, 0.0f, 0.3f );
mReverb = mClamp( mReverb, -10000, 2000 );
mReverbDelay = mClampF( mReverbDelay, 0.0f, 0.1f );
mEchoTime = mClampF( mEchoTime, 0.075f, 0.25f );
mEchoDepth = mClampF( mEchoDepth, 0.0f, 1.0f );
mModulationTime = mClampF( mModulationTime, 0.04f, 4.0f );
mModulationDepth = mClampF( mModulationDepth, 0.0f, 1.0f );
mAirAbsorptionHF = mClampF( mAirAbsorptionHF, -100.0f, 0.0f );
mHFReference = mClampF( mHFReference, 1000.0f, 20000.0f );
mLFReference = mClampF( mLFReference, 20.0f, 1000.0f );
mRoomRolloffFactor = mClampF( mRoomRolloffFactor, 0.0f, 10.0f );
mDiffusion = mClampF( mDiffusion, 0.0f, 100.0f );
mDensity = mClampF( mDensity, 0.0f, 100.0f );
}
public:
struct Parent;
float flDensity;
float flDiffusion;
float flGain;
float flGainHF;
float flGainLF;
float flDecayTime;
float flDecayHFRatio;
float flDecayLFRatio;
float flReflectionsGain;
float flReflectionsDelay;
float flReflectionsPan[3];
float flLateReverbGain;
float flLateReverbDelay;
float flLateReverbPan[3];
float flEchoTime;
float flEchoDepth;
float flModulationTime;
float flModulationDepth;
float flAirAbsorptionGainHF;
float flHFReference;
float flLFReference;
float flRoomRolloffFactor;
int iDecayHFLimit;
///set our defaults to be the same as no reverb otherwise our reverb
///effects menu sounds
SFXReverbProperties()
{
flDensity = 0.0f;
flDiffusion = 0.0f;
flGain = 0.0f;
flGainHF = 0.0f;
flGainLF = 0.0000f;
flDecayTime = 0.0f;
flDecayHFRatio = 0.0f;
flDecayLFRatio = 0.0f;
flReflectionsGain = 0.0f;
flReflectionsDelay = 0.0f;
flReflectionsPan[3] = 0.0f;
flLateReverbGain = 0.0f;
flLateReverbDelay = 0.0f;
flLateReverbPan[3] = 0.0f;
flEchoTime = 0.0f;
flEchoDepth = 0.0f;
flModulationTime = 0.0f;
flModulationDepth = 0.0f;
flAirAbsorptionGainHF = 0.0f;
flHFReference = 0.0f;
flLFReference = 0.0f;
flRoomRolloffFactor = 0.0f;
iDecayHFLimit = 0;
}
void validate()
{
flDensity = mClampF(flDensity, 0.0f, 1.0f);
flDiffusion = mClampF(flDiffusion, 0.0f, 1.0f);
flGain = mClampF(flGain, 0.0f, 1.0f);
flGainHF = mClampF(flGainHF, 0.0f, 1.0f);
flGainLF = mClampF(flGainLF, 0.0f, 1.0f);
flDecayTime = mClampF(flDecayTime, 0.1f, 20.0f);
flDecayHFRatio = mClampF(flDecayHFRatio, 0.1f, 2.0f);
flDecayLFRatio = mClampF(flDecayLFRatio, 0.1f, 2.0f);
flReflectionsGain = mClampF(flReflectionsGain, 0.0f, 3.16f);
flReflectionsDelay = mClampF(flReflectionsDelay, 0.0f, 0.3f);
flReflectionsPan[0] = mClampF(flReflectionsPan[0], -1.0f, 1.0f);
flReflectionsPan[1] = mClampF(flReflectionsPan[1], -1.0f, 1.0f);
flReflectionsPan[2] = mClampF(flReflectionsPan[2], -1.0f, 1.0f);
flLateReverbGain = mClampF(flLateReverbGain, 0.0f, 10.0f);
flLateReverbDelay = mClampF(flLateReverbDelay, 0.0f, 0.1f);
flLateReverbPan[0] = mClampF(flLateReverbPan[0], -1.0f, 1.0f);
flLateReverbPan[1] = mClampF(flLateReverbPan[1], -1.0f, 1.0f);
flLateReverbPan[2] = mClampF(flLateReverbPan[2], -1.0f, 1.0f);
flEchoTime = mClampF(flEchoTime, 0.075f, 0.25f);
flEchoDepth = mClampF(flEchoDepth, 0.0f, 1.0f);
flModulationTime = mClampF(flModulationTime, 0.04f, 4.0f);
flModulationDepth = mClampF(flModulationDepth, 0.0f, 1.0f);
flAirAbsorptionGainHF = mClampF(flAirAbsorptionGainHF, 0.892f, 1.0f);
flHFReference = mClampF(flHFReference, 1000.0f, 20000.0f);
flLFReference = mClampF(flLFReference, 20.0f, 1000.0f);
flRoomRolloffFactor = mClampF(flRoomRolloffFactor, 0.0f, 10.0f);
iDecayHFLimit = mClampF(iDecayHFLimit, 0, 1);
}
};
@ -415,73 +424,99 @@ class SFXReverbProperties
/// Sound reverb properties.
///
/// @note A given SFX device may not implement all properties.
///not in use by openal yet if u are going to use ambient reverb zones its
///probably best to not have reverb on the sound effect itself.
class SFXSoundReverbProperties
{
public:
typedef void Parent;
S32 mDirect;
S32 mDirectHF;
S32 mRoom;
S32 mRoomHF;
S32 mObstruction;
F32 mObstructionLFRatio;
S32 mOcclusion;
F32 mOcclusionLFRatio;
F32 mOcclusionRoomRatio;
F32 mOcclusionDirectRatio;
S32 mExclusion;
F32 mExclusionLFRatio;
S32 mOutsideVolumeHF;
F32 mDopplerFactor;
F32 mRolloffFactor;
F32 mRoomRolloffFactor;
F32 mAirAbsorptionFactor;
S32 mFlags;
SFXSoundReverbProperties()
: mDirect( 0 ),
mDirectHF( 0 ),
mRoom( 0 ),
mRoomHF( 0 ),
mObstruction( 0 ),
mObstructionLFRatio( 0.0f ),
mOcclusion( 0 ),
mOcclusionLFRatio( 0.25f ),
mOcclusionRoomRatio( 1.5f ),
mOcclusionDirectRatio( 1.0f ),
mExclusion( 0 ),
mExclusionLFRatio( 1.0f ),
mOutsideVolumeHF( 0 ),
mDopplerFactor( 0.0f ),
mRolloffFactor( 0.0f ),
mRoomRolloffFactor( 0.0f ),
mAirAbsorptionFactor( 1.0f ),
mFlags( 0 )
{
}
void validate()
{
mDirect = mClamp( mDirect, -10000, 1000 );
mDirectHF = mClamp( mDirectHF, -10000, 0 );
mRoom = mClamp( mRoom, -10000, 1000 );
mRoomHF = mClamp( mRoomHF, -10000, 0 );
mObstruction = mClamp( mObstruction, -10000, 0 );
mObstructionLFRatio = mClampF( mObstructionLFRatio, 0.0f, 1.0f );
mOcclusion = mClamp( mOcclusion, -10000, 0 );
mOcclusionLFRatio = mClampF( mOcclusionLFRatio, 0.0f, 1.0f );
mOcclusionRoomRatio = mClampF( mOcclusionRoomRatio, 0.0f, 10.0f );
mOcclusionDirectRatio= mClampF( mOcclusionDirectRatio, 0.0f, 10.0f );
mExclusion = mClamp( mExclusion, -10000, 0 );
mExclusionLFRatio = mClampF( mExclusionLFRatio, 0.0f, 1.0f );
mOutsideVolumeHF = mClamp( mOutsideVolumeHF, -10000, 0 );
mDopplerFactor = mClampF( mDopplerFactor, 0.0f, 10.0f );
mRolloffFactor = mClampF( mRolloffFactor, 0.0f, 10.0f );
mRoomRolloffFactor = mClampF( mRoomRolloffFactor, 0.0f, 10.0f );
mAirAbsorptionFactor = mClampF( mAirAbsorptionFactor, 0.0f, 10.0f );
}
public:
typedef void Parent;
float flDensity;
float flDiffusion;
float flGain;
float flGainHF;
float flGainLF;
float flDecayTime;
float flDecayHFRatio;
float flDecayLFRatio;
float flReflectionsGain;
float flReflectionsDelay;
float flReflectionsPan[3];
float flLateReverbGain;
float flLateReverbDelay;
float flLateReverbPan[3];
float flEchoTime;
float flEchoDepth;
float flModulationTime;
float flModulationDepth;
float flAirAbsorptionGainHF;
float flHFReference;
float flLFReference;
float flRoomRolloffFactor;
int iDecayHFLimit;
///Set our defaults to have no reverb
///if you are going to use zone reverbs its
///probably best not to use per-voice reverb
SFXSoundReverbProperties()
{
flDensity = 0.0f;
flDiffusion = 0.0f;
flGain = 0.0f;
flGainHF = 0.0f;
flGainLF = 0.0000f;
flDecayTime = 0.0f;
flDecayHFRatio = 0.0f;
flDecayLFRatio = 0.0f;
flReflectionsGain = 0.0f;
flReflectionsDelay = 0.0f;
flReflectionsPan[3] = 0.0f;
flLateReverbGain = 0.0f;
flLateReverbDelay = 0.0f;
flLateReverbPan[3] = 0.0f;
flEchoTime = 0.0f;
flEchoDepth = 0.0f;
flModulationTime = 0.0f;
flModulationDepth = 0.0f;
flAirAbsorptionGainHF = 0.0f;
flHFReference = 0.0f;
flLFReference = 0.0f;
flRoomRolloffFactor = 0.0f;
iDecayHFLimit = 0;
}
void validate()
{
flDensity = mClampF(flDensity, 0.0f, 1.0f);
flDiffusion = mClampF(flDiffusion, 0.0f, 1.0f);
flGain = mClampF(flGain, 0.0f, 1.0f);
flGainHF = mClampF(flGainHF, 0.0f, 1.0f);
flGainLF = mClampF(flGainLF, 0.0f, 1.0f);
flDecayTime = mClampF(flDecayTime, 0.1f, 20.0f);
flDecayHFRatio = mClampF(flDecayHFRatio, 0.1f, 2.0f);
flDecayLFRatio = mClampF(flDecayLFRatio, 0.1f, 2.0f);
flReflectionsGain = mClampF(flReflectionsGain, 0.0f, 3.16f);
flReflectionsDelay = mClampF(flReflectionsDelay, 0.0f, 0.3f);
flReflectionsPan[0] = mClampF(flReflectionsPan[0], -1.0f, 1.0f);
flReflectionsPan[1] = mClampF(flReflectionsPan[1], -1.0f, 1.0f);
flReflectionsPan[2] = mClampF(flReflectionsPan[2], -1.0f, 1.0f);
flLateReverbGain = mClampF(flLateReverbGain, 0.0f, 10.0f);
flLateReverbDelay = mClampF(flLateReverbDelay, 0.0f, 0.1f);
flLateReverbPan[0] = mClampF(flLateReverbPan[0], -1.0f, 1.0f);
flLateReverbPan[1] = mClampF(flLateReverbPan[1], -1.0f, 1.0f);
flLateReverbPan[2] = mClampF(flLateReverbPan[2], -1.0f, 1.0f);
flEchoTime = mClampF(flEchoTime, 0.075f, 0.25f);
flEchoDepth = mClampF(flEchoDepth, 0.0f, 1.0f);
flModulationTime = mClampF(flModulationTime, 0.04f, 4.0f);
flModulationDepth = mClampF(flModulationDepth, 0.0f, 1.0f);
flAirAbsorptionGainHF = mClampF(flAirAbsorptionGainHF, 0.892f, 1.0f);
flHFReference = mClampF(flHFReference, 1000.0f, 20000.0f);
flLFReference = mClampF(flLFReference, 20.0f, 1000.0f);
flRoomRolloffFactor = mClampF(flRoomRolloffFactor, 0.0f, 10.0f);
iDecayHFLimit = mClampF(iDecayHFLimit, 0, 1);
}
};

View file

@ -389,91 +389,55 @@ void SFXDescription::initPersistFields()
addGroup( "Reverb" );
addField( "useCustomReverb", TypeBool, Offset( mUseReverb, SFXDescription ),
"If true, use the reverb properties defined here on sounds.\n"
"By default, sounds will be assigned a generic reverb profile. By setting this flag to true, "
"a custom reverb setup can be defined using the \"Reverb\" properties that will then be assigned "
"to sounds playing with the description.\n\n"
"@ref SFX_reverb" );
addField( "reverbDirect", TypeS32, Offset( mReverb.mDirect, SFXDescription ),
"Direct path level (at low and mid frequencies).\n"
"@note SUPPORTED: EAX/I3DL2/FMODSFX\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbDirectHF", TypeS32, Offset( mReverb.mDirectHF, SFXDescription ),
"Relative direct path level at high frequencies.\n"
"@note SUPPORTED: EAX/I3DL2\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbRoom", TypeS32, Offset( mReverb.mRoom, SFXDescription ),
"Room effect level (at low and mid frequencies).\n"
"@note SUPPORTED: EAX/I3DL2/FMODSFX\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbRoomHF", TypeS32, Offset( mReverb.mRoomHF, SFXDescription ),
"Relative room effect level at high frequencies.\n"
"@note SUPPORTED: EAX/I3DL2\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbObstruction", TypeS32, Offset( mReverb.mObstruction, SFXDescription ),
"Main obstruction control (attenuation at high frequencies).\n"
"@note SUPPORTED: EAX/I3DL2\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbObstructionLFRatio", TypeF32, Offset( mReverb.mObstructionLFRatio, SFXDescription ),
"Obstruction low-frequency level re. main control.\n"
"@note SUPPORTED: EAX/I3DL2\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbOcclusion", TypeS32, Offset( mReverb.mOcclusion, SFXDescription ),
"Main occlusion control (attenuation at high frequencies)."
"@note SUPPORTED: EAX/I3DL2\n\n"
"\n@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbOcclusionLFRatio", TypeF32, Offset( mReverb.mOcclusionLFRatio, SFXDescription ),
"Occlusion low-frequency level re. main control.\n"
"@note SUPPORTED: EAX/I3DL2\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbOcclusionRoomRatio", TypeF32, Offset( mReverb.mOcclusionRoomRatio, SFXDescription ),
"Relative occlusion control for room effect.\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbOcclusionDirectRatio",TypeF32, Offset( mReverb.mOcclusionDirectRatio, SFXDescription ),
"Relative occlusion control for direct path.\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbExclusion", TypeS32, Offset( mReverb.mExclusion, SFXDescription ),
"Main exclusion control (attenuation at high frequencies).\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbExclusionLFRatio", TypeF32, Offset( mReverb.mExclusionLFRatio, SFXDescription ),
"Exclusion low-frequency level re. main control.\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbOutsideVolumeHF", TypeS32, Offset( mReverb.mOutsideVolumeHF, SFXDescription ),
"Outside sound cone level at high frequencies.\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbDopplerFactor", TypeF32, Offset( mReverb.mDopplerFactor, SFXDescription ),
"Per-source doppler factor.\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbReverbRolloffFactor", TypeF32, Offset( mReverb.mRolloffFactor, SFXDescription ),
"Per-source logarithmic falloff factor.\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbRoomRolloffFactor", TypeF32, Offset( mReverb.mRoomRolloffFactor, SFXDescription ),
"Room effect falloff factor.\n"
"@note SUPPORTED: EAX/I3DL2\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbAirAbsorptionFactor", TypeF32, Offset( mReverb.mAirAbsorptionFactor, SFXDescription ),
"Multiplies SFXEnvironment::airAbsorptionHR.\n"
"@note SUPPORTED: EAX Only\n\n"
"@see http://www.atc.creative.com/algorithms/eax20.pdf" );
addField( "reverbFlags", TypeS32, Offset( mReverb.mFlags, SFXDescription ),
"Bitfield combination of per-sound reverb flags.\n"
"@see REVERB_DIRECTHFAUTO\n"
"@see REVERB_ROOMAUTO\n"
"@see REVERB_ROOMHFAUTO\n"
"@see REVERB_INSTANCE0\n"
"@see REVERB_INSTANCE1\n"
"@see REVERB_INSTANCE2\n"
"@see REVERB_INSTANCE3\n" );
endGroup( "Reverb" );
addField("useCustomReverb", TypeBool, Offset(mUseReverb, SFXDescription),
"If true, use the reverb properties defined here on sounds.\n"
"By default, sounds will be assigned a generic reverb profile. By setting this flag to true, "
"a custom reverb setup can be defined using the \"Reverb\" properties that will then be assigned "
"to sounds playing with the description.\n\n"
"@ref SFX_reverb");
addField("reverbDensity", TypeF32, Offset(mReverb.flDensity, SFXDescription),
"Density of reverb environment.");
addField("reverbDiffusion", TypeF32, Offset(mReverb.flDiffusion, SFXDescription),
"Environment diffusion.");
addField("reverbGain", TypeF32, Offset(mReverb.flGain, SFXDescription),
"Reverb Gain Level.");
addField("reverbGainHF", TypeF32, Offset(mReverb.flGainHF, SFXDescription),
"Reverb Gain to high frequencies");
addField("reverbGainLF", TypeF32, Offset(mReverb.flGainLF, SFXDescription),
"Reverb Gain to high frequencies");
addField("reverbDecayTime", TypeF32, Offset(mReverb.flDecayTime, SFXDescription),
"Decay time for the reverb.");
addField("reverbDecayHFRatio", TypeF32, Offset(mReverb.flDecayHFRatio, SFXDescription),
"High frequency decay time ratio.");
addField("reverbDecayLFRatio", TypeF32, Offset(mReverb.flDecayLFRatio, SFXDescription),
"High frequency decay time ratio.");
addField("reflectionsGain", TypeF32, Offset(mReverb.flReflectionsGain, SFXDescription),
"Reflection Gain.");
addField("reflectionDelay", TypeF32, Offset(mReverb.flReflectionsDelay, SFXDescription),
"How long to delay reflections.");
addField("lateReverbGain", TypeF32, Offset(mReverb.flLateReverbGain, SFXDescription),
"Late reverb gain amount.");
addField("lateReverbDelay", TypeF32, Offset(mReverb.flLateReverbDelay, SFXDescription),
"Late reverb delay time.");
addField("reverbEchoTime", TypeF32, Offset(mReverb.flEchoTime, SFXDescription),
"Reverb echo time.");
addField("reverbEchoDepth", TypeF32, Offset(mReverb.flEchoDepth, SFXDescription),
"Reverb echo depth.");
addField("reverbModTime", TypeF32, Offset(mReverb.flModulationTime, SFXDescription),
"Reverb Modulation time.");
addField("reverbModTime", TypeF32, Offset(mReverb.flModulationDepth, SFXDescription),
"Reverb Modulation time.");
addField("airAbsorbtionGainHF", TypeF32, Offset(mReverb.flAirAbsorptionGainHF, SFXDescription),
"High Frequency air absorbtion");
addField("reverbHFRef", TypeF32, Offset(mReverb.flHFReference, SFXDescription),
"Reverb High Frequency Reference.");
addField("reverbLFRef", TypeF32, Offset(mReverb.flLFReference, SFXDescription),
"Reverb Low Frequency Reference.");
addField("roomRolloffFactor", TypeF32, Offset(mReverb.flRoomRolloffFactor, SFXDescription),
"Rolloff factor for reverb.");
addField("decayHFLimit", TypeS32, Offset(mReverb.iDecayHFLimit, SFXDescription),
"High Frequency decay limit.");
endGroup("Reverb");
Parent::initPersistFields();
}
@ -570,24 +534,27 @@ void SFXDescription::packData( BitStream *stream )
if( mUseReverb )
{
stream->writeRangedS32( mReverb.mDirect, -10000, 1000 );
stream->writeRangedS32( mReverb.mDirectHF, -10000, 0 );
stream->writeRangedS32( mReverb.mRoom, -10000, 1000 );
stream->writeRangedS32( mReverb.mRoomHF, -10000, 0 );
stream->writeRangedS32( mReverb.mObstruction, -10000, 0 );
stream->writeRangedF32( mReverb.mObstructionLFRatio, 0.0, 1.0, 7 );
stream->writeRangedS32( mReverb.mOcclusion, -10000, 0 );
stream->writeRangedF32( mReverb.mOcclusionLFRatio, 0.0, 1.0, 7 );
stream->writeRangedF32( mReverb.mOcclusionRoomRatio, 0.0, 10.0, 7 );
stream->writeRangedF32( mReverb.mOcclusionDirectRatio, 0.0, 10.0, 7 );
stream->writeRangedS32( mReverb.mExclusion, -10000, 0 );
stream->writeRangedF32( mReverb.mExclusionLFRatio, 0.0, 1.0, 7 );
stream->writeRangedS32( mReverb.mOutsideVolumeHF, -10000, 0 );
stream->writeRangedF32( mReverb.mDopplerFactor, 0.0, 10.0, 7 );
stream->writeRangedF32( mReverb.mRolloffFactor, 0.0, 10.0, 7 );
stream->writeRangedF32( mReverb.mRoomRolloffFactor, 0.0, 10.0, 7 );
stream->writeRangedF32( mReverb.mAirAbsorptionFactor, 0.0, 10.0, 7 );
stream->writeInt( mReverb.mFlags, 6 );
stream->write(mReverb.flDensity);
stream->write(mReverb.flDiffusion);
stream->write(mReverb.flGain);
stream->write(mReverb.flGainHF);
stream->write(mReverb.flGainLF);
stream->write(mReverb.flDecayTime);
stream->write(mReverb.flDecayHFRatio);
stream->write(mReverb.flDecayLFRatio);
stream->write(mReverb.flReflectionsGain);
stream->write(mReverb.flReflectionsDelay);
stream->write(mReverb.flLateReverbGain);
stream->write(mReverb.flLateReverbDelay);
stream->write(mReverb.flEchoTime);
stream->write(mReverb.flEchoDepth);
stream->write(mReverb.flModulationTime);
stream->write(mReverb.flModulationDepth);
stream->write(mReverb.flAirAbsorptionGainHF);
stream->write(mReverb.flHFReference);
stream->write(mReverb.flLFReference);
stream->write(mReverb.flRoomRolloffFactor);
stream->write(mReverb.iDecayHFLimit);
}
}
@ -640,24 +607,27 @@ void SFXDescription::unpackData( BitStream *stream )
if( mUseReverb )
{
mReverb.mDirect = stream->readRangedS32( -10000, 1000 );
mReverb.mDirectHF = stream->readRangedS32( -10000, 0 );
mReverb.mRoom = stream->readRangedS32( -10000, 1000 );
mReverb.mRoomHF = stream->readRangedS32( -10000, 0 );
mReverb.mObstruction = stream->readRangedS32( -10000, 0 );
mReverb.mObstructionLFRatio = stream->readRangedF32( 0.0, 1.0, 7 );
mReverb.mOcclusion = stream->readRangedS32( -10000, 0 );
mReverb.mOcclusionLFRatio = stream->readRangedF32( 0.0, 1.0, 7 );
mReverb.mOcclusionRoomRatio = stream->readRangedF32( 0.0, 10.0, 7 );
mReverb.mOcclusionDirectRatio = stream->readRangedF32( 0.0, 10.0, 7 );
mReverb.mExclusion = stream->readRangedS32( -10000, 0 );
mReverb.mExclusionLFRatio = stream->readRangedF32( 0.0, 1.0, 7 );
mReverb.mOutsideVolumeHF = stream->readRangedS32( -10000, 0 );
mReverb.mDopplerFactor = stream->readRangedF32( 0.0, 10.0, 7 );
mReverb.mRolloffFactor = stream->readRangedF32( 0.0, 10.0, 7 );
mReverb.mRoomRolloffFactor = stream->readRangedF32( 0.0, 10.0, 7 );
mReverb.mAirAbsorptionFactor = stream->readRangedF32( 0.0, 10.0, 7 );
mReverb.mFlags = stream->readInt( 6 );
stream->read(&mReverb.flDensity);
stream->read(&mReverb.flDiffusion);
stream->read(&mReverb.flGain);
stream->read(&mReverb.flGainHF);
stream->read(&mReverb.flGainLF);
stream->read(&mReverb.flDecayTime);
stream->read(&mReverb.flDecayHFRatio);
stream->read(&mReverb.flDecayLFRatio);
stream->read(&mReverb.flReflectionsGain);
stream->read(&mReverb.flReflectionsDelay);
stream->read(&mReverb.flLateReverbGain);
stream->read(&mReverb.flLateReverbDelay);
stream->read(&mReverb.flEchoTime);
stream->read(&mReverb.flEchoDepth);
stream->read(&mReverb.flModulationTime);
stream->read(&mReverb.flModulationDepth);
stream->read(&mReverb.flAirAbsorptionGainHF);
stream->read(&mReverb.flHFReference);
stream->read(&mReverb.flLFReference);
stream->read(&mReverb.flRoomRolloffFactor);
stream->read(&mReverb.iDecayHFLimit);
}
}

View file

@ -178,6 +178,9 @@ public:
/// Set the rolloff scale factor for distance attenuation of 3D sounds.
virtual void setRolloffFactor( F32 factor ) {}
/// send empty function to all sfxdevices
virtual void openSlots() {}
/// Set the global reverb environment.
virtual void setReverb( const SFXReverbProperties& reverb ) {}

View file

@ -144,70 +144,53 @@ void SFXEnvironment::initPersistFields()
{
addGroup( "Reverb" );
addField( "envSize", TypeF32, Offset( mReverb.mEnvSize, SFXEnvironment ),
"Environment size in meters." );
addField( "envDiffusion", TypeF32, Offset( mReverb.mEnvDiffusion, SFXEnvironment ),
"Environment diffusion." );
addField( "room", TypeS32, Offset( mReverb.mRoom, SFXEnvironment ),
"Room effect level at mid-frequencies." );
addField( "roomHF", TypeS32, Offset( mReverb.mRoomHF, SFXEnvironment ),
"Relative room effect level at high frequencies." );
addField( "roomLF", TypeS32, Offset( mReverb.mRoomLF, SFXEnvironment ),
"Relative room effect level at low frequencies." );
addField( "decayTime", TypeF32, Offset( mReverb.mDecayTime, SFXEnvironment ),
"Reverberation decay time at mid frequencies." );
addField( "decayHFRatio", TypeF32, Offset( mReverb.mDecayHFRatio, SFXEnvironment ),
"High-frequency to mid-frequency decay time ratio." );
addField( "decayLFRatio", TypeF32, Offset( mReverb.mDecayLFRatio, SFXEnvironment ),
"Low-frequency to mid-frequency decay time ratio." );
addField( "reflections", TypeS32, Offset( mReverb.mReflections, SFXEnvironment ),
"Early reflections level relative to room effect." );
addField( "reflectionsDelay", TypeF32, Offset( mReverb.mReflectionsDelay, SFXEnvironment ),
"Initial reflection delay time." );
addField( "reflectionsPan", TypeF32, Offset( mReverb.mReflectionsPan, SFXEnvironment ), 3,
"Early reflections panning vector." );
addField( "reverb", TypeS32, Offset( mReverb.mReverb, SFXEnvironment ),
"Late reverberation level relative to room effect." );
addField( "reverbDelay", TypeF32, Offset( mReverb.mReverbDelay, SFXEnvironment ),
"Late reverberation delay time relative to initial reflection." );
addField( "reverbPan", TypeF32, Offset( mReverb.mReverbPan, SFXEnvironment ), 3,
"Late reverberation panning vector." );
addField( "echoTime", TypeF32, Offset( mReverb.mEchoTime, SFXEnvironment ),
"Echo time." );
addField( "echoDepth", TypeF32, Offset( mReverb.mEchoDepth, SFXEnvironment ),
"Echo depth." );
addField( "modulationTime", TypeF32, Offset( mReverb.mModulationTime, SFXEnvironment ),
"Modulation time." );
addField( "modulationDepth", TypeF32, Offset( mReverb.mModulationDepth, SFXEnvironment ),
"Modulation depth." );
addField( "airAbsorptionHF", TypeF32, Offset( mReverb.mAirAbsorptionHF, SFXEnvironment ),
"Change in level per meter at high frequencies." );
addField( "HFReference", TypeF32, Offset( mReverb.mHFReference, SFXEnvironment ),
"Reference high frequency in Hertz." );
addField( "LFReference", TypeF32, Offset( mReverb.mLFReference, SFXEnvironment ),
"Reference low frequency in Hertz." );
addField( "roomRolloffFactor", TypeF32, Offset( mReverb.mRoomRolloffFactor, SFXEnvironment ),
"Logarithmic distance attenuation rolloff scale factor for reverb room size effect." );
addField( "diffusion", TypeF32, Offset( mReverb.mDiffusion, SFXEnvironment ),
"Value that controls the echo density in the late reverberation decay." );
addField( "density", TypeF32, Offset( mReverb.mDensity, SFXEnvironment ),
"Value that controls the modal density in the late reverberation decay." );
addField( "flags", TypeS32, Offset( mReverb.mFlags, SFXEnvironment ),
"A bitfield of reverb flags.\n"
"@see REVERB_DECAYTIMESCALE\n"
"@see REVERB_REFLECTIONSSCALE\n"
"@see REVERB_REFLECTIONSDELAYSCALE\n"
"@see REVERB_REVERBSCALE\n"
"@see REVERB_REVERBDELAYSCALE\n"
"@see REVERB_DECAYHFLIMIT\n"
"@see REVERB_ECHOTIMESCALE\n"
"@see REVERB_MODULATIONTIMESCALE\n"
"@see REVERB_CORE0\n"
"@see REVERB_CORE1\n"
"@see REVERB_HIGHQUALITYREVERB\n"
"@see REVERB_HIGHQUALITYDPL2REVERB\n" );
endGroup( "Reverb" );
addField("reverbDensity", TypeF32, Offset(mReverb.flDensity, SFXEnvironment),
"Density of reverb environment.");
addField("reverbDiffusion", TypeF32, Offset(mReverb.flDiffusion, SFXEnvironment),
"Environment diffusion.");
addField("reverbGain", TypeF32, Offset(mReverb.flGain, SFXEnvironment),
"Reverb Gain Level.");
addField("reverbGainHF", TypeF32, Offset(mReverb.flGainHF, SFXEnvironment),
"Reverb Gain to high frequencies");
addField("reverbGainLF", TypeF32, Offset(mReverb.flGainLF, SFXEnvironment),
"Reverb Gain to high frequencies");
addField("reverbDecayTime", TypeF32, Offset(mReverb.flDecayTime, SFXEnvironment),
"Decay time for the reverb.");
addField("reverbDecayHFRatio", TypeF32, Offset(mReverb.flDecayHFRatio, SFXEnvironment),
"High frequency decay time ratio.");
addField("reverbDecayLFRatio", TypeF32, Offset(mReverb.flDecayLFRatio, SFXEnvironment),
"High frequency decay time ratio.");
addField("reflectionsGain", TypeF32, Offset(mReverb.flReflectionsGain, SFXEnvironment),
"Reflection Gain.");
addField("reflectionDelay", TypeF32, Offset(mReverb.flReflectionsDelay, SFXEnvironment),
"How long to delay reflections.");
addField("reflectionsPan", TypeF32, Offset(mReverb.flReflectionsPan, SFXEnvironment), 3,
"Reflection reverberation panning vector.");
addField("lateReverbGain", TypeF32, Offset(mReverb.flLateReverbGain, SFXEnvironment),
"Late reverb gain amount.");
addField("lateReverbDelay", TypeF32, Offset(mReverb.flLateReverbDelay, SFXEnvironment),
"Late reverb delay time.");
addField("lateReverbPan", TypeF32, Offset(mReverb.flLateReverbPan, SFXEnvironment), 3,
"Late reverberation panning vector.");
addField("reverbEchoTime", TypeF32, Offset(mReverb.flEchoTime, SFXEnvironment),
"Reverb echo time.");
addField("reverbEchoDepth", TypeF32, Offset(mReverb.flEchoDepth, SFXEnvironment),
"Reverb echo depth.");
addField("reverbModTime", TypeF32, Offset(mReverb.flModulationTime, SFXEnvironment),
"Reverb Modulation time.");
addField("reverbModDepth", TypeF32, Offset(mReverb.flModulationDepth, SFXEnvironment),
"Reverb Modulation time.");
addField("airAbsorbtionGainHF", TypeF32, Offset(mReverb.flAirAbsorptionGainHF, SFXEnvironment),
"High Frequency air absorbtion");
addField("reverbHFRef", TypeF32, Offset(mReverb.flHFReference, SFXEnvironment),
"Reverb High Frequency Reference.");
addField("reverbLFRef", TypeF32, Offset(mReverb.flLFReference, SFXEnvironment),
"Reverb Low Frequency Reference.");
addField("roomRolloffFactor", TypeF32, Offset(mReverb.flRoomRolloffFactor, SFXEnvironment),
"Rolloff factor for reverb.");
addField("decayHFLimit", TypeS32, Offset(mReverb.iDecayHFLimit, SFXEnvironment),
"High Frequency decay limit.");
endGroup("Reverb");
Parent::initPersistFields();
}
@ -257,35 +240,27 @@ void SFXEnvironment::packData( BitStream* stream )
{
Parent::packData( stream );
stream->write( mReverb.mEnvSize );
stream->write( mReverb.mEnvDiffusion );
stream->write( mReverb.mRoom );
stream->write( mReverb.mRoomHF );
stream->write( mReverb.mRoomLF );
stream->write( mReverb.mDecayTime );
stream->write( mReverb.mDecayHFRatio );
stream->write( mReverb.mDecayLFRatio );
stream->write( mReverb.mReflections );
stream->write( mReverb.mReflectionsDelay );
stream->write( mReverb.mReflectionsPan[ 0 ] );
stream->write( mReverb.mReflectionsPan[ 1 ] );
stream->write( mReverb.mReflectionsPan[ 2 ] );
stream->write( mReverb.mReverb );
stream->write( mReverb.mReverbDelay );
stream->write( mReverb.mReverbPan[ 0 ] );
stream->write( mReverb.mReverbPan[ 1 ] );
stream->write( mReverb.mReverbPan[ 2 ] );
stream->write( mReverb.mEchoTime );
stream->write( mReverb.mEchoDepth );
stream->write( mReverb.mModulationTime );
stream->write( mReverb.mModulationDepth );
stream->write( mReverb.mAirAbsorptionHF );
stream->write( mReverb.mHFReference );
stream->write( mReverb.mLFReference );
stream->write( mReverb.mRoomRolloffFactor );
stream->write( mReverb.mDiffusion );
stream->write( mReverb.mDensity );
stream->write( mReverb.mFlags );
stream->write(mReverb.flDensity);
stream->write(mReverb.flDiffusion);
stream->write(mReverb.flGain);
stream->write(mReverb.flGainHF);
stream->write(mReverb.flGainLF);
stream->write(mReverb.flDecayTime);
stream->write(mReverb.flDecayHFRatio);
stream->write(mReverb.flDecayLFRatio);
stream->write(mReverb.flReflectionsGain);
stream->write(mReverb.flReflectionsDelay);
stream->write(mReverb.flLateReverbGain);
stream->write(mReverb.flLateReverbDelay);
stream->write(mReverb.flEchoTime);
stream->write(mReverb.flEchoDepth);
stream->write(mReverb.flModulationTime);
stream->write(mReverb.flModulationDepth);
stream->write(mReverb.flAirAbsorptionGainHF);
stream->write(mReverb.flHFReference);
stream->write(mReverb.flLFReference);
stream->write(mReverb.flRoomRolloffFactor);
stream->write(mReverb.iDecayHFLimit);
}
//-----------------------------------------------------------------------------
@ -294,33 +269,25 @@ void SFXEnvironment::unpackData( BitStream* stream )
{
Parent::unpackData( stream );
stream->read( &mReverb.mEnvSize );
stream->read( &mReverb.mEnvDiffusion );
stream->read( &mReverb.mRoom );
stream->read( &mReverb.mRoomHF );
stream->read( &mReverb.mRoomLF );
stream->read( &mReverb.mDecayTime );
stream->read( &mReverb.mDecayHFRatio );
stream->read( &mReverb.mDecayLFRatio );
stream->read( &mReverb.mReflections );
stream->read( &mReverb.mReflectionsDelay );
stream->read( &mReverb.mReflectionsPan[ 0 ] );
stream->read( &mReverb.mReflectionsPan[ 1 ] );
stream->read( &mReverb.mReflectionsPan[ 2 ] );
stream->read( &mReverb.mReverb );
stream->read( &mReverb.mReverbDelay );
stream->read( &mReverb.mReverbPan[ 0 ] );
stream->read( &mReverb.mReverbPan[ 1 ] );
stream->read( &mReverb.mReverbPan[ 2 ] );
stream->read( &mReverb.mEchoTime );
stream->read( &mReverb.mEchoDepth );
stream->read( &mReverb.mModulationTime );
stream->read( &mReverb.mModulationDepth );
stream->read( &mReverb.mAirAbsorptionHF );
stream->read( &mReverb.mHFReference );
stream->read( &mReverb.mLFReference );
stream->read( &mReverb.mRoomRolloffFactor );
stream->read( &mReverb.mDiffusion );
stream->read( &mReverb.mDensity );
stream->read( &mReverb.mFlags );
stream->read(&mReverb.flDensity);
stream->read(&mReverb.flDiffusion);
stream->read(&mReverb.flGain);
stream->read(&mReverb.flGainHF);
stream->read(&mReverb.flGainLF);
stream->read(&mReverb.flDecayTime);
stream->read(&mReverb.flDecayHFRatio);
stream->read(&mReverb.flDecayLFRatio);
stream->read(&mReverb.flReflectionsGain);
stream->read(&mReverb.flReflectionsDelay);
stream->read(&mReverb.flLateReverbGain);
stream->read(&mReverb.flLateReverbDelay);
stream->read(&mReverb.flEchoTime);
stream->read(&mReverb.flEchoDepth);
stream->read(&mReverb.flModulationTime);
stream->read(&mReverb.flModulationDepth);
stream->read(&mReverb.flAirAbsorptionGainHF);
stream->read(&mReverb.flHFReference);
stream->read(&mReverb.flLFReference);
stream->read(&mReverb.flRoomRolloffFactor);
stream->read(&mReverb.iDecayHFLimit);
}

View file

@ -81,6 +81,7 @@ SFXSound::SFXSound( SFXProfile *profile, SFXDescription* desc )
: Parent( profile, desc ),
mVoice( NULL )
{
mSetPositionValue = 0;
}
//-----------------------------------------------------------------------------
@ -411,6 +412,9 @@ void SFXSound::_play()
Platform::outputDebugString( "[SFXSound] virtualizing playback of source '%i'", getId() );
#endif
}
if(getPosition() != mSetPositionValue)
setPosition(mSetPositionValue);
mSetPositionValue = 0; //Non looping sounds need this to reset.
}
//-----------------------------------------------------------------------------
@ -421,6 +425,7 @@ void SFXSound::_stop()
if( mVoice )
mVoice->stop();
mSetPositionValue = 0;
}
//-----------------------------------------------------------------------------
@ -431,6 +436,7 @@ void SFXSound::_pause()
if( mVoice )
mVoice->pause();
mSetPositionValue = getPosition();
}
//-----------------------------------------------------------------------------
@ -511,6 +517,8 @@ void SFXSound::_updatePriority()
U32 SFXSound::getPosition() const
{
if( getLastStatus() == SFXStatusStopped)
return mSetPositionValue;
if( mVoice )
return mVoice->getFormat().getDuration( mVoice->getPosition() );
else
@ -522,6 +530,8 @@ U32 SFXSound::getPosition() const
void SFXSound::setPosition( U32 ms )
{
AssertFatal( ms < getDuration(), "SFXSound::setPosition() - position out of range" );
mSetPositionValue = ms;
if( mVoice )
mVoice->setPosition( mVoice->getFormat().getSampleCount( ms ) );
else
@ -693,8 +703,9 @@ DefineEngineMethod( SFXSound, setPosition, void, ( F32 position ),,
"playback will resume at the given position when play() is called.\n\n"
"@param position The new position of the play cursor (in seconds).\n" )
{
if( position >= 0 && position <= object->getDuration() )
object->setPosition( position * 1000.0f );
position *= 1000.0f;
if( position >= 0 && position < object->getDuration() )
object->setPosition( position );
}
//-----------------------------------------------------------------------------

View file

@ -81,6 +81,9 @@ class SFXSound : public SFXSource,
/// _initBuffer() used for managing virtual sources.
U32 mDuration;
///Used for setPosition (time in miliseconds)
U32 mSetPositionValue;
/// Create a new voice for this source.
bool _allocVoice( SFXDevice* device );

View file

@ -94,6 +94,9 @@ ImplementEnumType( SFXDistanceModel,
{ SFXDistanceModelLogarithmic, "Logarithmic",
"Volume attenuates logarithmically starting from the reference distance and halving every reference distance step from there on. "
"Attenuation stops at max distance but volume won't reach zero." },
{ SFXDistanceModelExponent, "Exponential",
"Volume attenuates exponentially starting from the reference distance and attenuating every reference distance step by the rolloff factor. "
"Attenuation stops at max distance but volume won't reach zero." },
EndImplementEnumType;
ImplementEnumType( SFXChannel,
@ -473,6 +476,9 @@ bool SFXSystem::createDevice( const String& providerName, const String& deviceNa
mDevice->setDistanceModel( mDistanceModel );
mDevice->setDopplerFactor( mDopplerFactor );
mDevice->setRolloffFactor( mRolloffFactor );
//OpenAL requires slots for effects, this creates an empty function
//that will run when a sfxdevice is created.
mDevice->openSlots();
mDevice->setReverb( mReverb );
// Signal system.

Some files were not shown because too many files have changed in this diff Show more