From 213b7020a3c94d6708489875fd467330e4f9dd7b Mon Sep 17 00:00:00 2001 From: yourarcade Date: Sun, 25 Sep 2016 16:53:00 -0700 Subject: [PATCH 01/50] Allow the gui to render for both vehicles and vehicle-mounted players. --- Engine/source/T3D/vehicles/guiSpeedometer.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Engine/source/T3D/vehicles/guiSpeedometer.cpp b/Engine/source/T3D/vehicles/guiSpeedometer.cpp index efd30ef27..79f3f8bdb 100644 --- a/Engine/source/T3D/vehicles/guiSpeedometer.cpp +++ b/Engine/source/T3D/vehicles/guiSpeedometer.cpp @@ -147,22 +147,29 @@ void GuiSpeedometerHud::initPersistFields() //----------------------------------------------------------------------------- /** Gui onRender method. - Renders a health bar with filled background and border. + Renders an analog speedometer needle over a specified bitmap background. */ void GuiSpeedometerHud::onRender(Point2I offset, const RectI &updateRect) { - // Must have a connection and player control object + // Must have a connection GameConnection* conn = GameConnection::getConnectionToServer(); if (!conn) return; - Vehicle* control = dynamic_cast(conn->getControlObject()); - if (!control) - return; + + // Requires either a vehicle control object or a vehicle-mounted player + Vehicle* vehicle = dynamic_cast(conn->getControlObject()); + if(!vehicle){ + Player * player = dynamic_cast(conn->getControlObject()); + if(!player) return; + if (!player->isMounted()) return; + vehicle = dynamic_cast(player->getObjectMount()); + if(!vehicle) return; + } Parent::onRender(offset,updateRect); // Use the vehicle's velocity as its speed... - mSpeed = control->getVelocity().len(); + mSpeed = vehicle->getVelocity().len(); if (mSpeed > mMaxSpeed) mSpeed = mMaxSpeed; From 8d610787a2054ec18b4a745e391abdeef6070261 Mon Sep 17 00:00:00 2001 From: yourarcade Date: Sun, 25 Sep 2016 17:48:27 -0700 Subject: [PATCH 02/50] Fix push/pop mismatch bug;add code to properly rotate, translate and render needle. --- Engine/source/T3D/vehicles/guiSpeedometer.cpp | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/Engine/source/T3D/vehicles/guiSpeedometer.cpp b/Engine/source/T3D/vehicles/guiSpeedometer.cpp index 79f3f8bdb..b43f65951 100644 --- a/Engine/source/T3D/vehicles/guiSpeedometer.cpp +++ b/Engine/source/T3D/vehicles/guiSpeedometer.cpp @@ -19,11 +19,11 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- - #include "gui/controls/guiBitmapCtrl.h" #include "console/consoleTypes.h" #include "T3D/gameBase/gameConnection.h" #include "T3D/vehicles/vehicle.h" +#include "T3D/player.h" #include "gfx/primBuilder.h" //----------------------------------------------------------------------------- @@ -173,23 +173,31 @@ void GuiSpeedometerHud::onRender(Point2I offset, const RectI &updateRect) if (mSpeed > mMaxSpeed) mSpeed = mMaxSpeed; - // Render the needle - GFX->pushWorldMatrix(); + // Calculate center point if necessary and roll in offsets Point2F center = mCenter; if (mIsZero(center.x) && mIsZero(center.y)) { center.x = getExtent().x / 2.0f; center.y = getExtent().y / 2.0f; } - MatrixF newMat(1); + F32 fillOffset = GFX->getFillConventionOffset(); // Find the fill offset + Point2F viewCenter(offset.x + fillOffset + center.x, offset.y + fillOffset + center.y); - newMat.setPosition(Point3F(getLeft() + center.x, getTop() + center.y, 0.0f)); - - F32 rotation = mMinAngle + (mMaxAngle - mMinAngle) * (mSpeed / mMaxSpeed); - AngAxisF newRot(Point3F(0.0f,0.0f,-1.0f), rotation); - - newRot.setMatrix(&newMat); + // Handle rotation calculations + F32 rotation, spinAngle; + rotation = mMinAngle + (mMaxAngle - mMinAngle) * (mSpeed / mMaxSpeed); + spinAngle = mDegToRad(rotation); + MatrixF rotMatrix(EulerF(0.0, 0.0, spinAngle)); + // Set up the needle vertex list + Point3F vertList[5]; + vertList[0].set(+mNeedleLength,-mNeedleWidth,0); + vertList[1].set(+mNeedleLength,+mNeedleWidth,0); + vertList[2].set(-mTailLength ,+mNeedleWidth,0); + vertList[3].set(-mTailLength ,-mNeedleWidth,0); + vertList[4].set(+mNeedleLength,-mNeedleWidth,0); //// Get back to the start! + + // Create a GFXStateBlock description if one has not been set. if (mBlendSB.isNull()) { GFXStateBlockDesc desc; @@ -198,22 +206,15 @@ void GuiSpeedometerHud::onRender(Point2I offset, const RectI &updateRect) desc.samplers[0].textureColorOp = GFXTOPDisable; mBlendSB = GFX->createStateBlock(desc); } - GFX->setStateBlock(mBlendSB); - GFX->setTexture(0, NULL); - PrimBuild::begin(GFXLineStrip, 5); + // Render the needle PrimBuild::color4f(mColor.red, mColor.green, mColor.blue, mColor.alpha); - - PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth); - PrimBuild::vertex2f(+mNeedleLength,+mNeedleWidth); - PrimBuild::vertex2f(-mTailLength ,+mNeedleWidth); - PrimBuild::vertex2f(-mTailLength ,-mNeedleWidth); - - //// Get back to the start! - PrimBuild::vertex2f(+mNeedleLength,-mNeedleWidth); - + PrimBuild::begin(GFXLineStrip, 5); + for(int k=0; k<5; k++){ + rotMatrix.mulP(vertList[k]); + PrimBuild::vertex2f(vertList[k].x + viewCenter.x, vertList[k].y + viewCenter.y); + } PrimBuild::end(); } - From c57b1a8b7045c92e9cc1afb24e0654d80ee51c4c Mon Sep 17 00:00:00 2001 From: Azaezel Date: Fri, 14 Oct 2016 17:26:13 -0500 Subject: [PATCH 03/50] clang reports: unclear || + && and &+| mixes. --- Engine/source/T3D/aiPlayer.cpp | 6 +++--- Engine/source/T3D/camera.cpp | 2 +- Engine/source/T3D/decal/decalManager.cpp | 4 ++-- Engine/source/T3D/lightFlareData.cpp | 2 +- Engine/source/T3D/player.cpp | 6 +++--- Engine/source/T3D/shapeImage.cpp | 10 +++++----- Engine/source/T3D/staticShape.cpp | 2 +- Engine/source/T3D/turret/aiTurretShape.cpp | 2 +- Engine/source/core/strings/unicode.cpp | 2 +- Engine/source/core/tagDictionary.cpp | 2 +- Engine/source/environment/river.cpp | 4 ++-- Engine/source/gfx/gl/gfxGLStateBlock.cpp | 2 +- Engine/source/gui/containers/guiRolloutCtrl.cpp | 2 +- Engine/source/navigation/navMesh.cpp | 6 ++++-- Engine/source/renderInstance/renderPrePassMgr.cpp | 4 ++-- Engine/source/scene/sceneContainer.cpp | 2 +- 16 files changed, 30 insertions(+), 28 deletions(-) diff --git a/Engine/source/T3D/aiPlayer.cpp b/Engine/source/T3D/aiPlayer.cpp index 88b500205..f4e71cb91 100644 --- a/Engine/source/T3D/aiPlayer.cpp +++ b/Engine/source/T3D/aiPlayer.cpp @@ -1043,9 +1043,9 @@ NavMesh *AIPlayer::findNavMesh() const } else { - if(getNavSize() == Small && !m->mSmallCharacters || - getNavSize() == Regular && !m->mRegularCharacters || - getNavSize() == Large && !m->mLargeCharacters) + if((getNavSize() == Small && !m->mSmallCharacters) || + (getNavSize() == Regular && !m->mRegularCharacters) || + (getNavSize() == Large && !m->mLargeCharacters)) continue; } if(!mesh || m->getWorldBox().getVolume() < mesh->getWorldBox().getVolume()) diff --git a/Engine/source/T3D/camera.cpp b/Engine/source/T3D/camera.cpp index 11914542a..a2acc3838 100644 --- a/Engine/source/T3D/camera.cpp +++ b/Engine/source/T3D/camera.cpp @@ -572,7 +572,7 @@ void Camera::processTick(const Move* move) // process input/determine rotation vector if(virtualMode != StationaryMode && virtualMode != TrackObjectMode && - (!mLocked || virtualMode != OrbitObjectMode && virtualMode != OrbitPointMode)) + (!mLocked || ((virtualMode != OrbitObjectMode) && (virtualMode != OrbitPointMode)))) { if(!strafeMode) { diff --git a/Engine/source/T3D/decal/decalManager.cpp b/Engine/source/T3D/decal/decalManager.cpp index f992705d1..2d2491a7f 100644 --- a/Engine/source/T3D/decal/decalManager.cpp +++ b/Engine/source/T3D/decal/decalManager.cpp @@ -632,9 +632,9 @@ DecalInstance* DecalManager::getClosestDecal( const Point3F &pos ) } } - if ( !collectedInsts.empty() && + if ( (!collectedInsts.empty() && collectedInsts[closestIndex] && - closestDistance < 1.0f || + closestDistance < 1.0f) || worldInstSphere.isContained( pos ) ) return collectedInsts[closestIndex]; else diff --git a/Engine/source/T3D/lightFlareData.cpp b/Engine/source/T3D/lightFlareData.cpp index 84058f6c8..37963c546 100644 --- a/Engine/source/T3D/lightFlareData.cpp +++ b/Engine/source/T3D/lightFlareData.cpp @@ -440,7 +440,7 @@ void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareS // We can only skip rendering if the light is not // visible, and it has elapsed the fade out time. if (mIsZero(occlusionFade) || - !lightVisible && visDelta > FadeOutTime) + (!lightVisible && visDelta > FadeOutTime)) return; const RectI &viewport = GFX->getViewport(); diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index db6a2ca42..850b35bb9 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -3930,9 +3930,9 @@ void Player::updateActionThread() if (mMountPending) mMountPending = (isMounted() ? 0 : (mMountPending - 1)); - if (mActionAnimation.action == PlayerData::NullAnimation || - ((!mActionAnimation.waitForEnd || mActionAnimation.atEnd)) && - !mActionAnimation.holdAtEnd && (mActionAnimation.delayTicks -= !mMountPending) <= 0) + if ((mActionAnimation.action == PlayerData::NullAnimation) || + ((!mActionAnimation.waitForEnd || mActionAnimation.atEnd) && + (!mActionAnimation.holdAtEnd && (mActionAnimation.delayTicks -= !mMountPending) <= 0))) { //The scripting language will get a call back when a script animation has finished... // example: When the chat menu animations are done playing... diff --git a/Engine/source/T3D/shapeImage.cpp b/Engine/source/T3D/shapeImage.cpp index cc8022b24..11c95bb7c 100644 --- a/Engine/source/T3D/shapeImage.cpp +++ b/Engine/source/T3D/shapeImage.cpp @@ -2638,7 +2638,7 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) F32 randomPos = Platform::getRandom(); for (U32 i=0; ishapeIsValid[i] || i != imageShapeIndex && !image.doAnimateAllShapes) + if (!image.dataBlock->shapeIsValid[i] || (i != imageShapeIndex && !image.doAnimateAllShapes)) continue; if (image.animThread[i] && image.state->sequence[i] != -1 && image.state->flashSequence[i]) { @@ -2779,7 +2779,7 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force) updateAnimThread(imageSlot, imageShapeIndex, lastState); for (U32 i=0; ishapeIsValid[i] || i != imageShapeIndex && !image.doAnimateAllShapes) + if (!image.dataBlock->shapeIsValid[i] || (i != imageShapeIndex && !image.doAnimateAllShapes)) continue; // Start spin thread @@ -2834,7 +2834,7 @@ void ShapeBase::updateAnimThread(U32 imageSlot, S32 imageShapeIndex, ShapeBaseIm F32 randomPos = Platform::getRandom(); for (U32 i=0; ishapeIsValid[i] || i != imageShapeIndex && !image.doAnimateAllShapes) + if (!image.dataBlock->shapeIsValid[i] || (i != imageShapeIndex && !image.doAnimateAllShapes)) continue; if (image.animThread[i] && stateData.sequence[i] != -1) @@ -3076,7 +3076,7 @@ TICKAGAIN: U32 imageShapeIndex = getImageShapeIndex(image); for (U32 i=0; ishapeIsValid[i] || i != imageShapeIndex && !image.doAnimateAllShapes) + if (!image.dataBlock->shapeIsValid[i] || (i != imageShapeIndex && !image.doAnimateAllShapes)) continue; if (image.spinThread[i]) @@ -3131,7 +3131,7 @@ void ShapeBase::updateImageAnimation(U32 imageSlot, F32 dt) // Advance animation threads for (U32 i=0; ishapeIsValid[i] || i != imageShapeIndex && !image.doAnimateAllShapes) + if (!image.dataBlock->shapeIsValid[i] || (i != imageShapeIndex && !image.doAnimateAllShapes)) continue; if (image.ambientThread[i]) diff --git a/Engine/source/T3D/staticShape.cpp b/Engine/source/T3D/staticShape.cpp index ffad91dd3..1ffd5436c 100644 --- a/Engine/source/T3D/staticShape.cpp +++ b/Engine/source/T3D/staticShape.cpp @@ -252,7 +252,7 @@ void StaticShape::onUnmount(ShapeBase*,S32) U32 StaticShape::packUpdate(NetConnection *connection, U32 mask, BitStream *bstream) { U32 retMask = Parent::packUpdate(connection,mask,bstream); - if (bstream->writeFlag(mask & PositionMask | ExtendedInfoMask)) + if (bstream->writeFlag(mask & (PositionMask | ExtendedInfoMask))) { // Write the transform (do _not_ use writeAffineTransform. Since this is a static diff --git a/Engine/source/T3D/turret/aiTurretShape.cpp b/Engine/source/T3D/turret/aiTurretShape.cpp index 5d895c8ab..ac36e30ea 100644 --- a/Engine/source/T3D/turret/aiTurretShape.cpp +++ b/Engine/source/T3D/turret/aiTurretShape.cpp @@ -1157,7 +1157,7 @@ U32 AITurretShape::packUpdate(NetConnection *connection, U32 mask, BitStream *bs U32 retMask = Parent::packUpdate(connection,mask,bstream); // Indicate that the transform has changed to update the scan box - bstream->writeFlag(mask & PositionMask | ExtendedInfoMask); + bstream->writeFlag(mask & (PositionMask | ExtendedInfoMask)); // Handle any state changes that need to be passed along if (bstream->writeFlag(mask & TurretStateMask)) diff --git a/Engine/source/core/strings/unicode.cpp b/Engine/source/core/strings/unicode.cpp index 64acee244..109327fe1 100644 --- a/Engine/source/core/strings/unicode.cpp +++ b/Engine/source/core/strings/unicode.cpp @@ -481,7 +481,7 @@ U32 oneUTF32toUTF8(const UTF32 codepoint, UTF8 *threeByteCodeunitBuf) // Process the 1st byte. filter based on the # of expected bytes. mask = sgByteMask8LUT[bytecount]; marker = ( ~mask << 1 ); - threeByteCodeunitBuf[0] = marker | working & mask; + threeByteCodeunitBuf[0] = marker | (working & mask); PROFILE_END(); return bytecount; diff --git a/Engine/source/core/tagDictionary.cpp b/Engine/source/core/tagDictionary.cpp index a25ed4f5b..1b9b80dd4 100644 --- a/Engine/source/core/tagDictionary.cpp +++ b/Engine/source/core/tagDictionary.cpp @@ -296,7 +296,7 @@ bool TagDictionary::match(const char* pattern, const char* str) return !*str; case '*': - return match(pattern+1, str) || *str && match(pattern, str+1); + return match(pattern+1, str) || (*str && match(pattern, str+1)); case '?': return *str && match(pattern+1, str+1); diff --git a/Engine/source/environment/river.cpp b/Engine/source/environment/river.cpp index ff11fdbc6..7d01827ec 100644 --- a/Engine/source/environment/river.cpp +++ b/Engine/source/environment/river.cpp @@ -2160,8 +2160,8 @@ void River::_makeRenderBatches( const Point3F &cameraPos ) F32 dist = getMin( dist0, dist1 ); highDetail = ( dist < lodDistSquared ); - if ( highDetail && lastDetail == 0 || - !highDetail && lastDetail == 1 ) + if ( (highDetail && lastDetail == 0) || + (!highDetail && lastDetail == 1) ) { // We hit a segment with a different lod than the previous. // Save what we have so far... diff --git a/Engine/source/gfx/gl/gfxGLStateBlock.cpp b/Engine/source/gfx/gl/gfxGLStateBlock.cpp index 9d446f27a..87d2b5953 100644 --- a/Engine/source/gfx/gl/gfxGLStateBlock.cpp +++ b/Engine/source/gfx/gl/gfxGLStateBlock.cpp @@ -99,7 +99,7 @@ void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState) #define STATE_CHANGE(state) (!oldState || oldState->mDesc.state != mDesc.state) #define TOGGLE_STATE(state, enum) if(mDesc.state) glEnable(enum); else glDisable(enum) -#define CHECK_TOGGLE_STATE(state, enum) if(!oldState || oldState->mDesc.state != mDesc.state) if(mDesc.state) glEnable(enum); else glDisable(enum) +#define CHECK_TOGGLE_STATE(state, enum) if(!oldState || oldState->mDesc.state != mDesc.state) {if(mDesc.state) glEnable(enum); else glDisable(enum);} // Blending CHECK_TOGGLE_STATE(blendEnable, GL_BLEND); diff --git a/Engine/source/gui/containers/guiRolloutCtrl.cpp b/Engine/source/gui/containers/guiRolloutCtrl.cpp index 919846b66..3a226f0bc 100644 --- a/Engine/source/gui/containers/guiRolloutCtrl.cpp +++ b/Engine/source/gui/containers/guiRolloutCtrl.cpp @@ -189,7 +189,7 @@ bool GuiRolloutCtrl::_onMouseUp( const GuiEvent &event, bool lockedMouse ) { // If Ctrl/Cmd-clicking a header, collapse all sibling GuiRolloutCtrls. - if( ( mAutoCollapseSiblings && !mIsExpanded && !( event.modifier & SI_PRIMARY_CTRL ) + if( (( mAutoCollapseSiblings && !mIsExpanded && !( event.modifier & SI_PRIMARY_CTRL )) || ( !mAutoCollapseSiblings && event.modifier & SI_PRIMARY_CTRL ) ) ) { for( SimSet::iterator iter = getParent()->begin(); iter != getParent()->end(); ++ iter ) diff --git a/Engine/source/navigation/navMesh.cpp b/Engine/source/navigation/navMesh.cpp index 9fb84c309..b98c648b3 100644 --- a/Engine/source/navigation/navMesh.cpp +++ b/Engine/source/navigation/navMesh.cpp @@ -1143,9 +1143,10 @@ void NavMesh::buildLinks() // Iterate over links for(U32 j = 0; j < mLinkIDs.size(); j++) { + if (mLinksUnsynced[j]) + { if(tile.box.isContained(getLinkStart(j)) || - tile.box.isContained(getLinkEnd(j)) && - mLinksUnsynced[j]) + tile.box.isContained(getLinkEnd(j))) { // Mark tile for build. mDirtyTiles.push_back_unique(i); @@ -1160,6 +1161,7 @@ void NavMesh::buildLinks() } } } + } if(mDirtyTiles.size()) ctx->startTimer(RC_TIMER_TOTAL); } diff --git a/Engine/source/renderInstance/renderPrePassMgr.cpp b/Engine/source/renderInstance/renderPrePassMgr.cpp index 2c3f2c4c2..6175c3eec 100644 --- a/Engine/source/renderInstance/renderPrePassMgr.cpp +++ b/Engine/source/renderInstance/renderPrePassMgr.cpp @@ -612,9 +612,9 @@ void ProcessedPrePassMaterial::_determineFeatures( U32 stageNum, mIsLightmappedGeometry = ( fd.features.hasFeature( MFT_ToneMap ) || fd.features.hasFeature( MFT_LightMap ) || fd.features.hasFeature( MFT_VertLit ) || - ( bEnableMRTLightmap && fd.features.hasFeature( MFT_IsTranslucent ) || + ( bEnableMRTLightmap && (fd.features.hasFeature( MFT_IsTranslucent ) || fd.features.hasFeature( MFT_ForwardShading ) || - fd.features.hasFeature( MFT_IsTranslucentZWrite ) ) ); + fd.features.hasFeature( MFT_IsTranslucentZWrite) ) ) ); // Integrate proper opaque stencil write state mUserDefined.addDesc( mPrePassMgr->getOpaqueStenciWriteDesc( mIsLightmappedGeometry ) ); diff --git a/Engine/source/scene/sceneContainer.cpp b/Engine/source/scene/sceneContainer.cpp index f5a271794..b4dd2058c 100644 --- a/Engine/source/scene/sceneContainer.cpp +++ b/Engine/source/scene/sceneContainer.cpp @@ -307,7 +307,7 @@ void SceneContainer::insertIntoBins(SceneObject* obj, // For huge objects, dump them into the overflow bin. Otherwise, everything // goes into the grid... // - if ((maxX - minX + 1) < csmNumBins || (maxY - minY + 1) < csmNumBins && !obj->isGlobalBounds()) + if ((maxX - minX + 1) < csmNumBins || ((maxY - minY + 1) < csmNumBins && !obj->isGlobalBounds())) { SceneObjectRef** pCurrInsert = &obj->mBinRefHead; From 1e671bfc7a283640e34d3c2a327b229f107f10a1 Mon Sep 17 00:00:00 2001 From: Areloch Date: Tue, 8 Nov 2016 20:49:49 -0600 Subject: [PATCH 04/50] Updates SDL to 2.0.5 --- Engine/lib/sdl/include/SDL.h | 20 +- Engine/lib/sdl/include/SDL_audio.h | 95 +- Engine/lib/sdl/include/SDL_config.h.cmake | 2 + Engine/lib/sdl/include/SDL_config.h.in | 4 + Engine/lib/sdl/include/SDL_config_android.h | 3 + Engine/lib/sdl/include/SDL_config_iphoneos.h | 6 +- Engine/lib/sdl/include/SDL_events.h | 8 +- Engine/lib/sdl/include/SDL_gamecontroller.h | 6 +- Engine/lib/sdl/include/SDL_haptic.h | 32 +- Engine/lib/sdl/include/SDL_hints.h | 112 +- Engine/lib/sdl/include/SDL_joystick.h | 2 +- Engine/lib/sdl/include/SDL_keyboard.h | 2 +- Engine/lib/sdl/include/SDL_main.h | 2 +- Engine/lib/sdl/include/SDL_mouse.h | 6 +- Engine/lib/sdl/include/SDL_opengles.h | 1 + Engine/lib/sdl/include/SDL_opengles2.h | 2 + Engine/lib/sdl/include/SDL_pixels.h | 14 + Engine/lib/sdl/include/SDL_platform.h | 14 +- Engine/lib/sdl/include/SDL_render.h | 27 +- Engine/lib/sdl/include/SDL_revision.h | 4 +- Engine/lib/sdl/include/SDL_rwops.h | 12 +- Engine/lib/sdl/include/SDL_stdinc.h | 10 +- Engine/lib/sdl/include/SDL_surface.h | 10 + Engine/lib/sdl/include/SDL_syswm.h | 22 +- Engine/lib/sdl/include/SDL_version.h | 2 +- Engine/lib/sdl/include/SDL_video.h | 133 ++- Engine/lib/sdl/src/SDL.c | 22 +- Engine/lib/sdl/src/SDL_error.c | 7 + Engine/lib/sdl/src/SDL_hints.c | 13 + Engine/lib/sdl/src/SDL_log.c | 8 +- Engine/lib/sdl/src/audio/SDL_audio.c | 551 ++++++---- Engine/lib/sdl/src/audio/SDL_audio_c.h | 3 - Engine/lib/sdl/src/audio/SDL_mixer.c | 50 +- Engine/lib/sdl/src/audio/SDL_sysaudio.h | 24 +- Engine/lib/sdl/src/audio/SDL_wave.c | 2 +- .../lib/sdl/src/audio/alsa/SDL_alsa_audio.c | 452 +++++++-- .../sdl/src/audio/android/SDL_androidaudio.c | 109 +- .../sdl/src/audio/android/SDL_androidaudio.h | 2 - Engine/lib/sdl/src/audio/arts/SDL_artsaudio.c | 33 +- Engine/lib/sdl/src/audio/bsd/SDL_bsdaudio.c | 165 ++- .../sdl/src/audio/coreaudio/SDL_coreaudio.h | 16 +- .../sdl/src/audio/coreaudio/SDL_coreaudio.m | 849 ++++++++++++++++ .../src/audio/directsound/SDL_directsound.c | 284 ++++-- .../src/audio/directsound/SDL_directsound.h | 3 +- Engine/lib/sdl/src/audio/disk/SDL_diskaudio.c | 161 +-- Engine/lib/sdl/src/audio/disk/SDL_diskaudio.h | 5 +- Engine/lib/sdl/src/audio/dsp/SDL_dspaudio.c | 74 +- .../lib/sdl/src/audio/dummy/SDL_dummyaudio.c | 27 +- .../audio/emscripten/SDL_emscriptenaudio.c | 288 ++++-- Engine/lib/sdl/src/audio/esd/SDL_esdaudio.c | 22 +- .../sdl/src/audio/fusionsound/SDL_fsaudio.c | 39 +- .../lib/sdl/src/audio/haiku/SDL_haikuaudio.cc | 24 +- Engine/lib/sdl/src/audio/nacl/SDL_naclaudio.c | 37 +- Engine/lib/sdl/src/audio/nas/SDL_nasaudio.c | 166 ++- Engine/lib/sdl/src/audio/paudio/SDL_paudio.c | 24 +- Engine/lib/sdl/src/audio/psp/SDL_pspaudio.c | 63 +- .../sdl/src/audio/pulseaudio/SDL_pulseaudio.c | 203 ++-- .../sdl/src/audio/pulseaudio/SDL_pulseaudio.h | 3 + Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.c | 92 +- Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.h | 2 +- .../lib/sdl/src/audio/sndio/SDL_sndioaudio.c | 31 +- Engine/lib/sdl/src/audio/sun/SDL_sunaudio.c | 21 +- Engine/lib/sdl/src/audio/winmm/SDL_winmm.c | 192 ++-- .../lib/sdl/src/audio/xaudio2/SDL_xaudio2.c | 84 +- Engine/lib/sdl/src/core/android/SDL_android.c | 330 ++++-- Engine/lib/sdl/src/core/android/SDL_android.h | 6 +- Engine/lib/sdl/src/core/linux/SDL_dbus.c | 2 +- Engine/lib/sdl/src/core/linux/SDL_evdev.c | 955 ++++++++++-------- Engine/lib/sdl/src/core/linux/SDL_evdev.h | 20 - Engine/lib/sdl/src/core/linux/SDL_fcitx.c | 553 ++++++++++ Engine/lib/sdl/src/core/linux/SDL_fcitx.h | 40 + Engine/lib/sdl/src/core/linux/SDL_ibus.c | 6 +- Engine/lib/sdl/src/core/linux/SDL_ime.c | 138 +++ Engine/lib/sdl/src/core/linux/SDL_ime.h | 38 + Engine/lib/sdl/src/core/linux/SDL_udev.c | 9 +- Engine/lib/sdl/src/core/linux/SDL_udev.h | 6 +- Engine/lib/sdl/src/core/windows/SDL_windows.c | 78 ++ Engine/lib/sdl/src/core/windows/SDL_windows.h | 3 + .../src/core/winrt/SDL_winrtapp_direct3d.cpp | 31 +- .../src/core/winrt/SDL_winrtapp_direct3d.h | 4 + Engine/lib/sdl/src/dynapi/SDL_dynapi.c | 2 +- Engine/lib/sdl/src/dynapi/SDL_dynapi.h | 10 +- .../lib/sdl/src/dynapi/SDL_dynapi_overrides.h | 15 + Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h | 13 + Engine/lib/sdl/src/events/SDL_dropevents.c | 68 +- Engine/lib/sdl/src/events/SDL_dropevents_c.h | 4 +- Engine/lib/sdl/src/events/SDL_events.c | 117 +-- Engine/lib/sdl/src/events/SDL_gesture.c | 2 +- Engine/lib/sdl/src/events/SDL_mouse.c | 70 +- Engine/lib/sdl/src/events/SDL_mouse_c.h | 3 + Engine/lib/sdl/src/events/SDL_quit.c | 4 +- Engine/lib/sdl/src/events/SDL_windowevents.c | 18 +- Engine/lib/sdl/src/events/scancodes_linux.h | 14 +- Engine/lib/sdl/src/events/scancodes_xfree86.h | 85 ++ .../src/filesystem/dummy/SDL_sysfilesystem.c | 4 +- .../src/filesystem/unix/SDL_sysfilesystem.c | 23 +- .../lib/sdl/src/haptic/linux/SDL_syshaptic.c | 4 +- .../sdl/src/haptic/windows/SDL_dinputhaptic.c | 19 +- .../src/haptic/windows/SDL_windowshaptic.c | 2 +- .../src/haptic/windows/SDL_windowshaptic_c.h | 4 +- .../sdl/src/haptic/windows/SDL_xinputhaptic.c | 19 +- .../lib/sdl/src/joystick/SDL_gamecontroller.c | 66 +- .../sdl/src/joystick/SDL_gamecontrollerdb.h | 14 + Engine/lib/sdl/src/joystick/SDL_joystick.c | 76 +- Engine/lib/sdl/src/joystick/SDL_joystick_c.h | 6 +- Engine/lib/sdl/src/joystick/SDL_sysjoystick.h | 1 + .../src/joystick/android/SDL_sysjoystick.c | 49 +- .../src/joystick/android/SDL_sysjoystick_c.h | 38 +- .../sdl/src/joystick/bsd/SDL_sysjoystick.c | 10 +- .../sdl/src/joystick/darwin/SDL_sysjoystick.c | 54 +- .../src/joystick/emscripten/SDL_sysjoystick.c | 41 +- .../joystick/emscripten/SDL_sysjoystick_c.h | 32 +- .../src/joystick/haiku/SDL_haikujoystick.cc | 4 +- .../src/joystick/iphoneos/SDL_sysjoystick.m | 132 ++- .../sdl/src/joystick/linux/SDL_sysjoystick.c | 37 +- .../sdl/src/joystick/psp/SDL_sysjoystick.c | 4 +- .../src/joystick/windows/SDL_dinputjoystick.c | 20 +- .../joystick/windows/SDL_windowsjoystick.c | 47 +- .../joystick/windows/SDL_windowsjoystick_c.h | 4 + .../src/joystick/windows/SDL_xinputjoystick.c | 10 +- .../lib/sdl/src/loadso/dlopen/SDL_sysloadso.c | 18 +- .../sdl/src/main/android/SDL_android_main.c | 11 +- Engine/lib/sdl/src/main/haiku/SDL_BApp.h | 14 +- Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc | 6 +- .../sdl/src/main/windows/SDL_windows_main.c | 84 +- Engine/lib/sdl/src/main/windows/version.rc | 8 +- .../winrt/SDL2-WinRTResource_BlankCursor.cur | Bin 0 -> 326 bytes .../sdl/src/main/winrt/SDL2-WinRTResources.rc | 3 + Engine/lib/sdl/src/power/uikit/SDL_syspower.m | 17 +- Engine/lib/sdl/src/render/SDL_render.c | 72 +- Engine/lib/sdl/src/render/SDL_sysrender.h | 3 + .../sdl/src/render/direct3d/SDL_render_d3d.c | 16 +- .../src/render/direct3d11/SDL_render_d3d11.c | 157 +-- .../lib/sdl/src/render/opengl/SDL_render_gl.c | 72 +- .../sdl/src/render/opengles/SDL_render_gles.c | 178 ++-- .../src/render/opengles2/SDL_render_gles2.c | 58 +- .../lib/sdl/src/render/psp/SDL_render_psp.c | 10 +- .../sdl/src/render/software/SDL_render_sw.c | 4 +- .../lib/sdl/src/render/software/SDL_rotate.c | 167 ++- Engine/lib/sdl/src/stdlib/SDL_iconv.c | 3 +- Engine/lib/sdl/src/stdlib/SDL_qsort.c | 481 +++++---- Engine/lib/sdl/src/stdlib/SDL_stdlib.c | 14 +- Engine/lib/sdl/src/stdlib/SDL_string.c | 16 +- Engine/lib/sdl/src/test/SDL_test_assert.c | 14 +- Engine/lib/sdl/src/test/SDL_test_common.c | 24 + Engine/lib/sdl/src/test/SDL_test_compare.c | 2 +- Engine/lib/sdl/src/test/SDL_test_harness.c | 51 +- Engine/lib/sdl/src/test/SDL_test_log.c | 3 +- Engine/lib/sdl/src/thread/SDL_systhread.h | 5 + Engine/lib/sdl/src/thread/SDL_thread.c | 59 +- Engine/lib/sdl/src/thread/SDL_thread_c.h | 1 + Engine/lib/sdl/src/thread/psp/SDL_systhread.c | 4 +- .../sdl/src/thread/pthread/SDL_systhread.c | 23 +- .../sdl/src/thread/stdcpp/SDL_systhread.cpp | 1 + .../sdl/src/thread/windows/SDL_systhread.c | 66 +- Engine/lib/sdl/src/timer/SDL_timer.c | 59 +- .../lib/sdl/src/timer/windows/SDL_systimer.c | 10 +- Engine/lib/sdl/src/video/SDL_blit_copy.c | 18 +- Engine/lib/sdl/src/video/SDL_blit_slow.c | 5 +- Engine/lib/sdl/src/video/SDL_bmp.c | 68 +- Engine/lib/sdl/src/video/SDL_egl.c | 5 +- Engine/lib/sdl/src/video/SDL_surface.c | 65 +- Engine/lib/sdl/src/video/SDL_sysvideo.h | 13 + Engine/lib/sdl/src/video/SDL_video.c | 220 +++- .../sdl/src/video/android/SDL_androidevents.c | 14 +- .../src/video/android/SDL_androidkeyboard.c | 20 +- .../sdl/src/video/android/SDL_androidmouse.c | 18 +- .../sdl/src/video/android/SDL_androidmouse.h | 1 + .../sdl/src/video/android/SDL_androidtouch.c | 2 +- .../sdl/src/video/android/SDL_androidvideo.c | 29 +- .../sdl/src/video/cocoa/SDL_cocoaclipboard.m | 16 +- .../lib/sdl/src/video/cocoa/SDL_cocoaevents.m | 114 ++- .../sdl/src/video/cocoa/SDL_cocoakeyboard.m | 160 ++- .../lib/sdl/src/video/cocoa/SDL_cocoamodes.h | 4 +- .../lib/sdl/src/video/cocoa/SDL_cocoamodes.m | 222 ++-- .../lib/sdl/src/video/cocoa/SDL_cocoamouse.m | 30 +- .../sdl/src/video/cocoa/SDL_cocoamousetap.m | 15 +- .../lib/sdl/src/video/cocoa/SDL_cocoaopengl.m | 2 + .../lib/sdl/src/video/cocoa/SDL_cocoashape.m | 4 +- .../lib/sdl/src/video/cocoa/SDL_cocoavideo.m | 15 +- .../lib/sdl/src/video/cocoa/SDL_cocoawindow.h | 2 + .../lib/sdl/src/video/cocoa/SDL_cocoawindow.m | 186 ++-- .../src/video/directfb/SDL_DirectFB_video.c | 1 + .../src/video/directfb/SDL_DirectFB_window.c | 13 + .../src/video/directfb/SDL_DirectFB_window.h | 1 + .../video/emscripten/SDL_emscriptenevents.c | 238 +++-- .../video/emscripten/SDL_emscriptenevents.h | 3 + .../emscripten/SDL_emscriptenframebuffer.c | 76 +- .../video/emscripten/SDL_emscriptenmouse.c | 4 + .../video/emscripten/SDL_emscriptenvideo.c | 80 +- .../video/emscripten/SDL_emscriptenvideo.h | 8 +- Engine/lib/sdl/src/video/haiku/SDL_BWin.h | 40 +- Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc | 1 + Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc | 6 + Engine/lib/sdl/src/video/haiku/SDL_bwindow.h | 1 + Engine/lib/sdl/src/video/mir/SDL_mirdyn.c | 15 +- Engine/lib/sdl/src/video/mir/SDL_mirdyn.h | 6 +- Engine/lib/sdl/src/video/mir/SDL_mirevents.c | 249 +++-- Engine/lib/sdl/src/video/mir/SDL_mirevents.h | 2 +- .../sdl/src/video/mir/SDL_mirframebuffer.c | 37 +- Engine/lib/sdl/src/video/mir/SDL_mirmouse.c | 149 ++- Engine/lib/sdl/src/video/mir/SDL_mirsym.h | 117 ++- Engine/lib/sdl/src/video/mir/SDL_mirvideo.c | 229 +++-- Engine/lib/sdl/src/video/mir/SDL_mirvideo.h | 13 +- Engine/lib/sdl/src/video/mir/SDL_mirwindow.c | 254 ++++- Engine/lib/sdl/src/video/mir/SDL_mirwindow.h | 32 +- .../lib/sdl/src/video/pandora/SDL_pandora.c | 32 +- .../lib/sdl/src/video/pandora/SDL_pandora.h | 2 +- Engine/lib/sdl/src/video/psp/SDL_pspevents.c | 4 +- Engine/lib/sdl/src/video/psp/SDL_pspvideo.c | 5 +- .../sdl/src/video/raspberry/SDL_rpimouse.c | 146 ++- .../sdl/src/video/raspberry/SDL_rpivideo.c | 23 +- .../src/video/uikit/SDL_uikitappdelegate.h | 2 +- .../src/video/uikit/SDL_uikitappdelegate.m | 100 +- .../sdl/src/video/uikit/SDL_uikitclipboard.h | 35 + .../sdl/src/video/uikit/SDL_uikitclipboard.m | 111 ++ .../lib/sdl/src/video/uikit/SDL_uikitevents.m | 4 + .../lib/sdl/src/video/uikit/SDL_uikitmodes.h | 1 + .../lib/sdl/src/video/uikit/SDL_uikitmodes.m | 49 +- .../sdl/src/video/uikit/SDL_uikitopengles.h | 2 + .../sdl/src/video/uikit/SDL_uikitopengles.m | 29 +- .../sdl/src/video/uikit/SDL_uikitopenglview.m | 2 +- .../lib/sdl/src/video/uikit/SDL_uikitvideo.h | 17 +- .../lib/sdl/src/video/uikit/SDL_uikitvideo.m | 122 ++- .../lib/sdl/src/video/uikit/SDL_uikitview.m | 71 +- .../src/video/uikit/SDL_uikitviewcontroller.h | 49 +- .../src/video/uikit/SDL_uikitviewcontroller.m | 36 + .../lib/sdl/src/video/uikit/SDL_uikitwindow.m | 14 +- .../sdl/src/video/vivante/SDL_vivantevideo.c | 8 +- .../sdl/src/video/wayland/SDL_waylanddyn.c | 17 - .../sdl/src/video/wayland/SDL_waylanddyn.h | 9 +- .../sdl/src/video/wayland/SDL_waylandevents.c | 201 +++- .../src/video/wayland/SDL_waylandevents_c.h | 9 + .../sdl/src/video/wayland/SDL_waylandmouse.c | 35 +- .../sdl/src/video/wayland/SDL_waylandsym.h | 19 +- .../sdl/src/video/wayland/SDL_waylandvideo.c | 79 +- .../sdl/src/video/wayland/SDL_waylandvideo.h | 7 +- .../sdl/src/video/wayland/SDL_waylandwindow.c | 64 ++ .../sdl/src/video/wayland/SDL_waylandwindow.h | 4 + .../sdl/src/video/windows/SDL_windowsevents.c | 125 ++- .../src/video/windows/SDL_windowskeyboard.c | 46 +- .../src/video/windows/SDL_windowskeyboard.h | 2 + .../src/video/windows/SDL_windowsmessagebox.c | 6 +- .../sdl/src/video/windows/SDL_windowsmodes.c | 123 ++- .../sdl/src/video/windows/SDL_windowsmodes.h | 1 + .../sdl/src/video/windows/SDL_windowsvideo.c | 3 + .../sdl/src/video/windows/SDL_windowswindow.c | 52 +- .../sdl/src/video/windows/SDL_windowswindow.h | 4 +- .../sdl/src/video/winrt/SDL_winrtevents.cpp | 3 +- .../sdl/src/video/winrt/SDL_winrtevents_c.h | 7 + .../sdl/src/video/winrt/SDL_winrtgamebar.cpp | 196 ++++ .../src/video/winrt/SDL_winrtgamebar_cpp.h | 35 + .../sdl/src/video/winrt/SDL_winrtkeyboard.cpp | 44 + .../sdl/src/video/winrt/SDL_winrtmouse.cpp | 63 +- .../sdl/src/video/winrt/SDL_winrtvideo.cpp | 98 +- .../sdl/src/video/winrt/SDL_winrtvideo_cpp.h | 11 + Engine/lib/sdl/src/video/x11/SDL_x11dyn.c | 15 - Engine/lib/sdl/src/video/x11/SDL_x11dyn.h | 6 - Engine/lib/sdl/src/video/x11/SDL_x11events.c | 215 ++-- .../lib/sdl/src/video/x11/SDL_x11keyboard.c | 154 ++- .../lib/sdl/src/video/x11/SDL_x11keyboard.h | 1 + Engine/lib/sdl/src/video/x11/SDL_x11modes.c | 74 +- Engine/lib/sdl/src/video/x11/SDL_x11modes.h | 1 + Engine/lib/sdl/src/video/x11/SDL_x11mouse.c | 57 +- Engine/lib/sdl/src/video/x11/SDL_x11opengl.c | 12 +- Engine/lib/sdl/src/video/x11/SDL_x11sym.h | 18 + Engine/lib/sdl/src/video/x11/SDL_x11video.c | 79 +- Engine/lib/sdl/src/video/x11/SDL_x11video.h | 18 +- Engine/lib/sdl/src/video/x11/SDL_x11window.c | 198 +++- Engine/lib/sdl/src/video/x11/SDL_x11window.h | 11 + Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c | 10 + Engine/lib/sdl/src/video/x11/edid-parse.c | 4 +- Engine/lib/sdl/src/video/x11/imKStoUCS.c | 496 ++++----- Engine/lib/sdl/src/video/x11/imKStoUCS.h | 39 +- 274 files changed, 11502 insertions(+), 4656 deletions(-) create mode 100644 Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.m create mode 100644 Engine/lib/sdl/src/core/linux/SDL_fcitx.c create mode 100644 Engine/lib/sdl/src/core/linux/SDL_fcitx.h create mode 100644 Engine/lib/sdl/src/core/linux/SDL_ime.c create mode 100644 Engine/lib/sdl/src/core/linux/SDL_ime.h create mode 100644 Engine/lib/sdl/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur create mode 100644 Engine/lib/sdl/src/main/winrt/SDL2-WinRTResources.rc create mode 100644 Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h create mode 100644 Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m create mode 100644 Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp create mode 100644 Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h diff --git a/Engine/lib/sdl/include/SDL.h b/Engine/lib/sdl/include/SDL.h index 7647b5111..1a3fa285c 100644 --- a/Engine/lib/sdl/include/SDL.h +++ b/Engine/lib/sdl/include/SDL.h @@ -72,14 +72,14 @@ extern "C" { * specify the subsystems which you will be using in your application. */ /* @{ */ -#define SDL_INIT_TIMER 0x00000001 -#define SDL_INIT_AUDIO 0x00000010 -#define SDL_INIT_VIDEO 0x00000020 /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ -#define SDL_INIT_JOYSTICK 0x00000200 /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ -#define SDL_INIT_HAPTIC 0x00001000 -#define SDL_INIT_GAMECONTROLLER 0x00002000 /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ -#define SDL_INIT_EVENTS 0x00004000 -#define SDL_INIT_NOPARACHUTE 0x00100000 /**< compatibility; this flag is ignored. */ +#define SDL_INIT_TIMER 0x00000001u +#define SDL_INIT_AUDIO 0x00000010u +#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ +#define SDL_INIT_HAPTIC 0x00001000u +#define SDL_INIT_GAMECONTROLLER 0x00002000u /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ +#define SDL_INIT_EVENTS 0x00004000u +#define SDL_INIT_NOPARACHUTE 0x00100000u /**< compatibility; this flag is ignored. */ #define SDL_INIT_EVERYTHING ( \ SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \ SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \ @@ -95,8 +95,8 @@ extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); * This function initializes specific SDL subsystems * * Subsystem initialization is ref-counted, you must call - * SDL_QuitSubSystem for each SDL_InitSubSystem to correctly - * shutdown a subsystem manually (or call SDL_Quit to force shutdown). + * SDL_QuitSubSystem() for each SDL_InitSubSystem() to correctly + * shutdown a subsystem manually (or call SDL_Quit() to force shutdown). * If a subsystem is already loaded then this call will * increase the ref-count and return. */ diff --git a/Engine/lib/sdl/include/SDL_audio.h b/Engine/lib/sdl/include/SDL_audio.h index 4f6552146..d51f0d1ce 100644 --- a/Engine/lib/sdl/include/SDL_audio.h +++ b/Engine/lib/sdl/include/SDL_audio.h @@ -278,7 +278,8 @@ extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); * protect data structures that it accesses by calling SDL_LockAudio() * and SDL_UnlockAudio() in your code. Alternately, you may pass a NULL * pointer here, and call SDL_QueueAudio() with some frequency, to queue - * more audio samples to be played. + * more audio samples to be played (or for capture devices, call + * SDL_DequeueAudio() with some frequency, to obtain audio samples). * - \c desired->userdata is passed as the first parameter to your callback * function. If you passed a NULL callback, this value is ignored. * @@ -482,6 +483,10 @@ extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, /** * Queue more audio on non-callback devices. * + * (If you are looking to retrieve queued audio from a non-callback capture + * device, you want SDL_DequeueAudio() instead. This will return -1 to + * signify an error if you use it with capture devices.) + * * SDL offers two ways to feed audio to the device: you can either supply a * callback that SDL triggers with some frequency to obtain more audio * (pull method), or you can supply no callback, and then SDL will expect @@ -516,21 +521,76 @@ extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, */ extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len); +/** + * Dequeue more audio on non-callback devices. + * + * (If you are looking to queue audio for output on a non-callback playback + * device, you want SDL_QueueAudio() instead. This will always return 0 + * if you use it with playback devices.) + * + * SDL offers two ways to retrieve audio from a capture device: you can + * either supply a callback that SDL triggers with some frequency as the + * device records more audio data, (push method), or you can supply no + * callback, and then SDL will expect you to retrieve data at regular + * intervals (pull method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Data from the device will keep queuing as + * necessary without further intervention from you. This means you will + * eventually run out of memory if you aren't routinely dequeueing data. + * + * Capture devices will not queue data when paused; if you are expecting + * to not need captured audio for some length of time, use + * SDL_PauseAudioDevice() to stop the capture device from queueing more + * data. This can be useful during, say, level loading times. When + * unpaused, capture devices will start queueing data from that point, + * having flushed any capturable data available while paused. + * + * This function is thread-safe, but dequeueing from the same device from + * two threads at once does not promise which thread will dequeued data + * first. + * + * You may not dequeue audio from a device that is using an + * application-supplied callback; doing so returns an error. You have to use + * the audio callback, or dequeue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * \param dev The device ID from which we will dequeue audio. + * \param data A pointer into where audio data should be copied. + * \param len The number of bytes (not samples!) to which (data) points. + * \return number of bytes dequeued, which could be less than requested. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_ClearQueuedAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len); + /** * Get the number of bytes of still-queued audio. * - * This is the number of bytes that have been queued for playback with - * SDL_QueueAudio(), but have not yet been sent to the hardware. + * For playback device: * - * Once we've sent it to the hardware, this function can not decide the exact - * byte boundary of what has been played. It's possible that we just gave the - * hardware several kilobytes right before you called this function, but it - * hasn't played any of it yet, or maybe half of it, etc. + * This is the number of bytes that have been queued for playback with + * SDL_QueueAudio(), but have not yet been sent to the hardware. This + * number may shrink at any time, so this only informs of pending data. + * + * Once we've sent it to the hardware, this function can not decide the + * exact byte boundary of what has been played. It's possible that we just + * gave the hardware several kilobytes right before you called this + * function, but it hasn't played any of it yet, or maybe half of it, etc. + * + * For capture devices: + * + * This is the number of bytes that have been captured by the device and + * are waiting for you to dequeue. This number may grow at any time, so + * this only informs of the lower-bound of available data. * * You may not queue audio on a device that is using an application-supplied * callback; calling this function on such a device always returns 0. - * You have to use the audio callback or queue audio with SDL_QueueAudio(), - * but not both. + * You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use + * the audio callback, but not both. * * You should not call SDL_LockAudio() on the device before querying; SDL * handles locking internally for this function. @@ -544,10 +604,17 @@ extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *da extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); /** - * Drop any queued audio data waiting to be sent to the hardware. + * Drop any queued audio data. For playback devices, this is any queued data + * still waiting to be submitted to the hardware. For capture devices, this + * is any data that was queued by the device that hasn't yet been dequeued by + * the application. * - * Immediately after this call, SDL_GetQueuedAudioSize() will return 0 and - * the hardware will start playing silence if more audio isn't queued. + * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For + * playback devices, the hardware will start playing silence if more audio + * isn't queued. Unpaused capture devices will start filling the queue again + * as soon as they have more data available (which, depending on the state + * of the hardware and the thread, could be before this function call + * returns!). * * This will not prevent playback of queued audio that's already been sent * to the hardware, as we can not undo that, so expect there to be some @@ -557,8 +624,8 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); * * You may not queue audio on a device that is using an application-supplied * callback; calling this function on such a device is always a no-op. - * You have to use the audio callback or queue audio with SDL_QueueAudio(), - * but not both. + * You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use + * the audio callback, but not both. * * You should not call SDL_LockAudio() on the device before clearing the * queue; SDL handles locking internally for this function. diff --git a/Engine/lib/sdl/include/SDL_config.h.cmake b/Engine/lib/sdl/include/SDL_config.h.cmake index 44173a053..98c62a994 100644 --- a/Engine/lib/sdl/include/SDL_config.h.cmake +++ b/Engine/lib/sdl/include/SDL_config.h.cmake @@ -81,6 +81,8 @@ #cmakedefine HAVE_PTHREAD_NP_H 1 #cmakedefine HAVE_LIBUDEV_H 1 #cmakedefine HAVE_DBUS_DBUS_H 1 +#cmakedefine HAVE_IBUS_IBUS_H 1 +#cmakedefine HAVE_FCITX_FRONTEND_H 1 /* C library functions */ #cmakedefine HAVE_MALLOC 1 diff --git a/Engine/lib/sdl/include/SDL_config.h.in b/Engine/lib/sdl/include/SDL_config.h.in index 2071be4e5..d610cd6ba 100644 --- a/Engine/lib/sdl/include/SDL_config.h.in +++ b/Engine/lib/sdl/include/SDL_config.h.in @@ -82,6 +82,7 @@ #undef HAVE_LIBUDEV_H #undef HAVE_DBUS_DBUS_H #undef HAVE_IBUS_IBUS_H +#undef HAVE_FCITX_FRONTEND_H /* C library functions */ #undef HAVE_MALLOC @@ -356,4 +357,7 @@ #undef SDL_ASSEMBLY_ROUTINES #undef SDL_ALTIVEC_BLITTERS +/* Enable ime support */ +#undef SDL_USE_IME + #endif /* _SDL_config_h */ diff --git a/Engine/lib/sdl/include/SDL_config_android.h b/Engine/lib/sdl/include/SDL_config_android.h index a388ba8de..996cf76c9 100644 --- a/Engine/lib/sdl/include/SDL_config_android.h +++ b/Engine/lib/sdl/include/SDL_config_android.h @@ -43,6 +43,7 @@ #define HAVE_STDINT_H 1 #define HAVE_CTYPE_H 1 #define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 /* C library functions */ #define HAVE_MALLOC 1 @@ -75,6 +76,7 @@ #define HAVE_STRTOULL 1 #define HAVE_STRTOD 1 #define HAVE_ATOI 1 +#define HAVE_ATOF 1 #define HAVE_STRCMP 1 #define HAVE_STRNCMP 1 #define HAVE_STRCASECMP 1 @@ -101,6 +103,7 @@ #define HAVE_SQRTF 1 #define HAVE_TAN 1 #define HAVE_TANF 1 +#define HAVE_SIGACTION 1 #define HAVE_SETJMP 1 #define HAVE_NANOSLEEP 1 #define HAVE_SYSCONF 1 diff --git a/Engine/lib/sdl/include/SDL_config_iphoneos.h b/Engine/lib/sdl/include/SDL_config_iphoneos.h index 304c89201..470985f80 100644 --- a/Engine/lib/sdl/include/SDL_config_iphoneos.h +++ b/Engine/lib/sdl/include/SDL_config_iphoneos.h @@ -119,11 +119,7 @@ #define SDL_JOYSTICK_MFI 1 /* Enable Unix style SO loading */ -/* Technically this works, but violates the iOS dev agreement prior to iOS 8 */ -/* #define SDL_LOADSO_DLOPEN 1 */ - -/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ -#define SDL_LOADSO_DISABLED 1 +#define SDL_LOADSO_DLOPEN 1 /* Enable various threading systems */ #define SDL_THREAD_PTHREAD 1 diff --git a/Engine/lib/sdl/include/SDL_events.h b/Engine/lib/sdl/include/SDL_events.h index 1437f4c70..edb89ef49 100644 --- a/Engine/lib/sdl/include/SDL_events.h +++ b/Engine/lib/sdl/include/SDL_events.h @@ -136,6 +136,9 @@ typedef enum /* Drag and drop events */ SDL_DROPFILE = 0x1000, /**< The system requests a file open */ + SDL_DROPTEXT, /**< text/plain drag-and-drop event */ + SDL_DROPBEGIN, /**< A new set of drops is beginning (NULL filename) */ + SDL_DROPCOMPLETE, /**< Current set of drops is now complete (NULL filename) */ /* Audio hotplug events */ SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */ @@ -461,9 +464,10 @@ typedef struct SDL_DollarGestureEvent */ typedef struct SDL_DropEvent { - Uint32 type; /**< ::SDL_DROPFILE */ + Uint32 type; /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */ Uint32 timestamp; - char *file; /**< The file name, which should be freed with SDL_free() */ + char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */ + Uint32 windowID; /**< The window that was dropped on, if any */ } SDL_DropEvent; diff --git a/Engine/lib/sdl/include/SDL_gamecontroller.h b/Engine/lib/sdl/include/SDL_gamecontroller.h index 42087eea1..e67fd9fd0 100644 --- a/Engine/lib/sdl/include/SDL_gamecontroller.h +++ b/Engine/lib/sdl/include/SDL_gamecontroller.h @@ -93,7 +93,7 @@ typedef struct SDL_GameControllerButtonBind * } * } * - * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: + * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: * guid,name,mappings * * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. @@ -136,14 +136,14 @@ extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping( const char* mappingStr /** * Get a mapping string for a GUID * - * \return the mapping string. Must be freed with SDL_free. Returns NULL if no mapping is available + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available */ extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid ); /** * Get a mapping string for an open GameController * - * \return the mapping string. Must be freed with SDL_free. Returns NULL if no mapping is available + * \return the mapping string. Must be freed with SDL_free(). Returns NULL if no mapping is available */ extern DECLSPEC char * SDLCALL SDL_GameControllerMapping( SDL_GameController * gamecontroller ); diff --git a/Engine/lib/sdl/include/SDL_haptic.h b/Engine/lib/sdl/include/SDL_haptic.h index b36d78b12..9421c8f17 100644 --- a/Engine/lib/sdl/include/SDL_haptic.h +++ b/Engine/lib/sdl/include/SDL_haptic.h @@ -149,7 +149,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticCondition */ -#define SDL_HAPTIC_CONSTANT (1<<0) +#define SDL_HAPTIC_CONSTANT (1u<<0) /** * \brief Sine wave effect supported. @@ -158,7 +158,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticPeriodic */ -#define SDL_HAPTIC_SINE (1<<1) +#define SDL_HAPTIC_SINE (1u<<1) /** * \brief Left/Right effect supported. @@ -169,7 +169,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry, * we ran out of bits, and this is important for XInput devices. */ -#define SDL_HAPTIC_LEFTRIGHT (1<<2) +#define SDL_HAPTIC_LEFTRIGHT (1u<<2) /* !!! FIXME: put this back when we have more bits in 2.1 */ /* #define SDL_HAPTIC_SQUARE (1<<2) */ @@ -181,7 +181,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticPeriodic */ -#define SDL_HAPTIC_TRIANGLE (1<<3) +#define SDL_HAPTIC_TRIANGLE (1u<<3) /** * \brief Sawtoothup wave effect supported. @@ -190,7 +190,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticPeriodic */ -#define SDL_HAPTIC_SAWTOOTHUP (1<<4) +#define SDL_HAPTIC_SAWTOOTHUP (1u<<4) /** * \brief Sawtoothdown wave effect supported. @@ -199,7 +199,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticPeriodic */ -#define SDL_HAPTIC_SAWTOOTHDOWN (1<<5) +#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5) /** * \brief Ramp effect supported. @@ -208,7 +208,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticRamp */ -#define SDL_HAPTIC_RAMP (1<<6) +#define SDL_HAPTIC_RAMP (1u<<6) /** * \brief Spring effect supported - uses axes position. @@ -218,7 +218,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticCondition */ -#define SDL_HAPTIC_SPRING (1<<7) +#define SDL_HAPTIC_SPRING (1u<<7) /** * \brief Damper effect supported - uses axes velocity. @@ -228,7 +228,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticCondition */ -#define SDL_HAPTIC_DAMPER (1<<8) +#define SDL_HAPTIC_DAMPER (1u<<8) /** * \brief Inertia effect supported - uses axes acceleration. @@ -238,7 +238,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticCondition */ -#define SDL_HAPTIC_INERTIA (1<<9) +#define SDL_HAPTIC_INERTIA (1u<<9) /** * \brief Friction effect supported - uses axes movement. @@ -248,14 +248,14 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticCondition */ -#define SDL_HAPTIC_FRICTION (1<<10) +#define SDL_HAPTIC_FRICTION (1u<<10) /** * \brief Custom effect is supported. * * User defined custom haptic effect. */ -#define SDL_HAPTIC_CUSTOM (1<<11) +#define SDL_HAPTIC_CUSTOM (1u<<11) /* @} *//* Haptic effects */ @@ -268,7 +268,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticSetGain */ -#define SDL_HAPTIC_GAIN (1<<12) +#define SDL_HAPTIC_GAIN (1u<<12) /** * \brief Device can set autocenter. @@ -277,7 +277,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticSetAutocenter */ -#define SDL_HAPTIC_AUTOCENTER (1<<13) +#define SDL_HAPTIC_AUTOCENTER (1u<<13) /** * \brief Device can be queried for effect status. @@ -286,7 +286,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * * \sa SDL_HapticGetEffectStatus */ -#define SDL_HAPTIC_STATUS (1<<14) +#define SDL_HAPTIC_STATUS (1u<<14) /** * \brief Device can be paused. @@ -294,7 +294,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * \sa SDL_HapticPause * \sa SDL_HapticUnpause */ -#define SDL_HAPTIC_PAUSE (1<<15) +#define SDL_HAPTIC_PAUSE (1u<<15) /** diff --git a/Engine/lib/sdl/include/SDL_hints.h b/Engine/lib/sdl/include/SDL_hints.h index 3bd5435fb..dd1546431 100644 --- a/Engine/lib/sdl/include/SDL_hints.h +++ b/Engine/lib/sdl/include/SDL_hints.h @@ -233,16 +233,27 @@ extern "C" { #define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" /** -* \brief A variable controlling whether relative mouse mode is implemented using mouse warping -* -* This variable can be set to the following values: -* "0" - Relative mouse mode uses raw input -* "1" - Relative mouse mode uses mouse warping -* -* By default SDL will use raw input for relative mouse mode -*/ + * \brief A variable controlling whether relative mouse mode is implemented using mouse warping + * + * This variable can be set to the following values: + * "0" - Relative mouse mode uses raw input + * "1" - Relative mouse mode uses mouse warping + * + * By default SDL will use raw input for relative mouse mode + */ #define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" +/** + * \brief Allow mouse click events when clicking to focus an SDL window + * + * This variable can be set to the following values: + * "0" - Ignore mouse clicks that activate a window + * "1" - Generate events for mouse clicks that activate a window + * + * By default SDL will ignore mouse clicks that activate a window + */ +#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH" + /** * \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true. * @@ -257,8 +268,8 @@ extern "C" { * this is problematic. This functionality can be disabled by setting this * hint. * - * As of SDL 2.0.4, SDL_EnableScreenSaver and SDL_DisableScreenSaver accomplish - * the same thing on iOS. They should be preferred over this hint. + * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver() + * accomplish the same thing on iOS. They should be preferred over this hint. * * This variable can be set to the following values: * "0" - Enable idle timer @@ -276,7 +287,35 @@ extern "C" { * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown" */ #define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" - + +/** + * \brief A variable controlling whether controllers used with the Apple TV + * generate UI events. + * + * When UI events are generated by controller input, the app will be + * backgrounded when the Apple TV remote's menu button is pressed, and when the + * pause or B buttons on gamepads are pressed. + * + * More information about properly making use of controllers for the Apple TV + * can be found here: + * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ + * + * This variable can be set to the following values: + * "0" - Controller input does not generate UI events (the default). + * "1" - Controller input generates UI events. + */ +#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS" + +/** + * \brief A variable controlling whether the Apple TV remote's joystick axes + * will automatically match the rotation of the remote. + * + * This variable can be set to the following values: + * "0" - Remote orientation does not affect joystick axes (the default). + * "1" - Joystick axes are based on the orientation of the remote. + */ +#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION" + /** * \brief A variable controlling whether the Android / iOS built-in * accelerometer should be listed as a joystick device, rather than listing @@ -369,7 +408,7 @@ extern "C" { * Use this hint in case you need to set SDL's threads stack size to other than the default. * This is specially useful if you build SDL against a non glibc libc library (such as musl) which * provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). -* Support for this hint is currently available only in the pthread backend. +* Support for this hint is currently available only in the pthread, Windows, and PSP backend. */ #define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" @@ -431,7 +470,7 @@ extern "C" { * privacy policy. * * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL - * before calling any SDL_Init functions. The contents of the hint should + * before calling any SDL_Init() functions. The contents of the hint should * be a valid URL. For example, "http://www.example.com". * * The default value is "", which will prevent SDL from adding a privacy policy @@ -461,7 +500,7 @@ extern "C" { * The contents of this hint should be encoded as a UTF8 string. * * The default value is "Privacy Policy". This hint should only be set during app - * initialization, preferably before any calls to SDL_Init. + * initialization, preferably before any calls to SDL_Init(). * * For additional information on linking to a privacy policy, see the documentation for * SDL_HINT_WINRT_PRIVACY_POLICY_URL. @@ -630,6 +669,44 @@ extern "C" { */ #define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" +/** + * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. + * + * The bitmap header version 4 is required for proper alpha channel support and + * SDL will use it when required. Should this not be desired, this hint can + * force the use of the 40 byte header version which is supported everywhere. + * + * The variable can be set to the following values: + * "0" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file with an alpha mask. SDL will use the bitmap + * header version 4 and set the alpha mask accordingly. + * "1" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file without an alpha mask. The alpha channel data + * will be in the file, but applications are going to ignore it. + * + * The default value is "0". + */ +#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT" + +/** + * \brief Tell SDL not to name threads on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will raise the 0x406D1388 Exception to name threads. + * This is the default behavior of SDL <= 2.0.4. (default) + * "1" - SDL will not raise this exception, and threads will be unnamed. + * For .NET languages this is required when running under a debugger. + */ +#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" + +/** + * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI + * + * Also known as Z-order. The variable can take a negative or positive value. + * The default is 10000. + */ +#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER" + /** * \brief An enumeration of hint priorities */ @@ -669,6 +746,13 @@ extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, */ extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); +/** + * \brief Get a hint + * + * \return The boolean value of a hint variable. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value); + /** * \brief Add a function to watch a particular hint * diff --git a/Engine/lib/sdl/include/SDL_joystick.h b/Engine/lib/sdl/include/SDL_joystick.h index 266f3b387..f5dbc9487 100644 --- a/Engine/lib/sdl/include/SDL_joystick.h +++ b/Engine/lib/sdl/include/SDL_joystick.h @@ -24,7 +24,7 @@ * * Include file for SDL joystick event handling * - * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks, with the exact joystick + * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick * behind a device_index changing as joysticks are plugged and unplugged. * * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted diff --git a/Engine/lib/sdl/include/SDL_keyboard.h b/Engine/lib/sdl/include/SDL_keyboard.h index bbba0f07b..f80b6d2de 100644 --- a/Engine/lib/sdl/include/SDL_keyboard.h +++ b/Engine/lib/sdl/include/SDL_keyboard.h @@ -136,7 +136,7 @@ extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *name); * copy it. If the key doesn't have a name, this function returns an * empty string (""). * - * \sa SDL_Key + * \sa SDL_Keycode */ extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key); diff --git a/Engine/lib/sdl/include/SDL_main.h b/Engine/lib/sdl/include/SDL_main.h index 9ce3754e9..67afea5e7 100644 --- a/Engine/lib/sdl/include/SDL_main.h +++ b/Engine/lib/sdl/include/SDL_main.h @@ -63,7 +63,7 @@ /* On Android SDL provides a Java class in SDLActivity.java that is the main activity entry point. - See README-android.txt for more details on extending that class. + See README-android.md for more details on extending that class. */ #define SDL_MAIN_NEEDED diff --git a/Engine/lib/sdl/include/SDL_mouse.h b/Engine/lib/sdl/include/SDL_mouse.h index ea9622f0f..46f046d0c 100644 --- a/Engine/lib/sdl/include/SDL_mouse.h +++ b/Engine/lib/sdl/include/SDL_mouse.h @@ -41,7 +41,7 @@ extern "C" { typedef struct SDL_Cursor SDL_Cursor; /* Implementation dependent */ /** - * \brief Cursor types for SDL_CreateSystemCursor. + * \brief Cursor types for SDL_CreateSystemCursor(). */ typedef enum { @@ -254,9 +254,11 @@ extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void); /** - * \brief Frees a cursor created with SDL_CreateCursor(). + * \brief Frees a cursor created with SDL_CreateCursor() or similar functions. * * \sa SDL_CreateCursor() + * \sa SDL_CreateColorCursor() + * \sa SDL_CreateSystemCursor() */ extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor); diff --git a/Engine/lib/sdl/include/SDL_opengles.h b/Engine/lib/sdl/include/SDL_opengles.h index bcc127779..15abee796 100644 --- a/Engine/lib/sdl/include/SDL_opengles.h +++ b/Engine/lib/sdl/include/SDL_opengles.h @@ -24,6 +24,7 @@ * * This is a simple file to encapsulate the OpenGL ES 1.X API headers. */ +#include "SDL_config.h" #ifdef __IPHONEOS__ #include diff --git a/Engine/lib/sdl/include/SDL_opengles2.h b/Engine/lib/sdl/include/SDL_opengles2.h index edcd1a24a..c961f0f7d 100644 --- a/Engine/lib/sdl/include/SDL_opengles2.h +++ b/Engine/lib/sdl/include/SDL_opengles2.h @@ -24,6 +24,8 @@ * * This is a simple file to encapsulate the OpenGL ES 2.0 API headers. */ +#include "SDL_config.h" + #ifndef _MSC_VER #ifdef __IPHONEOS__ diff --git a/Engine/lib/sdl/include/SDL_pixels.h b/Engine/lib/sdl/include/SDL_pixels.h index 8499c3289..cf6a33f08 100644 --- a/Engine/lib/sdl/include/SDL_pixels.h +++ b/Engine/lib/sdl/include/SDL_pixels.h @@ -29,6 +29,7 @@ #define _SDL_pixels_h #include "SDL_stdinc.h" +#include "SDL_endian.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ @@ -260,6 +261,19 @@ enum SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_2101010, 32, 4), + /* Aliases for RGBA byte arrays of color data, for the current platform */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888, +#else + SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, + SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888, +#endif + SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */ SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'), SDL_PIXELFORMAT_IYUV = /**< Planar mode: Y + U + V (3 planes) */ diff --git a/Engine/lib/sdl/include/SDL_platform.h b/Engine/lib/sdl/include/SDL_platform.h index c6c21398b..03cf17061 100644 --- a/Engine/lib/sdl/include/SDL_platform.h +++ b/Engine/lib/sdl/include/SDL_platform.h @@ -70,18 +70,22 @@ /* lets us know what version of Mac OS X we're compiling on */ #include "AvailabilityMacros.h" #include "TargetConditionals.h" +#if TARGET_OS_TV +#undef __TVOS__ +#define __TVOS__ 1 +#endif #if TARGET_OS_IPHONE -/* if compiling for iPhone */ +/* if compiling for iOS */ #undef __IPHONEOS__ #define __IPHONEOS__ 1 #undef __MACOSX__ #else -/* if not compiling for iPhone */ +/* if not compiling for iOS */ #undef __MACOSX__ #define __MACOSX__ 1 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 -# error SDL for Mac OS X only supports deploying on 10.5 and above. -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +# error SDL for Mac OS X only supports deploying on 10.6 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ #endif /* TARGET_OS_IPHONE */ #endif /* defined(__APPLE__) */ diff --git a/Engine/lib/sdl/include/SDL_render.h b/Engine/lib/sdl/include/SDL_render.h index e4ed2af69..60c87b66a 100644 --- a/Engine/lib/sdl/include/SDL_render.h +++ b/Engine/lib/sdl/include/SDL_render.h @@ -499,6 +499,30 @@ extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, in */ extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h); +/** + * \brief Set whether to force integer scales for resolution-independent rendering + * + * \param renderer The renderer for which integer scaling should be set. + * \param enable Enable or disable integer scaling + * + * This function restricts the logical viewport to integer values - that is, when + * a resolution is between two multiples of a logical size, the viewport size is + * rounded down to the lower multiple. + * + * \sa SDL_RenderSetLogicalSize() + */ +extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer, + SDL_bool enable); + +/** + * \brief Get whether integer scales are forced for resolution-independent rendering + * + * \param renderer The renderer from which integer scaling should be queried. + * + * \sa SDL_RenderSetIntegerScale() + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer); + /** * \brief Set the drawing area for rendering on the current target. * @@ -658,7 +682,8 @@ extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, /** * \brief Clear the current rendering target with the drawing color * - * This function clears the entire rendering target, ignoring the viewport. + * This function clears the entire rendering target, ignoring the viewport and + * the clip rectangle. * * \return 0 on success, or -1 on error */ diff --git a/Engine/lib/sdl/include/SDL_revision.h b/Engine/lib/sdl/include/SDL_revision.h index 6d7163d4d..341dc5cce 100644 --- a/Engine/lib/sdl/include/SDL_revision.h +++ b/Engine/lib/sdl/include/SDL_revision.h @@ -1,2 +1,2 @@ -#define SDL_REVISION "hg-10001:e12c38730512" -#define SDL_REVISION_NUMBER 10001 +#define SDL_REVISION "hg-10556:007dfe83abf8" +#define SDL_REVISION_NUMBER 10556 diff --git a/Engine/lib/sdl/include/SDL_rwops.h b/Engine/lib/sdl/include/SDL_rwops.h index f460ae7d4..1ad3ac406 100644 --- a/Engine/lib/sdl/include/SDL_rwops.h +++ b/Engine/lib/sdl/include/SDL_rwops.h @@ -39,12 +39,12 @@ extern "C" { #endif /* RWops Types */ -#define SDL_RWOPS_UNKNOWN 0 /* Unknown stream type */ -#define SDL_RWOPS_WINFILE 1 /* Win32 file */ -#define SDL_RWOPS_STDFILE 2 /* Stdio file */ -#define SDL_RWOPS_JNIFILE 3 /* Android asset */ -#define SDL_RWOPS_MEMORY 4 /* Memory stream */ -#define SDL_RWOPS_MEMORY_RO 5 /* Read-Only memory stream */ +#define SDL_RWOPS_UNKNOWN 0U /* Unknown stream type */ +#define SDL_RWOPS_WINFILE 1U /* Win32 file */ +#define SDL_RWOPS_STDFILE 2U /* Stdio file */ +#define SDL_RWOPS_JNIFILE 3U /* Android asset */ +#define SDL_RWOPS_MEMORY 4U /* Memory stream */ +#define SDL_RWOPS_MEMORY_RO 5U /* Read-Only memory stream */ /** * This is the read/write operation structure -- very basic. diff --git a/Engine/lib/sdl/include/SDL_stdinc.h b/Engine/lib/sdl/include/SDL_stdinc.h index 887bcd2d4..fdf96415f 100644 --- a/Engine/lib/sdl/include/SDL_stdinc.h +++ b/Engine/lib/sdl/include/SDL_stdinc.h @@ -83,9 +83,6 @@ #ifdef HAVE_FLOAT_H # include #endif -#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) -# include -#endif /** * The number of elements in an array. @@ -93,6 +90,13 @@ #define SDL_arraysize(array) (sizeof(array)/sizeof(array[0])) #define SDL_TABLESIZE(table) SDL_arraysize(table) +/** + * Macro useful for building other macros with strings in them + * + * e.g. #define LOG_ERROR(X) OutputDebugString(SDL_STRINGIFY_ARG(__FUNCTION__) ": " X "\n") + */ +#define SDL_STRINGIFY_ARG(arg) #arg + /** * \name Cast operators * diff --git a/Engine/lib/sdl/include/SDL_surface.h b/Engine/lib/sdl/include/SDL_surface.h index e63ca8903..e4a06a204 100644 --- a/Engine/lib/sdl/include/SDL_surface.h +++ b/Engine/lib/sdl/include/SDL_surface.h @@ -118,6 +118,8 @@ typedef int (*SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect, extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface (Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat + (Uint32 flags, int width, int height, int depth, Uint32 format); extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, @@ -127,6 +129,8 @@ extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom + (void *pixels, int width, int height, int depth, int pitch, Uint32 format); extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface); /** @@ -184,6 +188,12 @@ extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP_RW(SDL_RWops * src, /** * Save a surface to a seekable SDL data stream (memory or file). * + * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + * BMP directly. Other RGB formats with 8-bit or higher get converted to a + * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + * not supported. + * * If \c freedst is non-zero, the stream will be closed after being written. * * \return 0 if successful or -1 if there was an error. diff --git a/Engine/lib/sdl/include/SDL_syswm.h b/Engine/lib/sdl/include/SDL_syswm.h index 1056e526b..71ba5f1f3 100644 --- a/Engine/lib/sdl/include/SDL_syswm.h +++ b/Engine/lib/sdl/include/SDL_syswm.h @@ -106,6 +106,10 @@ typedef struct ANativeWindow ANativeWindow; typedef void *EGLSurface; #endif +#if defined(SDL_VIDEO_DRIVER_VIVANTE) +#include "SDL_egl.h" +#endif + /** * These are the various supported windowing subsystems */ @@ -120,7 +124,8 @@ typedef enum SDL_SYSWM_WAYLAND, SDL_SYSWM_MIR, SDL_SYSWM_WINRT, - SDL_SYSWM_ANDROID + SDL_SYSWM_ANDROID, + SDL_SYSWM_VIVANTE } SDL_SYSWM_TYPE; /** @@ -166,6 +171,13 @@ struct SDL_SysWMmsg int dummy; /* No UIKit window events yet */ } uikit; +#endif +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + int dummy; + /* No Vivante window events yet */ + } vivante; #endif /* Can't have an empty union */ int dummy; @@ -259,6 +271,14 @@ struct SDL_SysWMinfo } android; #endif +#if defined(SDL_VIDEO_DRIVER_VIVANTE) + struct + { + EGLNativeDisplayType display; + EGLNativeWindowType window; + } vivante; +#endif + /* Can't have an empty union */ int dummy; } info; diff --git a/Engine/lib/sdl/include/SDL_version.h b/Engine/lib/sdl/include/SDL_version.h index de1f16056..1700efdd1 100644 --- a/Engine/lib/sdl/include/SDL_version.h +++ b/Engine/lib/sdl/include/SDL_version.h @@ -59,7 +59,7 @@ typedef struct SDL_version */ #define SDL_MAJOR_VERSION 2 #define SDL_MINOR_VERSION 0 -#define SDL_PATCHLEVEL 4 +#define SDL_PATCHLEVEL 5 /** * \brief Macro to determine SDL version program was compiled against. diff --git a/Engine/lib/sdl/include/SDL_video.h b/Engine/lib/sdl/include/SDL_video.h index 52dbbc765..73c33eb32 100644 --- a/Engine/lib/sdl/include/SDL_video.h +++ b/Engine/lib/sdl/include/SDL_video.h @@ -83,6 +83,7 @@ typedef struct * \sa SDL_SetWindowPosition() * \sa SDL_SetWindowSize() * \sa SDL_SetWindowBordered() + * \sa SDL_SetWindowResizable() * \sa SDL_SetWindowTitle() * \sa SDL_ShowWindow() */ @@ -95,6 +96,7 @@ typedef struct SDL_Window SDL_Window; */ typedef enum { + /* !!! FIXME: change this to name = (1<id) == device); - if (!device->enabled) { + if (!SDL_AtomicGet(&device->enabled)) { return; } /* Ends the audio callback and mark the device as STOPPED, but the app still needs to close the device to free resources. */ current_audio.impl.LockDevice(device); - device->enabled = 0; + SDL_AtomicSet(&device->enabled, 0); current_audio.impl.UnlockDevice(device); /* Post the event, if desired */ @@ -404,13 +421,26 @@ mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *remove void SDL_RemoveAudioDevice(const int iscapture, void *handle) { + int device_index; + SDL_AudioDevice *device = NULL; + SDL_LockMutex(current_audio.detectionLock); if (iscapture) { mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved); } else { mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved); } + for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++) + { + device = open_devices[device_index]; + if (device != NULL && device->handle == handle) + { + SDL_OpenedAudioDeviceDisconnected(device); + break; + } + } SDL_UnlockMutex(current_audio.detectionLock); + current_audio.impl.FreeDeviceHandle(handle); } @@ -420,77 +450,24 @@ SDL_RemoveAudioDevice(const int iscapture, void *handle) /* this expects that you managed thread safety elsewhere. */ static void -free_audio_queue(SDL_AudioBufferQueue *buffer) +free_audio_queue(SDL_AudioBufferQueue *packet) { - while (buffer) { - SDL_AudioBufferQueue *next = buffer->next; - SDL_free(buffer); - buffer = next; + while (packet) { + SDL_AudioBufferQueue *next = packet->next; + SDL_free(packet); + packet = next; } } -static void SDLCALL -SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int _len) +/* NOTE: This assumes you'll hold the mixer lock before calling! */ +static int +queue_audio_to_device(SDL_AudioDevice *device, const Uint8 *data, Uint32 len) { - /* this function always holds the mixer lock before being called. */ - Uint32 len = (Uint32) _len; - SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; - SDL_AudioBufferQueue *buffer; - - SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ - SDL_assert(_len >= 0); /* this shouldn't ever happen, right?! */ - - while ((len > 0) && ((buffer = device->buffer_queue_head) != NULL)) { - const Uint32 avail = buffer->datalen - buffer->startpos; - const Uint32 cpy = SDL_min(len, avail); - SDL_assert(device->queued_bytes >= avail); - - SDL_memcpy(stream, buffer->data + buffer->startpos, cpy); - buffer->startpos += cpy; - stream += cpy; - device->queued_bytes -= cpy; - len -= cpy; - - if (buffer->startpos == buffer->datalen) { /* packet is done, put it in the pool. */ - device->buffer_queue_head = buffer->next; - SDL_assert((buffer->next != NULL) || (buffer == device->buffer_queue_tail)); - buffer->next = device->buffer_queue_pool; - device->buffer_queue_pool = buffer; - } - } - - SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0)); - - if (len > 0) { /* fill any remaining space in the stream with silence. */ - SDL_assert(device->buffer_queue_head == NULL); - SDL_memset(stream, device->spec.silence, len); - } - - if (device->buffer_queue_head == NULL) { - device->buffer_queue_tail = NULL; /* in case we drained the queue entirely. */ - } -} - -int -SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len) -{ - SDL_AudioDevice *device = get_audio_device(devid); - const Uint8 *data = (const Uint8 *) _data; SDL_AudioBufferQueue *orighead; SDL_AudioBufferQueue *origtail; Uint32 origlen; Uint32 datalen; - if (!device) { - return -1; /* get_audio_device() will have set the error state */ - } - - if (device->spec.callback != SDL_BufferQueueDrainCallback) { - return SDL_SetError("Audio device has a callback, queueing not allowed"); - } - - current_audio.impl.LockDevice(device); - orighead = device->buffer_queue_head; origtail = device->buffer_queue_tail; origlen = origtail ? origtail->datalen : 0; @@ -520,8 +497,6 @@ SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len) device->buffer_queue_tail = origtail; device->buffer_queue_pool = NULL; - current_audio.impl.UnlockDevice(device); - free_audio_queue(packet); /* give back what we can. */ return SDL_OutOfMemory(); @@ -548,22 +523,142 @@ SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len) device->queued_bytes += datalen; } - current_audio.impl.UnlockDevice(device); - return 0; } +/* NOTE: This assumes you'll hold the mixer lock before calling! */ +static Uint32 +dequeue_audio_from_device(SDL_AudioDevice *device, Uint8 *stream, Uint32 len) +{ + SDL_AudioBufferQueue *packet; + Uint8 *ptr = stream; + + while ((len > 0) && ((packet = device->buffer_queue_head) != NULL)) { + const Uint32 avail = packet->datalen - packet->startpos; + const Uint32 cpy = SDL_min(len, avail); + SDL_assert(device->queued_bytes >= avail); + + SDL_memcpy(ptr, packet->data + packet->startpos, cpy); + packet->startpos += cpy; + ptr += cpy; + device->queued_bytes -= cpy; + len -= cpy; + + if (packet->startpos == packet->datalen) { /* packet is done, put it in the pool. */ + device->buffer_queue_head = packet->next; + SDL_assert((packet->next != NULL) || (packet == device->buffer_queue_tail)); + packet->next = device->buffer_queue_pool; + device->buffer_queue_pool = packet; + } + } + + SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0)); + + if (device->buffer_queue_head == NULL) { + device->buffer_queue_tail = NULL; /* in case we drained the queue entirely. */ + } + + return (Uint32) (ptr - stream); +} + +static void SDLCALL +SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len) +{ + /* this function always holds the mixer lock before being called. */ + SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; + Uint32 written; + + SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ + SDL_assert(!device->iscapture); /* this shouldn't ever happen, right?! */ + SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ + + written = dequeue_audio_from_device(device, stream, (Uint32) len); + stream += written; + len -= (int) written; + + if (len > 0) { /* fill any remaining space in the stream with silence. */ + SDL_assert(device->buffer_queue_head == NULL); + SDL_memset(stream, device->spec.silence, len); + } +} + +static void SDLCALL +SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len) +{ + /* this function always holds the mixer lock before being called. */ + SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; + + SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ + SDL_assert(device->iscapture); /* this shouldn't ever happen, right?! */ + SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ + + /* note that if this needs to allocate more space and run out of memory, + we have no choice but to quietly drop the data and hope it works out + later, but you probably have bigger problems in this case anyhow. */ + queue_audio_to_device(device, stream, (Uint32) len); +} + +int +SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len) +{ + SDL_AudioDevice *device = get_audio_device(devid); + int rc = 0; + + if (!device) { + return -1; /* get_audio_device() will have set the error state */ + } else if (device->iscapture) { + return SDL_SetError("This is a capture device, queueing not allowed"); + } else if (device->spec.callback != SDL_BufferQueueDrainCallback) { + return SDL_SetError("Audio device has a callback, queueing not allowed"); + } + + if (len > 0) { + current_audio.impl.LockDevice(device); + rc = queue_audio_to_device(device, data, len); + current_audio.impl.UnlockDevice(device); + } + + return rc; +} + +Uint32 +SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len) +{ + SDL_AudioDevice *device = get_audio_device(devid); + Uint32 rc; + + if ( (len == 0) || /* nothing to do? */ + (!device) || /* called with bogus device id */ + (!device->iscapture) || /* playback devices can't dequeue */ + (device->spec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */ + return 0; /* just report zero bytes dequeued. */ + } + + current_audio.impl.LockDevice(device); + rc = dequeue_audio_from_device(device, data, len); + current_audio.impl.UnlockDevice(device); + return rc; +} + Uint32 SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid) { Uint32 retval = 0; SDL_AudioDevice *device = get_audio_device(devid); + if (!device) { + return 0; + } + /* Nothing to do unless we're set up for queueing. */ - if (device && (device->spec.callback == SDL_BufferQueueDrainCallback)) { + if (device->spec.callback == SDL_BufferQueueDrainCallback) { current_audio.impl.LockDevice(device); retval = device->queued_bytes + current_audio.impl.GetPendingBytes(device); current_audio.impl.UnlockDevice(device); + } else if (device->spec.callback == SDL_BufferQueueFillCallback) { + current_audio.impl.LockDevice(device); + retval = device->queued_bytes; + current_audio.impl.UnlockDevice(device); } return retval; @@ -573,25 +668,49 @@ void SDL_ClearQueuedAudio(SDL_AudioDeviceID devid) { SDL_AudioDevice *device = get_audio_device(devid); - SDL_AudioBufferQueue *buffer = NULL; + SDL_AudioBufferQueue *packet; + if (!device) { return; /* nothing to do. */ } /* Blank out the device and release the mutex. Free it afterwards. */ current_audio.impl.LockDevice(device); - buffer = device->buffer_queue_head; + + /* merge the available pool and the current queue into one list. */ + packet = device->buffer_queue_head; + if (packet) { + device->buffer_queue_tail->next = device->buffer_queue_pool; + } else { + packet = device->buffer_queue_pool; + } + + /* Remove the queued packets from the device. */ device->buffer_queue_tail = NULL; device->buffer_queue_head = NULL; device->queued_bytes = 0; + device->buffer_queue_pool = packet; + + /* Keep up to two packets in the pool to reduce future malloc pressure. */ + if (packet) { + if (!packet->next) { + packet = NULL; /* one packet (the only one) for the pool. */ + } else { + SDL_AudioBufferQueue *next = packet->next->next; + packet->next->next = NULL; /* two packets for the pool. */ + packet = next; /* rest will be freed. */ + } + } + current_audio.impl.UnlockDevice(device); - free_audio_queue(buffer); + /* free any extra packets we didn't keep in the pool. */ + free_audio_queue(packet); } /* The general mixing thread function */ -int SDLCALL +static int SDLCALL SDL_RunAudio(void *devicep) { SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; @@ -600,7 +719,9 @@ SDL_RunAudio(void *devicep) const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size; Uint8 *stream; void *udata = device->spec.userdata; - void (SDLCALL *fill) (void *, Uint8 *, int) = device->spec.callback; + void (SDLCALL *callback) (void *, Uint8 *, int) = device->spec.callback; + + SDL_assert(!device->iscapture); /* The audio mixing is always a high priority thread */ SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); @@ -610,11 +731,11 @@ SDL_RunAudio(void *devicep) current_audio.impl.ThreadInit(device); /* Loop, filling the audio buffers */ - while (!device->shutdown) { + while (!SDL_AtomicGet(&device->shutdown)) { /* Fill the current buffer with sound */ if (device->convert.needed) { stream = device->convert.buf; - } else if (device->enabled) { + } else if (SDL_AtomicGet(&device->enabled)) { stream = current_audio.impl.GetDeviceBuf(device); } else { /* if the device isn't enabled, we still write to the @@ -630,16 +751,18 @@ SDL_RunAudio(void *devicep) } /* !!! FIXME: this should be LockDevice. */ - SDL_LockMutex(device->mixer_lock); - if (device->paused) { - SDL_memset(stream, silence, stream_len); - } else { - (*fill) (udata, stream, stream_len); + if ( SDL_AtomicGet(&device->enabled) ) { + SDL_LockMutex(device->mixer_lock); + if (SDL_AtomicGet(&device->paused)) { + SDL_memset(stream, silence, stream_len); + } else { + (*callback) (udata, stream, stream_len); + } + SDL_UnlockMutex(device->mixer_lock); } - SDL_UnlockMutex(device->mixer_lock); /* Convert the audio if necessary */ - if (device->enabled && device->convert.needed) { + if (device->convert.needed && SDL_AtomicGet(&device->enabled)) { SDL_ConvertAudio(&device->convert); stream = current_audio.impl.GetDeviceBuf(device); if (stream == NULL) { @@ -659,8 +782,91 @@ SDL_RunAudio(void *devicep) } } + current_audio.impl.PrepareToClose(device); + /* Wait for the audio to drain. */ - current_audio.impl.WaitDone(device); + SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2); + + return 0; +} + +/* The general capture thread function */ +static int SDLCALL +SDL_CaptureAudio(void *devicep) +{ + SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; + const int silence = (int) device->spec.silence; + const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); + const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size; + Uint8 *stream; + void *udata = device->spec.userdata; + void (SDLCALL *callback) (void *, Uint8 *, int) = device->spec.callback; + + SDL_assert(device->iscapture); + + /* The audio mixing is always a high priority thread */ + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + + /* Perform any thread setup */ + device->threadid = SDL_ThreadID(); + current_audio.impl.ThreadInit(device); + + /* Loop, filling the audio buffers */ + while (!SDL_AtomicGet(&device->shutdown)) { + int still_need; + Uint8 *ptr; + + if (!SDL_AtomicGet(&device->enabled) || SDL_AtomicGet(&device->paused)) { + SDL_Delay(delay); /* just so we don't cook the CPU. */ + current_audio.impl.FlushCapture(device); /* dump anything pending. */ + continue; + } + + /* Fill the current buffer with sound */ + still_need = stream_len; + if (device->convert.needed) { + ptr = stream = device->convert.buf; + } else { + /* just use the "fake" stream to hold data read from the device. */ + ptr = stream = device->fake_stream; + } + + /* We still read from the device when "paused" to keep the state sane, + and block when there isn't data so this thread isn't eating CPU. + But we don't process it further or call the app's callback. */ + + while (still_need > 0) { + const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need); + SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */ + if (rc > 0) { + still_need -= rc; + ptr += rc; + } else { /* uhoh, device failed for some reason! */ + SDL_OpenedAudioDeviceDisconnected(device); + break; + } + } + + if (still_need > 0) { + /* Keep any data we already read, silence the rest. */ + SDL_memset(ptr, silence, still_need); + } + + if (device->convert.needed) { + SDL_ConvertAudio(&device->convert); + } + + /* !!! FIXME: this should be LockDevice. */ + SDL_LockMutex(device->mixer_lock); + if (SDL_AtomicGet(&device->paused)) { + current_audio.impl.FlushCapture(device); /* one snuck in! */ + } else { + (*callback)(udata, stream, stream_len); + } + SDL_UnlockMutex(device->mixer_lock); + } + + current_audio.impl.FlushCapture(device); return 0; } @@ -757,7 +963,7 @@ SDL_AudioInit(const char *driver_name) current_audio.detectionLock = SDL_CreateMutex(); - finalize_audio_entry_points(); + finish_audio_entry_points_init(); /* Make sure we have a list of devices available at startup. */ current_audio.impl.DetectDevices(); @@ -872,27 +1078,38 @@ SDL_GetAudioDeviceName(int index, int iscapture) static void close_audio_device(SDL_AudioDevice * device) { - device->enabled = 0; - device->shutdown = 1; + if (!device) { + return; + } + + if (device->id > 0) { + SDL_AudioDevice *opendev = open_devices[device->id - 1]; + SDL_assert((opendev == device) || (opendev == NULL)); + if (opendev == device) { + open_devices[device->id - 1] = NULL; + } + } + + SDL_AtomicSet(&device->shutdown, 1); + SDL_AtomicSet(&device->enabled, 0); if (device->thread != NULL) { SDL_WaitThread(device->thread, NULL); } if (device->mixer_lock != NULL) { SDL_DestroyMutex(device->mixer_lock); } - SDL_FreeAudioMem(device->fake_stream); + SDL_free(device->fake_stream); if (device->convert.needed) { - SDL_FreeAudioMem(device->convert.buf); + SDL_free(device->convert.buf); } - if (device->opened) { + if (device->hidden != NULL) { current_audio.impl.CloseDevice(device); - device->opened = 0; } free_audio_queue(device->buffer_queue_head); free_audio_queue(device->buffer_queue_pool); - SDL_FreeAudioMem(device); + SDL_free(device); } @@ -963,12 +1180,12 @@ open_audio_device(const char *devname, int iscapture, const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, int allowed_changes, int min_id) { + const SDL_bool is_internal_thread = (desired->callback != NULL); SDL_AudioDeviceID id = 0; SDL_AudioSpec _obtained; SDL_AudioDevice *device; SDL_bool build_cvt; void *handle = NULL; - Uint32 stream_len; int i = 0; if (!SDL_WasInit(SDL_INIT_AUDIO)) { @@ -981,6 +1198,7 @@ open_audio_device(const char *devname, int iscapture, return 0; } + /* !!! FIXME: there is a race condition here if two devices open from two threads at once. */ /* Find an available device ID... */ for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) { if (open_devices[id] == NULL) { @@ -1015,7 +1233,7 @@ open_audio_device(const char *devname, int iscapture, * opens of the default system device. */ - if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { + if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) { if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) { SDL_SetError("No such device"); return 0; @@ -1067,17 +1285,19 @@ open_audio_device(const char *devname, int iscapture, } } - device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice)); + device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice)); if (device == NULL) { SDL_OutOfMemory(); return 0; } - SDL_zerop(device); device->id = id + 1; device->spec = *obtained; - device->enabled = 1; - device->paused = 1; - device->iscapture = iscapture; + device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; + device->handle = handle; + + SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ + SDL_AtomicSet(&device->paused, 1); + SDL_AtomicSet(&device->enabled, 1); /* Create a mutex for locking the sound buffers */ if (!current_audio.impl.SkipMixerLock) { @@ -1093,7 +1313,10 @@ open_audio_device(const char *devname, int iscapture, close_audio_device(device); return 0; } - device->opened = 1; + + /* if your target really doesn't need it, set it to 0x1 or something. */ + /* otherwise, close_audio_device() won't call impl.CloseDevice(). */ + SDL_assert(device->hidden != NULL); /* See if we need to do any conversion */ build_cvt = SDL_FALSE; @@ -1143,7 +1366,7 @@ open_audio_device(const char *devname, int iscapture, device->convert.len_ratio); device->convert.buf = - (Uint8 *) SDL_AllocAudioMem(device->convert.len * + (Uint8 *) SDL_malloc(device->convert.len * device->convert.len_mult); if (device->convert.buf == NULL) { close_audio_device(device); @@ -1153,19 +1376,6 @@ open_audio_device(const char *devname, int iscapture, } } - /* Allocate a fake audio memory buffer */ - stream_len = (device->convert.needed) ? device->convert.len_cvt : 0; - if (device->spec.size > stream_len) { - stream_len = device->spec.size; - } - SDL_assert(stream_len > 0); - device->fake_stream = (Uint8 *)SDL_AllocAudioMem(stream_len); - if (device->fake_stream == NULL) { - close_audio_device(device); - SDL_OutOfMemory(); - return 0; - } - if (device->spec.callback == NULL) { /* use buffer queueing? */ /* pool a few packets to start. Enough for two callbacks. */ const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN; @@ -1181,7 +1391,7 @@ open_audio_device(const char *devname, int iscapture, } } - device->spec.callback = SDL_BufferQueueDrainCallback; + device->spec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback; device->spec.userdata = device; } @@ -1191,21 +1401,30 @@ open_audio_device(const char *devname, int iscapture, /* Start the audio thread if necessary */ if (!current_audio.impl.ProvidesOwnCallbackThread) { /* Start the audio thread */ - char name[64]; - SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id); -/* !!! FIXME: this is nasty. */ -#if defined(__WIN32__) && !defined(HAVE_LIBC) -#undef SDL_CreateThread -#if SDL_DYNAMIC_API - device->thread = SDL_CreateThread_REAL(SDL_RunAudio, name, device, NULL, NULL); -#else - device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL); -#endif -#else - device->thread = SDL_CreateThread(SDL_RunAudio, name, device); -#endif + /* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */ + /* buffer queueing callback only needs a few bytes, so make the stack tiny. */ + const size_t stacksize = is_internal_thread ? 64 * 1024 : 0; + char threadname[64]; + + /* Allocate a fake audio buffer; only used by our internal threads. */ + Uint32 stream_len = (device->convert.needed) ? device->convert.len_cvt : 0; + if (device->spec.size > stream_len) { + stream_len = device->spec.size; + } + SDL_assert(stream_len > 0); + + device->fake_stream = (Uint8 *) SDL_malloc(stream_len); + if (device->fake_stream == NULL) { + close_audio_device(device); + SDL_OutOfMemory(); + return 0; + } + + SDL_snprintf(threadname, sizeof (threadname), "SDLAudioDev%d", (int) device->id); + device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device); + if (device->thread == NULL) { - SDL_CloseAudioDevice(device->id); + close_audio_device(device); SDL_SetError("Couldn't create audio thread"); return 0; } @@ -1258,8 +1477,8 @@ SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) { SDL_AudioDevice *device = get_audio_device(devid); SDL_AudioStatus status = SDL_AUDIO_STOPPED; - if (device && device->enabled) { - if (device->paused) { + if (device && SDL_AtomicGet(&device->enabled)) { + if (SDL_AtomicGet(&device->paused)) { status = SDL_AUDIO_PAUSED; } else { status = SDL_AUDIO_PLAYING; @@ -1281,7 +1500,7 @@ SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) SDL_AudioDevice *device = get_audio_device(devid); if (device) { current_audio.impl.LockDevice(device); - device->paused = pause_on; + SDL_AtomicSet(&device->paused, pause_on ? 1 : 0); current_audio.impl.UnlockDevice(device); } } @@ -1328,11 +1547,7 @@ SDL_UnlockAudio(void) void SDL_CloseAudioDevice(SDL_AudioDeviceID devid) { - SDL_AudioDevice *device = get_audio_device(devid); - if (device) { - close_audio_device(device); - open_devices[devid - 1] = NULL; - } + close_audio_device(get_audio_device(devid)); } void @@ -1351,9 +1566,7 @@ SDL_AudioQuit(void) } for (i = 0; i < SDL_arraysize(open_devices); i++) { - if (open_devices[i] != NULL) { - SDL_CloseAudioDevice(i+1); - } + close_audio_device(open_devices[i]); } free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); diff --git a/Engine/lib/sdl/src/audio/SDL_audio_c.h b/Engine/lib/sdl/src/audio/SDL_audio_c.h index b03a9156f..7cde3a662 100644 --- a/Engine/lib/sdl/src/audio/SDL_audio_c.h +++ b/Engine/lib/sdl/src/audio/SDL_audio_c.h @@ -29,9 +29,6 @@ extern SDL_AudioFormat SDL_NextAudioFormat(void); /* Function to calculate the size and silence for a SDL_AudioSpec */ extern void SDL_CalculateAudioSpec(SDL_AudioSpec * spec); -/* The actual mixing thread function */ -extern int SDLCALL SDL_RunAudio(void *audiop); - /* this is used internally to access some autogenerated code. */ typedef struct { diff --git a/Engine/lib/sdl/src/audio/SDL_mixer.c b/Engine/lib/sdl/src/audio/SDL_mixer.c index b49c73dab..e0219392d 100644 --- a/Engine/lib/sdl/src/audio/SDL_mixer.c +++ b/Engine/lib/sdl/src/audio/SDL_mixer.c @@ -202,6 +202,54 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format, } break; + case AUDIO_U16LSB: + { + Uint16 src1, src2; + int dst_sample; + const int max_audioval = 0xFFFF; + + len /= 2; + while (len--) { + src1 = ((src[1]) << 8 | src[0]); + ADJUST_VOLUME(src1, volume); + src2 = ((dst[1]) << 8 | dst[0]); + src += 2; + dst_sample = src1 + src2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } + dst[0] = dst_sample & 0xFF; + dst_sample >>= 8; + dst[1] = dst_sample & 0xFF; + dst += 2; + } + } + break; + + case AUDIO_U16MSB: + { + Uint16 src1, src2; + int dst_sample; + const int max_audioval = 0xFFFF; + + len /= 2; + while (len--) { + src1 = ((src[0]) << 8 | src[1]); + ADJUST_VOLUME(src1, volume); + src2 = ((dst[0]) << 8 | dst[1]); + src += 2; + dst_sample = src1 + src2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } + dst[1] = dst_sample & 0xFF; + dst_sample >>= 8; + dst[0] = dst_sample & 0xFF; + dst += 2; + } + } + break; + case AUDIO_S32LSB: { const Uint32 *src32 = (Uint32 *) src; @@ -313,7 +361,7 @@ SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format, break; default: /* If this happens... FIXME! */ - SDL_SetError("SDL_MixAudio(): unknown audio format"); + SDL_SetError("SDL_MixAudioFormat(): unknown audio format"); return; } } diff --git a/Engine/lib/sdl/src/audio/SDL_sysaudio.h b/Engine/lib/sdl/src/audio/SDL_sysaudio.h index 426a190f1..943169bf7 100644 --- a/Engine/lib/sdl/src/audio/SDL_sysaudio.h +++ b/Engine/lib/sdl/src/audio/SDL_sysaudio.h @@ -26,6 +26,10 @@ #include "SDL_mutex.h" #include "SDL_thread.h" +/* !!! FIXME: These are wordy and unlocalized... */ +#define DEFAULT_OUTPUT_DEVNAME "System audio output device" +#define DEFAULT_INPUT_DEVNAME "System audio capture device" + /* The SDL audio driver */ typedef struct SDL_AudioDevice SDL_AudioDevice; #define _THIS SDL_AudioDevice *_this @@ -75,7 +79,9 @@ typedef struct SDL_AudioDriverImpl void (*PlayDevice) (_THIS); int (*GetPendingBytes) (_THIS); Uint8 *(*GetDeviceBuf) (_THIS); - void (*WaitDone) (_THIS); + int (*CaptureFromDevice) (_THIS, void *buffer, int buflen); + void (*FlushCapture) (_THIS); + void (*PrepareToClose) (_THIS); /**< Called between run and draining wait for playback devices */ void (*CloseDevice) (_THIS); void (*LockDevice) (_THIS); void (*UnlockDevice) (_THIS); @@ -87,10 +93,10 @@ typedef struct SDL_AudioDriverImpl /* Some flags to push duplicate code into the core and reduce #ifdefs. */ /* !!! FIXME: these should be SDL_bool */ int ProvidesOwnCallbackThread; - int SkipMixerLock; /* !!! FIXME: do we need this anymore? */ + int SkipMixerLock; int HasCaptureSupport; int OnlyHasDefaultOutputDevice; - int OnlyHasDefaultInputDevice; + int OnlyHasDefaultCaptureDevice; int AllowsArbitraryDeviceNames; } SDL_AudioDriverImpl; @@ -157,12 +163,10 @@ struct SDL_AudioDevice SDL_AudioStreamer streamer; /* Current state flags */ - /* !!! FIXME: should be SDL_bool */ - int iscapture; - int enabled; /* true if device is functioning and connected. */ - int shutdown; /* true if we are signaling the play thread to end. */ - int paused; - int opened; + SDL_atomic_t shutdown; /* true if we are signaling the play thread to end. */ + SDL_atomic_t enabled; /* true if device is functioning and connected. */ + SDL_atomic_t paused; + SDL_bool iscapture; /* Fake audio buffer for when the audio hardware is busy */ Uint8 *fake_stream; @@ -183,6 +187,8 @@ struct SDL_AudioDevice /* * * */ /* Data private to this driver */ struct SDL_PrivateAudioData *hidden; + + void *handle; }; #undef _THIS diff --git a/Engine/lib/sdl/src/audio/SDL_wave.c b/Engine/lib/sdl/src/audio/SDL_wave.c index 99daac64b..d173b4a92 100644 --- a/Engine/lib/sdl/src/audio/SDL_wave.c +++ b/Engine/lib/sdl/src/audio/SDL_wave.c @@ -504,7 +504,7 @@ SDL_LoadWAV_RW(SDL_RWops * src, int freesrc, was_error = 1; goto done; } - SDL_memset(spec, 0, (sizeof *spec)); + SDL_zerop(spec); spec->freq = SDL_SwapLE32(format->frequency); if (IEEE_float_encoded) { diff --git a/Engine/lib/sdl/src/audio/alsa/SDL_alsa_audio.c b/Engine/lib/sdl/src/audio/alsa/SDL_alsa_audio.c index af952371b..574d51bd5 100644 --- a/Engine/lib/sdl/src/audio/alsa/SDL_alsa_audio.c +++ b/Engine/lib/sdl/src/audio/alsa/SDL_alsa_audio.c @@ -29,9 +29,9 @@ #include #include +#include "SDL_assert.h" #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_alsa_audio.h" @@ -42,8 +42,10 @@ static int (*ALSA_snd_pcm_open) (snd_pcm_t **, const char *, snd_pcm_stream_t, int); static int (*ALSA_snd_pcm_close) (snd_pcm_t * pcm); -static snd_pcm_sframes_t(*ALSA_snd_pcm_writei) +static snd_pcm_sframes_t (*ALSA_snd_pcm_writei) (snd_pcm_t *, const void *, snd_pcm_uframes_t); +static snd_pcm_sframes_t (*ALSA_snd_pcm_readi) + (snd_pcm_t *, void *, snd_pcm_uframes_t); static int (*ALSA_snd_pcm_recover) (snd_pcm_t *, int, int); static int (*ALSA_snd_pcm_prepare) (snd_pcm_t *); static int (*ALSA_snd_pcm_drain) (snd_pcm_t *); @@ -85,6 +87,10 @@ static int (*ALSA_snd_pcm_nonblock) (snd_pcm_t *, int); static int (*ALSA_snd_pcm_wait)(snd_pcm_t *, int); static int (*ALSA_snd_pcm_sw_params_set_avail_min) (snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t); +static int (*ALSA_snd_pcm_reset)(snd_pcm_t *); +static int (*ALSA_snd_device_name_hint) (int, const char *, void ***); +static char* (*ALSA_snd_device_name_get_hint) (const void *, const char *); +static int (*ALSA_snd_device_name_free_hint) (void **); #ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC #define snd_pcm_hw_params_sizeof ALSA_snd_pcm_hw_params_sizeof @@ -118,6 +124,7 @@ load_alsa_syms(void) SDL_ALSA_SYM(snd_pcm_open); SDL_ALSA_SYM(snd_pcm_close); SDL_ALSA_SYM(snd_pcm_writei); + SDL_ALSA_SYM(snd_pcm_readi); SDL_ALSA_SYM(snd_pcm_recover); SDL_ALSA_SYM(snd_pcm_prepare); SDL_ALSA_SYM(snd_pcm_drain); @@ -144,6 +151,11 @@ load_alsa_syms(void) SDL_ALSA_SYM(snd_pcm_nonblock); SDL_ALSA_SYM(snd_pcm_wait); SDL_ALSA_SYM(snd_pcm_sw_params_set_avail_min); + SDL_ALSA_SYM(snd_pcm_reset); + SDL_ALSA_SYM(snd_device_name_hint); + SDL_ALSA_SYM(snd_device_name_get_hint); + SDL_ALSA_SYM(snd_device_name_free_hint); + return 0; } @@ -196,25 +208,27 @@ LoadALSALibrary(void) #endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ static const char * -get_audio_device(int channels) +get_audio_device(void *handle, const int channels) { const char *device; - device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */ - if (device == NULL) { - switch (channels) { - case 6: - device = "plug:surround51"; - break; - case 4: - device = "plug:surround40"; - break; - default: - device = "default"; - break; - } + if (handle != NULL) { + return (const char *) handle; } - return device; + + /* !!! FIXME: we also check "SDL_AUDIO_DEVICE_NAME" at the higher level. */ + device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */ + if (device != NULL) { + return device; + } + + if (channels == 6) { + return "plug:surround51"; + } else if (channels == 4) { + return "plug:surround40"; + } + + return "default"; } @@ -232,37 +246,37 @@ ALSA_WaitDevice(_THIS) * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE * and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR" */ -#define SWIZ6(T) \ - T *ptr = (T *) this->hidden->mixbuf; \ +#define SWIZ6(T, buf, numframes) \ + T *ptr = (T *) buf; \ Uint32 i; \ - for (i = 0; i < this->spec.samples; i++, ptr += 6) { \ + for (i = 0; i < numframes; i++, ptr += 6) { \ T tmp; \ tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \ tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \ } static SDL_INLINE void -swizzle_alsa_channels_6_64bit(_THIS) +swizzle_alsa_channels_6_64bit(void *buffer, Uint32 bufferlen) { - SWIZ6(Uint64); + SWIZ6(Uint64, buffer, bufferlen); } static SDL_INLINE void -swizzle_alsa_channels_6_32bit(_THIS) +swizzle_alsa_channels_6_32bit(void *buffer, Uint32 bufferlen) { - SWIZ6(Uint32); + SWIZ6(Uint32, buffer, bufferlen); } static SDL_INLINE void -swizzle_alsa_channels_6_16bit(_THIS) +swizzle_alsa_channels_6_16bit(void *buffer, Uint32 bufferlen) { - SWIZ6(Uint16); + SWIZ6(Uint16, buffer, bufferlen); } static SDL_INLINE void -swizzle_alsa_channels_6_8bit(_THIS) +swizzle_alsa_channels_6_8bit(void *buffer, Uint32 bufferlen) { - SWIZ6(Uint8); + SWIZ6(Uint8, buffer, bufferlen); } #undef SWIZ6 @@ -273,18 +287,16 @@ swizzle_alsa_channels_6_8bit(_THIS) * channels from Windows/Mac order to the format alsalib will want. */ static SDL_INLINE void -swizzle_alsa_channels(_THIS) +swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen) { if (this->spec.channels == 6) { - const Uint16 fmtsize = (this->spec.format & 0xFF); /* bits/channel. */ - if (fmtsize == 16) - swizzle_alsa_channels_6_16bit(this); - else if (fmtsize == 8) - swizzle_alsa_channels_6_8bit(this); - else if (fmtsize == 32) - swizzle_alsa_channels_6_32bit(this); - else if (fmtsize == 64) - swizzle_alsa_channels_6_64bit(this); + switch (SDL_AUDIO_BITSIZE(this->spec.format)) { + case 8: swizzle_alsa_channels_6_8bit(buffer, bufferlen); break; + case 16: swizzle_alsa_channels_6_16bit(buffer, bufferlen); break; + case 32: swizzle_alsa_channels_6_32bit(buffer, bufferlen); break; + case 64: swizzle_alsa_channels_6_64bit(buffer, bufferlen); break; + default: SDL_assert(!"unhandled bitsize"); break; + } } /* !!! FIXME: update this for 7.1 if needed, later. */ @@ -294,19 +306,29 @@ swizzle_alsa_channels(_THIS) static void ALSA_PlayDevice(_THIS) { - int status; const Uint8 *sample_buf = (const Uint8 *) this->hidden->mixbuf; - const int frame_size = (((int) (this->spec.format & 0xFF)) / 8) * + const int frame_size = (((int) SDL_AUDIO_BITSIZE(this->spec.format)) / 8) * this->spec.channels; snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t) this->spec.samples); - swizzle_alsa_channels(this); + swizzle_alsa_channels(this, this->hidden->mixbuf, frames_left); + + while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) { + int status; + + /* This wait is a work-around for a hang when USB devices are + unplugged. Normally it should not result in any waiting, + but in the case of a USB unplug, it serves as a way to + join the playback thread after the timeout occurs */ + status = ALSA_snd_pcm_wait(this->hidden->pcm_handle, 1000); + if (status == 0) { + /*fprintf(stderr, "ALSA timeout waiting for available buffer space\n");*/ + SDL_OpenedAudioDeviceDisconnected(this); + return; + } - while ( frames_left > 0 && this->enabled ) { - /* !!! FIXME: This works, but needs more testing before going live */ - /* ALSA_snd_pcm_wait(this->hidden->pcm_handle, -1); */ status = ALSA_snd_pcm_writei(this->hidden->pcm_handle, - sample_buf, frames_left); + sample_buf, frames_left); if (status < 0) { if (status == -EAGAIN) { @@ -336,20 +358,71 @@ ALSA_GetDeviceBuf(_THIS) return (this->hidden->mixbuf); } +static int +ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + Uint8 *sample_buf = (Uint8 *) buffer; + const int frame_size = (((int) SDL_AUDIO_BITSIZE(this->spec.format)) / 8) * + this->spec.channels; + const int total_frames = buflen / frame_size; + snd_pcm_uframes_t frames_left = total_frames; + + SDL_assert((buflen % frame_size) == 0); + + while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) { + /* !!! FIXME: This works, but needs more testing before going live */ + /* ALSA_snd_pcm_wait(this->hidden->pcm_handle, -1); */ + int status = ALSA_snd_pcm_readi(this->hidden->pcm_handle, + sample_buf, frames_left); + + if (status < 0) { + /*printf("ALSA: capture error %d\n", status);*/ + if (status == -EAGAIN) { + /* Apparently snd_pcm_recover() doesn't handle this case - + does it assume snd_pcm_wait() above? */ + SDL_Delay(1); + continue; + } + status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0); + if (status < 0) { + /* Hmm, not much we can do - abort */ + fprintf(stderr, "ALSA read failed (unrecoverable): %s\n", + ALSA_snd_strerror(status)); + return -1; + } + continue; + } + + /*printf("ALSA: captured %d bytes\n", status * frame_size);*/ + sample_buf += status * frame_size; + frames_left -= status; + } + + swizzle_alsa_channels(this, buffer, total_frames - frames_left); + + return (total_frames - frames_left) * frame_size; +} + +static void +ALSA_FlushCapture(_THIS) +{ + ALSA_snd_pcm_reset(this->hidden->pcm_handle); +} + static void ALSA_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->pcm_handle) { - ALSA_snd_pcm_drain(this->hidden->pcm_handle); - ALSA_snd_pcm_close(this->hidden->pcm_handle); - this->hidden->pcm_handle = NULL; - } - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->pcm_handle) { + /* Wait for the submitted audio to drain + ALSA_snd_pcm_drop() can hang, so don't use that. + */ + Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2; + SDL_Delay(delay); + + ALSA_snd_pcm_close(this->hidden->pcm_handle); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int @@ -482,16 +555,16 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Open the audio device */ /* Name of device should depend on # channels in spec */ status = ALSA_snd_pcm_open(&pcm_handle, - get_audio_device(this->spec.channels), - SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); + get_audio_device(handle, this->spec.channels), + iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, + SND_PCM_NONBLOCK); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status)); } @@ -502,7 +575,6 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) snd_pcm_hw_params_alloca(&hwparams); status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't get hardware config: %s", ALSA_snd_strerror(status)); } @@ -511,7 +583,6 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't set interleaved access: %s", ALSA_snd_strerror(status)); } @@ -565,7 +636,6 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } } if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't find any hardware audio formats"); } this->spec.format = test_format; @@ -577,7 +647,6 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (status < 0) { status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't set audio channels"); } this->spec.channels = channels; @@ -588,7 +657,6 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &rate, NULL); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't set audio frequency: %s", ALSA_snd_strerror(status)); } @@ -598,8 +666,8 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if ( ALSA_set_period_size(this, hwparams, 0) < 0 && ALSA_set_buffer_size(this, hwparams, 0) < 0 ) { /* Failed to set desired buffer size, do the best you can... */ - if ( ALSA_set_period_size(this, hwparams, 1) < 0 ) { - ALSA_CloseDevice(this); + status = ALSA_set_period_size(this, hwparams, 1); + if (status < 0) { return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status)); } } @@ -607,26 +675,22 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) snd_pcm_sw_params_alloca(&swparams); status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't get software config: %s", ALSA_snd_strerror(status)); } status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, this->spec.samples); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("Couldn't set minimum available samples: %s", ALSA_snd_strerror(status)); } status = ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("ALSA: Couldn't set start threshold: %s", ALSA_snd_strerror(status)); } status = ALSA_snd_pcm_sw_params(pcm_handle, swparams); if (status < 0) { - ALSA_CloseDevice(this); return SDL_SetError("Couldn't set software audio parameters: %s", ALSA_snd_strerror(status)); } @@ -635,13 +699,14 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) SDL_CalculateAudioSpec(&this->spec); /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - ALSA_CloseDevice(this); - return SDL_OutOfMemory(); + if (!iscapture) { + this->hidden->mixlen = this->spec.size; + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); + if (this->hidden->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen); } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen); /* Switch to blocking mode for playback */ ALSA_snd_pcm_nonblock(pcm_handle, 0); @@ -650,9 +715,238 @@ ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } +typedef struct ALSA_Device +{ + char *name; + SDL_bool iscapture; + struct ALSA_Device *next; +} ALSA_Device; + +static void +add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen) +{ + ALSA_Device *dev = SDL_malloc(sizeof (ALSA_Device)); + char *desc = ALSA_snd_device_name_get_hint(hint, "DESC"); + char *handle = NULL; + char *ptr; + + if (!desc) { + SDL_free(dev); + return; + } else if (!dev) { + free(desc); + return; + } + + SDL_assert(name != NULL); + + /* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output". + just chop the extra lines off, this seems to get a reasonable device + name without extra details. */ + if ((ptr = strchr(desc, '\n')) != NULL) { + *ptr = '\0'; + } + + /*printf("ALSA: adding %s device '%s' (%s)\n", iscapture ? "capture" : "output", name, desc);*/ + + handle = SDL_strdup(name); + if (!handle) { + free(desc); + SDL_free(dev); + return; + } + + SDL_AddAudioDevice(iscapture, desc, handle); + free(desc); + + dev->name = handle; + dev->iscapture = iscapture; + dev->next = *pSeen; + *pSeen = dev; +} + + +static SDL_atomic_t ALSA_hotplug_shutdown; +static SDL_Thread *ALSA_hotplug_thread; + +static int SDLCALL +ALSA_HotplugThread(void *arg) +{ + SDL_sem *first_run_semaphore = (SDL_sem *) arg; + ALSA_Device *devices = NULL; + ALSA_Device *next; + ALSA_Device *dev; + Uint32 ticks; + + while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) { + void **hints = NULL; + if (ALSA_snd_device_name_hint(-1, "pcm", &hints) != -1) { + ALSA_Device *unseen = devices; + ALSA_Device *seen = NULL; + ALSA_Device *prev; + int i, j; + const char *match = NULL; + int bestmatch = 0xFFFF; + size_t match_len = 0; + int defaultdev = -1; + static const char * const prefixes[] = { + "hw:", "sysdefault:", "default:", NULL + }; + + /* Apparently there are several different ways that ALSA lists + actual hardware. It could be prefixed with "hw:" or "default:" + or "sysdefault:" and maybe others. Go through the list and see + if we can find a preferred prefix for the system. */ + for (i = 0; hints[i]; i++) { + char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); + if (!name) { + continue; + } + + /* full name, not a prefix */ + if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) { + defaultdev = i; + } + + for (j = 0; prefixes[j]; j++) { + const char *prefix = prefixes[j]; + const size_t prefixlen = SDL_strlen(prefix); + if (SDL_strncmp(name, prefix, prefixlen) == 0) { + if (j < bestmatch) { + bestmatch = j; + match = prefix; + match_len = prefixlen; + } + } + } + + free(name); + } + + /* look through the list of device names to find matches */ + for (i = 0; hints[i]; i++) { + char *name; + + /* if we didn't find a device name prefix we like at all... */ + if ((!match) && (defaultdev != i)) { + continue; /* ...skip anything that isn't the default device. */ + } + + name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); + if (!name) { + continue; + } + + /* only want physical hardware interfaces */ + if (!match || (SDL_strncmp(name, match, match_len) == 0)) { + char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID"); + const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0); + const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0); + SDL_bool have_output = SDL_FALSE; + SDL_bool have_input = SDL_FALSE; + + free(ioid); + + if (!isoutput && !isinput) { + free(name); + continue; + } + + prev = NULL; + for (dev = unseen; dev; dev = next) { + next = dev->next; + if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) { + if (prev) { + prev->next = next; + } else { + unseen = next; + } + dev->next = seen; + seen = dev; + if (isinput) have_input = SDL_TRUE; + if (isoutput) have_output = SDL_TRUE; + } else { + prev = dev; + } + } + + if (isinput && !have_input) { + add_device(SDL_TRUE, name, hints[i], &seen); + } + if (isoutput && !have_output) { + add_device(SDL_FALSE, name, hints[i], &seen); + } + } + + free(name); + } + + ALSA_snd_device_name_free_hint(hints); + + devices = seen; /* now we have a known-good list of attached devices. */ + + /* report anything still in unseen as removed. */ + for (dev = unseen; dev; dev = next) { + /*printf("ALSA: removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/ + next = dev->next; + SDL_RemoveAudioDevice(dev->iscapture, dev->name); + SDL_free(dev->name); + SDL_free(dev); + } + } + + /* On first run, tell ALSA_DetectDevices() that we have a complete device list so it can return. */ + if (first_run_semaphore) { + SDL_SemPost(first_run_semaphore); + first_run_semaphore = NULL; /* let other thread clean it up. */ + } + + /* Block awhile before checking again, unless we're told to stop. */ + ticks = SDL_GetTicks() + 5000; + while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) { + SDL_Delay(100); + } + } + + /* Shutting down! Clean up any data we've gathered. */ + for (dev = devices; dev; dev = next) { + /*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/ + next = dev->next; + SDL_free(dev->name); + SDL_free(dev); + } + + return 0; +} + +static void +ALSA_DetectDevices(void) +{ + /* Start the device detection thread here, wait for an initial iteration to complete. */ + SDL_sem *semaphore = SDL_CreateSemaphore(0); + if (!semaphore) { + return; /* oh well. */ + } + + SDL_AtomicSet(&ALSA_hotplug_shutdown, 0); + + ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", semaphore); + if (ALSA_hotplug_thread) { + SDL_SemWait(semaphore); /* wait for the first iteration to finish. */ + } + + SDL_DestroySemaphore(semaphore); +} + static void ALSA_Deinitialize(void) { + if (ALSA_hotplug_thread != NULL) { + SDL_AtomicSet(&ALSA_hotplug_shutdown, 1); + SDL_WaitThread(ALSA_hotplug_thread, NULL); + ALSA_hotplug_thread = NULL; + } + UnloadALSALibrary(); } @@ -664,13 +958,17 @@ ALSA_Init(SDL_AudioDriverImpl * impl) } /* Set the function pointers */ + impl->DetectDevices = ALSA_DetectDevices; impl->OpenDevice = ALSA_OpenDevice; impl->WaitDevice = ALSA_WaitDevice; impl->GetDeviceBuf = ALSA_GetDeviceBuf; impl->PlayDevice = ALSA_PlayDevice; impl->CloseDevice = ALSA_CloseDevice; impl->Deinitialize = ALSA_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: Add device enum! */ + impl->CaptureFromDevice = ALSA_CaptureFromDevice; + impl->FlushCapture = ALSA_FlushCapture; + + impl->HasCaptureSupport = SDL_TRUE; return 1; /* this audio target is available. */ } diff --git a/Engine/lib/sdl/src/audio/android/SDL_androidaudio.c b/Engine/lib/sdl/src/audio/android/SDL_androidaudio.c index 4a4faadcf..96f6d631a 100644 --- a/Engine/lib/sdl/src/audio/android/SDL_androidaudio.c +++ b/Engine/lib/sdl/src/audio/android/SDL_androidaudio.c @@ -24,6 +24,7 @@ /* Output audio to Android */ +#include "SDL_assert.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" #include "SDL_androidaudio.h" @@ -33,23 +34,22 @@ #include static SDL_AudioDevice* audioDevice = NULL; +static SDL_AudioDevice* captureDevice = NULL; static int -AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { SDL_AudioFormat test_format; + SDL_assert((captureDevice == NULL) || !iscapture); + SDL_assert((audioDevice == NULL) || iscapture); + if (iscapture) { - /* TODO: implement capture */ - return SDL_SetError("Capture not supported on Android"); + captureDevice = this; + } else { + audioDevice = this; } - if (audioDevice != NULL) { - return SDL_SetError("Only one audio device at a time please!"); - } - - audioDevice = this; - this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); @@ -82,100 +82,137 @@ AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->spec.freq = 48000; } - /* TODO: pass in/return a (Java) device ID, also whether we're opening for input or output */ - this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples); - SDL_CalculateAudioSpec(&this->spec); + /* TODO: pass in/return a (Java) device ID */ + this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples); if (this->spec.samples == 0) { /* Init failed? */ return SDL_SetError("Java-side initialization failed!"); } + SDL_CalculateAudioSpec(&this->spec); + return 0; } static void -AndroidAUD_PlayDevice(_THIS) +ANDROIDAUDIO_PlayDevice(_THIS) { Android_JNI_WriteAudioBuffer(); } static Uint8 * -AndroidAUD_GetDeviceBuf(_THIS) +ANDROIDAUDIO_GetDeviceBuf(_THIS) { return Android_JNI_GetAudioBuffer(); } +static int +ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + return Android_JNI_CaptureAudioBuffer(buffer, buflen); +} + static void -AndroidAUD_CloseDevice(_THIS) +ANDROIDAUDIO_FlushCapture(_THIS) +{ + Android_JNI_FlushCapturedAudio(); +} + +static void +ANDROIDAUDIO_CloseDevice(_THIS) { /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread so it's safe to terminate the Java side buffer and AudioTrack */ - Android_JNI_CloseAudioDevice(); - - if (audioDevice == this) { - if (audioDevice->hidden != NULL) { - SDL_free(this->hidden); - this->hidden = NULL; - } + Android_JNI_CloseAudioDevice(this->iscapture); + if (this->iscapture) { + SDL_assert(captureDevice == this); + captureDevice = NULL; + } else { + SDL_assert(audioDevice == this); audioDevice = NULL; } + SDL_free(this->hidden); } static int -AndroidAUD_Init(SDL_AudioDriverImpl * impl) +ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl) { /* Set the function pointers */ - impl->OpenDevice = AndroidAUD_OpenDevice; - impl->PlayDevice = AndroidAUD_PlayDevice; - impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf; - impl->CloseDevice = AndroidAUD_CloseDevice; + impl->OpenDevice = ANDROIDAUDIO_OpenDevice; + impl->PlayDevice = ANDROIDAUDIO_PlayDevice; + impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf; + impl->CloseDevice = ANDROIDAUDIO_CloseDevice; + impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice; + impl->FlushCapture = ANDROIDAUDIO_FlushCapture; /* and the capabilities */ - impl->HasCaptureSupport = 0; /* TODO */ + impl->HasCaptureSupport = SDL_TRUE; impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultInputDevice = 1; + impl->OnlyHasDefaultCaptureDevice = 1; return 1; /* this audio target is available. */ } -AudioBootStrap ANDROIDAUD_bootstrap = { - "android", "SDL Android audio driver", AndroidAUD_Init, 0 +AudioBootStrap ANDROIDAUDIO_bootstrap = { + "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0 }; /* Pause (block) all non already paused audio devices by taking their mixer lock */ -void AndroidAUD_PauseDevices(void) +void ANDROIDAUDIO_PauseDevices(void) { /* TODO: Handle multiple devices? */ struct SDL_PrivateAudioData *private; if(audioDevice != NULL && audioDevice->hidden != NULL) { private = (struct SDL_PrivateAudioData *) audioDevice->hidden; - if (audioDevice->paused) { + if (SDL_AtomicGet(&audioDevice->paused)) { /* The device is already paused, leave it alone */ private->resume = SDL_FALSE; } else { SDL_LockMutex(audioDevice->mixer_lock); - audioDevice->paused = SDL_TRUE; + SDL_AtomicSet(&audioDevice->paused, 1); + private->resume = SDL_TRUE; + } + } + + if(captureDevice != NULL && captureDevice->hidden != NULL) { + private = (struct SDL_PrivateAudioData *) captureDevice->hidden; + if (SDL_AtomicGet(&captureDevice->paused)) { + /* The device is already paused, leave it alone */ + private->resume = SDL_FALSE; + } + else { + SDL_LockMutex(captureDevice->mixer_lock); + SDL_AtomicSet(&captureDevice->paused, 1); private->resume = SDL_TRUE; } } } /* Resume (unblock) all non already paused audio devices by releasing their mixer lock */ -void AndroidAUD_ResumeDevices(void) +void ANDROIDAUDIO_ResumeDevices(void) { /* TODO: Handle multiple devices? */ struct SDL_PrivateAudioData *private; if(audioDevice != NULL && audioDevice->hidden != NULL) { private = (struct SDL_PrivateAudioData *) audioDevice->hidden; if (private->resume) { - audioDevice->paused = SDL_FALSE; + SDL_AtomicSet(&audioDevice->paused, 0); private->resume = SDL_FALSE; SDL_UnlockMutex(audioDevice->mixer_lock); } } + + if(captureDevice != NULL && captureDevice->hidden != NULL) { + private = (struct SDL_PrivateAudioData *) captureDevice->hidden; + if (private->resume) { + SDL_AtomicSet(&captureDevice->paused, 0); + private->resume = SDL_FALSE; + SDL_UnlockMutex(captureDevice->mixer_lock); + } + } } diff --git a/Engine/lib/sdl/src/audio/android/SDL_androidaudio.h b/Engine/lib/sdl/src/audio/android/SDL_androidaudio.h index 639be9c08..133615302 100644 --- a/Engine/lib/sdl/src/audio/android/SDL_androidaudio.h +++ b/Engine/lib/sdl/src/audio/android/SDL_androidaudio.h @@ -34,8 +34,6 @@ struct SDL_PrivateAudioData int resume; }; -static void AndroidAUD_CloseDevice(_THIS); - #endif /* _SDL_androidaudio_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/audio/arts/SDL_artsaudio.c b/Engine/lib/sdl/src/audio/arts/SDL_artsaudio.c index 5d40cd14e..6054e36b6 100644 --- a/Engine/lib/sdl/src/audio/arts/SDL_artsaudio.c +++ b/Engine/lib/sdl/src/audio/arts/SDL_artsaudio.c @@ -32,7 +32,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_artsaudio.h" @@ -186,13 +185,6 @@ ARTS_PlayDevice(_THIS) #endif } -static void -ARTS_WaitDone(_THIS) -{ - /* !!! FIXME: camp here until buffer drains... SDL_Delay(???); */ -} - - static Uint8 * ARTS_GetDeviceBuf(_THIS) { @@ -203,17 +195,12 @@ ARTS_GetDeviceBuf(_THIS) static void ARTS_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->stream) { - SDL_NAME(arts_close_stream) (this->hidden->stream); - this->hidden->stream = 0; - } - SDL_NAME(arts_free) (); - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->stream) { + SDL_NAME(arts_close_stream) (this->hidden->stream); } + SDL_NAME(arts_free) (); + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int @@ -241,7 +228,7 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Try for a closest match on audio format */ for (test_format = SDL_FirstAudioFormat(this->spec.format); @@ -267,19 +254,16 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } } if (format == 0) { - ARTS_CloseDevice(this); return SDL_SetError("Couldn't find any hardware audio formats"); } this->spec.format = test_format; if ((rc = SDL_NAME(arts_init) ()) != 0) { - ARTS_CloseDevice(this); return SDL_SetError("Unable to initialize ARTS: %s", SDL_NAME(arts_error_text) (rc)); } if (!ARTS_Suspend()) { - ARTS_CloseDevice(this); return SDL_SetError("ARTS can not open audio device"); } @@ -297,7 +281,6 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Determine the power of two of the fragment size */ for (frag_spec = 0; (0x01 << frag_spec) < this->spec.size; ++frag_spec); if ((0x01 << frag_spec) != this->spec.size) { - ARTS_CloseDevice(this); return SDL_SetError("Fragment size must be a power of two"); } frag_spec |= 0x00020000; /* two fragments, for low latency */ @@ -316,9 +299,8 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { - ARTS_CloseDevice(this); return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -367,7 +349,6 @@ ARTS_Init(SDL_AudioDriverImpl * impl) impl->WaitDevice = ARTS_WaitDevice; impl->GetDeviceBuf = ARTS_GetDeviceBuf; impl->CloseDevice = ARTS_CloseDevice; - impl->WaitDone = ARTS_WaitDone; impl->Deinitialize = ARTS_Deinitialize; impl->OnlyHasDefaultOutputDevice = 1; diff --git a/Engine/lib/sdl/src/audio/bsd/SDL_bsdaudio.c b/Engine/lib/sdl/src/audio/bsd/SDL_bsdaudio.c index eeb257371..6a970b9c7 100644 --- a/Engine/lib/sdl/src/audio/bsd/SDL_bsdaudio.c +++ b/Engine/lib/sdl/src/audio/bsd/SDL_bsdaudio.c @@ -38,7 +38,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "../SDL_audiodev_c.h" #include "SDL_bsdaudio.h" @@ -63,13 +62,17 @@ BSDAUDIO_Status(_THIS) #ifdef DEBUG_AUDIO /* *INDENT-OFF* */ audio_info_t info; + const audio_prinfo *prinfo; if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { fprintf(stderr, "AUDIO_GETINFO failed.\n"); return; } + + prinfo = this->iscapture ? &info.play : &info.record; + fprintf(stderr, "\n" - "[play/record info]\n" + "[%s info]\n" "buffer size : %d bytes\n" "sample rate : %i Hz\n" "channels : %i\n" @@ -83,18 +86,19 @@ BSDAUDIO_Status(_THIS) "waiting : %s\n" "active : %s\n" "", - info.play.buffer_size, - info.play.sample_rate, - info.play.channels, - info.play.precision, - info.play.encoding, - info.play.seek, - info.play.samples, - info.play.eof, - info.play.pause ? "yes" : "no", - info.play.error ? "yes" : "no", - info.play.waiting ? "yes" : "no", - info.play.active ? "yes" : "no"); + this->iscapture ? "record" : "play", + prinfo->buffer_size, + prinfo->sample_rate, + prinfo->channels, + prinfo->precision, + prinfo->encoding, + prinfo->seek, + prinfo->samples, + prinfo->eof, + prinfo->pause ? "yes" : "no", + prinfo->error ? "yes" : "no", + prinfo->waiting ? "yes" : "no", + prinfo->active ? "yes" : "no"); fprintf(stderr, "\n" "[audio info]\n" @@ -182,11 +186,15 @@ BSDAUDIO_PlayDevice(_THIS) break; } - if (p < written +#ifdef DEBUG_AUDIO + fprintf(stderr, "Wrote %d bytes of audio data\n", written); +#endif + + if (p < this->hidden->mixlen || ((written < 0) && ((errno == 0) || (errno == EAGAIN)))) { SDL_Delay(1); /* Let a little CPU time go by */ } - } while (p < written); + } while (p < this->hidden->mixlen); /* If timer synchronization is enabled, set the next write frame */ if (this->hidden->frame_ticks) { @@ -197,9 +205,6 @@ BSDAUDIO_PlayDevice(_THIS) if (written < 0) { SDL_OpenedAudioDeviceDisconnected(this); } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", written); -#endif } static Uint8 * @@ -208,27 +213,74 @@ BSDAUDIO_GetDeviceBuf(_THIS) return (this->hidden->mixbuf); } + +static int +BSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen) +{ + Uint8 *buffer = (Uint8 *) _buffer; + int br, p = 0; + + /* Write the audio data, checking for EAGAIN on broken audio drivers */ + do { + br = read(this->hidden->audio_fd, buffer + p, buflen - p); + if (br > 0) + p += br; + if (br == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) { + /* Non recoverable error has occurred. It should be reported!!! */ + perror("audio"); + return p ? p : -1; + } + +#ifdef DEBUG_AUDIO + fprintf(stderr, "Captured %d bytes of audio data\n", br); +#endif + + if (p < buflen + || ((br < 0) && ((errno == 0) || (errno == EAGAIN)))) { + SDL_Delay(1); /* Let a little CPU time go by */ + } + } while (p < buflen); +} + +static void +BSDAUDIO_FlushCapture(_THIS) +{ + audio_info_t info; + size_t remain; + Uint8 buf[512]; + + if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { + return; /* oh well. */ + } + + remain = (size_t) (info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8)); + while (remain > 0) { + const size_t len = SDL_min(sizeof (buf), remain); + const int br = read(this->hidden->audio_fd, buf, len); + if (br <= 0) { + return; /* oh well. */ + } + remain -= br; + } +} + static void BSDAUDIO_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - this->hidden->audio_fd = -1; - } - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->audio_fd >= 0) { + close(this->hidden->audio_fd); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { - const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); + const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT; SDL_AudioFormat format = 0; audio_info_t info; + audio_prinfo *prinfo = iscapture ? &info.play : &info.record; /* We don't care what the devname is...we'll try to open anything. */ /* ...but default to first name in the list... */ @@ -245,7 +297,7 @@ BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Open the audio device */ this->hidden->audio_fd = open(devname, flags, 0); @@ -259,9 +311,8 @@ BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) SDL_CalculateAudioSpec(&this->spec); /* Set to play mode */ - info.mode = AUMODE_PLAY; + info.mode = iscapture ? AUMODE_RECORD : AUMODE_PLAY; if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) { - BSDAUDIO_CloseDevice(this); return SDL_SetError("Couldn't put device into play mode"); } @@ -270,28 +321,28 @@ BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) format; format = SDL_NextAudioFormat()) { switch (format) { case AUDIO_U8: - info.play.encoding = AUDIO_ENCODING_ULINEAR; - info.play.precision = 8; + prinfo->encoding = AUDIO_ENCODING_ULINEAR; + prinfo->precision = 8; break; case AUDIO_S8: - info.play.encoding = AUDIO_ENCODING_SLINEAR; - info.play.precision = 8; + prinfo->encoding = AUDIO_ENCODING_SLINEAR; + prinfo->precision = 8; break; case AUDIO_S16LSB: - info.play.encoding = AUDIO_ENCODING_SLINEAR_LE; - info.play.precision = 16; + prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE; + prinfo->precision = 16; break; case AUDIO_S16MSB: - info.play.encoding = AUDIO_ENCODING_SLINEAR_BE; - info.play.precision = 16; + prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE; + prinfo->precision = 16; break; case AUDIO_U16LSB: - info.play.encoding = AUDIO_ENCODING_ULINEAR_LE; - info.play.precision = 16; + prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE; + prinfo->precision = 16; break; case AUDIO_U16MSB: - info.play.encoding = AUDIO_ENCODING_ULINEAR_BE; - info.play.precision = 16; + prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE; + prinfo->precision = 16; break; default: continue; @@ -303,33 +354,34 @@ BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (!format) { - BSDAUDIO_CloseDevice(this); return SDL_SetError("No supported encoding for 0x%x", this->spec.format); } this->spec.format = format; AUDIO_INITINFO(&info); - info.play.channels = this->spec.channels; + prinfo->channels = this->spec.channels; if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) { this->spec.channels = 1; } AUDIO_INITINFO(&info); - info.play.sample_rate = this->spec.freq; + prinfo->sample_rate = this->spec.freq; info.blocksize = this->spec.size; info.hiwat = 5; info.lowat = 3; (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info); (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info); - this->spec.freq = info.play.sample_rate; - /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - BSDAUDIO_CloseDevice(this); - return SDL_OutOfMemory(); + this->spec.freq = prinfo->sample_rate; + + if (!iscapture) { + /* Allocate mixing buffer */ + this->hidden->mixlen = this->spec.size; + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); + if (this->hidden->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); BSDAUDIO_Status(this); @@ -347,7 +399,10 @@ BSDAUDIO_Init(SDL_AudioDriverImpl * impl) impl->WaitDevice = BSDAUDIO_WaitDevice; impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf; impl->CloseDevice = BSDAUDIO_CloseDevice; + impl->CaptureFromDevice = BSDAUDIO_CaptureFromDevice; + impl->FlushCapture = BSDAUDIO_FlushCapture; + impl->HasCaptureSupport = SDL_TRUE; impl->AllowsArbitraryDeviceNames = 1; return 1; /* this audio target is available. */ diff --git a/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.h b/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.h index 577f9fb32..b7e5b8e21 100644 --- a/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.h +++ b/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.h @@ -33,9 +33,11 @@ #include #include #else -#include +#import +#import #endif +#include #include /* Hidden "this" pointer for the audio functions */ @@ -43,13 +45,21 @@ struct SDL_PrivateAudioData { - AudioUnit audioUnit; - int audioUnitOpened; + SDL_Thread *thread; + AudioQueueRef audioQueue; + AudioQueueBufferRef audioBuffer[2]; void *buffer; UInt32 bufferOffset; UInt32 bufferSize; + AudioStreamBasicDescription strdesc; + SDL_sem *ready_semaphore; + char *thread_error; + SDL_atomic_t shutdown; #if MACOSX_COREAUDIO AudioDeviceID deviceID; +#else + SDL_bool interrupted; + CFTypeRef interruption_listener; #endif }; diff --git a/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.m b/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.m new file mode 100644 index 000000000..85129050f --- /dev/null +++ b/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.m @@ -0,0 +1,849 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_AUDIO_DRIVER_COREAUDIO + +/* !!! FIXME: clean out some of the macro salsa in here. */ + +#include "SDL_audio.h" +#include "../SDL_audio_c.h" +#include "../SDL_sysaudio.h" +#include "SDL_coreaudio.h" +#include "SDL_assert.h" +#include "../../thread/SDL_systhread.h" + +#define DEBUG_COREAUDIO 0 + +#define CHECK_RESULT(msg) \ + if (result != noErr) { \ + SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \ + return 0; \ + } + +#if MACOSX_COREAUDIO +static const AudioObjectPropertyAddress devlist_address = { + kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster +}; + +typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data); + +typedef struct AudioDeviceList +{ + AudioDeviceID devid; + SDL_bool alive; + struct AudioDeviceList *next; +} AudioDeviceList; + +static AudioDeviceList *output_devs = NULL; +static AudioDeviceList *capture_devs = NULL; + +static SDL_bool +add_to_internal_dev_list(const int iscapture, AudioDeviceID devId) +{ + AudioDeviceList *item = (AudioDeviceList *) SDL_malloc(sizeof (AudioDeviceList)); + if (item == NULL) { + return SDL_FALSE; + } + item->devid = devId; + item->alive = SDL_TRUE; + item->next = iscapture ? capture_devs : output_devs; + if (iscapture) { + capture_devs = item; + } else { + output_devs = item; + } + + return SDL_TRUE; +} + +static void +addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data) +{ + if (add_to_internal_dev_list(iscapture, devId)) { + SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); + } +} + +static void +build_device_list(int iscapture, addDevFn addfn, void *addfndata) +{ + OSStatus result = noErr; + UInt32 size = 0; + AudioDeviceID *devs = NULL; + UInt32 i = 0; + UInt32 max = 0; + + result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, + &devlist_address, 0, NULL, &size); + if (result != kAudioHardwareNoError) + return; + + devs = (AudioDeviceID *) alloca(size); + if (devs == NULL) + return; + + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, + &devlist_address, 0, NULL, &size, devs); + if (result != kAudioHardwareNoError) + return; + + max = size / sizeof (AudioDeviceID); + for (i = 0; i < max; i++) { + CFStringRef cfstr = NULL; + char *ptr = NULL; + AudioDeviceID dev = devs[i]; + AudioBufferList *buflist = NULL; + int usable = 0; + CFIndex len = 0; + const AudioObjectPropertyAddress addr = { + kAudioDevicePropertyStreamConfiguration, + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + const AudioObjectPropertyAddress nameaddr = { + kAudioObjectPropertyName, + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + + result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size); + if (result != noErr) + continue; + + buflist = (AudioBufferList *) SDL_malloc(size); + if (buflist == NULL) + continue; + + result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, + &size, buflist); + + if (result == noErr) { + UInt32 j; + for (j = 0; j < buflist->mNumberBuffers; j++) { + if (buflist->mBuffers[j].mNumberChannels > 0) { + usable = 1; + break; + } + } + } + + SDL_free(buflist); + + if (!usable) + continue; + + + size = sizeof (CFStringRef); + result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr); + if (result != kAudioHardwareNoError) + continue; + + len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), + kCFStringEncodingUTF8); + + ptr = (char *) SDL_malloc(len + 1); + usable = ((ptr != NULL) && + (CFStringGetCString + (cfstr, ptr, len + 1, kCFStringEncodingUTF8))); + + CFRelease(cfstr); + + if (usable) { + len = strlen(ptr); + /* Some devices have whitespace at the end...trim it. */ + while ((len > 0) && (ptr[len - 1] == ' ')) { + len--; + } + usable = (len > 0); + } + + if (usable) { + ptr[len] = '\0'; + +#if DEBUG_COREAUDIO + printf("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n", + ((iscapture) ? "capture" : "output"), + (int) i, ptr, (int) dev); +#endif + addfn(ptr, iscapture, dev, addfndata); + } + SDL_free(ptr); /* addfn() would have copied the string. */ + } +} + +static void +free_audio_device_list(AudioDeviceList **list) +{ + AudioDeviceList *item = *list; + while (item) { + AudioDeviceList *next = item->next; + SDL_free(item); + item = next; + } + *list = NULL; +} + +static void +COREAUDIO_DetectDevices(void) +{ + build_device_list(SDL_TRUE, addToDevList, NULL); + build_device_list(SDL_FALSE, addToDevList, NULL); +} + +static void +build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data) +{ + AudioDeviceList **list = (AudioDeviceList **) data; + AudioDeviceList *item; + for (item = *list; item != NULL; item = item->next) { + if (item->devid == devId) { + item->alive = SDL_TRUE; + return; + } + } + + add_to_internal_dev_list(iscapture, devId); /* new device, add it. */ + SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); +} + +static void +reprocess_device_list(const int iscapture, AudioDeviceList **list) +{ + AudioDeviceList *item; + AudioDeviceList *prev = NULL; + for (item = *list; item != NULL; item = item->next) { + item->alive = SDL_FALSE; + } + + build_device_list(iscapture, build_device_change_list, list); + + /* free items in the list that aren't still alive. */ + item = *list; + while (item != NULL) { + AudioDeviceList *next = item->next; + if (item->alive) { + prev = item; + } else { + SDL_RemoveAudioDevice(iscapture, (void *) ((size_t) item->devid)); + if (prev) { + prev->next = item->next; + } else { + *list = item->next; + } + SDL_free(item); + } + item = next; + } +} + +/* this is called when the system's list of available audio devices changes. */ +static OSStatus +device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) +{ + reprocess_device_list(SDL_TRUE, &capture_devs); + reprocess_device_list(SDL_FALSE, &output_devs); + return 0; +} +#endif + + +static int open_playback_devices = 0; +static int open_capture_devices = 0; + +#if !MACOSX_COREAUDIO + +static void interruption_begin(_THIS) +{ + if (this != NULL && this->hidden->audioQueue != NULL) { + this->hidden->interrupted = SDL_TRUE; + AudioQueuePause(this->hidden->audioQueue); + } +} + +static void interruption_end(_THIS) +{ + if (this != NULL && this->hidden != NULL && this->hidden->audioQueue != NULL + && this->hidden->interrupted) { + this->hidden->interrupted = SDL_FALSE; + AudioQueueStart(this->hidden->audioQueue, NULL); + } +} + +@interface SDLInterruptionListener : NSObject + +@property (nonatomic, assign) SDL_AudioDevice *device; + +@end + +@implementation SDLInterruptionListener + +- (void)audioSessionInterruption:(NSNotification *)note +{ + @synchronized (self) { + NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey]; + if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) { + interruption_begin(self.device); + } else { + interruption_end(self.device); + } + } +} + +- (void)applicationBecameActive:(NSNotification *)note +{ + @synchronized (self) { + interruption_end(self.device); + } +} + +@end + +static BOOL update_audio_session(_THIS, SDL_bool open) +{ + @autoreleasepool { + AVAudioSession *session = [AVAudioSession sharedInstance]; + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + NSString *category; + NSError *err = nil; + + if (open_playback_devices && open_capture_devices) { + category = AVAudioSessionCategoryPlayAndRecord; + } else if (open_capture_devices) { + category = AVAudioSessionCategoryRecord; + } else { + /* Set category to ambient so that other music continues playing. + You can change this at runtime in your own code if you need different + behavior. If this is common, we can add an SDL hint for this. */ + category = AVAudioSessionCategoryAmbient; + } + + if (![session setCategory:category error:&err]) { + NSString *desc = err.description; + SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String); + return NO; + } + + if (open_playback_devices + open_capture_devices == 1) { + if (![session setActive:YES error:&err]) { + NSString *desc = err.description; + SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String); + return NO; + } + } else if (!open_playback_devices && !open_capture_devices) { + [session setActive:NO error:nil]; + } + + if (open) { + SDLInterruptionListener *listener = [SDLInterruptionListener new]; + listener.device = this; + + [center addObserver:listener + selector:@selector(audioSessionInterruption:) + name:AVAudioSessionInterruptionNotification + object:session]; + + /* An interruption end notification is not guaranteed to be sent if + we were previously interrupted... resuming if needed when the app + becomes active seems to be the way to go. */ + [center addObserver:listener + selector:@selector(applicationBecameActive:) + name:UIApplicationDidBecomeActiveNotification + object:session]; + + [center addObserver:listener + selector:@selector(applicationBecameActive:) + name:UIApplicationWillEnterForegroundNotification + object:session]; + + this->hidden->interruption_listener = CFBridgingRetain(listener); + } else { + if (this->hidden->interruption_listener != NULL) { + SDLInterruptionListener *listener = nil; + listener = (SDLInterruptionListener *) CFBridgingRelease(this->hidden->interruption_listener); + @synchronized (listener) { + listener.device = NULL; + } + [center removeObserver:listener]; + } + } + } + + return YES; +} +#endif + + +/* The AudioQueue callback */ +static void +outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData; + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { + /* Supply silence if audio is enabled and not paused */ + SDL_memset(inBuffer->mAudioData, this->spec.silence, inBuffer->mAudioDataBytesCapacity); + } else { + UInt32 remaining = inBuffer->mAudioDataBytesCapacity; + Uint8 *ptr = (Uint8 *) inBuffer->mAudioData; + + while (remaining > 0) { + UInt32 len; + if (this->hidden->bufferOffset >= this->hidden->bufferSize) { + /* Generate the data */ + SDL_LockMutex(this->mixer_lock); + (*this->spec.callback)(this->spec.userdata, + this->hidden->buffer, this->hidden->bufferSize); + SDL_UnlockMutex(this->mixer_lock); + this->hidden->bufferOffset = 0; + } + + len = this->hidden->bufferSize - this->hidden->bufferOffset; + if (len > remaining) { + len = remaining; + } + SDL_memcpy(ptr, (char *)this->hidden->buffer + + this->hidden->bufferOffset, len); + ptr = ptr + len; + remaining -= len; + this->hidden->bufferOffset += len; + } + } + + if (!SDL_AtomicGet(&this->hidden->shutdown)) { + AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); + } + + inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity; +} + +static void +inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, + const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, + const AudioStreamPacketDescription *inPacketDescs ) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData; + if (SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) { /* ignore unless we're active. */ + const Uint8 *ptr = (const Uint8 *) inBuffer->mAudioData; + UInt32 remaining = inBuffer->mAudioDataByteSize; + while (remaining > 0) { + UInt32 len = this->hidden->bufferSize - this->hidden->bufferOffset; + if (len > remaining) { + len = remaining; + } + + SDL_memcpy((char *)this->hidden->buffer + this->hidden->bufferOffset, ptr, len); + ptr += len; + remaining -= len; + this->hidden->bufferOffset += len; + + if (this->hidden->bufferOffset >= this->hidden->bufferSize) { + SDL_LockMutex(this->mixer_lock); + (*this->spec.callback)(this->spec.userdata, this->hidden->buffer, this->hidden->bufferSize); + SDL_UnlockMutex(this->mixer_lock); + this->hidden->bufferOffset = 0; + } + } + } + + if (!SDL_AtomicGet(&this->hidden->shutdown)) { + AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); + } +} + + +#if MACOSX_COREAUDIO +static const AudioObjectPropertyAddress alive_address = +{ + kAudioDevicePropertyDeviceIsAlive, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster +}; + +static OSStatus +device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *) data; + SDL_bool dead = SDL_FALSE; + UInt32 isAlive = 1; + UInt32 size = sizeof (isAlive); + OSStatus error; + + if (!SDL_AtomicGet(&this->enabled)) { + return 0; /* already known to be dead. */ + } + + error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address, + 0, NULL, &size, &isAlive); + + if (error == kAudioHardwareBadDeviceError) { + dead = SDL_TRUE; /* device was unplugged. */ + } else if ((error == kAudioHardwareNoError) && (!isAlive)) { + dead = SDL_TRUE; /* device died in some other way. */ + } + + if (dead) { + SDL_OpenedAudioDeviceDisconnected(this); + } + + return 0; +} +#endif + +static void +COREAUDIO_CloseDevice(_THIS) +{ + const SDL_bool iscapture = this->iscapture; + int i; + +/* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */ +/* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */ +#if MACOSX_COREAUDIO + /* Fire a callback if the device stops being "alive" (disconnected, etc). */ + AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); +#endif + +#if !MACOSX_COREAUDIO + update_audio_session(this, SDL_FALSE); +#endif + + if (this->hidden->thread) { + SDL_AtomicSet(&this->hidden->shutdown, 1); + SDL_WaitThread(this->hidden->thread, NULL); + } + + if (this->hidden->audioQueue) { + for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) { + if (this->hidden->audioBuffer[i]) { + AudioQueueFreeBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i]); + } + } + AudioQueueDispose(this->hidden->audioQueue, 1); + } + + if (this->hidden->ready_semaphore) { + SDL_DestroySemaphore(this->hidden->ready_semaphore); + } + + SDL_free(this->hidden->thread_error); + SDL_free(this->hidden->buffer); + SDL_free(this->hidden); + + if (iscapture) { + open_capture_devices--; + } else { + open_playback_devices--; + } +} + +#if MACOSX_COREAUDIO +static int +prepare_device(_THIS, void *handle, int iscapture) +{ + AudioDeviceID devid = (AudioDeviceID) ((size_t) handle); + OSStatus result = noErr; + UInt32 size = 0; + UInt32 alive = 0; + pid_t pid = 0; + + AudioObjectPropertyAddress addr = { + 0, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster + }; + + if (handle == NULL) { + size = sizeof (AudioDeviceID); + addr.mSelector = + ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice : + kAudioHardwarePropertyDefaultOutputDevice); + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, + 0, NULL, &size, &devid); + CHECK_RESULT("AudioHardwareGetProperty (default device)"); + } + + addr.mSelector = kAudioDevicePropertyDeviceIsAlive; + addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : + kAudioDevicePropertyScopeOutput; + + size = sizeof (alive); + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive); + CHECK_RESULT + ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)"); + + if (!alive) { + SDL_SetError("CoreAudio: requested device exists, but isn't alive."); + return 0; + } + + addr.mSelector = kAudioDevicePropertyHogMode; + size = sizeof (pid); + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid); + + /* some devices don't support this property, so errors are fine here. */ + if ((result == noErr) && (pid != -1)) { + SDL_SetError("CoreAudio: requested device is being hogged."); + return 0; + } + + this->hidden->deviceID = devid; + return 1; +} +#endif + +static int +prepare_audioqueue(_THIS) +{ + const AudioStreamBasicDescription *strdesc = &this->hidden->strdesc; + const int iscapture = this->iscapture; + OSStatus result; + int i; + + SDL_assert(CFRunLoopGetCurrent() != NULL); + + if (iscapture) { + result = AudioQueueNewInput(strdesc, inputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue); + CHECK_RESULT("AudioQueueNewInput"); + } else { + result = AudioQueueNewOutput(strdesc, outputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue); + CHECK_RESULT("AudioQueueNewOutput"); + } + +#if MACOSX_COREAUDIO +{ + const AudioObjectPropertyAddress prop = { + kAudioDevicePropertyDeviceUID, + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMaster + }; + CFStringRef devuid; + UInt32 devuidsize = sizeof (devuid); + result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid); + CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)"); + result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize); + CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)"); + + /* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */ + /* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */ + /* Fire a callback if the device stops being "alive" (disconnected, etc). */ + AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); +} +#endif + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(&this->spec); + + /* Allocate a sample buffer */ + this->hidden->bufferSize = this->spec.size; + this->hidden->bufferOffset = iscapture ? 0 : this->hidden->bufferSize; + + this->hidden->buffer = SDL_malloc(this->hidden->bufferSize); + if (this->hidden->buffer == NULL) { + SDL_OutOfMemory(); + return 0; + } + + for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) { + result = AudioQueueAllocateBuffer(this->hidden->audioQueue, this->spec.size, &this->hidden->audioBuffer[i]); + CHECK_RESULT("AudioQueueAllocateBuffer"); + SDL_memset(this->hidden->audioBuffer[i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[i]->mAudioDataBytesCapacity); + this->hidden->audioBuffer[i]->mAudioDataByteSize = this->hidden->audioBuffer[i]->mAudioDataBytesCapacity; + result = AudioQueueEnqueueBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i], 0, NULL); + CHECK_RESULT("AudioQueueEnqueueBuffer"); + } + + result = AudioQueueStart(this->hidden->audioQueue, NULL); + CHECK_RESULT("AudioQueueStart"); + + /* We're running! */ + return 1; +} + +static int +audioqueue_thread(void *arg) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *) arg; + const int rc = prepare_audioqueue(this); + if (!rc) { + this->hidden->thread_error = SDL_strdup(SDL_GetError()); + SDL_SemPost(this->hidden->ready_semaphore); + return 0; + } + + /* init was successful, alert parent thread and start running... */ + SDL_SemPost(this->hidden->ready_semaphore); + while (!SDL_AtomicGet(&this->hidden->shutdown)) { + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1); + } + + if (this->iscapture) { /* just stop immediately for capture devices. */ + AudioQueueStop(this->hidden->audioQueue, 1); + } else { /* Drain off any pending playback. */ + AudioQueueStop(this->hidden->audioQueue, 0); + const CFTimeInterval secs = (((this->spec.size / (SDL_AUDIO_BITSIZE(this->spec.format) / 8)) / this->spec.channels) / ((CFTimeInterval) this->spec.freq)) * 2.0; + CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0); + } + + return 0; +} + +static int +COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +{ + AudioStreamBasicDescription *strdesc; + SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); + int valid_datatype = 0; + + /* Initialize all variables that we clean on shutdown */ + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc((sizeof *this->hidden)); + if (this->hidden == NULL) { + return SDL_OutOfMemory(); + } + SDL_zerop(this->hidden); + + strdesc = &this->hidden->strdesc; + + if (iscapture) { + open_capture_devices++; + } else { + open_playback_devices++; + } + +#if !MACOSX_COREAUDIO + if (!update_audio_session(this, SDL_TRUE)) { + return -1; + } +#endif + + /* Setup a AudioStreamBasicDescription with the requested format */ + SDL_zerop(strdesc); + strdesc->mFormatID = kAudioFormatLinearPCM; + strdesc->mFormatFlags = kLinearPCMFormatFlagIsPacked; + strdesc->mChannelsPerFrame = this->spec.channels; + strdesc->mSampleRate = this->spec.freq; + strdesc->mFramesPerPacket = 1; + + while ((!valid_datatype) && (test_format)) { + this->spec.format = test_format; + /* Just a list of valid SDL formats, so people don't pass junk here. */ + switch (test_format) { + case AUDIO_U8: + case AUDIO_S8: + case AUDIO_U16LSB: + case AUDIO_S16LSB: + case AUDIO_U16MSB: + case AUDIO_S16MSB: + case AUDIO_S32LSB: + case AUDIO_S32MSB: + case AUDIO_F32LSB: + case AUDIO_F32MSB: + valid_datatype = 1; + strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format); + if (SDL_AUDIO_ISBIGENDIAN(this->spec.format)) + strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; + + if (SDL_AUDIO_ISFLOAT(this->spec.format)) + strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat; + else if (SDL_AUDIO_ISSIGNED(this->spec.format)) + strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; + break; + } + } + + if (!valid_datatype) { /* shouldn't happen, but just in case... */ + return SDL_SetError("Unsupported audio format"); + } + + strdesc->mBytesPerFrame = strdesc->mBitsPerChannel * strdesc->mChannelsPerFrame / 8; + strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket; + +#if MACOSX_COREAUDIO + if (!prepare_device(this, handle, iscapture)) { + return -1; + } +#endif + + /* This has to init in a new thread so it can get its own CFRunLoop. :/ */ + SDL_AtomicSet(&this->hidden->shutdown, 0); + this->hidden->ready_semaphore = SDL_CreateSemaphore(0); + if (!this->hidden->ready_semaphore) { + return -1; /* oh well. */ + } + + this->hidden->thread = SDL_CreateThreadInternal(audioqueue_thread, "AudioQueue thread", 512 * 1024, this); + if (!this->hidden->thread) { + return -1; + } + + SDL_SemWait(this->hidden->ready_semaphore); + SDL_DestroySemaphore(this->hidden->ready_semaphore); + this->hidden->ready_semaphore = NULL; + + if ((this->hidden->thread != NULL) && (this->hidden->thread_error != NULL)) { + SDL_SetError("%s", this->hidden->thread_error); + return -1; + } + + return (this->hidden->thread != NULL) ? 0 : -1; +} + +static void +COREAUDIO_Deinitialize(void) +{ +#if MACOSX_COREAUDIO + AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); + free_audio_device_list(&capture_devs); + free_audio_device_list(&output_devs); +#endif +} + +static int +COREAUDIO_Init(SDL_AudioDriverImpl * impl) +{ + /* Set the function pointers */ + impl->OpenDevice = COREAUDIO_OpenDevice; + impl->CloseDevice = COREAUDIO_CloseDevice; + impl->Deinitialize = COREAUDIO_Deinitialize; + +#if MACOSX_COREAUDIO + impl->DetectDevices = COREAUDIO_DetectDevices; + AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); +#else + impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultCaptureDevice = 1; +#endif + + impl->ProvidesOwnCallbackThread = 1; + impl->HasCaptureSupport = 1; + + return 1; /* this audio target is available. */ +} + +AudioBootStrap COREAUDIO_bootstrap = { + "coreaudio", "CoreAudio", COREAUDIO_Init, 0 +}; + +#endif /* SDL_AUDIO_DRIVER_COREAUDIO */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/audio/directsound/SDL_directsound.c b/Engine/lib/sdl/src/audio/directsound/SDL_directsound.c index 065e163a6..5d261c92e 100644 --- a/Engine/lib/sdl/src/audio/directsound/SDL_directsound.c +++ b/Engine/lib/sdl/src/audio/directsound/SDL_directsound.c @@ -24,6 +24,7 @@ /* Allow access to a raw mixing buffer */ +#include "SDL_assert.h" #include "SDL_timer.h" #include "SDL_loadso.h" #include "SDL_audio.h" @@ -36,11 +37,13 @@ /* DirectX function pointers for audio */ static void* DSoundDLL = NULL; -typedef HRESULT(WINAPI*fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN); -typedef HRESULT(WINAPI*fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); -typedef HRESULT(WINAPI*fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID); +typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN); +typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); +typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN); +typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID); static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL; static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL; +static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL; static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL; static void @@ -48,6 +51,7 @@ DSOUND_Unload(void) { pDirectSoundCreate8 = NULL; pDirectSoundEnumerateW = NULL; + pDirectSoundCaptureCreate8 = NULL; pDirectSoundCaptureEnumerateW = NULL; if (DSoundDLL != NULL) { @@ -76,6 +80,7 @@ DSOUND_Load(void) loaded = 1; /* will reset if necessary. */ DSOUNDLOAD(DirectSoundCreate8); DSOUNDLOAD(DirectSoundEnumerateW); + DSOUNDLOAD(DirectSoundCaptureCreate8); DSOUNDLOAD(DirectSoundCaptureEnumerateW); #undef DSOUNDLOAD @@ -155,7 +160,7 @@ FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) { const int iscapture = (int) ((size_t) data); if (guid != NULL) { /* skip default device */ - char *str = WIN_StringToUTF8(desc); + char *str = WIN_LookupAudioDeviceName(desc, guid); if (str != NULL) { LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID)); SDL_memcpy(cpyguid, guid, sizeof (GUID)); @@ -197,7 +202,7 @@ DSOUND_WaitDevice(_THIS) return; } - while ((cursor / this->hidden->mixlen) == this->hidden->lastchunk) { + while ((cursor / this->spec.size) == this->hidden->lastchunk) { /* FIXME: find out how much time is left and sleep that long */ SDL_Delay(1); @@ -239,9 +244,8 @@ DSOUND_PlayDevice(_THIS) if (this->hidden->locked_buf) { IDirectSoundBuffer_Unlock(this->hidden->mixbuf, this->hidden->locked_buf, - this->hidden->mixlen, NULL, 0); + this->spec.size, NULL, 0); } - } static Uint8 * @@ -265,7 +269,7 @@ DSOUND_GetDeviceBuf(_THIS) SetDSerror("DirectSound GetCurrentPosition", result); return (NULL); } - cursor /= this->hidden->mixlen; + cursor /= this->spec.size; #ifdef DEBUG_SOUND /* Detect audio dropouts */ { @@ -281,17 +285,17 @@ DSOUND_GetDeviceBuf(_THIS) #endif this->hidden->lastchunk = cursor; cursor = (cursor + 1) % this->hidden->num_buffers; - cursor *= this->hidden->mixlen; + cursor *= this->spec.size; /* Lock the audio buffer */ result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, - this->hidden->mixlen, + this->spec.size, (LPVOID *) & this->hidden->locked_buf, &rawlen, NULL, &junk, 0); if (result == DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore(this->hidden->mixbuf); result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, - this->hidden->mixlen, + this->spec.size, (LPVOID *) & this-> hidden->locked_buf, &rawlen, NULL, &junk, 0); @@ -303,109 +307,106 @@ DSOUND_GetDeviceBuf(_THIS) return (this->hidden->locked_buf); } -static void -DSOUND_WaitDone(_THIS) +static int +DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) { - Uint8 *stream = DSOUND_GetDeviceBuf(this); + struct SDL_PrivateAudioData *h = this->hidden; + DWORD junk, cursor, ptr1len, ptr2len; + VOID *ptr1, *ptr2; - /* Wait for the playing chunk to finish */ - if (stream != NULL) { - SDL_memset(stream, this->spec.silence, this->hidden->mixlen); - DSOUND_PlayDevice(this); + SDL_assert(buflen == this->spec.size); + + while (SDL_TRUE) { + if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */ + SDL_memset(buffer, this->spec.silence, buflen); + return buflen; + } + + if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) { + return -1; + } + if ((cursor / this->spec.size) == h->lastchunk) { + SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */ + } else { + break; + } } - DSOUND_WaitDevice(this); - /* Stop the looping sound buffer */ - IDirectSoundBuffer_Stop(this->hidden->mixbuf); + if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * this->spec.size, this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) { + return -1; + } + + SDL_assert(ptr1len == this->spec.size); + SDL_assert(ptr2 == NULL); + SDL_assert(ptr2len == 0); + + SDL_memcpy(buffer, ptr1, ptr1len); + + if (IDirectSoundCaptureBuffer_Unlock(h->capturebuf, ptr1, ptr1len, ptr2, ptr2len) != DS_OK) { + return -1; + } + + h->lastchunk = (h->lastchunk + 1) % h->num_buffers; + + return ptr1len; +} + +static void +DSOUND_FlushCapture(_THIS) +{ + struct SDL_PrivateAudioData *h = this->hidden; + DWORD junk, cursor; + if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) { + h->lastchunk = cursor / this->spec.size; + } } static void DSOUND_CloseDevice(_THIS) { - if (this->hidden != NULL) { - if (this->hidden->sound != NULL) { - if (this->hidden->mixbuf != NULL) { - /* Clean up the audio buffer */ - IDirectSoundBuffer_Release(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - } - IDirectSound_Release(this->hidden->sound); - this->hidden->sound = NULL; - } - - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->mixbuf != NULL) { + IDirectSoundBuffer_Stop(this->hidden->mixbuf); + IDirectSoundBuffer_Release(this->hidden->mixbuf); } + if (this->hidden->sound != NULL) { + IDirectSound_Release(this->hidden->sound); + } + if (this->hidden->capturebuf != NULL) { + IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf); + IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf); + } + if (this->hidden->capture != NULL) { + IDirectSoundCapture_Release(this->hidden->capture); + } + SDL_free(this->hidden); } /* This function tries to create a secondary audio buffer, and returns the - number of audio chunks available in the created buffer. + number of audio chunks available in the created buffer. This is for + playback devices, not capture. */ static int -CreateSecondary(_THIS, HWND focus) +CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) { LPDIRECTSOUND sndObj = this->hidden->sound; LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf; - Uint32 chunksize = this->spec.size; - const int numchunks = 8; HRESULT result = DS_OK; DSBUFFERDESC format; LPVOID pvAudioPtr1, pvAudioPtr2; DWORD dwAudioBytes1, dwAudioBytes2; - WAVEFORMATEX wfmt; - - SDL_zero(wfmt); - - if (SDL_AUDIO_ISFLOAT(this->spec.format)) { - wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - } else { - wfmt.wFormatTag = WAVE_FORMAT_PCM; - } - - wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); - wfmt.nChannels = this->spec.channels; - wfmt.nSamplesPerSec = this->spec.freq; - wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8); - wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign; - - /* Update the fragment size as size in bytes */ - SDL_CalculateAudioSpec(&this->spec); - - /* Try to set primary mixing privileges */ - if (focus) { - result = IDirectSound_SetCooperativeLevel(sndObj, - focus, DSSCL_PRIORITY); - } else { - result = IDirectSound_SetCooperativeLevel(sndObj, - GetDesktopWindow(), - DSSCL_NORMAL); - } - if (result != DS_OK) { - return SetDSerror("DirectSound SetCooperativeLevel", result); - } /* Try to create the secondary buffer */ SDL_zero(format); format.dwSize = sizeof(format); format.dwFlags = DSBCAPS_GETCURRENTPOSITION2; - if (!focus) { - format.dwFlags |= DSBCAPS_GLOBALFOCUS; - } else { - format.dwFlags |= DSBCAPS_STICKYFOCUS; - } - format.dwBufferBytes = numchunks * chunksize; - if ((format.dwBufferBytes < DSBSIZE_MIN) || - (format.dwBufferBytes > DSBSIZE_MAX)) { - return SDL_SetError("Sound buffer size must be between %d and %d", - DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks); - } - format.dwReserved = 0; - format.lpwfxFormat = &wfmt; + format.dwFlags |= DSBCAPS_GLOBALFOCUS; + format.dwBufferBytes = bufsize; + format.lpwfxFormat = wfmt; result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL); if (result != DS_OK) { return SetDSerror("DirectSound CreateSoundBuffer", result); } - IDirectSoundBuffer_SetFormat(*sndbuf, &wfmt); + IDirectSoundBuffer_SetFormat(*sndbuf, wfmt); /* Silence the initial audio buffer */ result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, @@ -420,31 +421,90 @@ CreateSecondary(_THIS, HWND focus) } /* We're ready to go */ - return (numchunks); + return 0; +} + +/* This function tries to create a capture buffer, and returns the + number of audio chunks available in the created buffer. This is for + capture devices, not playback. +*/ +static int +CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) +{ + LPDIRECTSOUNDCAPTURE capture = this->hidden->capture; + LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf; + DSCBUFFERDESC format; +// DWORD junk, cursor; + HRESULT result; + + SDL_zero(format); + format.dwSize = sizeof (format); + format.dwFlags = DSCBCAPS_WAVEMAPPED; + format.dwBufferBytes = bufsize; + format.lpwfxFormat = wfmt; + + result = IDirectSoundCapture_CreateCaptureBuffer(capture, &format, capturebuf, NULL); + if (result != DS_OK) { + return SetDSerror("DirectSound CreateCaptureBuffer", result); + } + + result = IDirectSoundCaptureBuffer_Start(*capturebuf, DSCBSTART_LOOPING); + if (result != DS_OK) { + IDirectSoundCaptureBuffer_Release(*capturebuf); + return SetDSerror("DirectSound Start", result); + } + +#if 0 + /* presumably this starts at zero, but just in case... */ + result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor); + if (result != DS_OK) { + IDirectSoundCaptureBuffer_Stop(*capturebuf); + IDirectSoundCaptureBuffer_Release(*capturebuf); + return SetDSerror("DirectSound GetCurrentPosition", result); + } + + this->hidden->lastchunk = cursor / this->spec.size; +#endif + + return 0; } static int DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { + const DWORD numchunks = 8; HRESULT result; SDL_bool valid_format = SDL_FALSE; SDL_bool tried_format = SDL_FALSE; SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); LPGUID guid = (LPGUID) handle; - + DWORD bufsize; + /* Initialize all variables that we clean on shutdown */ this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Open the audio device */ - result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL); - if (result != DS_OK) { - DSOUND_CloseDevice(this); - return SetDSerror("DirectSoundCreate", result); + if (iscapture) { + result = pDirectSoundCaptureCreate8(guid, &this->hidden->capture, NULL); + if (result != DS_OK) { + return SetDSerror("DirectSoundCaptureCreate8", result); + } + } else { + result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL); + if (result != DS_OK) { + return SetDSerror("DirectSoundCreate8", result); + } + result = IDirectSound_SetCooperativeLevel(this->hidden->sound, + GetDesktopWindow(), + DSSCL_NORMAL); + if (result != DS_OK) { + return SetDSerror("DirectSound SetCooperativeLevel", result); + } } while ((!valid_format) && (test_format)) { @@ -454,10 +514,38 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) case AUDIO_S32: case AUDIO_F32: tried_format = SDL_TRUE; + this->spec.format = test_format; - this->hidden->num_buffers = CreateSecondary(this, NULL); - if (this->hidden->num_buffers > 0) { - valid_format = SDL_TRUE; + + /* Update the fragment size as size in bytes */ + SDL_CalculateAudioSpec(&this->spec); + + bufsize = numchunks * this->spec.size; + if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) { + SDL_SetError("Sound buffer size must be between %d and %d", + (DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks, + DSBSIZE_MAX / numchunks); + } else { + int rc; + WAVEFORMATEX wfmt; + SDL_zero(wfmt); + if (SDL_AUDIO_ISFLOAT(this->spec.format)) { + wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + } else { + wfmt.wFormatTag = WAVE_FORMAT_PCM; + } + + wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); + wfmt.nChannels = this->spec.channels; + wfmt.nSamplesPerSec = this->spec.freq; + wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8); + wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign; + + rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt); + if (rc == 0) { + this->hidden->num_buffers = numchunks; + valid_format = SDL_TRUE; + } } break; } @@ -465,15 +553,13 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (!valid_format) { - DSOUND_CloseDevice(this); if (tried_format) { return -1; /* CreateSecondary() should have called SDL_SetError(). */ } return SDL_SetError("DirectSound: Unsupported audio format"); } - /* The buffer will auto-start playing in DSOUND_WaitDevice() */ - this->hidden->mixlen = this->spec.size; + /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */ return 0; /* good to go. */ } @@ -498,13 +584,15 @@ DSOUND_Init(SDL_AudioDriverImpl * impl) impl->OpenDevice = DSOUND_OpenDevice; impl->PlayDevice = DSOUND_PlayDevice; impl->WaitDevice = DSOUND_WaitDevice; - impl->WaitDone = DSOUND_WaitDone; impl->GetDeviceBuf = DSOUND_GetDeviceBuf; + impl->CaptureFromDevice = DSOUND_CaptureFromDevice; + impl->FlushCapture = DSOUND_FlushCapture; impl->CloseDevice = DSOUND_CloseDevice; impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle; - impl->Deinitialize = DSOUND_Deinitialize; + impl->HasCaptureSupport = SDL_TRUE; + return 1; /* this audio target is available. */ } diff --git a/Engine/lib/sdl/src/audio/directsound/SDL_directsound.h b/Engine/lib/sdl/src/audio/directsound/SDL_directsound.h index 0d5f6bd76..d646c303f 100644 --- a/Engine/lib/sdl/src/audio/directsound/SDL_directsound.h +++ b/Engine/lib/sdl/src/audio/directsound/SDL_directsound.h @@ -35,8 +35,9 @@ struct SDL_PrivateAudioData { LPDIRECTSOUND sound; LPDIRECTSOUNDBUFFER mixbuf; + LPDIRECTSOUNDCAPTURE capture; + LPDIRECTSOUNDCAPTUREBUFFER capturebuf; int num_buffers; - int mixlen; DWORD lastchunk; Uint8 *locked_buf; }; diff --git a/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.c b/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.c index 28745f9d0..ee5368844 100644 --- a/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.c +++ b/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.c @@ -31,46 +31,33 @@ #include "SDL_rwops.h" #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_diskaudio.h" +/* !!! FIXME: these should be SDL hints, not environment variables. */ /* environment variables and defaults. */ #define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE" #define DISKDEFAULT_OUTFILE "sdlaudio.raw" -#define DISKENVR_WRITEDELAY "SDL_DISKAUDIODELAY" -#define DISKDEFAULT_WRITEDELAY 150 - -static const char * -DISKAUD_GetOutputFilename(const char *devname) -{ - if (devname == NULL) { - devname = SDL_getenv(DISKENVR_OUTFILE); - if (devname == NULL) { - devname = DISKDEFAULT_OUTFILE; - } - } - return devname; -} +#define DISKENVR_INFILE "SDL_DISKAUDIOFILEIN" +#define DISKDEFAULT_INFILE "sdlaudio-in.raw" +#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY" /* This function waits until it is possible to write a full sound buffer */ static void -DISKAUD_WaitDevice(_THIS) +DISKAUDIO_WaitDevice(_THIS) { - SDL_Delay(this->hidden->write_delay); + SDL_Delay(this->hidden->io_delay); } static void -DISKAUD_PlayDevice(_THIS) +DISKAUDIO_PlayDevice(_THIS) { - size_t written; - - /* Write the audio data */ - written = SDL_RWwrite(this->hidden->output, - this->hidden->mixbuf, 1, this->hidden->mixlen); + const size_t written = SDL_RWwrite(this->hidden->io, + this->hidden->mixbuf, + 1, this->spec.size); /* If we couldn't write, assume fatal error for now */ - if (written != this->hidden->mixlen) { + if (written != this->spec.size) { SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO @@ -79,63 +66,105 @@ DISKAUD_PlayDevice(_THIS) } static Uint8 * -DISKAUD_GetDeviceBuf(_THIS) +DISKAUDIO_GetDeviceBuf(_THIS) { return (this->hidden->mixbuf); } -static void -DISKAUD_CloseDevice(_THIS) +static int +DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->output != NULL) { - SDL_RWclose(this->hidden->output); - this->hidden->output = NULL; + struct SDL_PrivateAudioData *h = this->hidden; + const int origbuflen = buflen; + + SDL_Delay(h->io_delay); + + if (h->io) { + const size_t br = SDL_RWread(h->io, buffer, 1, buflen); + buflen -= (int) br; + buffer = ((Uint8 *) buffer) + br; + if (buflen > 0) { /* EOF (or error, but whatever). */ + SDL_RWclose(h->io); + h->io = NULL; } - SDL_free(this->hidden); - this->hidden = NULL; } + + /* if we ran out of file, just write silence. */ + SDL_memset(buffer, this->spec.silence, buflen); + + return origbuflen; +} + +static void +DISKAUDIO_FlushCapture(_THIS) +{ + /* no op...we don't advance the file pointer or anything. */ +} + + +static void +DISKAUDIO_CloseDevice(_THIS) +{ + if (this->hidden->io != NULL) { + SDL_RWclose(this->hidden->io); + } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); +} + + +static const char * +get_filename(const int iscapture, const char *devname) +{ + if (devname == NULL) { + devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE); + if (devname == NULL) { + devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE; + } + } + return devname; } static int -DISKAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { /* handle != NULL means "user specified the placeholder name on the fake detected device list" */ - const char *fname = DISKAUD_GetOutputFilename(handle ? NULL : devname); - const char *envr = SDL_getenv(DISKENVR_WRITEDELAY); + const char *fname = get_filename(iscapture, handle ? NULL : devname); + const char *envr = SDL_getenv(DISKENVR_IODELAY); this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, sizeof(*this->hidden)); + SDL_zerop(this->hidden); - this->hidden->mixlen = this->spec.size; - this->hidden->write_delay = - (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY; + if (envr != NULL) { + this->hidden->io_delay = SDL_atoi(envr); + } else { + this->hidden->io_delay = ((this->spec.samples * 1000) / this->spec.freq); + } /* Open the audio device */ - this->hidden->output = SDL_RWFromFile(fname, "wb"); - if (this->hidden->output == NULL) { - DISKAUD_CloseDevice(this); + this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb"); + if (this->hidden->io == NULL) { return -1; } /* Allocate mixing buffer */ - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - DISKAUD_CloseDevice(this); - return -1; + if (!iscapture) { + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); + if (this->hidden->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); #if HAVE_STDIO_H fprintf(stderr, - "WARNING: You are using the SDL disk writer audio driver!\n" - " Writing to file [%s].\n", fname); + "WARNING: You are using the SDL disk i/o audio driver!\n" + " %s file [%s].\n", iscapture ? "Reading from" : "Writing to", + fname); #endif /* We're ready to rock and roll. :-) */ @@ -143,30 +172,34 @@ DISKAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } static void -DISKAUD_DetectDevices(void) +DISKAUDIO_DetectDevices(void) { - /* !!! FIXME: stole this literal string from DEFAULT_OUTPUT_DEVNAME in SDL_audio.c */ - SDL_AddAudioDevice(SDL_FALSE, "System audio output device", (void *) 0x1); + SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) 0x1); + SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) 0x2); } static int -DISKAUD_Init(SDL_AudioDriverImpl * impl) +DISKAUDIO_Init(SDL_AudioDriverImpl * impl) { /* Set the function pointers */ - impl->OpenDevice = DISKAUD_OpenDevice; - impl->WaitDevice = DISKAUD_WaitDevice; - impl->PlayDevice = DISKAUD_PlayDevice; - impl->GetDeviceBuf = DISKAUD_GetDeviceBuf; - impl->CloseDevice = DISKAUD_CloseDevice; - impl->DetectDevices = DISKAUD_DetectDevices; + impl->OpenDevice = DISKAUDIO_OpenDevice; + impl->WaitDevice = DISKAUDIO_WaitDevice; + impl->PlayDevice = DISKAUDIO_PlayDevice; + impl->GetDeviceBuf = DISKAUDIO_GetDeviceBuf; + impl->CaptureFromDevice = DISKAUDIO_CaptureFromDevice; + impl->FlushCapture = DISKAUDIO_FlushCapture; + + impl->CloseDevice = DISKAUDIO_CloseDevice; + impl->DetectDevices = DISKAUDIO_DetectDevices; impl->AllowsArbitraryDeviceNames = 1; + impl->HasCaptureSupport = SDL_TRUE; return 1; /* this audio target is available. */ } -AudioBootStrap DISKAUD_bootstrap = { - "disk", "direct-to-disk audio", DISKAUD_Init, 1 +AudioBootStrap DISKAUDIO_bootstrap = { + "disk", "direct-to-disk audio", DISKAUDIO_Init, 1 }; #endif /* SDL_AUDIO_DRIVER_DISK */ diff --git a/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.h b/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.h index b5666f7fc..ad152a9ce 100644 --- a/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.h +++ b/Engine/lib/sdl/src/audio/disk/SDL_diskaudio.h @@ -32,10 +32,9 @@ struct SDL_PrivateAudioData { /* The file descriptor for the audio device */ - SDL_RWops *output; + SDL_RWops *io; + Uint32 io_delay; Uint8 *mixbuf; - Uint32 mixlen; - Uint32 write_delay; }; #endif /* _SDL_diskaudio_h */ diff --git a/Engine/lib/sdl/src/audio/dsp/SDL_dspaudio.c b/Engine/lib/sdl/src/audio/dsp/SDL_dspaudio.c index 17e029e1d..a5a31b3aa 100644 --- a/Engine/lib/sdl/src/audio/dsp/SDL_dspaudio.c +++ b/Engine/lib/sdl/src/audio/dsp/SDL_dspaudio.c @@ -44,7 +44,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "../SDL_audiodev_c.h" #include "SDL_dspaudio.h" @@ -60,16 +59,11 @@ DSP_DetectDevices(void) static void DSP_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - this->hidden->audio_fd = -1; - } - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->audio_fd >= 0) { + close(this->hidden->audio_fd); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } @@ -106,23 +100,20 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Open the audio device */ this->hidden->audio_fd = open(devname, flags, 0); if (this->hidden->audio_fd < 0) { - DSP_CloseDevice(this); return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); } - this->hidden->mixbuf = NULL; - /* Make the file descriptor use blocking writes with fcntl() */ + /* Make the file descriptor use blocking i/o with fcntl() */ { long ctlflags; ctlflags = fcntl(this->hidden->audio_fd, F_GETFL); ctlflags &= ~O_NONBLOCK; if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) { - DSP_CloseDevice(this); return SDL_SetError("Couldn't set audio blocking mode"); } } @@ -130,7 +121,6 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Get a list of supported hardware formats */ if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) { perror("SNDCTL_DSP_GETFMTS"); - DSP_CloseDevice(this); return SDL_SetError("Couldn't get audio format list"); } @@ -187,7 +177,6 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } } if (format == 0) { - DSP_CloseDevice(this); return SDL_SetError("Couldn't find any hardware audio formats"); } this->spec.format = test_format; @@ -197,7 +186,6 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if ((ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) { perror("SNDCTL_DSP_SETFMT"); - DSP_CloseDevice(this); return SDL_SetError("Couldn't set audio format"); } @@ -205,7 +193,6 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) value = this->spec.channels; if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) { perror("SNDCTL_DSP_CHANNELS"); - DSP_CloseDevice(this); return SDL_SetError("Cannot set the number of channels"); } this->spec.channels = value; @@ -214,7 +201,6 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) value = this->spec.freq; if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) { perror("SNDCTL_DSP_SPEED"); - DSP_CloseDevice(this); return SDL_SetError("Couldn't set audio frequency"); } this->spec.freq = value; @@ -225,7 +211,6 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Determine the power of two of the fragment size */ for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec); if ((0x01U << frag_spec) != this->spec.size) { - DSP_CloseDevice(this); return SDL_SetError("Fragment size must be a power of two"); } frag_spec |= 0x00020000; /* two fragments, for low latency */ @@ -250,13 +235,14 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) #endif /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - DSP_CloseDevice(this); - return SDL_OutOfMemory(); + if (!iscapture) { + this->hidden->mixlen = this->spec.size; + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); + if (this->hidden->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); /* We're ready to rock and roll. :-) */ return 0; @@ -266,14 +252,13 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) static void DSP_PlayDevice(_THIS) { - const Uint8 *mixbuf = this->hidden->mixbuf; - const int mixlen = this->hidden->mixlen; - if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) { + struct SDL_PrivateAudioData *h = this->hidden; + if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) { perror("Audio write"); SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen); + fprintf(stderr, "Wrote %d bytes of audio data\n", h->mixlen); #endif } @@ -283,6 +268,30 @@ DSP_GetDeviceBuf(_THIS) return (this->hidden->mixbuf); } +static int +DSP_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + return (int) read(this->hidden->audio_fd, buffer, buflen); +} + +static void +DSP_FlushCapture(_THIS) +{ + struct SDL_PrivateAudioData *h = this->hidden; + audio_buf_info info; + if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) { + while (info.bytes > 0) { + char buf[512]; + const size_t len = SDL_min(sizeof (buf), info.bytes); + const ssize_t br = read(h->audio_fd, buf, len); + if (br <= 0) { + break; + } + info.bytes -= br; + } + } +} + static int DSP_Init(SDL_AudioDriverImpl * impl) { @@ -292,8 +301,11 @@ DSP_Init(SDL_AudioDriverImpl * impl) impl->PlayDevice = DSP_PlayDevice; impl->GetDeviceBuf = DSP_GetDeviceBuf; impl->CloseDevice = DSP_CloseDevice; + impl->CaptureFromDevice = DSP_CaptureFromDevice; + impl->FlushCapture = DSP_FlushCapture; impl->AllowsArbitraryDeviceNames = 1; + impl->HasCaptureSupport = SDL_TRUE; return 1; /* this audio target is available. */ } diff --git a/Engine/lib/sdl/src/audio/dummy/SDL_dummyaudio.c b/Engine/lib/sdl/src/audio/dummy/SDL_dummyaudio.c index 107f0b073..b39f8e327 100644 --- a/Engine/lib/sdl/src/audio/dummy/SDL_dummyaudio.c +++ b/Engine/lib/sdl/src/audio/dummy/SDL_dummyaudio.c @@ -22,27 +22,44 @@ /* Output audio to nowhere... */ +#include "SDL_timer.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" #include "SDL_dummyaudio.h" static int -DUMMYAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +DUMMYAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { return 0; /* always succeeds. */ } static int -DUMMYAUD_Init(SDL_AudioDriverImpl * impl) +DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + /* Delay to make this sort of simulate real audio input. */ + SDL_Delay((this->spec.samples * 1000) / this->spec.freq); + + /* always return a full buffer of silence. */ + SDL_memset(buffer, this->spec.silence, buflen); + return buflen; +} + +static int +DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl) { /* Set the function pointers */ - impl->OpenDevice = DUMMYAUD_OpenDevice; + impl->OpenDevice = DUMMYAUDIO_OpenDevice; + impl->CaptureFromDevice = DUMMYAUDIO_CaptureFromDevice; + impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultCaptureDevice = 1; + impl->HasCaptureSupport = SDL_TRUE; + return 1; /* this audio target is available. */ } -AudioBootStrap DUMMYAUD_bootstrap = { - "dummy", "SDL dummy audio driver", DUMMYAUD_Init, 1 +AudioBootStrap DUMMYAUDIO_bootstrap = { + "dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, 1 }; /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c b/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c index 8378233ca..839d445ee 100644 --- a/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/Engine/lib/sdl/src/audio/emscripten/SDL_emscriptenaudio.c @@ -61,16 +61,15 @@ HandleAudioProcess(_THIS) Uint8 *buf = NULL; int byte_len = 0; int bytes = SDL_AUDIO_BITSIZE(this->spec.format) / 8; - int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8; - /* Only do soemthing if audio is enabled */ - if (!this->enabled) - return; - - if (this->paused) + /* Only do something if audio is enabled */ + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { return; + } if (this->convert.needed) { + const int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8; + if (this->hidden->conv_in_len != 0) { this->convert.len = this->hidden->conv_in_len * bytes_in * this->spec.channels; } @@ -128,7 +127,7 @@ HandleAudioProcess(_THIS) } for (var j = 0; j < $1; ++j) { - channelData[j] = getValue($0 + (j*numChannels + c)*4, 'float'); + channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; } } }, buf, byte_len / bytes / this->spec.channels); @@ -136,29 +135,147 @@ HandleAudioProcess(_THIS) } static void -Emscripten_CloseDevice(_THIS) +HandleCaptureProcess(_THIS) { - if (this->hidden != NULL) { - if (this->hidden->mixbuf != NULL) { - /* Clean up the audio buffer */ - SDL_free(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - } + Uint8 *buf; + int buflen; - SDL_free(this->hidden); - this->hidden = NULL; + /* Only do something if audio is enabled */ + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { + return; } + + if (this->convert.needed) { + buf = this->convert.buf; + buflen = this->convert.len_cvt; + } else { + if (!this->hidden->mixbuf) { + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); + if (!this->hidden->mixbuf) { + return; /* oh well. */ + } + } + buf = this->hidden->mixbuf; + buflen = this->spec.size; + } + + EM_ASM_ARGS({ + var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; + if (numChannels == 1) { /* fastpath this a little for the common (mono) case. */ + var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(0); + if (channelData.length != $1) { + throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; + } + for (var j = 0; j < $1; ++j) { + setValue($0 + (j * 4), channelData[j], 'float'); + } + } else { + for (var c = 0; c < numChannels; ++c) { + var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c); + if (channelData.length != $1) { + throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!'; + } + + for (var j = 0; j < $1; ++j) { + setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float'); + } + } + } + }, buf, (this->spec.size / sizeof (float)) / this->spec.channels); + + /* okay, we've got an interleaved float32 array in C now. */ + + if (this->convert.needed) { + SDL_ConvertAudio(&this->convert); + } + + /* Send it to the app. */ + (*this->spec.callback) (this->spec.userdata, buf, buflen); +} + + + +static void +EMSCRIPTENAUDIO_CloseDevice(_THIS) +{ + EM_ASM_({ + if ($0) { + if (SDL2.capture.silenceTimer !== undefined) { + clearTimeout(SDL2.capture.silenceTimer); + } + if (SDL2.capture.stream !== undefined) { + var tracks = SDL2.capture.stream.getAudioTracks(); + for (var i = 0; i < tracks.length; i++) { + SDL2.capture.stream.removeTrack(tracks[i]); + } + SDL2.capture.stream = undefined; + } + if (SDL2.capture.scriptProcessorNode !== undefined) { + SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; + SDL2.capture.scriptProcessorNode.disconnect(); + SDL2.capture.scriptProcessorNode = undefined; + } + if (SDL2.capture.mediaStreamNode !== undefined) { + SDL2.capture.mediaStreamNode.disconnect(); + SDL2.capture.mediaStreamNode = undefined; + } + if (SDL2.capture.silenceBuffer !== undefined) { + SDL2.capture.silenceBuffer = undefined + } + SDL2.capture = undefined; + } else { + if (SDL2.audio.scriptProcessorNode != undefined) { + SDL2.audio.scriptProcessorNode.disconnect(); + SDL2.audio.scriptProcessorNode = undefined; + } + SDL2.audio = undefined; + } + if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) { + SDL2.audioContext.close(); + SDL2.audioContext = undefined; + } + }, this->iscapture); + + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int -Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { SDL_bool valid_format = SDL_FALSE; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); + SDL_AudioFormat test_format; int i; float f; int result; + /* based on parts of library_sdl.js */ + + /* create context (TODO: this puts stuff in the global namespace...)*/ + result = EM_ASM_INT({ + if(typeof(SDL2) === 'undefined') { + SDL2 = {}; + } + if (!$0) { + SDL2.audio = {}; + } else { + SDL2.capture = {}; + } + + if (!SDL2.audioContext) { + if (typeof(AudioContext) !== 'undefined') { + SDL2.audioContext = new AudioContext(); + } else if (typeof(webkitAudioContext) !== 'undefined') { + SDL2.audioContext = new webkitAudioContext(); + } + } + return SDL2.audioContext === undefined ? -1 : 0; + }, iscapture); + if (result < 0) { + return SDL_SetError("Web Audio API is not available!"); + } + + test_format = SDL_FirstAudioFormat(this->spec.format); while ((!valid_format) && (test_format)) { switch (test_format) { case AUDIO_F32: /* web audio only supports floats */ @@ -181,36 +298,11 @@ Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); - - /* based on parts of library_sdl.js */ - - /* create context (TODO: this puts stuff in the global namespace...)*/ - result = EM_ASM_INT_V({ - if(typeof(SDL2) === 'undefined') - SDL2 = {}; - - if(typeof(SDL2.audio) === 'undefined') - SDL2.audio = {}; - - if (!SDL2.audioContext) { - if (typeof(AudioContext) !== 'undefined') { - SDL2.audioContext = new AudioContext(); - } else if (typeof(webkitAudioContext) !== 'undefined') { - SDL2.audioContext = new webkitAudioContext(); - } else { - return -1; - } - } - return 0; - }); - if (result < 0) { - return SDL_SetError("Web Audio API is not available!"); - } + SDL_zerop(this->hidden); /* limit to native freq */ - int sampleRate = EM_ASM_INT_V({ - return SDL2.audioContext['sampleRate']; + const int sampleRate = EM_ASM_INT_V({ + return SDL2.audioContext.sampleRate; }); if(this->spec.freq != sampleRate) { @@ -227,26 +319,86 @@ Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) SDL_CalculateAudioSpec(&this->spec); - /* setup a ScriptProcessorNode */ - EM_ASM_ARGS({ - SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); - SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { - SDL2.audio.currentOutputBuffer = e['outputBuffer']; - Runtime.dynCall('vi', $2, [$3]); - }; - SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); - }, this->spec.channels, this->spec.samples, HandleAudioProcess, this); + if (iscapture) { + /* The idea is to take the capture media stream, hook it up to an + audio graph where we can pass it through a ScriptProcessorNode + to access the raw PCM samples and push them to the SDL app's + callback. From there, we "process" the audio data into silence + and forget about it. */ + + /* This should, strictly speaking, use MediaRecorder for capture, but + this API is cleaner to use and better supported, and fires a + callback whenever there's enough data to fire down into the app. + The downside is that we are spending CPU time silencing a buffer + that the audiocontext uselessly mixes into any output. On the + upside, both of those things are not only run in native code in + the browser, they're probably SIMD code, too. MediaRecorder + feels like it's a pretty inefficient tapdance in similar ways, + to be honest. */ + + EM_ASM_({ + var have_microphone = function(stream) { + //console.log('SDL audio capture: we have a microphone! Replacing silence callback.'); + if (SDL2.capture.silenceTimer !== undefined) { + clearTimeout(SDL2.capture.silenceTimer); + SDL2.capture.silenceTimer = undefined; + } + SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); + SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); + SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) { + if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; } + audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0); + SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer; + Runtime.dynCall('vi', $2, [$3]); + }; + SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode); + SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination); + SDL2.capture.stream = stream; + }; + + var no_microphone = function(error) { + //console.log('SDL audio capture: we DO NOT have a microphone! (' + error.name + ')...leaving silence callback running.'); + }; + + /* we write silence to the audio callback until the microphone is available (user approves use, etc). */ + SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); + SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0); + var silence_callback = function() { + SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer; + Runtime.dynCall('vi', $2, [$3]); + }; + + SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); + + if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { + navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); + } else if (navigator.webkitGetUserMedia !== undefined) { + navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone); + } + }, this->spec.channels, this->spec.samples, HandleCaptureProcess, this); + } else { + /* setup a ScriptProcessorNode */ + EM_ASM_ARGS({ + SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); + SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { + if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } + SDL2.audio.currentOutputBuffer = e['outputBuffer']; + Runtime.dynCall('vi', $2, [$3]); + }; + SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); + }, this->spec.channels, this->spec.samples, HandleAudioProcess, this); + } + return 0; } static int -Emscripten_Init(SDL_AudioDriverImpl * impl) +EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl) { /* Set the function pointers */ - impl->OpenDevice = Emscripten_OpenDevice; - impl->CloseDevice = Emscripten_CloseDevice; + impl->OpenDevice = EMSCRIPTENAUDIO_OpenDevice; + impl->CloseDevice = EMSCRIPTENAUDIO_CloseDevice; - /* only one output */ impl->OnlyHasDefaultOutputDevice = 1; /* no threads here */ @@ -254,7 +406,7 @@ Emscripten_Init(SDL_AudioDriverImpl * impl) impl->ProvidesOwnCallbackThread = 1; /* check availability */ - int available = EM_ASM_INT_V({ + const int available = EM_ASM_INT_V({ if (typeof(AudioContext) !== 'undefined') { return 1; } else if (typeof(webkitAudioContext) !== 'undefined') { @@ -267,11 +419,23 @@ Emscripten_Init(SDL_AudioDriverImpl * impl) SDL_SetError("No audio context available"); } + const int capture_available = available && EM_ASM_INT_V({ + if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { + return 1; + } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { + return 1; + } + return 0; + }); + + impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE; + impl->OnlyHasDefaultCaptureDevice = capture_available ? SDL_TRUE : SDL_FALSE; + return available; } -AudioBootStrap EmscriptenAudio_bootstrap = { - "emscripten", "SDL emscripten audio driver", Emscripten_Init, 0 +AudioBootStrap EMSCRIPTENAUDIO_bootstrap = { + "emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0 }; #endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */ diff --git a/Engine/lib/sdl/src/audio/esd/SDL_esdaudio.c b/Engine/lib/sdl/src/audio/esd/SDL_esdaudio.c index 6a7882dcb..3eb719791 100644 --- a/Engine/lib/sdl/src/audio/esd/SDL_esdaudio.c +++ b/Engine/lib/sdl/src/audio/esd/SDL_esdaudio.c @@ -32,7 +32,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_esdaudio.h" @@ -174,17 +173,11 @@ ESD_GetDeviceBuf(_THIS) static void ESD_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->audio_fd >= 0) { - SDL_NAME(esd_close) (this->hidden->audio_fd); - this->hidden->audio_fd = -1; - } - - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->audio_fd >= 0) { + SDL_NAME(esd_close) (this->hidden->audio_fd); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } /* Try to get the name of the program */ @@ -227,7 +220,7 @@ ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); this->hidden->audio_fd = -1; /* Convert audio spec to the ESD audio format */ @@ -252,7 +245,6 @@ ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (!found) { - ESD_CloseDevice(this); return SDL_SetError("Couldn't find any hardware audio formats"); } @@ -271,7 +263,6 @@ ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) get_progname()); if (this->hidden->audio_fd < 0) { - ESD_CloseDevice(this); return SDL_SetError("Couldn't open ESD connection"); } @@ -283,9 +274,8 @@ ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { - ESD_CloseDevice(this); return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); diff --git a/Engine/lib/sdl/src/audio/fusionsound/SDL_fsaudio.c b/Engine/lib/sdl/src/audio/fusionsound/SDL_fsaudio.c index b22a3e9a3..daa0f9dd6 100644 --- a/Engine/lib/sdl/src/audio/fusionsound/SDL_fsaudio.c +++ b/Engine/lib/sdl/src/audio/fusionsound/SDL_fsaudio.c @@ -22,6 +22,8 @@ #if SDL_AUDIO_DRIVER_FUSIONSOUND +/* !!! FIXME: why is this is SDL_FS_* instead of FUSIONSOUND_*? */ + /* Allow access to a raw mixing buffer */ #ifdef HAVE_SIGNAL_H @@ -31,7 +33,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_fsaudio.h" @@ -150,13 +151,6 @@ SDL_FS_PlayDevice(_THIS) #endif } -static void -SDL_FS_WaitDone(_THIS) -{ - this->hidden->stream->Wait(this->hidden->stream, - this->hidden->mixsamples * FUSION_BUFFERS); -} - static Uint8 * SDL_FS_GetDeviceBuf(_THIS) @@ -168,20 +162,14 @@ SDL_FS_GetDeviceBuf(_THIS) static void SDL_FS_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->stream) { - this->hidden->stream->Release(this->hidden->stream); - this->hidden->stream = NULL; - } - if (this->hidden->fs) { - this->hidden->fs->Release(this->hidden->fs); - this->hidden->fs = NULL; - } - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->stream) { + this->hidden->stream->Release(this->hidden->stream); } + if (this->hidden->fs) { + this->hidden->fs->Release(this->hidden->fs); + } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } @@ -200,7 +188,7 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Try for a closest match on audio format */ for (test_format = SDL_FirstAudioFormat(this->spec.format); @@ -239,7 +227,6 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (format == 0) { - SDL_FS_CloseDevice(this); return SDL_SetError("Couldn't find any hardware audio formats"); } this->spec.format = test_format; @@ -247,7 +234,6 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Retrieve the main sound interface. */ ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs); if (ret) { - SDL_FS_CloseDevice(this); return SDL_SetError("Unable to initialize FusionSound: %d", ret); } @@ -266,7 +252,6 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->hidden->fs->CreateStream(this->hidden->fs, &desc, &this->hidden->stream); if (ret) { - SDL_FS_CloseDevice(this); return SDL_SetError("Unable to create FusionSoundStream: %d", ret); } @@ -285,9 +270,8 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { - SDL_FS_CloseDevice(this); return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -328,7 +312,6 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl) impl->WaitDevice = SDL_FS_WaitDevice; impl->GetDeviceBuf = SDL_FS_GetDeviceBuf; impl->CloseDevice = SDL_FS_CloseDevice; - impl->WaitDone = SDL_FS_WaitDone; impl->Deinitialize = SDL_FS_Deinitialize; impl->OnlyHasDefaultOutputDevice = 1; diff --git a/Engine/lib/sdl/src/audio/haiku/SDL_haikuaudio.cc b/Engine/lib/sdl/src/audio/haiku/SDL_haikuaudio.cc index 38f3b9621..25b1fa217 100644 --- a/Engine/lib/sdl/src/audio/haiku/SDL_haikuaudio.cc +++ b/Engine/lib/sdl/src/audio/haiku/SDL_haikuaudio.cc @@ -49,10 +49,11 @@ FillSound(void *device, void *stream, size_t len, SDL_AudioDevice *audio = (SDL_AudioDevice *) device; /* Only do soemthing if audio is enabled */ - if (!audio->enabled) + if (!SDL_AtomicGet(&audio->enabled)) { return; + } - if (!audio->paused) { + if (!SDL_AtomicGet(&audio->paused)) { if (audio->convert.needed) { SDL_LockMutex(audio->mixer_lock); (*audio->spec.callback) (audio->spec.userdata, @@ -73,16 +74,11 @@ FillSound(void *device, void *stream, size_t len, static void HAIKUAUDIO_CloseDevice(_THIS) { - if (_this->hidden != NULL) { - if (_this->hidden->audio_obj) { - _this->hidden->audio_obj->Stop(); - delete _this->hidden->audio_obj; - _this->hidden->audio_obj = NULL; - } - - delete _this->hidden; - _this->hidden = NULL; + if (_this->hidden->audio_obj) { + _this->hidden->audio_obj->Stop(); + delete _this->hidden->audio_obj; } + delete _this->hidden; } @@ -122,10 +118,10 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (_this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(_this->hidden, 0, (sizeof *_this->hidden)); + SDL_zerop(_this->hidden); /* Parse the audio format and fill the Be raw audio format */ - SDL_memset(&format, '\0', sizeof(media_raw_audio_format)); + SDL_zero(format); format.byte_order = B_MEDIA_LITTLE_ENDIAN; format.frame_rate = (float) _this->spec.freq; format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */ @@ -176,7 +172,6 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (!valid_datatype) { /* shouldn't happen, but just in case... */ - HAIKUAUDIO_CloseDevice(_this); return SDL_SetError("Unsupported audio format"); } @@ -195,7 +190,6 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (_this->hidden->audio_obj->Start() == B_NO_ERROR) { _this->hidden->audio_obj->SetHasData(true); } else { - HAIKUAUDIO_CloseDevice(_this); return SDL_SetError("Unable to start Be audio"); } diff --git a/Engine/lib/sdl/src/audio/nacl/SDL_naclaudio.c b/Engine/lib/sdl/src/audio/nacl/SDL_naclaudio.c index 2d1ee73e9..33cbe1c83 100644 --- a/Engine/lib/sdl/src/audio/nacl/SDL_naclaudio.c +++ b/Engine/lib/sdl/src/audio/nacl/SDL_naclaudio.c @@ -27,7 +27,6 @@ #include "SDL_audio.h" #include "SDL_mutex.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "../SDL_audiodev_c.h" @@ -38,22 +37,20 @@ #include "ppapi_simple/ps_event.h" /* The tag name used by NACL audio */ -#define NACLAUD_DRIVER_NAME "nacl" +#define NACLAUDIO_DRIVER_NAME "nacl" #define SAMPLE_FRAME_COUNT 4096 /* Audio driver functions */ -static int NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture); -static void NACLAUD_CloseDevice(_THIS); static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data); /* FIXME: Make use of latency if needed */ static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data) { SDL_AudioDevice* _this = (SDL_AudioDevice*) data; - SDL_LockMutex(private->mutex); + SDL_LockMutex(private->mutex); /* !!! FIXME: is this mutex necessary? */ - if (_this->enabled && !_this->paused) { + if (SDL_AtomicGet(&_this->enabled) && !SDL_AtomicGet(&_this->paused)) { if (_this->convert.needed) { SDL_LockMutex(_this->mixer_lock); (*_this->spec.callback) (_this->spec.userdata, @@ -68,13 +65,13 @@ static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelt SDL_UnlockMutex(_this->mixer_lock); } } else { - SDL_memset(samples, 0, buffer_size); + SDL_memset(samples, _this->spec.silence, buffer_size); } - return; + SDL_UnlockMutex(private->mutex); } -static void NACLAUD_CloseDevice(SDL_AudioDevice *device) { +static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) { const PPB_Core *core = PSInterfaceCore(); const PPB_Audio *ppb_audio = PSInterfaceAudio(); SDL_PrivateAudioData *hidden = (SDL_PrivateAudioData *) device->hidden; @@ -85,7 +82,7 @@ static void NACLAUD_CloseDevice(SDL_AudioDevice *device) { } static int -NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { +NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { PP_Instance instance = PSGetInstanceId(); const PPB_Audio *ppb_audio = PSInterfaceAudio(); const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig(); @@ -121,30 +118,30 @@ NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { } static int -NACLAUD_Init(SDL_AudioDriverImpl * impl) +NACLAUDIO_Init(SDL_AudioDriverImpl * impl) { if (PSGetInstanceId() == 0) { return 0; } /* Set the function pointers */ - impl->OpenDevice = NACLAUD_OpenDevice; - impl->CloseDevice = NACLAUD_CloseDevice; + impl->OpenDevice = NACLAUDIO_OpenDevice; + impl->CloseDevice = NACLAUDIO_CloseDevice; impl->OnlyHasDefaultOutputDevice = 1; impl->ProvidesOwnCallbackThread = 1; /* - * impl->WaitDevice = NACLAUD_WaitDevice; - * impl->GetDeviceBuf = NACLAUD_GetDeviceBuf; - * impl->PlayDevice = NACLAUD_PlayDevice; - * impl->Deinitialize = NACLAUD_Deinitialize; + * impl->WaitDevice = NACLAUDIO_WaitDevice; + * impl->GetDeviceBuf = NACLAUDIO_GetDeviceBuf; + * impl->PlayDevice = NACLAUDIO_PlayDevice; + * impl->Deinitialize = NACLAUDIO_Deinitialize; */ return 1; } -AudioBootStrap NACLAUD_bootstrap = { - NACLAUD_DRIVER_NAME, "SDL NaCl Audio Driver", - NACLAUD_Init, 0 +AudioBootStrap NACLAUDIO_bootstrap = { + NACLAUDIO_DRIVER_NAME, "SDL NaCl Audio Driver", + NACLAUDIO_Init, 0 }; #endif /* SDL_AUDIO_DRIVER_NACL */ diff --git a/Engine/lib/sdl/src/audio/nas/SDL_nasaudio.c b/Engine/lib/sdl/src/audio/nas/SDL_nasaudio.c index 9de5ff8b4..fe15cd696 100644 --- a/Engine/lib/sdl/src/audio/nas/SDL_nasaudio.c +++ b/Engine/lib/sdl/src/audio/nas/SDL_nasaudio.c @@ -30,22 +30,21 @@ #include "SDL_timer.h" #include "SDL_audio.h" #include "SDL_loadso.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_nasaudio.h" -static struct SDL_PrivateAudioData *this2 = NULL; - - static void (*NAS_AuCloseServer) (AuServer *); static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *); static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *); +static void (*NAS_AuHandleEvents) (AuServer *); static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *); static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *); static void (*NAS_AuSetElements) (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *); static void (*NAS_AuWriteElement) (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *); +static AuUint32 (*NAS_AuReadElement) + (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuStatus *); static AuServer *(*NAS_AuOpenServer) (_AuConst char *, int, _AuConst char *, int, _AuConst char *, char **); static AuEventHandlerRec *(*NAS_AuRegisterEventHandler) @@ -80,10 +79,12 @@ load_nas_syms(void) SDL_NAS_SYM(AuCloseServer); SDL_NAS_SYM(AuNextEvent); SDL_NAS_SYM(AuDispatchEvent); + SDL_NAS_SYM(AuHandleEvents); SDL_NAS_SYM(AuCreateFlow); SDL_NAS_SYM(AuStartFlow); SDL_NAS_SYM(AuSetElements); SDL_NAS_SYM(AuWriteElement); + SDL_NAS_SYM(AuReadElement); SDL_NAS_SYM(AuOpenServer); SDL_NAS_SYM(AuRegisterEventHandler); return 0; @@ -187,19 +188,53 @@ NAS_GetDeviceBuf(_THIS) return (this->hidden->mixbuf); } +static int +NAS_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + struct SDL_PrivateAudioData *h = this->hidden; + int retval; + + while (SDL_TRUE) { + /* just keep the event queue moving and the server chattering. */ + NAS_AuHandleEvents(h->aud); + + retval = (int) NAS_AuReadElement(h->aud, h->flow, 1, buflen, buffer, NULL); + /*printf("read %d capture bytes\n", (int) retval);*/ + if (retval == 0) { + SDL_Delay(10); /* don't burn the CPU if we're waiting for data. */ + } else { + break; + } + } + + return retval; +} + +static void +NAS_FlushCapture(_THIS) +{ + struct SDL_PrivateAudioData *h = this->hidden; + AuUint32 total = 0; + AuUint32 br; + Uint8 buf[512]; + + do { + /* just keep the event queue moving and the server chattering. */ + NAS_AuHandleEvents(h->aud); + br = NAS_AuReadElement(h->aud, h->flow, 1, sizeof (buf), buf, NULL); + /*printf("flushed %d capture bytes\n", (int) br);*/ + total += br; + } while ((br == sizeof (buf)) && (total < this->spec.size)); +} + static void NAS_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->aud) { - NAS_AuCloseServer(this->hidden->aud); - this->hidden->aud = 0; - } - SDL_free(this->hidden); - this2 = this->hidden = NULL; + if (this->hidden->aud) { + NAS_AuCloseServer(this->hidden->aud); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static unsigned char @@ -225,6 +260,12 @@ sdlformat_to_auformat(unsigned int fmt) static AuBool event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) { + SDL_AudioDevice *this = (SDL_AudioDevice *) hnd->data; + struct SDL_PrivateAudioData *h = this->hidden; + if (this->iscapture) { + return AuTrue; /* we don't (currently) care about any of this for capture devices */ + } + switch (ev->type) { case AuEventTypeElementNotify: { @@ -232,24 +273,24 @@ event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) switch (event->kind) { case AuElementNotifyKindLowWater: - if (this2->buf_free >= 0) { - this2->really += event->num_bytes; - gettimeofday(&this2->last_tv, 0); - this2->buf_free += event->num_bytes; + if (h->buf_free >= 0) { + h->really += event->num_bytes; + gettimeofday(&h->last_tv, 0); + h->buf_free += event->num_bytes; } else { - this2->buf_free = event->num_bytes; + h->buf_free = event->num_bytes; } break; case AuElementNotifyKindState: switch (event->cur_state) { case AuStatePause: if (event->reason != AuReasonUser) { - if (this2->buf_free >= 0) { - this2->really += event->num_bytes; - gettimeofday(&this2->last_tv, 0); - this2->buf_free += event->num_bytes; + if (h->buf_free >= 0) { + h->really += event->num_bytes; + gettimeofday(&h->last_tv, 0); + h->buf_free += event->num_bytes; } else { - this2->buf_free = event->num_bytes; + h->buf_free = event->num_bytes; } } break; @@ -261,15 +302,29 @@ event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) } static AuDeviceID -find_device(_THIS, int nch) +find_device(_THIS) { /* These "Au" things are all macros, not functions... */ + struct SDL_PrivateAudioData *h = this->hidden; + const unsigned int devicekind = this->iscapture ? AuComponentKindPhysicalInput : AuComponentKindPhysicalOutput; + const int numdevs = AuServerNumDevices(h->aud); + const int nch = this->spec.channels; int i; - for (i = 0; i < AuServerNumDevices(this->hidden->aud); i++) { - if ((AuDeviceKind(AuServerDevice(this->hidden->aud, i)) == - AuComponentKindPhysicalOutput) && - AuDeviceNumTracks(AuServerDevice(this->hidden->aud, i)) == nch) { - return AuDeviceIdentifier(AuServerDevice(this->hidden->aud, i)); + + /* Try to find exact match on channels first... */ + for (i = 0; i < numdevs; i++) { + const AuDeviceAttributes *dev = AuServerDevice(h->aud, i); + if ((AuDeviceKind(dev) == devicekind) && (AuDeviceNumTracks(dev) == nch)) { + return AuDeviceIdentifier(dev); + } + } + + /* Take anything, then... */ + for (i = 0; i < numdevs; i++) { + const AuDeviceAttributes *dev = AuServerDevice(h->aud, i); + if (AuDeviceKind(dev) == devicekind) { + this->spec.channels = AuDeviceNumTracks(dev); + return AuDeviceIdentifier(dev); } } return AuNone; @@ -288,7 +343,7 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Try for a closest match on audio format */ format = 0; @@ -300,21 +355,18 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } } if (format == 0) { - NAS_CloseDevice(this); return SDL_SetError("NAS: Couldn't find any hardware audio formats"); } this->spec.format = test_format; this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL); if (this->hidden->aud == 0) { - NAS_CloseDevice(this); return SDL_SetError("NAS: Couldn't open connection to NAS server"); } - this->hidden->dev = find_device(this, this->spec.channels); + this->hidden->dev = find_device(this); if ((this->hidden->dev == AuNone) || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) { - NAS_CloseDevice(this); return SDL_SetError("NAS: Couldn't find a fitting device on NAS server"); } @@ -328,29 +380,38 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(&this->spec); - this2 = this->hidden; + if (iscapture) { + AuMakeElementImportDevice(elms, this->spec.freq, this->hidden->dev, + AuUnlimitedSamples, 0, NULL); + AuMakeElementExportClient(elms + 1, 0, this->spec.freq, format, + this->spec.channels, AuTrue, buffer_size, + buffer_size, 0, NULL); + } else { + AuMakeElementImportClient(elms, this->spec.freq, format, + this->spec.channels, AuTrue, buffer_size, + buffer_size / 4, 0, NULL); + AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq, + AuUnlimitedSamples, 0, NULL); + } + + NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, + 2, elms, NULL); - AuMakeElementImportClient(elms, this->spec.freq, format, - this->spec.channels, AuTrue, buffer_size, - buffer_size / 4, 0, NULL); - AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq, - AuUnlimitedSamples, 0, NULL); - NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms, - NULL); NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0, this->hidden->flow, event_handler, - (AuPointer) NULL); + (AuPointer) this); NAS_AuStartFlow(this->hidden->aud, this->hidden->flow, NULL); /* Allocate mixing buffer */ - this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { - NAS_CloseDevice(this); - return SDL_OutOfMemory(); + if (!iscapture) { + this->hidden->mixlen = this->spec.size; + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); + if (this->hidden->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); /* We're ready to rock and roll. :-) */ return 0; @@ -381,9 +442,14 @@ NAS_Init(SDL_AudioDriverImpl * impl) impl->PlayDevice = NAS_PlayDevice; impl->WaitDevice = NAS_WaitDevice; impl->GetDeviceBuf = NAS_GetDeviceBuf; + impl->CaptureFromDevice = NAS_CaptureFromDevice; + impl->FlushCapture = NAS_FlushCapture; impl->CloseDevice = NAS_CloseDevice; impl->Deinitialize = NAS_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this true? */ + + impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultCaptureDevice = 1; + impl->HasCaptureSupport = SDL_TRUE; return 1; /* this audio target is available. */ } diff --git a/Engine/lib/sdl/src/audio/paudio/SDL_paudio.c b/Engine/lib/sdl/src/audio/paudio/SDL_paudio.c index 14c9701f4..57202245f 100644 --- a/Engine/lib/sdl/src/audio/paudio/SDL_paudio.c +++ b/Engine/lib/sdl/src/audio/paudio/SDL_paudio.c @@ -35,7 +35,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" #include "SDL_stdinc.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_paudio.h" @@ -228,16 +227,11 @@ PAUDIO_GetDeviceBuf(_THIS) static void PAUDIO_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - this->hidden->audio_fd = -1; - } - SDL_free(this->hidden); - this->hidden = NULL; + if (this->hidden->audio_fd >= 0) { + close(this->hidden->audio_fd); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int @@ -262,13 +256,12 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Open the audio device */ fd = OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); this->hidden->audio_fd = fd; if (fd < 0) { - PAUDIO_CloseDevice(this); return SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); } @@ -277,7 +270,6 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) * that we can have. */ if (ioctl(fd, AUDIO_BUFFER, &paud_bufinfo) < 0) { - PAUDIO_CloseDevice(this); return SDL_SetError("Couldn't get audio buffer information"); } @@ -391,7 +383,6 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) #ifdef DEBUG_AUDIO fprintf(stderr, "Couldn't find any hardware audio formats\n"); #endif - PAUDIO_CloseDevice(this); return SDL_SetError("Couldn't find any hardware audio formats"); } this->spec.format = test_format; @@ -449,15 +440,13 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (err != NULL) { - PAUDIO_CloseDevice(this); return SDL_SetError("Paudio: %s", err); } /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { - PAUDIO_CloseDevice(this); return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -492,7 +481,6 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) paud_control.ioctl_request = AUDIO_START; paud_control.position = 0; if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) { - PAUDIO_CloseDevice(this); #ifdef DEBUG_AUDIO fprintf(stderr, "Can't start audio play\n"); #endif diff --git a/Engine/lib/sdl/src/audio/psp/SDL_pspaudio.c b/Engine/lib/sdl/src/audio/psp/SDL_pspaudio.c index 18d2947e4..bd3456d3f 100644 --- a/Engine/lib/sdl/src/audio/psp/SDL_pspaudio.c +++ b/Engine/lib/sdl/src/audio/psp/SDL_pspaudio.c @@ -30,7 +30,6 @@ #include "SDL_audio.h" #include "SDL_error.h" #include "SDL_timer.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "../SDL_audiodev_c.h" #include "../SDL_sysaudio.h" @@ -40,10 +39,10 @@ #include /* The tag name used by PSP audio */ -#define PSPAUD_DRIVER_NAME "psp" +#define PSPAUDIO_DRIVER_NAME "psp" static int -PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { int format, mixlen, i; this->hidden = (struct SDL_PrivateAudioData *) @@ -51,7 +50,7 @@ PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, sizeof(*this->hidden)); + SDL_zerop(this->hidden); switch (this->spec.format & 0xff) { case 8: case 16: @@ -66,20 +65,7 @@ PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->spec.freq = 44100; /* Update the fragment size as size in bytes. */ -/* SDL_CalculateAudioSpec(this->spec); MOD */ - switch (this->spec.format) { - case AUDIO_U8: - this->spec.silence = 0x80; - break; - default: - this->spec.silence = 0x00; - break; - } - this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8; - this->spec.size *= this->spec.channels; - this->spec.size *= this->spec.samples; - -/* ========================================== */ + SDL_CalculateAudioSpec(&this->spec); /* Allocate the mixing buffer. Its size and starting address must be a multiple of 64 bytes. Our sample count is already a multiple of @@ -112,7 +98,7 @@ PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void PSPAUD_PlayDevice(_THIS) +static void PSPAUDIO_PlayDevice(_THIS) { Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; @@ -126,28 +112,25 @@ static void PSPAUD_PlayDevice(_THIS) } /* This function waits until it is possible to write a full sound buffer */ -static void PSPAUD_WaitDevice(_THIS) +static void PSPAUDIO_WaitDevice(_THIS) { /* Because we block when sending audio, there's no need for this function to do anything. */ } -static Uint8 *PSPAUD_GetDeviceBuf(_THIS) +static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS) { return this->hidden->mixbufs[this->hidden->next_buffer]; } -static void PSPAUD_CloseDevice(_THIS) +static void PSPAUDIO_CloseDevice(_THIS) { if (this->hidden->channel >= 0) { sceAudioChRelease(this->hidden->channel); - this->hidden->channel = -1; - } - - if (this->hidden->rawbuf != NULL) { - free(this->hidden->rawbuf); - this->hidden->rawbuf = NULL; } + free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */ + SDL_free(this->hidden); } -static void PSPAUD_ThreadInit(_THIS) + +static void PSPAUDIO_ThreadInit(_THIS) { /* Increase the priority of this audio thread by 1 to put it ahead of other SDL threads. */ @@ -162,24 +145,22 @@ static void PSPAUD_ThreadInit(_THIS) static int -PSPAUD_Init(SDL_AudioDriverImpl * impl) +PSPAUDIO_Init(SDL_AudioDriverImpl * impl) { - /* Set the function pointers */ - impl->OpenDevice = PSPAUD_OpenDevice; - impl->PlayDevice = PSPAUD_PlayDevice; - impl->WaitDevice = PSPAUD_WaitDevice; - impl->GetDeviceBuf = PSPAUD_GetDeviceBuf; - impl->WaitDone = PSPAUD_WaitDevice; - impl->CloseDevice = PSPAUD_CloseDevice; - impl->ThreadInit = PSPAUD_ThreadInit; + impl->OpenDevice = PSPAUDIO_OpenDevice; + impl->PlayDevice = PSPAUDIO_PlayDevice; + impl->WaitDevice = PSPAUDIO_WaitDevice; + impl->GetDeviceBuf = PSPAUDIO_GetDeviceBuf; + impl->CloseDevice = PSPAUDIO_CloseDevice; + impl->ThreadInit = PSPAUDIO_ThreadInit; /* PSP audio device */ impl->OnlyHasDefaultOutputDevice = 1; /* impl->HasCaptureSupport = 1; - impl->OnlyHasDefaultInputDevice = 1; + impl->OnlyHasDefaultCaptureDevice = 1; */ /* impl->DetectDevices = DSOUND_DetectDevices; @@ -188,8 +169,8 @@ PSPAUD_Init(SDL_AudioDriverImpl * impl) return 1; /* this audio target is available. */ } -AudioBootStrap PSPAUD_bootstrap = { - "psp", "PSP audio driver", PSPAUD_Init, 0 +AudioBootStrap PSPAUDIO_bootstrap = { + "psp", "PSP audio driver", PSPAUDIO_Init, 0 }; /* SDL_AUDI */ diff --git a/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.c b/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.c index 6b11e066f..9ced49d21 100644 --- a/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.c @@ -42,10 +42,10 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_pulseaudio.h" #include "SDL_loadso.h" +#include "../../thread/SDL_systhread.h" #if (PA_API_VERSION < 12) /** Return non-zero if the passed state is one of the connected states */ @@ -99,12 +99,19 @@ static pa_stream * (*PULSEAUDIO_pa_stream_new) (pa_context *, const char *, const pa_sample_spec *, const pa_channel_map *); static int (*PULSEAUDIO_pa_stream_connect_playback) (pa_stream *, const char *, const pa_buffer_attr *, pa_stream_flags_t, pa_cvolume *, pa_stream *); +static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *, + const pa_buffer_attr *, pa_stream_flags_t); static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *); static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *); +static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *); static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t, pa_free_cb_t, int64_t, pa_seek_mode_t); static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *, pa_stream_success_cb_t, void *); +static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *); +static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *); +static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *, + pa_stream_success_cb_t, void *); static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *); static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *); @@ -205,11 +212,16 @@ load_pulseaudio_syms(void) SDL_PULSEAUDIO_SYM(pa_context_unref); SDL_PULSEAUDIO_SYM(pa_stream_new); SDL_PULSEAUDIO_SYM(pa_stream_connect_playback); + SDL_PULSEAUDIO_SYM(pa_stream_connect_record); SDL_PULSEAUDIO_SYM(pa_stream_get_state); SDL_PULSEAUDIO_SYM(pa_stream_writable_size); + SDL_PULSEAUDIO_SYM(pa_stream_readable_size); SDL_PULSEAUDIO_SYM(pa_stream_write); SDL_PULSEAUDIO_SYM(pa_stream_drain); SDL_PULSEAUDIO_SYM(pa_stream_disconnect); + SDL_PULSEAUDIO_SYM(pa_stream_peek); + SDL_PULSEAUDIO_SYM(pa_stream_drop); + SDL_PULSEAUDIO_SYM(pa_stream_flush); SDL_PULSEAUDIO_SYM(pa_stream_unref); SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto); SDL_PULSEAUDIO_SYM(pa_strerror); @@ -238,6 +250,12 @@ getAppName(void) return "SDL Application"; /* oh well. */ } +static void +stream_operation_complete_no_op(pa_stream *s, int success, void *userdata) +{ + /* no-op for pa_stream_drain(), etc, to use for callback. */ +} + static void WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o) { @@ -325,7 +343,7 @@ PULSEAUDIO_WaitDevice(_THIS) { struct SDL_PrivateAudioData *h = this->hidden; - while (this->enabled) { + while (SDL_AtomicGet(&this->enabled)) { if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { @@ -343,41 +361,13 @@ PULSEAUDIO_PlayDevice(_THIS) { /* Write the audio data */ struct SDL_PrivateAudioData *h = this->hidden; - if (this->enabled) { + if (SDL_AtomicGet(&this->enabled)) { if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { SDL_OpenedAudioDeviceDisconnected(this); } } } -static void -stream_drain_complete(pa_stream *s, int success, void *userdata) -{ - /* no-op for pa_stream_drain() to use for callback. */ -} - -static void -PULSEAUDIO_WaitDone(_THIS) -{ - if (this->enabled) { - struct SDL_PrivateAudioData *h = this->hidden; - pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL); - if (o) { - while (PULSEAUDIO_pa_operation_get_state(o) != PA_OPERATION_DONE) { - if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || - PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || - PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { - PULSEAUDIO_pa_operation_cancel(o); - break; - } - } - PULSEAUDIO_pa_operation_unref(o); - } - } -} - - - static Uint8 * PULSEAUDIO_GetDeviceBuf(_THIS) { @@ -385,24 +375,96 @@ PULSEAUDIO_GetDeviceBuf(_THIS) } +static int +PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + struct SDL_PrivateAudioData *h = this->hidden; + const void *data = NULL; + size_t nbytes = 0; + + while (SDL_AtomicGet(&this->enabled)) { + if (h->capturebuf != NULL) { + const int cpy = SDL_min(buflen, h->capturelen); + SDL_memcpy(buffer, h->capturebuf, cpy); + /*printf("PULSEAUDIO: fed %d captured bytes\n", cpy);*/ + h->capturebuf += cpy; + h->capturelen -= cpy; + if (h->capturelen == 0) { + h->capturebuf = NULL; + PULSEAUDIO_pa_stream_drop(h->stream); /* done with this fragment. */ + } + return cpy; /* new data, return it. */ + } + + if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY || + PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY || + PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { + SDL_OpenedAudioDeviceDisconnected(this); + return -1; /* uhoh, pulse failed! */ + } + + if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) { + continue; /* no data available yet. */ + } + + /* a new fragment is available! */ + PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes); + SDL_assert(nbytes > 0); + if (data == NULL) { /* NULL==buffer had a hole. Ignore that. */ + PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */ + } else { + /* store this fragment's data, start feeding it to SDL. */ + /*printf("PULSEAUDIO: captured %d new bytes\n", (int) nbytes);*/ + h->capturebuf = (const Uint8 *) data; + h->capturelen = nbytes; + } + } + + return -1; /* not enabled? */ +} + +static void +PULSEAUDIO_FlushCapture(_THIS) +{ + struct SDL_PrivateAudioData *h = this->hidden; + + if (h->capturebuf != NULL) { + PULSEAUDIO_pa_stream_drop(h->stream); + h->capturebuf = NULL; + h->capturelen = 0; + } + + WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_stream_flush(h->stream, stream_operation_complete_no_op, NULL)); +} + static void PULSEAUDIO_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - SDL_free(this->hidden->device_name); - if (this->hidden->stream) { - PULSEAUDIO_pa_stream_disconnect(this->hidden->stream); - PULSEAUDIO_pa_stream_unref(this->hidden->stream); + if (this->hidden->stream) { + if (this->hidden->capturebuf != NULL) { + PULSEAUDIO_pa_stream_drop(this->hidden->stream); } - DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context); - SDL_free(this->hidden); - this->hidden = NULL; + PULSEAUDIO_pa_stream_disconnect(this->hidden->stream); + PULSEAUDIO_pa_stream_unref(this->hidden->stream); + } + + DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context); + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden->device_name); + SDL_free(this->hidden); +} + +static void +SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data) +{ + if (i) { + char **devname = (char **) data; + *devname = SDL_strdup(i->name); } } static void -DeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data) +SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data) { if (i) { char **devname = (char **) data; @@ -411,7 +473,7 @@ DeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data } static SDL_bool -FindDeviceName(struct SDL_PrivateAudioData *h, void *handle) +FindDeviceName(struct SDL_PrivateAudioData *h, const int iscapture, void *handle) { const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1; @@ -419,7 +481,16 @@ FindDeviceName(struct SDL_PrivateAudioData *h, void *handle) return SDL_TRUE; } - WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx, DeviceNameCallback, &h->device_name)); + if (iscapture) { + WaitForPulseOperation(h->mainloop, + PULSEAUDIO_pa_context_get_source_info_by_index(h->context, idx, + SourceDeviceNameCallback, &h->device_name)); + } else { + WaitForPulseOperation(h->mainloop, + PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx, + SinkDeviceNameCallback, &h->device_name)); + } + return (h->device_name != NULL); } @@ -433,15 +504,15 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) pa_channel_map pacmap; pa_stream_flags_t flags = 0; int state = 0; + int rc = 0; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) + h = this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc((sizeof *this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); - h = this->hidden; + SDL_zerop(this->hidden); paspec.format = PA_SAMPLE_INVALID; @@ -482,7 +553,6 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } } if (paspec.format == PA_SAMPLE_INVALID) { - PULSEAUDIO_CloseDevice(this); return SDL_SetError("Couldn't find any hardware audio formats"); } this->spec.format = test_format; @@ -494,13 +564,14 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) SDL_CalculateAudioSpec(&this->spec); /* Allocate mixing buffer */ - h->mixlen = this->spec.size; - h->mixbuf = (Uint8 *) SDL_AllocAudioMem(h->mixlen); - if (h->mixbuf == NULL) { - PULSEAUDIO_CloseDevice(this); - return SDL_OutOfMemory(); + if (!iscapture) { + h->mixlen = this->spec.size; + h->mixbuf = (Uint8 *) SDL_malloc(h->mixlen); + if (h->mixbuf == NULL) { + return SDL_OutOfMemory(); + } + SDL_memset(h->mixbuf, this->spec.silence, this->spec.size); } - SDL_memset(h->mixbuf, this->spec.silence, this->spec.size); paspec.channels = this->spec.channels; paspec.rate = this->spec.freq; @@ -522,13 +593,11 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) #endif if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) { - PULSEAUDIO_CloseDevice(this); return SDL_SetError("Could not connect to PulseAudio server"); } - if (!FindDeviceName(h, handle)) { - PULSEAUDIO_CloseDevice(this); - return SDL_SetError("Requested PulseAudio sink missing?"); + if (!FindDeviceName(h, iscapture, handle)) { + return SDL_SetError("Requested PulseAudio sink/source missing?"); } /* The SDL ALSA output hints us that we use Windows' channel mapping */ @@ -544,7 +613,6 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) ); if (h->stream == NULL) { - PULSEAUDIO_CloseDevice(this); return SDL_SetError("Could not set up PulseAudio stream"); } @@ -554,20 +622,22 @@ PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) flags |= PA_STREAM_DONT_MOVE; } - if (PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, - NULL, NULL) < 0) { - PULSEAUDIO_CloseDevice(this); + if (iscapture) { + rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags); + } else { + rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL); + } + + if (rc < 0) { return SDL_SetError("Could not connect PulseAudio stream"); } do { if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) { - PULSEAUDIO_CloseDevice(this); return SDL_SetError("pa_mainloop_iterate() failed"); } state = PULSEAUDIO_pa_stream_get_state(h->stream); if (!PA_STREAM_IS_GOOD(state)) { - PULSEAUDIO_CloseDevice(this); return SDL_SetError("Could not connect PulseAudio stream"); } } while (state != PA_STREAM_READY); @@ -646,7 +716,7 @@ PULSEAUDIO_DetectDevices() WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, NULL)); /* ok, we have a sane list, let's set up hotplug notifications now... */ - hotplug_thread = SDL_CreateThread(HotplugThread, "PulseHotplug", NULL); + hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL); } static void @@ -684,8 +754,11 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl) impl->WaitDevice = PULSEAUDIO_WaitDevice; impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf; impl->CloseDevice = PULSEAUDIO_CloseDevice; - impl->WaitDone = PULSEAUDIO_WaitDone; impl->Deinitialize = PULSEAUDIO_Deinitialize; + impl->CaptureFromDevice = PULSEAUDIO_CaptureFromDevice; + impl->FlushCapture = PULSEAUDIO_FlushCapture; + + impl->HasCaptureSupport = SDL_TRUE; return 1; /* this audio target is available. */ } diff --git a/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.h b/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.h index c57ab7132..e12000f2a 100644 --- a/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.h +++ b/Engine/lib/sdl/src/audio/pulseaudio/SDL_pulseaudio.h @@ -42,6 +42,9 @@ struct SDL_PrivateAudioData /* Raw mixing buffer */ Uint8 *mixbuf; int mixlen; + + const Uint8 *capturebuf; + int capturelen; }; #endif /* _SDL_pulseaudio_h */ diff --git a/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.c b/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.c index 1899ca6d9..149cad90a 100644 --- a/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.c +++ b/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.c @@ -45,7 +45,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_qsa_audio.h" @@ -138,8 +137,7 @@ QSA_ThreadInit(_THIS) static void QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) { - SDL_memset(cpars, 0, sizeof(snd_pcm_channel_params_t)); - + SDL_zerop(cpars); cpars->channel = SND_PCM_CHANNEL_PLAYBACK; cpars->mode = SND_PCM_MODE_BLOCK; cpars->start_mode = SND_PCM_START_DATA; @@ -229,7 +227,7 @@ QSA_PlayDevice(_THIS) int towrite; void *pcmbuffer; - if ((!this->enabled) || (!this->hidden)) { + if (!SDL_AtomicGet(&this->enabled) || !this->hidden) { return; } @@ -262,7 +260,7 @@ QSA_PlayDevice(_THIS) continue; } else { if ((errno == EINVAL) || (errno == EIO)) { - SDL_memset(&cstatus, 0, sizeof(cstatus)); + SDL_zero(cstatus); if (!this->hidden->iscapture) { cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; } else { @@ -305,7 +303,7 @@ QSA_PlayDevice(_THIS) towrite -= written; pcmbuffer += written * this->spec.channels; } - } while ((towrite > 0) && (this->enabled)); + } while ((towrite > 0) && SDL_AtomicGet(&this->enabled)); /* If we couldn't write, assume fatal error for now */ if (towrite != 0) { @@ -322,27 +320,21 @@ QSA_GetDeviceBuf(_THIS) static void QSA_CloseDevice(_THIS) { - if (this->hidden != NULL) { - if (this->hidden->audio_handle != NULL) { - if (!this->hidden->iscapture) { - /* Finish playing available samples */ - snd_pcm_plugin_flush(this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } else { - /* Cancel unread samples during capture */ - snd_pcm_plugin_flush(this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - snd_pcm_close(this->hidden->audio_handle); - this->hidden->audio_handle = NULL; + if (this->hidden->audio_handle != NULL) { + if (!this->hidden->iscapture) { + /* Finish playing available samples */ + snd_pcm_plugin_flush(this->hidden->audio_handle, + SND_PCM_CHANNEL_PLAYBACK); + } else { + /* Cancel unread samples during capture */ + snd_pcm_plugin_flush(this->hidden->audio_handle, + SND_PCM_CHANNEL_CAPTURE); } - - SDL_FreeAudioMem(this->hidden->pcm_buf); - this->hidden->pcm_buf = NULL; - - SDL_free(this->hidden); - this->hidden = NULL; + snd_pcm_close(this->hidden->audio_handle); } + + SDL_free(this->hidden->pcm_buf); + SDL_free(this->hidden); } static int @@ -365,13 +357,13 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, sizeof(struct SDL_PrivateAudioData)); + SDL_zerop(this->hidden); /* Initialize channel transfer parameters to default */ QSA_InitAudioParams(&cparams); /* Initialize channel direction: capture or playback */ - this->hidden->iscapture = iscapture; + this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; if (device != NULL) { /* Open requested audio device */ @@ -391,7 +383,6 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Check if requested device is opened */ if (status < 0) { this->hidden->audio_handle = NULL; - QSA_CloseDevice(this); return QSA_SetError("snd_pcm_open", status); } @@ -401,7 +392,6 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) snd_pcm_plugin_set_disable(this->hidden->audio_handle, PLUGIN_DISABLE_MMAP); if (status < 0) { - QSA_CloseDevice(this); return QSA_SetError("snd_pcm_plugin_set_disable", status); } } @@ -487,7 +477,6 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* assumes test_format not 0 on success */ if (test_format == 0) { - QSA_CloseDevice(this); return SDL_SetError("QSA: Couldn't find any hardware audio formats"); } @@ -505,12 +494,11 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Setup the transfer parameters according to cparams */ status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams); if (status < 0) { - QSA_CloseDevice(this); return QSA_SetError("snd_pcm_channel_params", status); } /* Make sure channel is setup right one last time */ - SDL_memset(&csetup, 0, sizeof(csetup)); + SDL_zero(csetup); if (!this->hidden->iscapture) { csetup.channel = SND_PCM_CHANNEL_PLAYBACK; } else { @@ -519,7 +507,6 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Setup an audio channel */ if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) { - QSA_CloseDevice(this); return SDL_SetError("QSA: Unable to setup channel"); } @@ -540,9 +527,8 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) * closest multiple) */ this->hidden->pcm_buf = - (Uint8 *) SDL_AllocAudioMem(this->hidden->pcm_len); + (Uint8 *) SDL_malloc(this->hidden->pcm_len); if (this->hidden->pcm_buf == NULL) { - QSA_CloseDevice(this); return SDL_OutOfMemory(); } SDL_memset(this->hidden->pcm_buf, this->spec.silence, @@ -560,7 +546,6 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (this->hidden->audio_fd < 0) { - QSA_CloseDevice(this); return QSA_SetError("snd_pcm_file_descriptor", status); } @@ -578,7 +563,6 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (status < 0) { - QSA_CloseDevice(this); return QSA_SetError("snd_pcm_plugin_prepare", status); } @@ -724,32 +708,13 @@ QSA_DetectDevices(void) } } -static void -QSA_WaitDone(_THIS) -{ - if (!this->hidden->iscapture) { - if (this->hidden->audio_handle != NULL) { - /* Wait till last fragment is played and stop channel */ - snd_pcm_plugin_flush(this->hidden->audio_handle, - SND_PCM_CHANNEL_PLAYBACK); - } - } else { - if (this->hidden->audio_handle != NULL) { - /* Discard all unread data and stop channel */ - snd_pcm_plugin_flush(this->hidden->audio_handle, - SND_PCM_CHANNEL_CAPTURE); - } - } -} - static void QSA_Deinitialize(void) { /* Clear devices array on shutdown */ - SDL_memset(qsa_playback_device, 0x00, - sizeof(QSA_Device) * QSA_MAX_DEVICES); - SDL_memset(qsa_capture_device, 0x00, - sizeof(QSA_Device) * QSA_MAX_DEVICES); + /* !!! FIXME: we zero these on init...any reason to do it here? */ + SDL_zero(qsa_playback_device); + SDL_zero(qsa_capture_device); qsa_playback_devices = 0; qsa_capture_devices = 0; } @@ -761,10 +726,8 @@ QSA_Init(SDL_AudioDriverImpl * impl) int32_t status = 0; /* Clear devices array */ - SDL_memset(qsa_playback_device, 0x00, - sizeof(QSA_Device) * QSA_MAX_DEVICES); - SDL_memset(qsa_capture_device, 0x00, - sizeof(QSA_Device) * QSA_MAX_DEVICES); + SDL_zero(qsa_playback_device); + SDL_zero(qsa_capture_device); qsa_playback_devices = 0; qsa_capture_devices = 0; @@ -778,7 +741,6 @@ QSA_Init(SDL_AudioDriverImpl * impl) impl->PlayDevice = QSA_PlayDevice; impl->GetDeviceBuf = QSA_GetDeviceBuf; impl->CloseDevice = QSA_CloseDevice; - impl->WaitDone = QSA_WaitDone; impl->Deinitialize = QSA_Deinitialize; impl->LockDevice = NULL; impl->UnlockDevice = NULL; @@ -788,7 +750,7 @@ QSA_Init(SDL_AudioDriverImpl * impl) impl->SkipMixerLock = 0; impl->HasCaptureSupport = 1; impl->OnlyHasDefaultOutputDevice = 0; - impl->OnlyHasDefaultInputDevice = 0; + impl->OnlyHasDefaultCaptureDevice = 0; /* Check if io-audio manager is running or not */ status = snd_cards(); diff --git a/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.h b/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.h index 53d37e96f..19a2215aa 100644 --- a/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.h +++ b/Engine/lib/sdl/src/audio/qsa/SDL_qsa_audio.h @@ -34,7 +34,7 @@ struct SDL_PrivateAudioData { /* SDL capture state */ - int iscapture; + SDL_bool iscapture; /* The audio device handle */ int cardno; diff --git a/Engine/lib/sdl/src/audio/sndio/SDL_sndioaudio.c b/Engine/lib/sdl/src/audio/sndio/SDL_sndioaudio.c index 64565ae88..fb7d78ff1 100644 --- a/Engine/lib/sdl/src/audio/sndio/SDL_sndioaudio.c +++ b/Engine/lib/sdl/src/audio/sndio/SDL_sndioaudio.c @@ -36,7 +36,6 @@ #include #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "SDL_sndioaudio.h" @@ -171,25 +170,15 @@ SNDIO_GetDeviceBuf(_THIS) return this->hidden->mixbuf; } -static void -SNDIO_WaitDone(_THIS) -{ - SNDIO_sio_stop(this->hidden->dev); -} - static void SNDIO_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - if ( this->hidden->dev != NULL ) { - SNDIO_sio_close(this->hidden->dev); - this->hidden->dev = NULL; - } - SDL_free(this->hidden); - this->hidden = NULL; + if ( this->hidden->dev != NULL ) { + SNDIO_sio_stop(this->hidden->dev); + SNDIO_sio_close(this->hidden->dev); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int @@ -204,13 +193,12 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, sizeof(*this->hidden)); + SDL_zerop(this->hidden); this->hidden->mixlen = this->spec.size; /* !!! FIXME: SIO_DEVANY can be a specific device... */ if ((this->hidden->dev = SNDIO_sio_open(SIO_DEVANY, SIO_PLAY, 0)) == NULL) { - SNDIO_CloseDevice(this); return SDL_SetError("sio_open() failed"); } @@ -233,7 +221,6 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) continue; } if (SNDIO_sio_getpar(this->hidden->dev, &par) == 0) { - SNDIO_CloseDevice(this); return SDL_SetError("sio_getpar() failed"); } if (par.bps != SIO_BPS(par.bits)) { @@ -248,7 +235,6 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (status < 0) { - SNDIO_CloseDevice(this); return SDL_SetError("sndio: Couldn't find any hardware audio formats"); } @@ -269,7 +255,6 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) else if ((par.bps == 1) && (!par.sig)) this->spec.format = AUDIO_U8; else { - SNDIO_CloseDevice(this); return SDL_SetError("sndio: Got unsupported hardware audio format."); } @@ -282,9 +267,8 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { - SNDIO_CloseDevice(this); return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen); @@ -315,7 +299,6 @@ SNDIO_Init(SDL_AudioDriverImpl * impl) impl->WaitDevice = SNDIO_WaitDevice; impl->PlayDevice = SNDIO_PlayDevice; impl->GetDeviceBuf = SNDIO_GetDeviceBuf; - impl->WaitDone = SNDIO_WaitDone; impl->CloseDevice = SNDIO_CloseDevice; impl->Deinitialize = SNDIO_Deinitialize; impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: sndio can handle multiple devices. */ diff --git a/Engine/lib/sdl/src/audio/sun/SDL_sunaudio.c b/Engine/lib/sdl/src/audio/sun/SDL_sunaudio.c index 71029d21f..b994c12c3 100644 --- a/Engine/lib/sdl/src/audio/sun/SDL_sunaudio.c +++ b/Engine/lib/sdl/src/audio/sun/SDL_sunaudio.c @@ -40,7 +40,6 @@ #include "SDL_timer.h" #include "SDL_audio.h" -#include "../SDL_audiomem.h" #include "../SDL_audio_c.h" #include "../SDL_audiodev_c.h" #include "SDL_sunaudio.h" @@ -183,18 +182,12 @@ SUNAUDIO_GetDeviceBuf(_THIS) static void SUNAUDIO_CloseDevice(_THIS) { - if (this->hidden != NULL) { - SDL_FreeAudioMem(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - SDL_free(this->hidden->ulaw_buf); - this->hidden->ulaw_buf = NULL; - if (this->hidden->audio_fd >= 0) { - close(this->hidden->audio_fd); - this->hidden->audio_fd = -1; - } - SDL_free(this->hidden); - this->hidden = NULL; + SDL_free(this->hidden->ulaw_buf); + if (this->hidden->audio_fd >= 0) { + close(this->hidden->audio_fd); } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int @@ -219,7 +212,7 @@ SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Open the audio device */ this->hidden->audio_fd = open(devname, flags, 0); @@ -340,7 +333,7 @@ SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) SDL_CalculateAudioSpec(&this->spec); /* Allocate mixing buffer */ - this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size); + this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); if (this->hidden->mixbuf == NULL) { return SDL_OutOfMemory(); } diff --git a/Engine/lib/sdl/src/audio/winmm/SDL_winmm.c b/Engine/lib/sdl/src/audio/winmm/SDL_winmm.c index 6d05a65ef..34f543ddb 100644 --- a/Engine/lib/sdl/src/audio/winmm/SDL_winmm.c +++ b/Engine/lib/sdl/src/audio/winmm/SDL_winmm.c @@ -27,6 +27,7 @@ #include "../../core/windows/SDL_windows.h" #include +#include "SDL_assert.h" #include "SDL_timer.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" @@ -40,11 +41,11 @@ static void DetectWave##typ##Devs(void) { \ const UINT iscapture = iscap ? 1 : 0; \ const UINT devcount = wave##typ##GetNumDevs(); \ - capstyp caps; \ + capstyp##2W caps; \ UINT i; \ for (i = 0; i < devcount; i++) { \ - if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ - char *name = WIN_StringToUTF8(caps.szPname); \ + if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ + char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \ if (name != NULL) { \ SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \ SDL_free(name); \ @@ -134,63 +135,87 @@ WINMM_PlayDevice(_THIS) this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; } -static void -WINMM_WaitDone(_THIS) +static int +WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen) { - int i, left; + const int nextbuf = this->hidden->next_buffer; + MMRESULT result; - do { - left = NUM_BUFFERS; - for (i = 0; i < NUM_BUFFERS; ++i) { - if (this->hidden->wavebuf[i].dwFlags & WHDR_DONE) { - --left; - } - } - if (left > 0) { - SDL_Delay(100); - } - } while (left > 0); + SDL_assert(buflen == this->spec.size); + + /* Wait for an audio chunk to finish */ + WaitForSingleObject(this->hidden->audio_sem, INFINITE); + + /* Copy it to caller's buffer... */ + SDL_memcpy(buffer, this->hidden->wavebuf[nextbuf].lpData, this->spec.size); + + /* requeue the buffer that just finished. */ + result = waveInAddBuffer(this->hidden->hin, + &this->hidden->wavebuf[nextbuf], + sizeof (this->hidden->wavebuf[nextbuf])); + if (result != MMSYSERR_NOERROR) { + return -1; /* uhoh! Disable the device. */ + } + + /* queue the next buffer in sequence, next time. */ + this->hidden->next_buffer = (nextbuf + 1) % NUM_BUFFERS; + return this->spec.size; +} + +static void +WINMM_FlushCapture(_THIS) +{ + /* Wait for an audio chunk to finish */ + if (WaitForSingleObject(this->hidden->audio_sem, 0) == WAIT_OBJECT_0) { + const int nextbuf = this->hidden->next_buffer; + /* requeue the buffer that just finished without reading from it. */ + waveInAddBuffer(this->hidden->hin, + &this->hidden->wavebuf[nextbuf], + sizeof (this->hidden->wavebuf[nextbuf])); + this->hidden->next_buffer = (nextbuf + 1) % NUM_BUFFERS; + } } static void WINMM_CloseDevice(_THIS) { - /* Close up audio */ - if (this->hidden != NULL) { - int i; + int i; - if (this->hidden->audio_sem) { - CloseHandle(this->hidden->audio_sem); - this->hidden->audio_sem = 0; - } + if (this->hidden->hout) { + waveOutReset(this->hidden->hout); /* Clean up mixing buffers */ for (i = 0; i < NUM_BUFFERS; ++i) { if (this->hidden->wavebuf[i].dwUser != 0xFFFF) { waveOutUnprepareHeader(this->hidden->hout, &this->hidden->wavebuf[i], - sizeof(this->hidden->wavebuf[i])); - this->hidden->wavebuf[i].dwUser = 0xFFFF; + sizeof (this->hidden->wavebuf[i])); } } - /* Free raw mixing buffer */ - SDL_free(this->hidden->mixbuf); - this->hidden->mixbuf = NULL; - - if (this->hidden->hin) { - waveInClose(this->hidden->hin); - this->hidden->hin = 0; - } - - if (this->hidden->hout) { - waveOutClose(this->hidden->hout); - this->hidden->hout = 0; - } - - SDL_free(this->hidden); - this->hidden = NULL; + waveOutClose(this->hidden->hout); } + + if (this->hidden->hin) { + waveInReset(this->hidden->hin); + + /* Clean up mixing buffers */ + for (i = 0; i < NUM_BUFFERS; ++i) { + if (this->hidden->wavebuf[i].dwUser != 0xFFFF) { + waveInUnprepareHeader(this->hidden->hin, + &this->hidden->wavebuf[i], + sizeof (this->hidden->wavebuf[i])); + } + } + waveInClose(this->hidden->hin); + } + + if (this->hidden->audio_sem) { + CloseHandle(this->hidden->audio_sem); + } + + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static SDL_bool @@ -239,7 +264,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->hidden == NULL) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); /* Initialize the wavebuf structures for closing */ for (i = 0; i < NUM_BUFFERS; ++i) @@ -269,7 +294,6 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (!valid_datatype) { - WINMM_CloseDevice(this); return SDL_SetError("Unsupported audio format"); } @@ -281,36 +305,45 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) result = waveInOpen(&this->hidden->hin, devId, &waveformat, (DWORD_PTR) CaptureSound, (DWORD_PTR) this, CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + return SetMMerror("waveInOpen()", result); + } } else { result = waveOutOpen(&this->hidden->hout, devId, &waveformat, (DWORD_PTR) FillSound, (DWORD_PTR) this, CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) { + return SetMMerror("waveOutOpen()", result); + } } - if (result != MMSYSERR_NOERROR) { - WINMM_CloseDevice(this); - return SetMMerror("waveOutOpen()", result); - } #ifdef SOUND_DEBUG /* Check the sound device we retrieved */ { - WAVEOUTCAPS caps; - - result = waveOutGetDevCaps((UINT) this->hidden->hout, - &caps, sizeof(caps)); - if (result != MMSYSERR_NOERROR) { - WINMM_CloseDevice(this); - return SetMMerror("waveOutGetDevCaps()", result); + if (iscapture) { + WAVEINCAPS caps; + result = waveInGetDevCaps((UINT) this->hidden->hout, + &caps, sizeof (caps)); + if (result != MMSYSERR_NOERROR) { + return SetMMerror("waveInGetDevCaps()", result); + } + printf("Audio device: %s\n", caps.szPname); + } else { + WAVEOUTCAPS caps; + result = waveOutGetDevCaps((UINT) this->hidden->hout, + &caps, sizeof(caps)); + if (result != MMSYSERR_NOERROR) { + return SetMMerror("waveOutGetDevCaps()", result); + } + printf("Audio device: %s\n", caps.szPname); } - printf("Audio device: %s\n", caps.szPname); } #endif /* Create the audio buffer semaphore */ this->hidden->audio_sem = - CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL); + CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL); if (this->hidden->audio_sem == NULL) { - WINMM_CloseDevice(this); return SDL_SetError("Couldn't create semaphore"); } @@ -318,22 +351,44 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->hidden->mixbuf = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); if (this->hidden->mixbuf == NULL) { - WINMM_CloseDevice(this); return SDL_OutOfMemory(); } + + SDL_zero(this->hidden->wavebuf); for (i = 0; i < NUM_BUFFERS; ++i) { - SDL_memset(&this->hidden->wavebuf[i], 0, - sizeof(this->hidden->wavebuf[i])); this->hidden->wavebuf[i].dwBufferLength = this->spec.size; this->hidden->wavebuf[i].dwFlags = WHDR_DONE; this->hidden->wavebuf[i].lpData = (LPSTR) & this->hidden->mixbuf[i * this->spec.size]; - result = waveOutPrepareHeader(this->hidden->hout, - &this->hidden->wavebuf[i], - sizeof(this->hidden->wavebuf[i])); + + if (iscapture) { + result = waveInPrepareHeader(this->hidden->hin, + &this->hidden->wavebuf[i], + sizeof(this->hidden->wavebuf[i])); + if (result != MMSYSERR_NOERROR) { + return SetMMerror("waveInPrepareHeader()", result); + } + + result = waveInAddBuffer(this->hidden->hin, + &this->hidden->wavebuf[i], + sizeof(this->hidden->wavebuf[i])); + if (result != MMSYSERR_NOERROR) { + return SetMMerror("waveInAddBuffer()", result); + } + } else { + result = waveOutPrepareHeader(this->hidden->hout, + &this->hidden->wavebuf[i], + sizeof(this->hidden->wavebuf[i])); + if (result != MMSYSERR_NOERROR) { + return SetMMerror("waveOutPrepareHeader()", result); + } + } + } + + if (iscapture) { + result = waveInStart(this->hidden->hin); if (result != MMSYSERR_NOERROR) { - WINMM_CloseDevice(this); - return SetMMerror("waveOutPrepareHeader()", result); + return SetMMerror("waveInStart()", result); } } @@ -349,10 +404,13 @@ WINMM_Init(SDL_AudioDriverImpl * impl) impl->OpenDevice = WINMM_OpenDevice; impl->PlayDevice = WINMM_PlayDevice; impl->WaitDevice = WINMM_WaitDevice; - impl->WaitDone = WINMM_WaitDone; impl->GetDeviceBuf = WINMM_GetDeviceBuf; + impl->CaptureFromDevice = WINMM_CaptureFromDevice; + impl->FlushCapture = WINMM_FlushCapture; impl->CloseDevice = WINMM_CloseDevice; + impl->HasCaptureSupport = SDL_TRUE; + return 1; /* this audio target is available. */ } diff --git a/Engine/lib/sdl/src/audio/xaudio2/SDL_xaudio2.c b/Engine/lib/sdl/src/audio/xaudio2/SDL_xaudio2.c index dff234b40..a18e5d24e 100644 --- a/Engine/lib/sdl/src/audio/xaudio2/SDL_xaudio2.c +++ b/Engine/lib/sdl/src/audio/xaudio2/SDL_xaudio2.c @@ -195,7 +195,7 @@ XAUDIO2_PlayDevice(_THIS) IXAudio2SourceVoice *source = this->hidden->source; HRESULT result = S_OK; - if (!this->enabled) { /* shutting down? */ + if (!SDL_AtomicGet(&this->enabled)) { /* shutting down? */ return; } @@ -226,64 +226,47 @@ XAUDIO2_PlayDevice(_THIS) static void XAUDIO2_WaitDevice(_THIS) { - if (this->enabled) { + if (SDL_AtomicGet(&this->enabled)) { SDL_SemWait(this->hidden->semaphore); } } static void -XAUDIO2_WaitDone(_THIS) +XAUDIO2_PrepareToClose(_THIS) { IXAudio2SourceVoice *source = this->hidden->source; - XAUDIO2_VOICE_STATE state; - SDL_assert(!this->enabled); /* flag that stops playing. */ - IXAudio2SourceVoice_Discontinuity(source); -#if SDL_XAUDIO2_WIN8 - IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED); -#else - IXAudio2SourceVoice_GetState(source, &state); -#endif - while (state.BuffersQueued > 0) { - SDL_SemWait(this->hidden->semaphore); -#if SDL_XAUDIO2_WIN8 - IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED); -#else - IXAudio2SourceVoice_GetState(source, &state); -#endif + if (source) { + IXAudio2SourceVoice_Discontinuity(source); } } - static void XAUDIO2_CloseDevice(_THIS) { - if (this->hidden != NULL) { - IXAudio2 *ixa2 = this->hidden->ixa2; - IXAudio2SourceVoice *source = this->hidden->source; - IXAudio2MasteringVoice *mastering = this->hidden->mastering; + IXAudio2 *ixa2 = this->hidden->ixa2; + IXAudio2SourceVoice *source = this->hidden->source; + IXAudio2MasteringVoice *mastering = this->hidden->mastering; - if (source != NULL) { - IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW); - IXAudio2SourceVoice_FlushSourceBuffers(source); - IXAudio2SourceVoice_DestroyVoice(source); - } - if (ixa2 != NULL) { - IXAudio2_StopEngine(ixa2); - } - if (mastering != NULL) { - IXAudio2MasteringVoice_DestroyVoice(mastering); - } - if (ixa2 != NULL) { - IXAudio2_Release(ixa2); - } - SDL_free(this->hidden->mixbuf); - if (this->hidden->semaphore != NULL) { - SDL_DestroySemaphore(this->hidden->semaphore); - } - - SDL_free(this->hidden); - this->hidden = NULL; + if (source != NULL) { + IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW); + IXAudio2SourceVoice_FlushSourceBuffers(source); + IXAudio2SourceVoice_DestroyVoice(source); } + if (ixa2 != NULL) { + IXAudio2_StopEngine(ixa2); + } + if (mastering != NULL) { + IXAudio2MasteringVoice_DestroyVoice(mastering); + } + if (ixa2 != NULL) { + IXAudio2_Release(ixa2); + } + if (this->hidden->semaphore != NULL) { + SDL_DestroySemaphore(this->hidden->semaphore); + } + + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); } static int @@ -345,12 +328,11 @@ XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) IXAudio2_Release(ixa2); return SDL_OutOfMemory(); } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + SDL_zerop(this->hidden); this->hidden->ixa2 = ixa2; this->hidden->semaphore = SDL_CreateSemaphore(1); if (this->hidden->semaphore == NULL) { - XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: CreateSemaphore() failed!"); } @@ -368,7 +350,6 @@ XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } if (!valid_format) { - XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Unsupported audio format"); } @@ -379,11 +360,10 @@ XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen); if (this->hidden->mixbuf == NULL) { - XAUDIO2_CloseDevice(this); return SDL_OutOfMemory(); } this->hidden->nextbuf = this->hidden->mixbuf; - SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen); + SDL_memset(this->hidden->mixbuf, this->spec.silence, 2 * this->hidden->mixlen); /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On Xbox360, this means 5.1 output, but on Windows, it means "figure out @@ -401,7 +381,6 @@ XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->spec.freq, 0, devId, NULL); #endif if (result != S_OK) { - XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't create mastering voice"); } @@ -436,7 +415,6 @@ XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) #endif if (result != S_OK) { - XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't create source voice"); } this->hidden->source = source; @@ -444,13 +422,11 @@ XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Start everything playing! */ result = IXAudio2_StartEngine(ixa2); if (result != S_OK) { - XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't start engine"); } result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW); if (result != S_OK) { - XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't start source voice"); } @@ -499,7 +475,7 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl) impl->OpenDevice = XAUDIO2_OpenDevice; impl->PlayDevice = XAUDIO2_PlayDevice; impl->WaitDevice = XAUDIO2_WaitDevice; - impl->WaitDone = XAUDIO2_WaitDone; + impl->PrepareToClose = XAUDIO2_PrepareToClose; impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf; impl->CloseDevice = XAUDIO2_CloseDevice; impl->Deinitialize = XAUDIO2_Deinitialize; diff --git a/Engine/lib/sdl/src/core/android/SDL_android.c b/Engine/lib/sdl/src/core/android/SDL_android.c index f6e0a833c..b93b16255 100644 --- a/Engine/lib/sdl/src/core/android/SDL_android.c +++ b/Engine/lib/sdl/src/core/android/SDL_android.c @@ -71,10 +71,14 @@ static jclass mActivityClass; /* method signatures */ static jmethodID midGetNativeSurface; -static jmethodID midAudioInit; +static jmethodID midAudioOpen; static jmethodID midAudioWriteShortBuffer; static jmethodID midAudioWriteByteBuffer; -static jmethodID midAudioQuit; +static jmethodID midAudioClose; +static jmethodID midCaptureOpen; +static jmethodID midCaptureReadShortBuffer; +static jmethodID midCaptureReadByteBuffer; +static jmethodID midCaptureClose; static jmethodID midPollInputDevices; /* Accelerometer data storage */ @@ -118,34 +122,45 @@ JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls) midGetNativeSurface = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getNativeSurface","()Landroid/view/Surface;"); - midAudioInit = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "audioInit", "(IZZI)I"); + midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "audioOpen", "(IZZI)I"); midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "audioWriteShortBuffer", "([S)V"); midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "audioWriteByteBuffer", "([B)V"); - midAudioQuit = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "audioQuit", "()V"); + midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "audioClose", "()V"); + midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "captureOpen", "(IZZI)I"); + midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "captureReadShortBuffer", "([SZ)I"); + midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "captureReadByteBuffer", "([BZ)I"); + midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "captureClose", "()V"); midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "pollInputDevices", "()V"); bHasNewData = SDL_FALSE; - if (!midGetNativeSurface || !midAudioInit || - !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit || !midPollInputDevices) { + if (!midGetNativeSurface || + !midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose || + !midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose || + !midPollInputDevices) { __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly"); } __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init() finished!"); } /* Drop file */ -void Java_org_libsdl_app_SDLActivity_onNativeDropFile( +JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeDropFile( JNIEnv* env, jclass jcls, jstring filename) { const char *path = (*env)->GetStringUTFChars(env, filename, NULL); - SDL_SendDropFile(path); + SDL_SendDropFile(NULL, path); (*env)->ReleaseStringUTFChars(env, filename, path); + SDL_SendDropComplete(NULL); } /* Resize */ @@ -555,11 +570,15 @@ int Android_JNI_SetupThread(void) static jboolean audioBuffer16Bit = JNI_FALSE; static jobject audioBuffer = NULL; static void* audioBufferPinned = NULL; +static jboolean captureBuffer16Bit = JNI_FALSE; +static jobject captureBuffer = NULL; -int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames) +int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames) { jboolean audioBufferStereo; int audioBufferFrames; + jobject jbufobj = NULL; + jboolean isCopy; JNIEnv *env = Android_JNI_GetEnv(); @@ -568,14 +587,24 @@ int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, i } Android_JNI_SetupThread(); - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device"); - audioBuffer16Bit = is16Bit; audioBufferStereo = channelCount > 1; - if ((*env)->CallStaticIntMethod(env, mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { - /* Error during audio initialization */ - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!"); - return 0; + if (iscapture) { + __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture"); + captureBuffer16Bit = is16Bit; + if ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { + /* Error during audio initialization */ + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!"); + return 0; + } + } else { + __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output"); + audioBuffer16Bit = is16Bit; + if ((*env)->CallStaticIntMethod(env, mActivityClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { + /* Error during audio initialization */ + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!"); + return 0; + } } /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on @@ -584,31 +613,43 @@ int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, i if (is16Bit) { jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); if (audioBufferLocal) { - audioBuffer = (*env)->NewGlobalRef(env, audioBufferLocal); + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); (*env)->DeleteLocalRef(env, audioBufferLocal); } } else { jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); if (audioBufferLocal) { - audioBuffer = (*env)->NewGlobalRef(env, audioBufferLocal); + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); (*env)->DeleteLocalRef(env, audioBufferLocal); } } - if (audioBuffer == NULL) { + if (jbufobj == NULL) { __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!"); return 0; } - jboolean isCopy = JNI_FALSE; - if (audioBuffer16Bit) { - audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); + if (iscapture) { + captureBuffer = jbufobj; + } else { + audioBuffer = jbufobj; + } + + isCopy = JNI_FALSE; + + if (is16Bit) { + if (!iscapture) { + audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); + } audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer); } else { - audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy); + if (!iscapture) { + audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy); + } audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer); } + if (audioBufferStereo) { audioBufferFrames /= 2; } @@ -636,16 +677,71 @@ void Android_JNI_WriteAudioBuffer(void) /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */ } -void Android_JNI_CloseAudioDevice(void) +int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen) +{ + JNIEnv *env = Android_JNI_GetEnv(); + jboolean isCopy = JNI_FALSE; + jint br; + + if (captureBuffer16Bit) { + SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2)); + br = (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE); + if (br > 0) { + jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy); + br *= 2; + SDL_memcpy(buffer, ptr, br); + (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT); + } + } else { + SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); + br = (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); + if (br > 0) { + jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy); + SDL_memcpy(buffer, ptr, br); + (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT); + } + } + + return (int) br; +} + +void Android_JNI_FlushCapturedAudio(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + #if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */ + if (captureBuffer16Bit) { + const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } else { + const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } + #else + if (captureBuffer16Bit) { + (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); + } else { + (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE); + } + #endif +} + +void Android_JNI_CloseAudioDevice(const int iscapture) { JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mActivityClass, midAudioQuit); - - if (audioBuffer) { - (*env)->DeleteGlobalRef(env, audioBuffer); - audioBuffer = NULL; - audioBufferPinned = NULL; + if (iscapture) { + (*env)->CallStaticVoidMethod(env, mActivityClass, midCaptureClose); + if (captureBuffer) { + (*env)->DeleteGlobalRef(env, captureBuffer); + captureBuffer = NULL; + } + } else { + (*env)->CallStaticVoidMethod(env, mActivityClass, midAudioClose); + if (audioBuffer) { + (*env)->DeleteGlobalRef(env, audioBuffer); + audioBuffer = NULL; + audioBufferPinned = NULL; + } } } @@ -653,10 +749,12 @@ void Android_JNI_CloseAudioDevice(void) /* If the parameter silent is truthy then SDL_SetError() will not be called. */ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) { - SDL_assert(LocalReferenceHolder_IsActive()); JNIEnv *mEnv = Android_JNI_GetEnv(); + jthrowable exception; - jthrowable exception = (*mEnv)->ExceptionOccurred(mEnv); + SDL_assert(LocalReferenceHolder_IsActive()); + + exception = (*mEnv)->ExceptionOccurred(mEnv); if (exception != NULL) { jmethodID mid; @@ -666,13 +764,16 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) if (!silent) { jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception); jclass classClass = (*mEnv)->FindClass(mEnv, "java/lang/Class"); + jstring exceptionName; + const char* exceptionNameUTF8; + jstring exceptionMessage; mid = (*mEnv)->GetMethodID(mEnv, classClass, "getName", "()Ljava/lang/String;"); - jstring exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid); - const char* exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0); + exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid); + exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0); mid = (*mEnv)->GetMethodID(mEnv, exceptionClass, "getMessage", "()Ljava/lang/String;"); - jstring exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid); + exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid); if (exceptionMessage != NULL) { const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0); @@ -855,6 +956,7 @@ int Android_JNI_FileOpen(SDL_RWops* ctx, struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); JNIEnv *mEnv = Android_JNI_GetEnv(); int retval; + jstring fileNameJString; if (!LocalReferenceHolder_Init(&refs, mEnv)) { LocalReferenceHolder_Cleanup(&refs); @@ -866,7 +968,7 @@ int Android_JNI_FileOpen(SDL_RWops* ctx, return -1; } - jstring fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName); + fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName); ctx->hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString); ctx->hidden.androidio.inputStreamRef = NULL; ctx->hidden.androidio.readableByteChannelRef = NULL; @@ -885,10 +987,11 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, if (ctx->hidden.androidio.assetFileDescriptorRef) { size_t bytesMax = size * maxnum; + size_t result; if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) { bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position; } - size_t result = read(ctx->hidden.androidio.fd, buffer, bytesMax ); + result = read(ctx->hidden.androidio.fd, buffer, bytesMax ); if (result > 0) { ctx->hidden.androidio.position += result; LocalReferenceHolder_Cleanup(&refs); @@ -900,19 +1003,23 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, jlong bytesRemaining = (jlong) (size * maxnum); jlong bytesMax = (jlong) (ctx->hidden.androidio.size - ctx->hidden.androidio.position); int bytesRead = 0; + JNIEnv *mEnv; + jobject readableByteChannel; + jmethodID readMethod; + jobject byteBuffer; /* Don't read more bytes than those that remain in the file, otherwise we get an exception */ if (bytesRemaining > bytesMax) bytesRemaining = bytesMax; - JNIEnv *mEnv = Android_JNI_GetEnv(); + mEnv = Android_JNI_GetEnv(); if (!LocalReferenceHolder_Init(&refs, mEnv)) { LocalReferenceHolder_Cleanup(&refs); return 0; } - jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef; - jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod; - jobject byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining); + readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef; + readMethod = (jmethodID)ctx->hidden.androidio.readMethod; + byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining); while (bytesRemaining > 0) { /* result = readableByteChannel.read(...); */ @@ -1002,6 +1109,7 @@ Sint64 Android_JNI_FileSize(SDL_RWops* ctx) Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence) { if (ctx->hidden.androidio.assetFileDescriptorRef) { + off_t ret; switch (whence) { case RW_SEEK_SET: if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size; @@ -1020,11 +1128,12 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence) } whence = SEEK_SET; - off_t ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET); + ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET); if (ret == -1) return -1; ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset; } else { Sint64 newPosition; + Sint64 movement; switch (whence) { case RW_SEEK_SET: @@ -1048,17 +1157,18 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence) newPosition = ctx->hidden.androidio.size; } - Sint64 movement = newPosition - ctx->hidden.androidio.position; + movement = newPosition - ctx->hidden.androidio.position; if (movement > 0) { unsigned char buffer[4096]; /* The easy case where we're seeking forwards */ while (movement > 0) { Sint64 amount = sizeof (buffer); + size_t result; if (amount > movement) { amount = movement; } - size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount); + result = Android_JNI_FileRead(ctx, buffer, 1, amount); if (result <= 0) { /* Failed to read/skip the required amount, so fail */ return -1; @@ -1091,21 +1201,23 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name) struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); JNIEnv* env = Android_JNI_GetEnv(); jobject retval = NULL; + jstring service; + jmethodID mid; + jobject context; + jobject manager; if (!LocalReferenceHolder_Init(&refs, env)) { LocalReferenceHolder_Cleanup(&refs); return NULL; } - jstring service = (*env)->NewStringUTF(env, name); - - jmethodID mid; + service = (*env)->NewStringUTF(env, name); mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); - jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); + context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); mid = (*env)->GetMethodID(env, mActivityClass, "getSystemServiceFromUiThread", "(Ljava/lang/String;)Ljava/lang/Object;"); - jobject manager = (*env)->CallObjectMethod(env, context, mid, service); + manager = (*env)->CallObjectMethod(env, context, mid, service); (*env)->DeleteLocalRef(env, service); @@ -1117,11 +1229,12 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name) #define SETUP_CLIPBOARD(error) \ struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); \ JNIEnv* env = Android_JNI_GetEnv(); \ + jobject clipboard; \ if (!LocalReferenceHolder_Init(&refs, env)) { \ LocalReferenceHolder_Cleanup(&refs); \ return error; \ } \ - jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \ + clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \ if (!clipboard) { \ LocalReferenceHolder_Cleanup(&refs); \ return error; \ @@ -1132,14 +1245,17 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name) int Android_JNI_SetClipboardText(const char* text) { + /* Watch out for C89 scoping rules because of the macro */ SETUP_CLIPBOARD(-1) - jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V"); - jstring string = (*env)->NewStringUTF(env, text); - (*env)->CallVoidMethod(env, clipboard, mid, string); - (*env)->DeleteGlobalRef(env, clipboard); - (*env)->DeleteLocalRef(env, string); - + /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */ + { + jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V"); + jstring string = (*env)->NewStringUTF(env, text); + (*env)->CallVoidMethod(env, clipboard, mid, string); + (*env)->DeleteGlobalRef(env, clipboard); + (*env)->DeleteLocalRef(env, string); + } CLEANUP_CLIPBOARD(); return 0; @@ -1147,25 +1263,30 @@ int Android_JNI_SetClipboardText(const char* text) char* Android_JNI_GetClipboardText(void) { + /* Watch out for C89 scoping rules because of the macro */ SETUP_CLIPBOARD(SDL_strdup("")) - jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;"); - jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid); - (*env)->DeleteGlobalRef(env, clipboard); - if (sequence) { - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;"); - jstring string = (jstring)((*env)->CallObjectMethod(env, sequence, mid)); - const char* utf = (*env)->GetStringUTFChars(env, string, 0); - if (utf) { - char* text = SDL_strdup(utf); - (*env)->ReleaseStringUTFChars(env, string, utf); + /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */ + { + jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;"); + jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid); + (*env)->DeleteGlobalRef(env, clipboard); + if (sequence) { + jstring string; + const char* utf; + mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;"); + string = (jstring)((*env)->CallObjectMethod(env, sequence, mid)); + utf = (*env)->GetStringUTFChars(env, string, 0); + if (utf) { + char* text = SDL_strdup(utf); + (*env)->ReleaseStringUTFChars(env, string, utf); - CLEANUP_CLIPBOARD(); + CLEANUP_CLIPBOARD(); - return text; + return text; + } } } - CLEANUP_CLIPBOARD(); return SDL_strdup(""); @@ -1173,10 +1294,13 @@ char* Android_JNI_GetClipboardText(void) SDL_bool Android_JNI_HasClipboardText(void) { + jmethodID mid; + jboolean has; + /* Watch out for C89 scoping rules because of the macro */ SETUP_CLIPBOARD(SDL_FALSE) - jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z"); - jboolean has = (*env)->CallBooleanMethod(env, clipboard, mid); + mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z"); + has = (*env)->CallBooleanMethod(env, clipboard, mid); (*env)->DeleteGlobalRef(env, clipboard); CLEANUP_CLIPBOARD(); @@ -1193,49 +1317,61 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco { struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); JNIEnv* env = Android_JNI_GetEnv(); + jmethodID mid; + jobject context; + jstring action; + jclass cls; + jobject filter; + jobject intent; + jstring iname; + jmethodID imid; + jstring bname; + jmethodID bmid; if (!LocalReferenceHolder_Init(&refs, env)) { LocalReferenceHolder_Cleanup(&refs); return -1; } - jmethodID mid; mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); - jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); + context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); - jstring action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); + action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); - jclass cls = (*env)->FindClass(env, "android/content/IntentFilter"); + cls = (*env)->FindClass(env, "android/content/IntentFilter"); mid = (*env)->GetMethodID(env, cls, "", "(Ljava/lang/String;)V"); - jobject filter = (*env)->NewObject(env, cls, mid, action); + filter = (*env)->NewObject(env, cls, mid, action); (*env)->DeleteLocalRef(env, action); mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); - jobject intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); + intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); (*env)->DeleteLocalRef(env, filter); cls = (*env)->GetObjectClass(env, intent); - jstring iname; - jmethodID imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); + imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); + /* Watch out for C89 scoping rules because of the macro */ #define GET_INT_EXTRA(var, key) \ + int var; \ iname = (*env)->NewStringUTF(env, key); \ - int var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ + var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ (*env)->DeleteLocalRef(env, iname); - jstring bname; - jmethodID bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); + bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); + /* Watch out for C89 scoping rules because of the macro */ #define GET_BOOL_EXTRA(var, key) \ + int var; \ bname = (*env)->NewStringUTF(env, key); \ - int var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ + var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ (*env)->DeleteLocalRef(env, bname); if (plugged) { + /* Watch out for C89 scoping rules because of the macro */ GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */ if (plug == -1) { LocalReferenceHolder_Cleanup(&refs); @@ -1247,6 +1383,7 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco } if (charged) { + /* Watch out for C89 scoping rules because of the macro */ GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */ if (status == -1) { LocalReferenceHolder_Cleanup(&refs); @@ -1266,8 +1403,20 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco } if (percent) { - GET_INT_EXTRA(level, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */ - GET_INT_EXTRA(scale, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */ + int level; + int scale; + + /* Watch out for C89 scoping rules because of the macro */ + { + GET_INT_EXTRA(level_temp, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */ + level = level_temp; + } + /* Watch out for C89 scoping rules because of the macro */ + { + GET_INT_EXTRA(scale_temp, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */ + scale = scale_temp; + } + if ((level == -1) || (scale == -1)) { LocalReferenceHolder_Cleanup(&refs); return -1; @@ -1320,14 +1469,16 @@ void Android_JNI_PollInputDevices(void) int Android_JNI_SendMessage(int command, int param) { JNIEnv *env = Android_JNI_GetEnv(); + jmethodID mid; + jboolean success; if (!env) { return -1; } - jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z"); + mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z"); if (!mid) { return -1; } - jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param); + success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param); return success ? 0 : -1; } @@ -1339,11 +1490,12 @@ void Android_JNI_SuspendScreenSaver(SDL_bool suspend) void Android_JNI_ShowTextInput(SDL_Rect *inputRect) { JNIEnv *env = Android_JNI_GetEnv(); + jmethodID mid; if (!env) { return; } - jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z"); + mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z"); if (!mid) { return; } diff --git a/Engine/lib/sdl/src/core/android/SDL_android.h b/Engine/lib/sdl/src/core/android/SDL_android.h index 8e2ab93c3..cb7ff0736 100644 --- a/Engine/lib/sdl/src/core/android/SDL_android.h +++ b/Engine/lib/sdl/src/core/android/SDL_android.h @@ -40,10 +40,12 @@ extern void Android_JNI_HideTextInput(void); extern ANativeWindow* Android_JNI_GetNativeWindow(void); /* Audio support */ -extern int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames); +extern int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames); extern void* Android_JNI_GetAudioBuffer(void); extern void Android_JNI_WriteAudioBuffer(void); -extern void Android_JNI_CloseAudioDevice(void); +extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen); +extern void Android_JNI_FlushCapturedAudio(void); +extern void Android_JNI_CloseAudioDevice(const int iscapture); #include "SDL_rwops.h" diff --git a/Engine/lib/sdl/src/core/linux/SDL_dbus.c b/Engine/lib/sdl/src/core/linux/SDL_dbus.c index 5d0df050c..ab73ca17c 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_dbus.c +++ b/Engine/lib/sdl/src/core/linux/SDL_dbus.c @@ -27,7 +27,7 @@ static const char *dbus_library = "libdbus-1.so.3"; static void *dbus_handle = NULL; static unsigned int screensaver_cookie = 0; -static SDL_DBusContext dbus = {0}; +static SDL_DBusContext dbus; static int LoadDBUSSyms(void) diff --git a/Engine/lib/sdl/src/core/linux/SDL_evdev.c b/Engine/lib/sdl/src/core/linux/SDL_evdev.c index a8f2b138e..4761f3e46 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_evdev.c +++ b/Engine/lib/sdl/src/core/linux/SDL_evdev.c @@ -29,10 +29,7 @@ * The evtest application is also useful to debug the protocol */ - #include "SDL_evdev.h" -#define _THIS SDL_EVDEV_PrivateData *_this -static _THIS = NULL; #include #include @@ -43,18 +40,8 @@ static _THIS = NULL; #ifdef SDL_INPUT_LINUXKD #include #include -#endif - - -/* We need this to prevent keystrokes from appear in the console */ -#ifndef KDSKBMUTE -#define KDSKBMUTE 0x4B51 -#endif -#ifndef KDSKBMODE -#define KDSKBMODE 0x4B45 -#endif -#ifndef K_OFF -#define K_OFF 0x04 +#include +#include /* for TIOCL_GETSHIFTSTATE */ #endif #include "SDL.h" @@ -63,273 +50,71 @@ static _THIS = NULL; #include "../../core/linux/SDL_udev.h" #include "SDL_scancode.h" #include "../../events/SDL_events_c.h" +#include "../../events/scancodes_linux.h" /* adds linux_scancode_table */ /* This isn't defined in older Linux kernel headers */ #ifndef SYN_DROPPED #define SYN_DROPPED 3 #endif +typedef struct SDL_evdevlist_item +{ + char *path; + int fd; + + /* TODO: use this for every device, not just touchscreen */ + int out_of_sync; + + /* TODO: expand on this to have data for every possible class (mouse, + keyboard, touchpad, etc.). Also there's probably some things in here we + can pull out to the SDL_evdevlist_item i.e. name */ + int is_touchscreen; + struct { + char* name; + + int min_x, max_x, range_x; + int min_y, max_y, range_y; + + int max_slots; + int current_slot; + struct { + enum { + EVDEV_TOUCH_SLOTDELTA_NONE = 0, + EVDEV_TOUCH_SLOTDELTA_DOWN, + EVDEV_TOUCH_SLOTDELTA_UP, + EVDEV_TOUCH_SLOTDELTA_MOVE + } delta; + int tracking_id; + int x, y; + } * slots; + } * touchscreen_data; + + struct SDL_evdevlist_item *next; +} SDL_evdevlist_item; + +typedef struct SDL_EVDEV_PrivateData +{ + SDL_evdevlist_item *first; + SDL_evdevlist_item *last; + int num_devices; + int ref_count; + int console_fd; + int kb_mode; +} SDL_EVDEV_PrivateData; + +#define _THIS SDL_EVDEV_PrivateData *_this +static _THIS = NULL; + static SDL_Scancode SDL_EVDEV_translate_keycode(int keycode); static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item); -static int SDL_EVDEV_device_removed(const char *devpath); +static int SDL_EVDEV_device_removed(const char *dev_path); #if SDL_USE_LIBUDEV -static int SDL_EVDEV_device_added(const char *devpath); -void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath); +static int SDL_EVDEV_device_added(const char *dev_path, int udev_class); +void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, + const char *dev_path); #endif /* SDL_USE_LIBUDEV */ -static SDL_Scancode EVDEV_Keycodes[] = { - SDL_SCANCODE_UNKNOWN, /* KEY_RESERVED 0 */ - SDL_SCANCODE_ESCAPE, /* KEY_ESC 1 */ - SDL_SCANCODE_1, /* KEY_1 2 */ - SDL_SCANCODE_2, /* KEY_2 3 */ - SDL_SCANCODE_3, /* KEY_3 4 */ - SDL_SCANCODE_4, /* KEY_4 5 */ - SDL_SCANCODE_5, /* KEY_5 6 */ - SDL_SCANCODE_6, /* KEY_6 7 */ - SDL_SCANCODE_7, /* KEY_7 8 */ - SDL_SCANCODE_8, /* KEY_8 9 */ - SDL_SCANCODE_9, /* KEY_9 10 */ - SDL_SCANCODE_0, /* KEY_0 11 */ - SDL_SCANCODE_MINUS, /* KEY_MINUS 12 */ - SDL_SCANCODE_EQUALS, /* KEY_EQUAL 13 */ - SDL_SCANCODE_BACKSPACE, /* KEY_BACKSPACE 14 */ - SDL_SCANCODE_TAB, /* KEY_TAB 15 */ - SDL_SCANCODE_Q, /* KEY_Q 16 */ - SDL_SCANCODE_W, /* KEY_W 17 */ - SDL_SCANCODE_E, /* KEY_E 18 */ - SDL_SCANCODE_R, /* KEY_R 19 */ - SDL_SCANCODE_T, /* KEY_T 20 */ - SDL_SCANCODE_Y, /* KEY_Y 21 */ - SDL_SCANCODE_U, /* KEY_U 22 */ - SDL_SCANCODE_I, /* KEY_I 23 */ - SDL_SCANCODE_O, /* KEY_O 24 */ - SDL_SCANCODE_P, /* KEY_P 25 */ - SDL_SCANCODE_LEFTBRACKET, /* KEY_LEFTBRACE 26 */ - SDL_SCANCODE_RIGHTBRACKET, /* KEY_RIGHTBRACE 27 */ - SDL_SCANCODE_RETURN, /* KEY_ENTER 28 */ - SDL_SCANCODE_LCTRL, /* KEY_LEFTCTRL 29 */ - SDL_SCANCODE_A, /* KEY_A 30 */ - SDL_SCANCODE_S, /* KEY_S 31 */ - SDL_SCANCODE_D, /* KEY_D 32 */ - SDL_SCANCODE_F, /* KEY_F 33 */ - SDL_SCANCODE_G, /* KEY_G 34 */ - SDL_SCANCODE_H, /* KEY_H 35 */ - SDL_SCANCODE_J, /* KEY_J 36 */ - SDL_SCANCODE_K, /* KEY_K 37 */ - SDL_SCANCODE_L, /* KEY_L 38 */ - SDL_SCANCODE_SEMICOLON, /* KEY_SEMICOLON 39 */ - SDL_SCANCODE_APOSTROPHE, /* KEY_APOSTROPHE 40 */ - SDL_SCANCODE_GRAVE, /* KEY_GRAVE 41 */ - SDL_SCANCODE_LSHIFT, /* KEY_LEFTSHIFT 42 */ - SDL_SCANCODE_BACKSLASH, /* KEY_BACKSLASH 43 */ - SDL_SCANCODE_Z, /* KEY_Z 44 */ - SDL_SCANCODE_X, /* KEY_X 45 */ - SDL_SCANCODE_C, /* KEY_C 46 */ - SDL_SCANCODE_V, /* KEY_V 47 */ - SDL_SCANCODE_B, /* KEY_B 48 */ - SDL_SCANCODE_N, /* KEY_N 49 */ - SDL_SCANCODE_M, /* KEY_M 50 */ - SDL_SCANCODE_COMMA, /* KEY_COMMA 51 */ - SDL_SCANCODE_PERIOD, /* KEY_DOT 52 */ - SDL_SCANCODE_SLASH, /* KEY_SLASH 53 */ - SDL_SCANCODE_RSHIFT, /* KEY_RIGHTSHIFT 54 */ - SDL_SCANCODE_KP_MULTIPLY, /* KEY_KPASTERISK 55 */ - SDL_SCANCODE_LALT, /* KEY_LEFTALT 56 */ - SDL_SCANCODE_SPACE, /* KEY_SPACE 57 */ - SDL_SCANCODE_CAPSLOCK, /* KEY_CAPSLOCK 58 */ - SDL_SCANCODE_F1, /* KEY_F1 59 */ - SDL_SCANCODE_F2, /* KEY_F2 60 */ - SDL_SCANCODE_F3, /* KEY_F3 61 */ - SDL_SCANCODE_F4, /* KEY_F4 62 */ - SDL_SCANCODE_F5, /* KEY_F5 63 */ - SDL_SCANCODE_F6, /* KEY_F6 64 */ - SDL_SCANCODE_F7, /* KEY_F7 65 */ - SDL_SCANCODE_F8, /* KEY_F8 66 */ - SDL_SCANCODE_F9, /* KEY_F9 67 */ - SDL_SCANCODE_F10, /* KEY_F10 68 */ - SDL_SCANCODE_NUMLOCKCLEAR, /* KEY_NUMLOCK 69 */ - SDL_SCANCODE_SCROLLLOCK, /* KEY_SCROLLLOCK 70 */ - SDL_SCANCODE_KP_7, /* KEY_KP7 71 */ - SDL_SCANCODE_KP_8, /* KEY_KP8 72 */ - SDL_SCANCODE_KP_9, /* KEY_KP9 73 */ - SDL_SCANCODE_KP_MINUS, /* KEY_KPMINUS 74 */ - SDL_SCANCODE_KP_4, /* KEY_KP4 75 */ - SDL_SCANCODE_KP_5, /* KEY_KP5 76 */ - SDL_SCANCODE_KP_6, /* KEY_KP6 77 */ - SDL_SCANCODE_KP_PLUS, /* KEY_KPPLUS 78 */ - SDL_SCANCODE_KP_1, /* KEY_KP1 79 */ - SDL_SCANCODE_KP_2, /* KEY_KP2 80 */ - SDL_SCANCODE_KP_3, /* KEY_KP3 81 */ - SDL_SCANCODE_KP_0, /* KEY_KP0 82 */ - SDL_SCANCODE_KP_PERIOD, /* KEY_KPDOT 83 */ - SDL_SCANCODE_UNKNOWN, /* 84 */ - SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU 85 */ - SDL_SCANCODE_UNKNOWN, /* KEY_102ND 86 */ - SDL_SCANCODE_F11, /* KEY_F11 87 */ - SDL_SCANCODE_F12, /* KEY_F12 88 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RO 89 */ - SDL_SCANCODE_LANG3, /* KEY_KATAKANA 90 */ - SDL_SCANCODE_LANG4, /* KEY_HIRAGANA 91 */ - SDL_SCANCODE_UNKNOWN, /* KEY_HENKAN 92 */ - SDL_SCANCODE_LANG3, /* KEY_KATAKANAHIRAGANA 93 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MUHENKAN 94 */ - SDL_SCANCODE_KP_COMMA, /* KEY_KPJPCOMMA 95 */ - SDL_SCANCODE_KP_ENTER, /* KEY_KPENTER 96 */ - SDL_SCANCODE_RCTRL, /* KEY_RIGHTCTRL 97 */ - SDL_SCANCODE_KP_DIVIDE, /* KEY_KPSLASH 98 */ - SDL_SCANCODE_SYSREQ, /* KEY_SYSRQ 99 */ - SDL_SCANCODE_RALT, /* KEY_RIGHTALT 100 */ - SDL_SCANCODE_UNKNOWN, /* KEY_LINEFEED 101 */ - SDL_SCANCODE_HOME, /* KEY_HOME 102 */ - SDL_SCANCODE_UP, /* KEY_UP 103 */ - SDL_SCANCODE_PAGEUP, /* KEY_PAGEUP 104 */ - SDL_SCANCODE_LEFT, /* KEY_LEFT 105 */ - SDL_SCANCODE_RIGHT, /* KEY_RIGHT 106 */ - SDL_SCANCODE_END, /* KEY_END 107 */ - SDL_SCANCODE_DOWN, /* KEY_DOWN 108 */ - SDL_SCANCODE_PAGEDOWN, /* KEY_PAGEDOWN 109 */ - SDL_SCANCODE_INSERT, /* KEY_INSERT 110 */ - SDL_SCANCODE_DELETE, /* KEY_DELETE 111 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MACRO 112 */ - SDL_SCANCODE_MUTE, /* KEY_MUTE 113 */ - SDL_SCANCODE_VOLUMEDOWN, /* KEY_VOLUMEDOWN 114 */ - SDL_SCANCODE_VOLUMEUP, /* KEY_VOLUMEUP 115 */ - SDL_SCANCODE_POWER, /* KEY_POWER 116 SC System Power Down */ - SDL_SCANCODE_KP_EQUALS, /* KEY_KPEQUAL 117 */ - SDL_SCANCODE_KP_MINUS, /* KEY_KPPLUSMINUS 118 */ - SDL_SCANCODE_PAUSE, /* KEY_PAUSE 119 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCALE 120 AL Compiz Scale (Expose) */ - SDL_SCANCODE_KP_COMMA, /* KEY_KPCOMMA 121 */ - SDL_SCANCODE_LANG1, /* KEY_HANGEUL,KEY_HANGUEL 122 */ - SDL_SCANCODE_LANG2, /* KEY_HANJA 123 */ - SDL_SCANCODE_INTERNATIONAL3,/* KEY_YEN 124 */ - SDL_SCANCODE_LGUI, /* KEY_LEFTMETA 125 */ - SDL_SCANCODE_RGUI, /* KEY_RIGHTMETA 126 */ - SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE 127 */ - SDL_SCANCODE_STOP, /* KEY_STOP 128 AC Stop */ - SDL_SCANCODE_AGAIN, /* KEY_AGAIN 129 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PROPS 130 AC Properties */ - SDL_SCANCODE_UNDO, /* KEY_UNDO 131 AC Undo */ - SDL_SCANCODE_UNKNOWN, /* KEY_FRONT 132 */ - SDL_SCANCODE_COPY, /* KEY_COPY 133 AC Copy */ - SDL_SCANCODE_UNKNOWN, /* KEY_OPEN 134 AC Open */ - SDL_SCANCODE_PASTE, /* KEY_PASTE 135 AC Paste */ - SDL_SCANCODE_FIND, /* KEY_FIND 136 AC Search */ - SDL_SCANCODE_CUT, /* KEY_CUT 137 AC Cut */ - SDL_SCANCODE_HELP, /* KEY_HELP 138 AL Integrated Help Center */ - SDL_SCANCODE_MENU, /* KEY_MENU 139 Menu (show menu) */ - SDL_SCANCODE_CALCULATOR, /* KEY_CALC 140 AL Calculator */ - SDL_SCANCODE_UNKNOWN, /* KEY_SETUP 141 */ - SDL_SCANCODE_SLEEP, /* KEY_SLEEP 142 SC System Sleep */ - SDL_SCANCODE_UNKNOWN, /* KEY_WAKEUP 143 System Wake Up */ - SDL_SCANCODE_UNKNOWN, /* KEY_FILE 144 AL Local Machine Browser */ - SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE 145 */ - SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE 146 */ - SDL_SCANCODE_UNKNOWN, /* KEY_XFER 147 */ - SDL_SCANCODE_APP1, /* KEY_PROG1 148 */ - SDL_SCANCODE_APP1, /* KEY_PROG2 149 */ - SDL_SCANCODE_WWW, /* KEY_WWW 150 AL Internet Browser */ - SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS 151 */ - SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE,KEY_SCREENLOCK 152 AL Terminal Lock/Screensaver */ - SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION 153 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CYCLEWINDOWS 154 */ - SDL_SCANCODE_MAIL, /* KEY_MAIL 155 */ - SDL_SCANCODE_AC_BOOKMARKS, /* KEY_BOOKMARKS 156 AC Bookmarks */ - SDL_SCANCODE_COMPUTER, /* KEY_COMPUTER 157 */ - SDL_SCANCODE_AC_BACK, /* KEY_BACK 158 AC Back */ - SDL_SCANCODE_AC_FORWARD, /* KEY_FORWARD 159 AC Forward */ - SDL_SCANCODE_UNKNOWN, /* KEY_CLOSECD 160 */ - SDL_SCANCODE_EJECT, /* KEY_EJECTCD 161 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EJECTCLOSECD 162 */ - SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG 163 */ - SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE 164 */ - SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG 165 */ - SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD 166 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RECORD 167 */ - SDL_SCANCODE_UNKNOWN, /* KEY_REWIND 168 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PHONE 169 Media Select Telephone */ - SDL_SCANCODE_UNKNOWN, /* KEY_ISO 170 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CONFIG 171 AL Consumer Control Configuration */ - SDL_SCANCODE_AC_HOME, /* KEY_HOMEPAGE 172 AC Home */ - SDL_SCANCODE_AC_REFRESH, /* KEY_REFRESH 173 AC Refresh */ - SDL_SCANCODE_UNKNOWN, /* KEY_EXIT 174 AC Exit */ - SDL_SCANCODE_UNKNOWN, /* KEY_MOVE 175 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EDIT 176 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLUP 177 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLDOWN 178 */ - SDL_SCANCODE_KP_LEFTPAREN, /* KEY_KPLEFTPAREN 179 */ - SDL_SCANCODE_KP_RIGHTPAREN, /* KEY_KPRIGHTPAREN 180 */ - SDL_SCANCODE_UNKNOWN, /* KEY_NEW 181 AC New */ - SDL_SCANCODE_AGAIN, /* KEY_REDO 182 AC Redo/Repeat */ - SDL_SCANCODE_F13, /* KEY_F13 183 */ - SDL_SCANCODE_F14, /* KEY_F14 184 */ - SDL_SCANCODE_F15, /* KEY_F15 185 */ - SDL_SCANCODE_F16, /* KEY_F16 186 */ - SDL_SCANCODE_F17, /* KEY_F17 187 */ - SDL_SCANCODE_F18, /* KEY_F18 188 */ - SDL_SCANCODE_F19, /* KEY_F19 189 */ - SDL_SCANCODE_F20, /* KEY_F20 190 */ - SDL_SCANCODE_F21, /* KEY_F21 191 */ - SDL_SCANCODE_F22, /* KEY_F22 192 */ - SDL_SCANCODE_F23, /* KEY_F23 193 */ - SDL_SCANCODE_F24, /* KEY_F24 194 */ - SDL_SCANCODE_UNKNOWN, /* 195 */ - SDL_SCANCODE_UNKNOWN, /* 196 */ - SDL_SCANCODE_UNKNOWN, /* 197 */ - SDL_SCANCODE_UNKNOWN, /* 198 */ - SDL_SCANCODE_UNKNOWN, /* 199 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PLAYCD 200 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PAUSECD 201 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PROG3 202 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PROG4 203 */ - SDL_SCANCODE_UNKNOWN, /* KEY_DASHBOARD 204 AL Dashboard */ - SDL_SCANCODE_UNKNOWN, /* KEY_SUSPEND 205 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CLOSE 206 AC Close */ - SDL_SCANCODE_UNKNOWN, /* KEY_PLAY 207 */ - SDL_SCANCODE_UNKNOWN, /* KEY_FASTFORWARD 208 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BASSBOOST 209 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PRINT 210 AC Print */ - SDL_SCANCODE_UNKNOWN, /* KEY_HP 211 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA 212 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SOUND 213 */ - SDL_SCANCODE_UNKNOWN, /* KEY_QUESTION 214 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EMAIL 215 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CHAT 216 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SEARCH 217 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CONNECT 218 */ - SDL_SCANCODE_UNKNOWN, /* KEY_FINANCE 219 AL Checkbook/Finance */ - SDL_SCANCODE_UNKNOWN, /* KEY_SPORT 220 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SHOP 221 */ - SDL_SCANCODE_UNKNOWN, /* KEY_ALTERASE 222 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CANCEL 223 AC Cancel */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSDOWN 224 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSUP 225 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MEDIA 226 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SWITCHVIDEOMODE 227 Cycle between available video outputs (Monitor/LCD/TV-out/etc) */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMTOGGLE 228 */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMDOWN 229 */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMUP 230 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SEND 231 AC Send */ - SDL_SCANCODE_UNKNOWN, /* KEY_REPLY 232 AC Reply */ - SDL_SCANCODE_UNKNOWN, /* KEY_FORWARDMAIL 233 AC Forward Msg */ - SDL_SCANCODE_UNKNOWN, /* KEY_SAVE 234 AC Save */ - SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS 235 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY 236 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BLUETOOTH 237 */ - SDL_SCANCODE_UNKNOWN, /* KEY_WLAN 238 */ - SDL_SCANCODE_UNKNOWN, /* KEY_UWB 239 */ - SDL_SCANCODE_UNKNOWN, /* KEY_UNKNOWN 240 */ - SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_NEXT 241 drive next video source */ - SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_PREV 242 drive previous video source */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_CYCLE 243 brightness up, after max is min */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_ZERO 244 brightness off, use ambient */ - SDL_SCANCODE_UNKNOWN, /* KEY_DISPLAY_OFF 245 display device to off state */ - SDL_SCANCODE_UNKNOWN, /* KEY_WIMAX 246 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RFKILL 247 Key that controls all radios */ - SDL_SCANCODE_UNKNOWN, /* KEY_MICMUTE 248 Mute / unmute the microphone */ -}; - static Uint8 EVDEV_MouseButtons[] = { SDL_BUTTON_LEFT, /* BTN_LEFT 0x110 */ SDL_BUTTON_RIGHT, /* BTN_RIGHT 0x111 */ @@ -342,121 +127,98 @@ static Uint8 EVDEV_MouseButtons[] = { }; static const char* EVDEV_consoles[] = { - "/proc/self/fd/0", + /* "/proc/self/fd/0", "/dev/tty", - "/dev/tty0", + "/dev/tty0", */ /* the tty ioctl's prohibit these */ "/dev/tty1", "/dev/tty2", "/dev/tty3", "/dev/tty4", "/dev/tty5", "/dev/tty6", + "/dev/tty7", /* usually X is spawned in tty7 */ "/dev/vc/0", "/dev/console" }; -#define IS_CONSOLE(fd) isatty (fd) && ioctl(fd, KDGKBTYPE, &arg) == 0 && ((arg == KB_101) || (arg == KB_84)) - -static int SDL_EVDEV_get_console_fd(void) -{ - int fd, i; - char arg = 0; +static int SDL_EVDEV_is_console(int fd) { + int type; - /* Try a few consoles to see which one we have read access to */ - - for(i = 0; i < SDL_arraysize(EVDEV_consoles); i++) { - fd = open(EVDEV_consoles[i], O_RDONLY); - if (fd >= 0) { - if (IS_CONSOLE(fd)) return fd; - close(fd); - } - } - - /* Try stdin, stdout, stderr */ - - for(fd = 0; fd < 3; fd++) { - if (IS_CONSOLE(fd)) return fd; - } - - /* We won't be able to send SDL_TEXTINPUT events */ - return -1; + return isatty(fd) && ioctl(fd, KDGKBTYPE, &type) == 0 && + (type == KB_101 || type == KB_84); } /* Prevent keystrokes from reaching the tty */ -static int SDL_EVDEV_mute_keyboard(int tty, int *kb_mode) +static int SDL_EVDEV_mute_keyboard(int tty_fd, int* old_kb_mode) { - char arg; - - *kb_mode = 0; /* FIXME: Is this a sane default in case KDGKBMODE fails? */ - if (!IS_CONSOLE(tty)) { + if (!SDL_EVDEV_is_console(tty_fd)) { return SDL_SetError("Tried to mute an invalid tty"); } - ioctl(tty, KDGKBMODE, kb_mode); /* It's not fatal if this fails */ - if (ioctl(tty, KDSKBMUTE, 1) && ioctl(tty, KDSKBMODE, K_OFF)) { - return SDL_SetError("EVDEV: Failed muting keyboard"); + + if (ioctl(tty_fd, KDGKBMODE, old_kb_mode) < 0) { + return SDL_SetError("Failed to get keyboard mode during muting"); } + /* FIXME: atm this absolutely ruins the vt, and KDSKBMUTE isn't implemented + in the kernel */ + /* + if (ioctl(tty_fd, KDSKBMODE, K_OFF) < 0) { + return SDL_SetError("Failed to set keyboard mode during muting"); + } + */ + return 0; } /* Restore the keyboard mode for given tty */ -static void SDL_EVDEV_unmute_keyboard(int tty, int kb_mode) +static void SDL_EVDEV_unmute_keyboard(int tty_fd, int kb_mode) { - if (ioctl(tty, KDSKBMUTE, 0) && ioctl(tty, KDSKBMODE, kb_mode)) { - SDL_Log("EVDEV: Failed restoring keyboard mode"); + /* read above */ + /* + if (ioctl(tty_fd, KDSKBMODE, kb_mode) < 0) { + SDL_Log("Failed to unmute keyboard"); } + */ } -/* Read /sys/class/tty/tty0/active and open the tty */ static int SDL_EVDEV_get_active_tty() -{ - int fd, len; - char ttyname[NAME_MAX + 1]; - char ttypath[PATH_MAX+1] = "/dev/"; - char arg; +{ + int i, fd, ret, tty = 0; + char tiocl; + struct vt_stat vt_state; + char path[PATH_MAX + 1]; - fd = open("/sys/class/tty/tty0/active", O_RDONLY); - if (fd < 0) { - return SDL_SetError("Could not determine which tty is active"); - } - - len = read(fd, ttyname, NAME_MAX); - close(fd); - - if (len <= 0) { - return SDL_SetError("Could not read which tty is active"); - } - - if (ttyname[len-1] == '\n') { - ttyname[len-1] = '\0'; - } - else { - ttyname[len] = '\0'; - } - - SDL_strlcat(ttypath, ttyname, PATH_MAX); - fd = open(ttypath, O_RDWR | O_NOCTTY); - if (fd < 0) { - return SDL_SetError("Could not open tty: %s", ttypath); - } - - if (!IS_CONSOLE(fd)) { + for(i = 0; i < SDL_arraysize(EVDEV_consoles); i++) { + fd = open(EVDEV_consoles[i], O_RDONLY); + + if (fd < 0 && !SDL_EVDEV_is_console(fd)) + break; + + tiocl = TIOCL_GETFGCONSOLE; + if ((ret = ioctl(fd, TIOCLINUX, &tiocl)) >= 0) + tty = ret + 1; + else if (ioctl(fd, VT_GETSTATE, &vt_state) == 0) + tty = vt_state.v_active; + close(fd); - return SDL_SetError("Invalid tty obtained: %s", ttypath); + + if (tty) { + sprintf(path, "/dev/tty%u", tty); + fd = open(path, O_RDONLY); + if (fd >= 0 && SDL_EVDEV_is_console(fd)) + return fd; + } } - - return fd; + + return SDL_SetError("Failed to determine active tty"); } int SDL_EVDEV_Init(void) { - int retval = 0; - if (_this == NULL) { - - _this = (SDL_EVDEV_PrivateData *) SDL_calloc(1, sizeof(*_this)); - if(_this == NULL) { + _this = (SDL_EVDEV_PrivateData*)SDL_calloc(1, sizeof(*_this)); + if (_this == NULL) { return SDL_OutOfMemory(); } @@ -469,7 +231,9 @@ SDL_EVDEV_Init(void) /* Set up the udev callback */ if (SDL_UDEV_AddCallback(SDL_EVDEV_udev_callback) < 0) { - SDL_EVDEV_Quit(); + SDL_UDEV_Quit(); + SDL_free(_this); + _this = NULL; return -1; } @@ -479,26 +243,18 @@ SDL_EVDEV_Init(void) /* TODO: Scan the devices manually, like a caveman */ #endif /* SDL_USE_LIBUDEV */ - /* We need a physical terminal (not PTS) to be able to translate key code to symbols via the kernel tables */ - _this->console_fd = SDL_EVDEV_get_console_fd(); + /* We need a physical terminal (not PTS) to be able to translate key + code to symbols via the kernel tables */ + _this->console_fd = SDL_EVDEV_get_active_tty(); - /* Mute the keyboard so keystrokes only generate evdev events and do not leak through to the console */ - _this->tty = STDIN_FILENO; - if (SDL_EVDEV_mute_keyboard(_this->tty, &_this->kb_mode) < 0) { - /* stdin is not a tty, probably we were launched remotely, so we try to disable the active tty */ - _this->tty = SDL_EVDEV_get_active_tty(); - if (_this->tty >= 0) { - if (SDL_EVDEV_mute_keyboard(_this->tty, &_this->kb_mode) < 0) { - close(_this->tty); - _this->tty = -1; - } - } - } + /* Mute the keyboard so keystrokes only generate evdev events and do not + leak through to the console */ + SDL_EVDEV_mute_keyboard(_this->console_fd, &_this->kb_mode); } _this->ref_count += 1; - return retval; + return 0; } void @@ -511,21 +267,16 @@ SDL_EVDEV_Quit(void) _this->ref_count -= 1; if (_this->ref_count < 1) { - #if SDL_USE_LIBUDEV SDL_UDEV_DelCallback(SDL_EVDEV_udev_callback); SDL_UDEV_Quit(); #endif /* SDL_USE_LIBUDEV */ if (_this->console_fd >= 0) { + SDL_EVDEV_unmute_keyboard(_this->console_fd, _this->kb_mode); close(_this->console_fd); } - if (_this->tty >= 0) { - SDL_EVDEV_unmute_keyboard(_this->tty, _this->kb_mode); - close(_this->tty); - } - /* Remove existing devices */ while(_this->first != NULL) { SDL_EVDEV_device_removed(_this->first->path); @@ -533,7 +284,7 @@ SDL_EVDEV_Quit(void) SDL_assert(_this->first == NULL); SDL_assert(_this->last == NULL); - SDL_assert(_this->numdevices == 0); + SDL_assert(_this->num_devices == 0); SDL_free(_this); _this = NULL; @@ -541,47 +292,116 @@ SDL_EVDEV_Quit(void) } #if SDL_USE_LIBUDEV -void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath) +void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_class, + const char* dev_path) { - if (devpath == NULL) { + if (dev_path == NULL) { return; } - switch(udev_type) { + switch(udev_event) { case SDL_UDEV_DEVICEADDED: - if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE|SDL_UDEV_DEVICE_KEYBOARD))) { + if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD | + SDL_UDEV_DEVICE_TOUCHSCREEN))) return; - } - SDL_EVDEV_device_added(devpath); - break; - + + SDL_EVDEV_device_added(dev_path, udev_class); + break; case SDL_UDEV_DEVICEREMOVED: - SDL_EVDEV_device_removed(devpath); + SDL_EVDEV_device_removed(dev_path); break; - default: break; } } - #endif /* SDL_USE_LIBUDEV */ +#ifdef SDL_INPUT_LINUXKD +/* this logic is pulled from kbd_keycode() in drivers/tty/vt/keyboard.c in the + Linux kernel source */ +static void SDL_EVDEV_do_text_input(unsigned short keycode) { + char shift_state; + int locks_state; + struct kbentry kbe; + unsigned char type; + char text[2] = { 0 }; + + if (_this->console_fd < 0) + return; + + shift_state = TIOCL_GETSHIFTSTATE; + if (ioctl(_this->console_fd, TIOCLINUX, &shift_state) < 0) { + /* TODO: error */ + return; + } + + kbe.kb_table = shift_state; + kbe.kb_index = keycode; + + if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) { + /* TODO: error */ + return; + } + + type = KTYP(kbe.kb_value); + + if (type < 0xf0) { + /* + * FIXME: keysyms with a type below 0xf0 represent a unicode character + * which requires special handling due to dead characters, diacritics, + * etc. For perfect input a proper way to deal with such characters + * should be implemented. + * + * For reference, the only place I was able to find out about this + * special 0xf0 value was in an unused? couple of patches listed below. + * + * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-keyboard.diff + * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-console.diff + */ + + return; + } + + type -= 0xf0; + + /* if type is KT_LETTER then it can be affected by Caps Lock */ + if (type == KT_LETTER) { + type = KT_LATIN; + + if (ioctl(_this->console_fd, KDGKBLED, &locks_state) < 0) { + /* TODO: error */ + return; + } + + if (locks_state & K_CAPSLOCK) { + kbe.kb_table = shift_state ^ (1 << KG_SHIFT); + + if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) { + /* TODO: error */ + return; + } + } + } + + /* TODO: convert values >= 0x80 from ISO-8859-1? to UTF-8 */ + if (type != KT_LATIN || KVAL(kbe.kb_value) >= 0x80) + return; + + *text = KVAL(kbe.kb_value); + SDL_SendKeyboardText(text); +} +#endif /* SDL_INPUT_LINUXKD */ + void SDL_EVDEV_Poll(void) { struct input_event events[32]; - int i, len; + int i, j, len; SDL_evdevlist_item *item; SDL_Scancode scan_code; int mouse_button; SDL_Mouse *mouse; -#ifdef SDL_INPUT_LINUXKD - Uint16 modstate; - struct kbentry kbe; - static char keysym[8]; - char *end; - Uint32 kval; -#endif + float norm_x, norm_y; if (!_this) { return; @@ -597,6 +417,13 @@ SDL_EVDEV_Poll(void) while ((len = read(item->fd, events, (sizeof events))) > 0) { len /= sizeof(events[0]); for (i = 0; i < len; ++i) { + /* special handling for touchscreen, that should eventually be + used for all devices */ + if (item->out_of_sync && item->is_touchscreen && + events[i].type == EV_SYN && events[i].code != SYN_REPORT) { + break; + } + switch (events[i].type) { case EV_KEY: if (events[i].code >= BTN_MOUSE && events[i].code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) { @@ -614,57 +441,55 @@ SDL_EVDEV_Poll(void) if (scan_code != SDL_SCANCODE_UNKNOWN) { if (events[i].value == 0) { SDL_SendKeyboardKey(SDL_RELEASED, scan_code); - } else if (events[i].value == 1 || events[i].value == 2 /* Key repeated */) { + } else if (events[i].value == 1 || events[i].value == 2 /* key repeated */) { SDL_SendKeyboardKey(SDL_PRESSED, scan_code); #ifdef SDL_INPUT_LINUXKD - if (_this->console_fd >= 0) { - kbe.kb_index = events[i].code; - /* Convert the key to an UTF-8 char */ - /* Ref: http://www.linuxjournal.com/article/2783 */ - modstate = SDL_GetModState(); - kbe.kb_table = 0; - - /* Ref: http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching */ - kbe.kb_table |= -((modstate & KMOD_LCTRL) != 0) & (1 << KG_CTRLL | 1 << KG_CTRL); - kbe.kb_table |= -((modstate & KMOD_RCTRL) != 0) & (1 << KG_CTRLR | 1 << KG_CTRL); - kbe.kb_table |= -((modstate & KMOD_LSHIFT) != 0) & (1 << KG_SHIFTL | 1 << KG_SHIFT); - kbe.kb_table |= -((modstate & KMOD_RSHIFT) != 0) & (1 << KG_SHIFTR | 1 << KG_SHIFT); - kbe.kb_table |= -((modstate & KMOD_LALT) != 0) & (1 << KG_ALT); - kbe.kb_table |= -((modstate & KMOD_RALT) != 0) & (1 << KG_ALTGR); - - if (ioctl(_this->console_fd, KDGKBENT, (unsigned long)&kbe) == 0 && - ((KTYP(kbe.kb_value) == KT_LATIN) || (KTYP(kbe.kb_value) == KT_ASCII) || (KTYP(kbe.kb_value) == KT_LETTER))) - { - kval = KVAL(kbe.kb_value); - - /* While there's a KG_CAPSSHIFT symbol, it's not useful to build the table index with it - * because 1 << KG_CAPSSHIFT overflows the 8 bits of kb_table - * So, we do the CAPS LOCK logic here. Note that isalpha depends on the locale! - */ - if (modstate & KMOD_CAPS && isalpha(kval)) { - if (isupper(kval)) { - kval = tolower(kval); - } else { - kval = toupper(kval); - } - } - - /* Convert to UTF-8 and send */ - end = SDL_UCS4ToUTF8(kval, keysym); - *end = '\0'; - SDL_SendKeyboardText(keysym); - } - } + SDL_EVDEV_do_text_input(events[i].code); #endif /* SDL_INPUT_LINUXKD */ } } break; case EV_ABS: switch(events[i].code) { + case ABS_MT_SLOT: + if (!item->is_touchscreen) /* FIXME: temp hack */ + break; + item->touchscreen_data->current_slot = events[i].value; + break; + case ABS_MT_TRACKING_ID: + if (!item->is_touchscreen) /* FIXME: temp hack */ + break; + if (events[i].value >= 0) { + item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = events[i].value; + item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; + } else { + item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_UP; + } + break; + case ABS_MT_POSITION_X: + if (!item->is_touchscreen) /* FIXME: temp hack */ + break; + item->touchscreen_data->slots[item->touchscreen_data->current_slot].x = events[i].value; + if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { + item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; + } + break; + case ABS_MT_POSITION_Y: + if (!item->is_touchscreen) /* FIXME: temp hack */ + break; + item->touchscreen_data->slots[item->touchscreen_data->current_slot].y = events[i].value; + if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { + item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; + } + break; case ABS_X: + if (item->is_touchscreen) /* FIXME: temp hack */ + break; SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, events[i].value, mouse->y); break; case ABS_Y: + if (item->is_touchscreen) /* FIXME: temp hack */ + break; SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, mouse->x, events[i].value); break; default: @@ -691,7 +516,41 @@ SDL_EVDEV_Poll(void) break; case EV_SYN: switch (events[i].code) { + case SYN_REPORT: + if (!item->is_touchscreen) /* FIXME: temp hack */ + break; + + for(j = 0; j < item->touchscreen_data->max_slots; j++) { + norm_x = (float)(item->touchscreen_data->slots[j].x - item->touchscreen_data->min_x) / + (float)item->touchscreen_data->range_x; + norm_y = (float)(item->touchscreen_data->slots[j].y - item->touchscreen_data->min_y) / + (float)item->touchscreen_data->range_y; + + switch(item->touchscreen_data->slots[j].delta) { + case EVDEV_TOUCH_SLOTDELTA_DOWN: + SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_TRUE, norm_x, norm_y, 1.0f); + item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; + break; + case EVDEV_TOUCH_SLOTDELTA_UP: + SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_FALSE, norm_x, norm_y, 1.0f); + item->touchscreen_data->slots[j].tracking_id = -1; + item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; + break; + case EVDEV_TOUCH_SLOTDELTA_MOVE: + SDL_SendTouchMotion(item->fd, item->touchscreen_data->slots[j].tracking_id, norm_x, norm_y, 1.0f); + item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; + break; + default: + break; + } + } + + if (item->out_of_sync) + item->out_of_sync = 0; + break; case SYN_DROPPED: + if (item->is_touchscreen) + item->out_of_sync = 1; SDL_EVDEV_sync_device(item); break; default: @@ -709,30 +568,227 @@ SDL_EVDEV_translate_keycode(int keycode) { SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; - if (keycode < SDL_arraysize(EVDEV_Keycodes)) { - scancode = EVDEV_Keycodes[keycode]; - } + if (keycode < SDL_arraysize(linux_scancode_table)) + scancode = linux_scancode_table[keycode]; + if (scancode == SDL_SCANCODE_UNKNOWN) { - SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list EVDEV KeyCode %d \n", keycode); + SDL_Log("The key you just pressed is not recognized by SDL. To help " + "get this fixed, please report this to the SDL mailing list " + " EVDEV KeyCode %d\n", keycode); } + return scancode; } +#ifdef SDL_USE_LIBUDEV +static int +SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item) +{ + int ret, i; + char name[64]; + struct input_absinfo abs_info; + + if (!item->is_touchscreen) + return 0; + + item->touchscreen_data = SDL_calloc(1, sizeof(*item->touchscreen_data)); + if (item->touchscreen_data == NULL) + return SDL_OutOfMemory(); + + ret = ioctl(item->fd, EVIOCGNAME(sizeof(name)), name); + if (ret < 0) { + SDL_free(item->touchscreen_data); + return SDL_SetError("Failed to get evdev touchscreen name"); + } + + item->touchscreen_data->name = SDL_strdup(name); + if (item->touchscreen_data->name == NULL) { + SDL_free(item->touchscreen_data); + return SDL_OutOfMemory(); + } + + ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_info); + if (ret < 0) { + SDL_free(item->touchscreen_data->name); + SDL_free(item->touchscreen_data); + return SDL_SetError("Failed to get evdev touchscreen limits"); + } + item->touchscreen_data->min_x = abs_info.minimum; + item->touchscreen_data->max_x = abs_info.maximum; + item->touchscreen_data->range_x = abs_info.maximum - abs_info.minimum; + + ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_info); + if (ret < 0) { + SDL_free(item->touchscreen_data->name); + SDL_free(item->touchscreen_data); + return SDL_SetError("Failed to get evdev touchscreen limits"); + } + item->touchscreen_data->min_y = abs_info.minimum; + item->touchscreen_data->max_y = abs_info.maximum; + item->touchscreen_data->range_y = abs_info.maximum - abs_info.minimum; + + ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info); + if (ret < 0) { + SDL_free(item->touchscreen_data->name); + SDL_free(item->touchscreen_data); + return SDL_SetError("Failed to get evdev touchscreen limits"); + } + item->touchscreen_data->max_slots = abs_info.maximum + 1; + + item->touchscreen_data->slots = SDL_calloc( + item->touchscreen_data->max_slots, + sizeof(*item->touchscreen_data->slots)); + if (item->touchscreen_data->slots == NULL) { + SDL_free(item->touchscreen_data->name); + SDL_free(item->touchscreen_data); + return SDL_OutOfMemory(); + } + + for(i = 0; i < item->touchscreen_data->max_slots; i++) { + item->touchscreen_data->slots[i].tracking_id = -1; + } + + ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */ + item->touchscreen_data->name); + if (ret < 0) { + SDL_free(item->touchscreen_data->slots); + SDL_free(item->touchscreen_data->name); + SDL_free(item->touchscreen_data); + return ret; + } + + return 0; +} +#endif /* SDL_USE_LIBUDEV */ + +static void +SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item* item) { + if (!item->is_touchscreen) + return; + + SDL_DelTouch(item->fd); + SDL_free(item->touchscreen_data->slots); + SDL_free(item->touchscreen_data->name); + SDL_free(item->touchscreen_data); +} + static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item) { - /* TODO: get full state of device and report whatever is required */ +#ifdef EVIOCGMTSLOTS + int i, ret; + struct input_absinfo abs_info; + /* + * struct input_mt_request_layout { + * __u32 code; + * __s32 values[num_slots]; + * }; + * + * this is the structure we're trying to emulate + */ + __u32* mt_req_code; + __s32* mt_req_values; + size_t mt_req_size; + + /* TODO: sync devices other than touchscreen */ + if (!item->is_touchscreen) + return; + + mt_req_size = sizeof(*mt_req_code) + + sizeof(*mt_req_values) * item->touchscreen_data->max_slots; + + mt_req_code = SDL_calloc(1, mt_req_size); + if (mt_req_code == NULL) { + return; + } + + mt_req_values = (__s32*)mt_req_code + 1; + + *mt_req_code = ABS_MT_TRACKING_ID; + ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code); + if (ret < 0) { + SDL_free(mt_req_code); + return; + } + for(i = 0; i < item->touchscreen_data->max_slots; i++) { + /* + * This doesn't account for the very edge case of the user removing their + * finger and replacing it on the screen during the time we're out of sync, + * which'll mean that we're not going from down -> up or up -> down, we're + * going from down -> down but with a different tracking id, meaning we'd + * have to tell SDL of the two events, but since we wait till SYN_REPORT in + * SDL_EVDEV_Poll to tell SDL, the current structure of this code doesn't + * allow it. Lets just pray to God it doesn't happen. + */ + if (item->touchscreen_data->slots[i].tracking_id < 0 && + mt_req_values[i] >= 0) { + item->touchscreen_data->slots[i].tracking_id = mt_req_values[i]; + item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; + } else if (item->touchscreen_data->slots[i].tracking_id >= 0 && + mt_req_values[i] < 0) { + item->touchscreen_data->slots[i].tracking_id = -1; + item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_UP; + } + } + + *mt_req_code = ABS_MT_POSITION_X; + ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code); + if (ret < 0) { + SDL_free(mt_req_code); + return; + } + for(i = 0; i < item->touchscreen_data->max_slots; i++) { + if (item->touchscreen_data->slots[i].tracking_id >= 0 && + item->touchscreen_data->slots[i].x != mt_req_values[i]) { + item->touchscreen_data->slots[i].x = mt_req_values[i]; + if (item->touchscreen_data->slots[i].delta == + EVDEV_TOUCH_SLOTDELTA_NONE) { + item->touchscreen_data->slots[i].delta = + EVDEV_TOUCH_SLOTDELTA_MOVE; + } + } + } + + *mt_req_code = ABS_MT_POSITION_Y; + ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code); + if (ret < 0) { + SDL_free(mt_req_code); + return; + } + for(i = 0; i < item->touchscreen_data->max_slots; i++) { + if (item->touchscreen_data->slots[i].tracking_id >= 0 && + item->touchscreen_data->slots[i].y != mt_req_values[i]) { + item->touchscreen_data->slots[i].y = mt_req_values[i]; + if (item->touchscreen_data->slots[i].delta == + EVDEV_TOUCH_SLOTDELTA_NONE) { + item->touchscreen_data->slots[i].delta = + EVDEV_TOUCH_SLOTDELTA_MOVE; + } + } + } + + ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info); + if (ret < 0) { + SDL_free(mt_req_code); + return; + } + item->touchscreen_data->current_slot = abs_info.value; + + SDL_free(mt_req_code); + +#endif /* EVIOCGMTSLOTS */ } #if SDL_USE_LIBUDEV static int -SDL_EVDEV_device_added(const char *devpath) +SDL_EVDEV_device_added(const char *dev_path, int udev_class) { + int ret; SDL_evdevlist_item *item; /* Check to make sure it's not already in list. */ for (item = _this->first; item != NULL; item = item->next) { - if (SDL_strcmp(devpath, item->path) == 0) { + if (SDL_strcmp(dev_path, item->path) == 0) { return -1; /* already have this one */ } } @@ -742,21 +798,28 @@ SDL_EVDEV_device_added(const char *devpath) return SDL_OutOfMemory(); } - item->fd = open(devpath, O_RDONLY, 0); + item->fd = open(dev_path, O_RDONLY | O_NONBLOCK); if (item->fd < 0) { SDL_free(item); - return SDL_SetError("Unable to open %s", devpath); + return SDL_SetError("Unable to open %s", dev_path); } - item->path = SDL_strdup(devpath); + item->path = SDL_strdup(dev_path); if (item->path == NULL) { close(item->fd); SDL_free(item); return SDL_OutOfMemory(); } - /* Non blocking read mode */ - fcntl(item->fd, F_SETFL, O_NONBLOCK); + if (udev_class & SDL_UDEV_DEVICE_TOUCHSCREEN) { + item->is_touchscreen = 1; + + if ((ret = SDL_EVDEV_init_touchscreen(item)) < 0) { + close(item->fd); + SDL_free(item); + return ret; + } + } if (_this->last == NULL) { _this->first = _this->last = item; @@ -767,19 +830,19 @@ SDL_EVDEV_device_added(const char *devpath) SDL_EVDEV_sync_device(item); - return _this->numdevices++; + return _this->num_devices++; } #endif /* SDL_USE_LIBUDEV */ static int -SDL_EVDEV_device_removed(const char *devpath) +SDL_EVDEV_device_removed(const char *dev_path) { SDL_evdevlist_item *item; SDL_evdevlist_item *prev = NULL; for (item = _this->first; item != NULL; item = item->next) { /* found it, remove it. */ - if (SDL_strcmp(devpath, item->path) == 0) { + if (SDL_strcmp(dev_path, item->path) == 0) { if (prev != NULL) { prev->next = item->next; } else { @@ -789,10 +852,13 @@ SDL_EVDEV_device_removed(const char *devpath) if (item == _this->last) { _this->last = prev; } + if (item->is_touchscreen) { + SDL_EVDEV_destroy_touchscreen(item); + } close(item->fd); SDL_free(item->path); SDL_free(item); - _this->numdevices--; + _this->num_devices--; return 0; } prev = item; @@ -805,4 +871,3 @@ SDL_EVDEV_device_removed(const char *devpath) #endif /* SDL_INPUT_LINUXEV */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/Engine/lib/sdl/src/core/linux/SDL_evdev.h b/Engine/lib/sdl/src/core/linux/SDL_evdev.h index 989ced858..85b193864 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_evdev.h +++ b/Engine/lib/sdl/src/core/linux/SDL_evdev.h @@ -27,31 +27,11 @@ #ifdef SDL_INPUT_LINUXEV #include "SDL_events.h" -#include - -typedef struct SDL_evdevlist_item -{ - char *path; - int fd; - struct SDL_evdevlist_item *next; -} SDL_evdevlist_item; - -typedef struct SDL_EVDEV_PrivateData -{ - SDL_evdevlist_item *first; - SDL_evdevlist_item *last; - int numdevices; - int ref_count; - int console_fd; - int kb_mode; - int tty; -} SDL_EVDEV_PrivateData; extern int SDL_EVDEV_Init(void); extern void SDL_EVDEV_Quit(void); extern void SDL_EVDEV_Poll(void); - #endif /* SDL_INPUT_LINUXEV */ #endif /* _SDL_evdev_h */ diff --git a/Engine/lib/sdl/src/core/linux/SDL_fcitx.c b/Engine/lib/sdl/src/core/linux/SDL_fcitx.c new file mode 100644 index 000000000..83d19e690 --- /dev/null +++ b/Engine/lib/sdl/src/core/linux/SDL_fcitx.c @@ -0,0 +1,553 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#ifdef HAVE_FCITX_FRONTEND_H + +#include +#include + +#include "SDL_fcitx.h" +#include "SDL_keycode.h" +#include "SDL_keyboard.h" +#include "../../events/SDL_keyboard_c.h" +#include "SDL_dbus.h" +#include "SDL_syswm.h" +#if SDL_VIDEO_DRIVER_X11 +# include "../../video/x11/SDL_x11video.h" +#endif +#include "SDL_hints.h" + +#define FCITX_DBUS_SERVICE "org.fcitx.Fcitx" + +#define FCITX_IM_DBUS_PATH "/inputmethod" +#define FCITX_IC_DBUS_PATH "/inputcontext_%d" + +#define FCITX_IM_DBUS_INTERFACE "org.fcitx.Fcitx.InputMethod" +#define FCITX_IC_DBUS_INTERFACE "org.fcitx.Fcitx.InputContext" + +#define IC_NAME_MAX 64 +#define DBUS_TIMEOUT 500 + +typedef struct _FcitxClient +{ + SDL_DBusContext *dbus; + + char servicename[IC_NAME_MAX]; + char icname[IC_NAME_MAX]; + + int id; + + SDL_Rect cursor_rect; +} FcitxClient; + +static FcitxClient fcitx_client; + +static int +GetDisplayNumber() +{ + const char *display = SDL_getenv("DISPLAY"); + const char *p = NULL; + int number = 0; + + if (display == NULL) + return 0; + + display = SDL_strchr(display, ':'); + if (display == NULL) + return 0; + + display++; + p = SDL_strchr(display, '.'); + if (p == NULL && display != NULL) { + number = SDL_strtod(display, NULL); + } else { + char *buffer = SDL_strdup(display); + buffer[p - display] = '\0'; + number = SDL_strtod(buffer, NULL); + SDL_free(buffer); + } + + return number; +} + +static char* +GetAppName() +{ +#if defined(__LINUX__) || defined(__FREEBSD__) + char *spot; + char procfile[1024]; + char linkfile[1024]; + int linksize; + +#if defined(__LINUX__) + SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid()); +#elif defined(__FREEBSD__) + SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid()); +#endif + linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1); + if (linksize > 0) { + linkfile[linksize] = '\0'; + spot = SDL_strrchr(linkfile, '/'); + if (spot) { + return SDL_strdup(spot + 1); + } else { + return SDL_strdup(linkfile); + } + } +#endif /* __LINUX__ || __FREEBSD__ */ + + return SDL_strdup("SDL_App"); +} + +/* + * Copied from fcitx source + */ +#define CONT(i) ISUTF8_CB(in[i]) +#define VAL(i, s) ((in[i]&0x3f) << s) + +static char * +_fcitx_utf8_get_char(const char *i, uint32_t *chr) +{ + const unsigned char* in = (const unsigned char *)i; + if (!(in[0] & 0x80)) { + *(chr) = *(in); + return (char *)in + 1; + } + + /* 2-byte, 0x80-0x7ff */ + if ((in[0] & 0xe0) == 0xc0 && CONT(1)) { + *chr = ((in[0] & 0x1f) << 6) | VAL(1, 0); + return (char *)in + 2; + } + + /* 3-byte, 0x800-0xffff */ + if ((in[0] & 0xf0) == 0xe0 && CONT(1) && CONT(2)) { + *chr = ((in[0] & 0xf) << 12) | VAL(1, 6) | VAL(2, 0); + return (char *)in + 3; + } + + /* 4-byte, 0x10000-0x1FFFFF */ + if ((in[0] & 0xf8) == 0xf0 && CONT(1) && CONT(2) && CONT(3)) { + *chr = ((in[0] & 0x7) << 18) | VAL(1, 12) | VAL(2, 6) | VAL(3, 0); + return (char *)in + 4; + } + + /* 5-byte, 0x200000-0x3FFFFFF */ + if ((in[0] & 0xfc) == 0xf8 && CONT(1) && CONT(2) && CONT(3) && CONT(4)) { + *chr = ((in[0] & 0x3) << 24) | VAL(1, 18) | VAL(2, 12) | VAL(3, 6) | VAL(4, 0); + return (char *)in + 5; + } + + /* 6-byte, 0x400000-0x7FFFFFF */ + if ((in[0] & 0xfe) == 0xfc && CONT(1) && CONT(2) && CONT(3) && CONT(4) && CONT(5)) { + *chr = ((in[0] & 0x1) << 30) | VAL(1, 24) | VAL(2, 18) | VAL(3, 12) | VAL(4, 6) | VAL(5, 0); + return (char *)in + 6; + } + + *chr = *in; + + return (char *)in + 1; +} + +static size_t +_fcitx_utf8_strlen(const char *s) +{ + unsigned int l = 0; + + while (*s) { + uint32_t chr; + + s = _fcitx_utf8_get_char(s, &chr); + l++; + } + + return l; +} + +static DBusHandlerResult +DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data) +{ + SDL_DBusContext *dbus = (SDL_DBusContext *)data; + + if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "CommitString")) { + DBusMessageIter iter; + const char *text = NULL; + + dbus->message_iter_init(msg, &iter); + dbus->message_iter_get_basic(&iter, &text); + + if (text) + SDL_SendKeyboardText(text); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "UpdatePreedit")) { + DBusMessageIter iter; + const char *text; + + dbus->message_iter_init(msg, &iter); + dbus->message_iter_get_basic(&iter, &text); + + if (text && *text) { + char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + size_t text_bytes = SDL_strlen(text), i = 0; + size_t cursor = 0; + + while (i < text_bytes) { + size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf)); + size_t chars = _fcitx_utf8_strlen(buf); + + SDL_SendEditingText(buf, cursor, chars); + + i += sz; + cursor += chars; + } + } + + SDL_Fcitx_UpdateTextRect(NULL); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusMessage* +FcitxClientICNewMethod(FcitxClient *client, + const char *method) +{ + SDL_DBusContext *dbus = client->dbus; + return dbus->message_new_method_call( + client->servicename, + client->icname, + FCITX_IC_DBUS_INTERFACE, + method); +} + +static void +FcitxClientICCallMethod(FcitxClient *client, + const char *method) +{ + SDL_DBusContext *dbus = client->dbus; + DBusMessage *msg = FcitxClientICNewMethod(client, method); + + if (msg == NULL) + return ; + + if (dbus->connection_send(dbus->session_conn, msg, NULL)) { + dbus->connection_flush(dbus->session_conn); + } + + dbus->message_unref(msg); +} + +static void +Fcitx_SetCapabilities(void *data, + const char *name, + const char *old_val, + const char *internal_editing) +{ + FcitxClient *client = (FcitxClient *)data; + SDL_DBusContext *dbus = client->dbus; + Uint32 caps = CAPACITY_NONE; + + DBusMessage *msg = FcitxClientICNewMethod(client, "SetCapacity"); + if (msg == NULL) + return ; + + if (!(internal_editing && *internal_editing == '1')) { + caps |= CAPACITY_PREEDIT; + } + + dbus->message_append_args(msg, + DBUS_TYPE_UINT32, &caps, + DBUS_TYPE_INVALID); + if (dbus->connection_send(dbus->session_conn, msg, NULL)) { + dbus->connection_flush(dbus->session_conn); + } + + dbus->message_unref(msg); +} + +static void +FcitxClientCreateIC(FcitxClient *client) +{ + char *appname = NULL; + pid_t pid = 0; + int id = 0; + SDL_bool enable; + Uint32 arg1, arg2, arg3, arg4; + + SDL_DBusContext *dbus = client->dbus; + DBusMessage *reply = NULL; + DBusMessage *msg = dbus->message_new_method_call( + client->servicename, + FCITX_IM_DBUS_PATH, + FCITX_IM_DBUS_INTERFACE, + "CreateICv3" + ); + + if (msg == NULL) + return ; + + appname = GetAppName(); + pid = getpid(); + dbus->message_append_args(msg, + DBUS_TYPE_STRING, &appname, + DBUS_TYPE_INT32, &pid, + DBUS_TYPE_INVALID); + + do { + reply = dbus->connection_send_with_reply_and_block( + dbus->session_conn, + msg, + DBUS_TIMEOUT, + NULL); + + if (!reply) + break; + if (!dbus->message_get_args(reply, NULL, + DBUS_TYPE_INT32, &id, + DBUS_TYPE_BOOLEAN, &enable, + DBUS_TYPE_UINT32, &arg1, + DBUS_TYPE_UINT32, &arg2, + DBUS_TYPE_UINT32, &arg3, + DBUS_TYPE_UINT32, &arg4, + DBUS_TYPE_INVALID)) + break; + + if (id < 0) + break; + client->id = id; + + SDL_snprintf(client->icname, IC_NAME_MAX, + FCITX_IC_DBUS_PATH, client->id); + + dbus->bus_add_match(dbus->session_conn, + "type='signal', interface='org.fcitx.Fcitx.InputContext'", + NULL); + dbus->connection_add_filter(dbus->session_conn, + &DBus_MessageFilter, dbus, + NULL); + dbus->connection_flush(dbus->session_conn); + + SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, &Fcitx_SetCapabilities, client); + } + while (0); + + if (reply) + dbus->message_unref(reply); + dbus->message_unref(msg); + SDL_free(appname); +} + +static Uint32 +Fcitx_ModState(void) +{ + Uint32 fcitx_mods = 0; + SDL_Keymod sdl_mods = SDL_GetModState(); + + if (sdl_mods & KMOD_SHIFT) fcitx_mods |= FcitxKeyState_Shift; + if (sdl_mods & KMOD_CAPS) fcitx_mods |= FcitxKeyState_CapsLock; + if (sdl_mods & KMOD_CTRL) fcitx_mods |= FcitxKeyState_Ctrl; + if (sdl_mods & KMOD_ALT) fcitx_mods |= FcitxKeyState_Alt; + if (sdl_mods & KMOD_NUM) fcitx_mods |= FcitxKeyState_NumLock; + if (sdl_mods & KMOD_LGUI) fcitx_mods |= FcitxKeyState_Super; + if (sdl_mods & KMOD_RGUI) fcitx_mods |= FcitxKeyState_Meta; + + return fcitx_mods; +} + +SDL_bool +SDL_Fcitx_Init() +{ + fcitx_client.dbus = SDL_DBus_GetContext(); + + fcitx_client.cursor_rect.x = -1; + fcitx_client.cursor_rect.y = -1; + fcitx_client.cursor_rect.w = 0; + fcitx_client.cursor_rect.h = 0; + + SDL_snprintf(fcitx_client.servicename, IC_NAME_MAX, + "%s-%d", + FCITX_DBUS_SERVICE, GetDisplayNumber()); + + FcitxClientCreateIC(&fcitx_client); + + return SDL_TRUE; +} + +void +SDL_Fcitx_Quit() +{ + FcitxClientICCallMethod(&fcitx_client, "DestroyIC"); +} + +void +SDL_Fcitx_SetFocus(SDL_bool focused) +{ + if (focused) { + FcitxClientICCallMethod(&fcitx_client, "FocusIn"); + } else { + FcitxClientICCallMethod(&fcitx_client, "FocusOut"); + } +} + +void +SDL_Fcitx_Reset(void) +{ + FcitxClientICCallMethod(&fcitx_client, "Reset"); + FcitxClientICCallMethod(&fcitx_client, "CloseIC"); +} + +SDL_bool +SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) +{ + DBusMessage *msg = NULL; + DBusMessage *reply = NULL; + SDL_DBusContext *dbus = fcitx_client.dbus; + + Uint32 state = 0; + SDL_bool handled = SDL_FALSE; + int type = FCITX_PRESS_KEY; + Uint32 event_time = 0; + + msg = FcitxClientICNewMethod(&fcitx_client, "ProcessKeyEvent"); + if (msg == NULL) + return SDL_FALSE; + + state = Fcitx_ModState(); + dbus->message_append_args(msg, + DBUS_TYPE_UINT32, &keysym, + DBUS_TYPE_UINT32, &keycode, + DBUS_TYPE_UINT32, &state, + DBUS_TYPE_INT32, &type, + DBUS_TYPE_UINT32, &event_time, + DBUS_TYPE_INVALID); + + reply = dbus->connection_send_with_reply_and_block(dbus->session_conn, + msg, + -1, + NULL); + + if (reply) { + dbus->message_get_args(reply, + NULL, + DBUS_TYPE_INT32, &handled, + DBUS_TYPE_INVALID); + + dbus->message_unref(reply); + } + + if (handled) { + SDL_Fcitx_UpdateTextRect(NULL); + } + + return handled; +} + +void +SDL_Fcitx_UpdateTextRect(SDL_Rect *rect) +{ + SDL_Window *focused_win = NULL; + SDL_SysWMinfo info; + int x = 0, y = 0; + SDL_Rect *cursor = &fcitx_client.cursor_rect; + + SDL_DBusContext *dbus = fcitx_client.dbus; + DBusMessage *msg = NULL; + DBusConnection *conn; + + if (rect) { + SDL_memcpy(cursor, rect, sizeof(SDL_Rect)); + } + + focused_win = SDL_GetKeyboardFocus(); + if (!focused_win) { + return ; + } + + SDL_VERSION(&info.version); + if (!SDL_GetWindowWMInfo(focused_win, &info)) { + return; + } + + SDL_GetWindowPosition(focused_win, &x, &y); + +#if SDL_VIDEO_DRIVER_X11 + if (info.subsystem == SDL_SYSWM_X11) { + SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(focused_win)->driverdata; + + Display *x_disp = info.info.x11.display; + Window x_win = info.info.x11.window; + int x_screen = displaydata->screen; + Window unused; + X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &y, &unused); + } +#endif + + if (cursor->x == -1 && cursor->y == -1 && cursor->w == 0 && cursor->h == 0) { + // move to bottom left + int w = 0, h = 0; + SDL_GetWindowSize(focused_win, &w, &h); + cursor->x = 0; + cursor->y = h; + } + + x += cursor->x; + y += cursor->y; + + msg = FcitxClientICNewMethod(&fcitx_client, "SetCursorRect"); + if (msg == NULL) + return ; + + dbus->message_append_args(msg, + DBUS_TYPE_INT32, &x, + DBUS_TYPE_INT32, &y, + DBUS_TYPE_INT32, &cursor->w, + DBUS_TYPE_INT32, &cursor->h, + DBUS_TYPE_INVALID); + + conn = dbus->session_conn; + if (dbus->connection_send(conn, msg, NULL)) + dbus->connection_flush(conn); + + dbus->message_unref(msg); +} + +void +SDL_Fcitx_PumpEvents() +{ + SDL_DBusContext *dbus = fcitx_client.dbus; + DBusConnection *conn = dbus->session_conn; + + dbus->connection_read_write(conn, 0); + + while (dbus->connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS) { + /* Do nothing, actual work happens in DBus_MessageFilter */ + usleep(10); + } +} + +#endif /* HAVE_FCITX_FRONTEND_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/core/linux/SDL_fcitx.h b/Engine/lib/sdl/src/core/linux/SDL_fcitx.h new file mode 100644 index 000000000..64020475c --- /dev/null +++ b/Engine/lib/sdl/src/core/linux/SDL_fcitx.h @@ -0,0 +1,40 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_fcitx_h +#define _SDL_fcitx_h + +#include "../../SDL_internal.h" + +#include "SDL_stdinc.h" +#include "SDL_rect.h" + +extern SDL_bool SDL_Fcitx_Init(void); +extern void SDL_Fcitx_Quit(void); +extern void SDL_Fcitx_SetFocus(SDL_bool focused); +extern void SDL_Fcitx_Reset(void); +extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); +extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect); +extern void SDL_Fcitx_PumpEvents(); + +#endif /* _SDL_fcitx_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/core/linux/SDL_ibus.c b/Engine/lib/sdl/src/core/linux/SDL_ibus.c index c9804c90a..3d63b8b30 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_ibus.c +++ b/Engine/lib/sdl/src/core/linux/SDL_ibus.c @@ -42,7 +42,7 @@ static const char IBUS_INTERFACE[] = "org.freedesktop.IBus"; static const char IBUS_INPUT_INTERFACE[] = "org.freedesktop.IBus.InputContext"; static char *input_ctx_path = NULL; -static SDL_Rect ibus_cursor_rect = {0}; +static SDL_Rect ibus_cursor_rect = { 0, 0, 0, 0 }; static DBusConnection *ibus_conn = NULL; static char *ibus_addr_file = NULL; int inotify_fd = -1, inotify_wd = -1; @@ -341,7 +341,9 @@ IBus_SetupConnection(SDL_DBusContext *dbus, const char* addr) const char *path = NULL; SDL_bool result = SDL_FALSE; DBusMessage *msg; - DBusObjectPathVTable ibus_vtable = {0}; + DBusObjectPathVTable ibus_vtable; + + SDL_zero(ibus_vtable); ibus_vtable.message_function = &IBus_MessageHandler; ibus_conn = dbus->connection_open_private(addr, NULL); diff --git a/Engine/lib/sdl/src/core/linux/SDL_ime.c b/Engine/lib/sdl/src/core/linux/SDL_ime.c new file mode 100644 index 000000000..049bd6e02 --- /dev/null +++ b/Engine/lib/sdl/src/core/linux/SDL_ime.c @@ -0,0 +1,138 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_ime.h" +#include "SDL_ibus.h" +#include "SDL_fcitx.h" + +typedef SDL_bool (*_SDL_IME_Init)(); +typedef void (*_SDL_IME_Quit)(); +typedef void (*_SDL_IME_SetFocus)(SDL_bool); +typedef void (*_SDL_IME_Reset)(); +typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32); +typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *); +typedef void (*_SDL_IME_PumpEvents)(); + +static _SDL_IME_Init SDL_IME_Init_Real = NULL; +static _SDL_IME_Quit SDL_IME_Quit_Real = NULL; +static _SDL_IME_SetFocus SDL_IME_SetFocus_Real = NULL; +static _SDL_IME_Reset SDL_IME_Reset_Real = NULL; +static _SDL_IME_ProcessKeyEvent SDL_IME_ProcessKeyEvent_Real = NULL; +static _SDL_IME_UpdateTextRect SDL_IME_UpdateTextRect_Real = NULL; +static _SDL_IME_PumpEvents SDL_IME_PumpEvents_Real = NULL; + +static void +InitIME() +{ + static SDL_bool inited = SDL_FALSE; +#ifdef HAVE_FCITX_FRONTEND_H + const char *im_module = SDL_getenv("SDL_IM_MODULE"); + const char *xmodifiers = SDL_getenv("XMODIFIERS"); +#endif + + if (inited == SDL_TRUE) + return; + + inited = SDL_TRUE; + + /* See if fcitx IME support is being requested */ +#ifdef HAVE_FCITX_FRONTEND_H + if (!SDL_IME_Init_Real && + ((im_module && SDL_strcmp(im_module, "fcitx") == 0) || + (!im_module && xmodifiers && SDL_strstr(xmodifiers, "@im=fcitx") != NULL))) { + SDL_IME_Init_Real = SDL_Fcitx_Init; + SDL_IME_Quit_Real = SDL_Fcitx_Quit; + SDL_IME_SetFocus_Real = SDL_Fcitx_SetFocus; + SDL_IME_Reset_Real = SDL_Fcitx_Reset; + SDL_IME_ProcessKeyEvent_Real = SDL_Fcitx_ProcessKeyEvent; + SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect; + SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents; + } +#endif /* HAVE_FCITX_FRONTEND_H */ + + /* default to IBus */ +#ifdef HAVE_IBUS_IBUS_H + if (!SDL_IME_Init_Real) { + SDL_IME_Init_Real = SDL_IBus_Init; + SDL_IME_Quit_Real = SDL_IBus_Quit; + SDL_IME_SetFocus_Real = SDL_IBus_SetFocus; + SDL_IME_Reset_Real = SDL_IBus_Reset; + SDL_IME_ProcessKeyEvent_Real = SDL_IBus_ProcessKeyEvent; + SDL_IME_UpdateTextRect_Real = SDL_IBus_UpdateTextRect; + SDL_IME_PumpEvents_Real = SDL_IBus_PumpEvents; + } +#endif /* HAVE_IBUS_IBUS_H */ +} + +SDL_bool +SDL_IME_Init(void) +{ + InitIME(); + + if (SDL_IME_Init_Real) + return SDL_IME_Init_Real(); + + return SDL_FALSE; +} + +void +SDL_IME_Quit(void) +{ + if (SDL_IME_Quit_Real) + SDL_IME_Quit_Real(); +} + +void +SDL_IME_SetFocus(SDL_bool focused) +{ + if (SDL_IME_SetFocus_Real) + SDL_IME_SetFocus_Real(focused); +} + +void +SDL_IME_Reset(void) +{ + if (SDL_IME_Reset_Real) + SDL_IME_Reset_Real(); +} + +SDL_bool +SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) +{ + if (SDL_IME_ProcessKeyEvent_Real) + return SDL_IME_ProcessKeyEvent_Real(keysym, keycode); + + return SDL_FALSE; +} + +void +SDL_IME_UpdateTextRect(SDL_Rect *rect) +{ + if (SDL_IME_UpdateTextRect_Real) + SDL_IME_UpdateTextRect_Real(rect); +} + +void +SDL_IME_PumpEvents() +{ + if (SDL_IME_PumpEvents_Real) + SDL_IME_PumpEvents_Real(); +} diff --git a/Engine/lib/sdl/src/core/linux/SDL_ime.h b/Engine/lib/sdl/src/core/linux/SDL_ime.h new file mode 100644 index 000000000..22b31de39 --- /dev/null +++ b/Engine/lib/sdl/src/core/linux/SDL_ime.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef _SDL_ime_h +#define _SDL_ime_h + +#include "../../SDL_internal.h" + +#include "SDL_stdinc.h" +#include "SDL_rect.h" + +extern SDL_bool SDL_IME_Init(); +extern void SDL_IME_Quit(); +extern void SDL_IME_SetFocus(SDL_bool focused); +extern void SDL_IME_Reset(); +extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); +extern void SDL_IME_UpdateTextRect(SDL_Rect *rect); +extern void SDL_IME_PumpEvents(); + +#endif /* _SDL_ime_h */ diff --git a/Engine/lib/sdl/src/core/linux/SDL_udev.c b/Engine/lib/sdl/src/core/linux/SDL_udev.c index 099cc435e..ae78ddd68 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_udev.c +++ b/Engine/lib/sdl/src/core/linux/SDL_udev.c @@ -349,7 +349,9 @@ guess_device_class(struct udev_device *dev) } else if (test_bit(BTN_MOUSE, bitmask_key)) { devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */ } else if (test_bit(BTN_TOUCH, bitmask_key)) { - ; /* ID_INPUT_TOUCHSCREEN */ + /* TODO: better determining between touchscreen and multitouch touchpad, + see https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-input_id.c */ + devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; /* ID_INPUT_TOUCHSCREEN */ } if (test_bit(BTN_TRIGGER, bitmask_key) || @@ -411,6 +413,11 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev) if (val != NULL && SDL_strcmp(val, "1") == 0 ) { devclass |= SDL_UDEV_DEVICE_MOUSE; } + + val = _this->udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"); + if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; + } /* The undocumented rule is: - All devices with keys get ID_INPUT_KEY diff --git a/Engine/lib/sdl/src/core/linux/SDL_udev.h b/Engine/lib/sdl/src/core/linux/SDL_udev.h index 2e4434e62..9ffbb3252 100644 --- a/Engine/lib/sdl/src/core/linux/SDL_udev.h +++ b/Engine/lib/sdl/src/core/linux/SDL_udev.h @@ -42,17 +42,19 @@ typedef enum { - SDL_UDEV_DEVICEADDED = 0x0001, + SDL_UDEV_DEVICEADDED = 1, SDL_UDEV_DEVICEREMOVED } SDL_UDEV_deviceevent; /* A device can be any combination of these classes */ typedef enum { + SDL_UDEV_DEVICE_UNKNOWN = 0x0000, SDL_UDEV_DEVICE_MOUSE = 0x0001, SDL_UDEV_DEVICE_KEYBOARD = 0x0002, SDL_UDEV_DEVICE_JOYSTICK = 0x0004, - SDL_UDEV_DEVICE_SOUND = 0x0008 + SDL_UDEV_DEVICE_SOUND = 0x0008, + SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010 } SDL_UDEV_deviceclass; typedef void (*SDL_UDEV_Callback)(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath); diff --git a/Engine/lib/sdl/src/core/windows/SDL_windows.c b/Engine/lib/sdl/src/core/windows/SDL_windows.c index bc4afe0aa..6433fe26f 100644 --- a/Engine/lib/sdl/src/core/windows/SDL_windows.c +++ b/Engine/lib/sdl/src/core/windows/SDL_windows.c @@ -124,6 +124,84 @@ BOOL WIN_IsWindowsVistaOrGreater() #endif } +/* +WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's +longer. However, since WinXP, you can use the WAVExxxCAPS2 structure, which +will give you a name GUID. The full name is in the Windows Registry under +that GUID, located here: HKLM\System\CurrentControlSet\Control\MediaCategories + +Note that drivers can report GUID_NULL for the name GUID, in which case, +Windows makes a best effort to fill in those 31 bytes in the usual place. +This info summarized from MSDN: + +http://web.archive.org/web/20131027093034/http://msdn.microsoft.com/en-us/library/windows/hardware/ff536382(v=vs.85).aspx + +Always look this up in the registry if possible, because the strings are +different! At least on Win10, I see "Yeti Stereo Microphone" in the +Registry, and a unhelpful "Microphone(Yeti Stereo Microph" in winmm. Sigh. + +(Also, DirectSound shouldn't be limited to 32 chars, but its device enum +has the same problem.) +*/ +char * +WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid) +{ +#if __WINRT__ + return WIN_StringToUTF8(name); /* No registry access on WinRT/UWP, go with what we've got. */ +#else + static const GUID nullguid = { 0 }; + const unsigned char *ptr; + char keystr[128]; + WCHAR *strw = NULL; + SDL_bool rc; + HKEY hkey; + DWORD len = 0; + char *retval = NULL; + + if (SDL_memcmp(guid, &nullguid, sizeof (*guid)) == 0) { + return WIN_StringToUTF8(name); /* No GUID, go with what we've got. */ + } + + ptr = (const unsigned char *) guid; + SDL_snprintf(keystr, sizeof (keystr), + "System\\CurrentControlSet\\Control\\MediaCategories\\{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + ptr[3], ptr[2], ptr[1], ptr[0], ptr[5], ptr[4], ptr[7], ptr[6], + ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]); + + strw = WIN_UTF8ToString(keystr); + rc = (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strw, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS); + SDL_free(strw); + if (!rc) { + return WIN_StringToUTF8(name); /* oh well. */ + } + + rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, NULL, &len) == ERROR_SUCCESS); + if (!rc) { + RegCloseKey(hkey); + return WIN_StringToUTF8(name); /* oh well. */ + } + + strw = (WCHAR *) SDL_malloc(len + sizeof (WCHAR)); + if (!strw) { + RegCloseKey(hkey); + return WIN_StringToUTF8(name); /* oh well. */ + } + + rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, (LPBYTE) strw, &len) == ERROR_SUCCESS); + RegCloseKey(hkey); + if (!rc) { + SDL_free(strw); + return WIN_StringToUTF8(name); /* oh well. */ + } + + strw[len / 2] = 0; /* make sure it's null-terminated. */ + + retval = WIN_StringToUTF8(strw); + SDL_free(strw); + return retval ? retval : WIN_StringToUTF8(name); +#endif /* if __WINRT__ / else */ +} + #endif /* __WIN32__ || __WINRT__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/core/windows/SDL_windows.h b/Engine/lib/sdl/src/core/windows/SDL_windows.h index 0c99b03d4..0f67e4be5 100644 --- a/Engine/lib/sdl/src/core/windows/SDL_windows.h +++ b/Engine/lib/sdl/src/core/windows/SDL_windows.h @@ -59,6 +59,9 @@ extern void WIN_CoUninitialize(void); /* Returns SDL_TRUE if we're running on Windows Vista and newer */ extern BOOL WIN_IsWindowsVistaOrGreater(); +/* You need to SDL_free() the result of this call. */ +extern char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid); + #endif /* _INCLUDED_WINDOWS_H */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.cpp b/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.cpp index 5ab2ef9a2..e4ffadaad 100644 --- a/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -254,6 +254,18 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) CoreApplication::Exiting += ref new EventHandler(this, &SDL_WinRTApp::OnExiting); + +#if NTDDI_VERSION >= NTDDI_WIN10 + /* HACK ALERT! Xbox One doesn't seem to detect gamepads unless something + gets registered to receive Win10's Windows.Gaming.Input.Gamepad.GamepadAdded + events. We'll register an event handler for these events here, to make + sure that gamepad detection works later on, if requested. + */ + Windows::Gaming::Input::Gamepad::GamepadAdded += + ref new Windows::Foundation::EventHandler( + this, &SDL_WinRTApp::OnGamepadAdded + ); +#endif } #if NTDDI_VERSION > NTDDI_WIN8 @@ -810,11 +822,8 @@ static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args) SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK); SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK); - const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON); - if (hint) { - if (*hint == '1') { - args->Handled = true; - } + if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) { + args->Handled = true; } } @@ -832,3 +841,15 @@ void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone: } #endif +#if NTDDI_VERSION >= NTDDI_WIN10 +void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad) +{ + /* HACK ALERT: Nothing needs to be done here, as this method currently + only exists to allow something to be registered with Win10's + GamepadAdded event, an operation that seems to be necessary to get + Xinput-based detection to work on Xbox One. + */ +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.h b/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.h index 0b69c2bb9..4b48115f0 100644 --- a/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/Engine/lib/sdl/src/core/winrt/SDL_winrtapp_direct3d.h @@ -80,6 +80,10 @@ protected: void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args); #endif +#if NTDDI_VERSION >= NTDDI_WIN10 + void OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad); +#endif + private: bool m_windowClosed; bool m_windowVisible; diff --git a/Engine/lib/sdl/src/dynapi/SDL_dynapi.c b/Engine/lib/sdl/src/dynapi/SDL_dynapi.c index 1411f8c93..c26baf379 100644 --- a/Engine/lib/sdl/src/dynapi/SDL_dynapi.c +++ b/Engine/lib/sdl/src/dynapi/SDL_dynapi.c @@ -293,7 +293,7 @@ SDL_InitDynamicAPI(void) * SDL_CreateThread() would also call this function before building the * new thread). */ - static volatile SDL_bool already_initialized = SDL_FALSE; + static SDL_bool already_initialized = SDL_FALSE; /* SDL_AtomicLock calls SDL mutex functions to emulate if SDL_ATOMIC_DISABLED, which we can't do here, so in such a diff --git a/Engine/lib/sdl/src/dynapi/SDL_dynapi.h b/Engine/lib/sdl/src/dynapi/SDL_dynapi.h index 5faac2194..5e78338f2 100644 --- a/Engine/lib/sdl/src/dynapi/SDL_dynapi.h +++ b/Engine/lib/sdl/src/dynapi/SDL_dynapi.h @@ -43,9 +43,15 @@ #include "TargetConditionals.h" #endif -#if TARGET_OS_IPHONE || __native_client__ || __EMSCRIPTEN__ /* probably not useful on iOS, NACL or Emscripten. */ +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE /* probably not useful on iOS. */ #define SDL_DYNAMIC_API 0 -#elif SDL_BUILDING_WINRT /* probaly not useful on WinRT, given current .dll loading restrictions */ +#elif defined(__native_client__) && __native_client__ /* probably not useful on NACL. */ +#define SDL_DYNAMIC_API 0 +#elif defined(__EMSCRIPTEN__) && __EMSCRIPTEN__ /* probably not useful on Emscripten. */ +#define SDL_DYNAMIC_API 0 +#elif defined(SDL_BUILDING_WINRT) && SDL_BUILDING_WINRT /* probably not useful on WinRT, given current .dll loading restrictions */ +#define SDL_DYNAMIC_API 0 +#elif defined(__PSP__) && __PSP__ #define SDL_DYNAMIC_API 0 #elif defined(__clang_analyzer__) #define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */ diff --git a/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h b/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h index c9ebfffe2..9541611ce 100644 --- a/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h +++ b/Engine/lib/sdl/src/dynapi/SDL_dynapi_overrides.h @@ -445,6 +445,8 @@ #define SDL_iconv_close SDL_iconv_close_REAL #define SDL_iconv SDL_iconv_REAL #define SDL_iconv_string SDL_iconv_string_REAL +#define SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat_REAL +#define SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom_REAL #define SDL_CreateRGBSurface SDL_CreateRGBSurface_REAL #define SDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom_REAL #define SDL_FreeSurface SDL_FreeSurface_REAL @@ -597,3 +599,16 @@ #define SDL_JoystickCurrentPowerLevel SDL_JoystickCurrentPowerLevel_REAL #define SDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID_REAL #define SDL_JoystickFromInstanceID SDL_JoystickFromInstanceID_REAL +#define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL +#define SDL_GetWindowBordersSize SDL_GetWindowBordersSize_REAL +#define SDL_SetWindowOpacity SDL_SetWindowOpacity_REAL +#define SDL_GetWindowOpacity SDL_GetWindowOpacity_REAL +#define SDL_SetWindowInputFocus SDL_SetWindowInputFocus_REAL +#define SDL_SetWindowModalFor SDL_SetWindowModalFor_REAL +#define SDL_RenderSetIntegerScale SDL_RenderSetIntegerScale_REAL +#define SDL_RenderGetIntegerScale SDL_RenderGetIntegerScale_REAL +#define SDL_DequeueAudio SDL_DequeueAudio_REAL +#define SDL_SetWindowResizable SDL_SetWindowResizable_REAL +#define SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat_REAL +#define SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom_REAL +#define SDL_GetHintBoolean SDL_GetHintBoolean_REAL diff --git a/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h b/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h index 3f11a25f9..a08835b26 100644 --- a/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h +++ b/Engine/lib/sdl/src/dynapi/SDL_dynapi_procs.h @@ -631,3 +631,16 @@ SDL_DYNAPI_PROC(int,SDL_GetDisplayDPI,(int a, float *b, float *c, float *d),(a,b SDL_DYNAPI_PROC(SDL_JoystickPowerLevel,SDL_JoystickCurrentPowerLevel,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(SDL_GameController*,SDL_GameControllerFromInstanceID,(SDL_JoystickID a),(a),return) SDL_DYNAPI_PROC(SDL_Joystick*,SDL_JoystickFromInstanceID,(SDL_JoystickID a),(a),return) +SDL_DYNAPI_PROC(int,SDL_GetDisplayUsableBounds,(int a, SDL_Rect *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GetWindowBordersSize,(SDL_Window *a, int *b, int *c, int *d, int *e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(int,SDL_SetWindowOpacity,(SDL_Window *a, float b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GetWindowOpacity,(SDL_Window *a, float *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_SetWindowInputFocus,(SDL_Window *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_SetWindowModalFor,(SDL_Window *a, SDL_Window *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_RenderSetIntegerScale,(SDL_Renderer *a, SDL_bool b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_RenderGetIntegerScale,(SDL_Renderer *a),(a),return) +SDL_DYNAPI_PROC(Uint32,SDL_DequeueAudio,(SDL_AudioDeviceID a, void *b, Uint32 c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_SetWindowResizable,(SDL_Window *a, SDL_bool b),(a,b),) +SDL_DYNAPI_PROC(SDL_Surface*,SDL_CreateRGBSurfaceWithFormat,(Uint32 a, int b, int c, int d, Uint32 e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(SDL_Surface*,SDL_CreateRGBSurfaceWithFormatFrom,(void *a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GetHintBoolean,(const char *a, SDL_bool b),(a,b),return) diff --git a/Engine/lib/sdl/src/events/SDL_dropevents.c b/Engine/lib/sdl/src/events/SDL_dropevents.c index 8f4405efa..49b07d9a6 100644 --- a/Engine/lib/sdl/src/events/SDL_dropevents.c +++ b/Engine/lib/sdl/src/events/SDL_dropevents.c @@ -26,21 +26,73 @@ #include "SDL_events_c.h" #include "SDL_dropevents_c.h" +#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */ -int -SDL_SendDropFile(const char *file) + +static int +SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data) { - int posted; + static SDL_bool app_is_dropping = SDL_FALSE; + int posted = 0; /* Post the event, if desired */ - posted = 0; - if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) { + if (SDL_GetEventState(evtype) == SDL_ENABLE) { + const SDL_bool need_begin = window ? !window->is_dropping : !app_is_dropping; SDL_Event event; - event.type = SDL_DROPFILE; - event.drop.file = SDL_strdup(file); + + if (need_begin) { + SDL_zero(event); + event.type = SDL_DROPBEGIN; + + if (window) { + event.drop.windowID = window->id; + } + + posted = (SDL_PushEvent(&event) > 0); + if (!posted) { + return 0; + } + if (window) { + window->is_dropping = SDL_TRUE; + } else { + app_is_dropping = SDL_TRUE; + } + } + + SDL_zero(event); + event.type = evtype; + event.drop.file = data ? SDL_strdup(data) : NULL; + event.drop.windowID = window ? window->id : 0; posted = (SDL_PushEvent(&event) > 0); + + if (posted && (evtype == SDL_DROPCOMPLETE)) { + if (window) { + window->is_dropping = SDL_FALSE; + } else { + app_is_dropping = SDL_FALSE; + } + } } - return (posted); + return posted; } +int +SDL_SendDropFile(SDL_Window *window, const char *file) +{ + return SDL_SendDrop(window, SDL_DROPFILE, file); +} + +int +SDL_SendDropText(SDL_Window *window, const char *text) +{ + return SDL_SendDrop(window, SDL_DROPTEXT, text); +} + +int +SDL_SendDropComplete(SDL_Window *window) +{ + return SDL_SendDrop(window, SDL_DROPCOMPLETE, NULL); +} + + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/events/SDL_dropevents_c.h b/Engine/lib/sdl/src/events/SDL_dropevents_c.h index a60e089f3..a7adb8560 100644 --- a/Engine/lib/sdl/src/events/SDL_dropevents_c.h +++ b/Engine/lib/sdl/src/events/SDL_dropevents_c.h @@ -23,7 +23,9 @@ #ifndef _SDL_dropevents_c_h #define _SDL_dropevents_c_h -extern int SDL_SendDropFile(const char *file); +extern int SDL_SendDropFile(SDL_Window *window, const char *file); +extern int SDL_SendDropText(SDL_Window *window, const char *text); +extern int SDL_SendDropComplete(SDL_Window *window); #endif /* _SDL_dropevents_c_h */ diff --git a/Engine/lib/sdl/src/events/SDL_events.c b/Engine/lib/sdl/src/events/SDL_events.c index ffd103824..2f5b0af29 100644 --- a/Engine/lib/sdl/src/events/SDL_events.c +++ b/Engine/lib/sdl/src/events/SDL_events.c @@ -73,15 +73,15 @@ typedef struct _SDL_SysWMEntry static struct { SDL_mutex *lock; - volatile SDL_bool active; - volatile int count; - volatile int max_events_seen; + SDL_atomic_t active; + SDL_atomic_t count; + int max_events_seen; SDL_EventEntry *head; SDL_EventEntry *tail; SDL_EventEntry *free; SDL_SysWMEntry *wmmsg_used; SDL_SysWMEntry *wmmsg_free; -} SDL_EventQ = { NULL, SDL_TRUE, 0, 0, NULL, NULL, NULL, NULL, NULL }; +} SDL_EventQ = { NULL, { 1 }, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }; /* Public functions */ @@ -98,7 +98,7 @@ SDL_StopEventLoop(void) SDL_LockMutex(SDL_EventQ.lock); } - SDL_EventQ.active = SDL_FALSE; + SDL_AtomicSet(&SDL_EventQ.active, 0); if (report && SDL_atoi(report)) { SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n", @@ -127,7 +127,7 @@ SDL_StopEventLoop(void) wmmsg = next; } - SDL_EventQ.count = 0; + SDL_AtomicSet(&SDL_EventQ.count, 0); SDL_EventQ.max_events_seen = 0; SDL_EventQ.head = NULL; SDL_EventQ.tail = NULL; @@ -171,7 +171,7 @@ SDL_StartEventLoop(void) SDL_EventQ.lock = SDL_CreateMutex(); } if (SDL_EventQ.lock == NULL) { - return (-1); + return -1; } #endif /* !SDL_THREADS_DISABLED */ @@ -180,9 +180,9 @@ SDL_StartEventLoop(void) SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE); - SDL_EventQ.active = SDL_TRUE; + SDL_AtomicSet(&SDL_EventQ.active, 1); - return (0); + return 0; } @@ -191,9 +191,11 @@ static int SDL_AddEvent(SDL_Event * event) { SDL_EventEntry *entry; + const int initial_count = SDL_AtomicGet(&SDL_EventQ.count); + int final_count; - if (SDL_EventQ.count >= SDL_MAX_QUEUED_EVENTS) { - SDL_SetError("Event queue is full (%d events)", SDL_EventQ.count); + if (initial_count >= SDL_MAX_QUEUED_EVENTS) { + SDL_SetError("Event queue is full (%d events)", initial_count); return 0; } @@ -225,10 +227,10 @@ SDL_AddEvent(SDL_Event * event) entry->prev = NULL; entry->next = NULL; } - ++SDL_EventQ.count; - if (SDL_EventQ.count > SDL_EventQ.max_events_seen) { - SDL_EventQ.max_events_seen = SDL_EventQ.count; + final_count = SDL_AtomicAdd(&SDL_EventQ.count, 1) + 1; + if (final_count > SDL_EventQ.max_events_seen) { + SDL_EventQ.max_events_seen = final_count; } return 1; @@ -256,8 +258,8 @@ SDL_CutEvent(SDL_EventEntry *entry) entry->next = SDL_EventQ.free; SDL_EventQ.free = entry; - SDL_assert(SDL_EventQ.count > 0); - --SDL_EventQ.count; + SDL_assert(SDL_AtomicGet(&SDL_EventQ.count) > 0); + SDL_AtomicAdd(&SDL_EventQ.count, -1); } /* Lock the event queue, take a peep at it, and unlock it */ @@ -268,7 +270,7 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, int i, used; /* Don't look after we've quit */ - if (!SDL_EventQ.active) { + if (!SDL_AtomicGet(&SDL_EventQ.active)) { /* We get a few spurious events at shutdown, so don't warn then */ if (action != SDL_ADDEVENT) { SDL_SetError("The event system has been shut down"); @@ -285,56 +287,54 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, } else { SDL_EventEntry *entry, *next; SDL_SysWMEntry *wmmsg, *wmmsg_next; - SDL_Event tmpevent; Uint32 type; - /* If 'events' is NULL, just see if they exist */ - if (events == NULL) { - action = SDL_PEEKEVENT; - numevents = 1; - events = &tmpevent; + if (action == SDL_GETEVENT) { + /* Clean out any used wmmsg data + FIXME: Do we want to retain the data for some period of time? + */ + for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) { + wmmsg_next = wmmsg->next; + wmmsg->next = SDL_EventQ.wmmsg_free; + SDL_EventQ.wmmsg_free = wmmsg; + } + SDL_EventQ.wmmsg_used = NULL; } - /* Clean out any used wmmsg data - FIXME: Do we want to retain the data for some period of time? - */ - for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) { - wmmsg_next = wmmsg->next; - wmmsg->next = SDL_EventQ.wmmsg_free; - SDL_EventQ.wmmsg_free = wmmsg; - } - SDL_EventQ.wmmsg_used = NULL; - - for (entry = SDL_EventQ.head; entry && used < numevents; entry = next) { + for (entry = SDL_EventQ.head; entry && (!events || used < numevents); entry = next) { next = entry->next; type = entry->event.type; if (minType <= type && type <= maxType) { - events[used] = entry->event; - if (entry->event.type == SDL_SYSWMEVENT) { - /* We need to copy the wmmsg somewhere safe. - For now we'll guarantee it's valid at least until - the next call to SDL_PeepEvents() - */ - if (SDL_EventQ.wmmsg_free) { - wmmsg = SDL_EventQ.wmmsg_free; - SDL_EventQ.wmmsg_free = wmmsg->next; - } else { - wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg)); + if (events) { + events[used] = entry->event; + if (entry->event.type == SDL_SYSWMEVENT) { + /* We need to copy the wmmsg somewhere safe. + For now we'll guarantee it's valid at least until + the next call to SDL_PeepEvents() + */ + if (SDL_EventQ.wmmsg_free) { + wmmsg = SDL_EventQ.wmmsg_free; + SDL_EventQ.wmmsg_free = wmmsg->next; + } else { + wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg)); + } + wmmsg->msg = *entry->event.syswm.msg; + wmmsg->next = SDL_EventQ.wmmsg_used; + SDL_EventQ.wmmsg_used = wmmsg; + events[used].syswm.msg = &wmmsg->msg; + } + + if (action == SDL_GETEVENT) { + SDL_CutEvent(entry); } - wmmsg->msg = *entry->event.syswm.msg; - wmmsg->next = SDL_EventQ.wmmsg_used; - SDL_EventQ.wmmsg_used = wmmsg; - events[used].syswm.msg = &wmmsg->msg; } ++used; - - if (action == SDL_GETEVENT) { - SDL_CutEvent(entry); - } } } } - SDL_UnlockMutex(SDL_EventQ.lock); + if (SDL_EventQ.lock) { + SDL_UnlockMutex(SDL_EventQ.lock); + } } else { return SDL_SetError("Couldn't lock event queue"); } @@ -363,7 +363,7 @@ void SDL_FlushEvents(Uint32 minType, Uint32 maxType) { /* Don't look after we've quit */ - if (!SDL_EventQ.active) { + if (!SDL_AtomicGet(&SDL_EventQ.active)) { return; } @@ -376,7 +376,7 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType) #endif /* Lock the event queue */ - if (SDL_LockMutex(SDL_EventQ.lock) == 0) { + if (SDL_EventQ.lock && SDL_LockMutex(SDL_EventQ.lock) == 0) { SDL_EventEntry *entry, *next; Uint32 type; for (entry = SDL_EventQ.head; entry; entry = next) { @@ -437,8 +437,6 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout) switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) { case -1: return 0; - case 1: - return 1; case 0: if (timeout == 0) { /* Polling and no events, just return */ @@ -450,6 +448,9 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout) } SDL_Delay(10); break; + default: + /* Has events */ + return 1; } } } diff --git a/Engine/lib/sdl/src/events/SDL_gesture.c b/Engine/lib/sdl/src/events/SDL_gesture.c index 66def4429..43914202c 100644 --- a/Engine/lib/sdl/src/events/SDL_gesture.c +++ b/Engine/lib/sdl/src/events/SDL_gesture.c @@ -21,7 +21,7 @@ #include "../SDL_internal.h" -/* General mouse handling code for SDL */ +/* General gesture handling code for SDL */ #include "SDL_events.h" #include "SDL_endian.h" diff --git a/Engine/lib/sdl/src/events/SDL_mouse.c b/Engine/lib/sdl/src/events/SDL_mouse.c index 7793de870..4236a9901 100644 --- a/Engine/lib/sdl/src/events/SDL_mouse.c +++ b/Engine/lib/sdl/src/events/SDL_mouse.c @@ -322,15 +322,13 @@ static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button) return &mouse->clickstate[button]; } -int -SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button) +static int +SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; Uint32 type; Uint32 buttonstate = mouse->buttonstate; - SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button); - Uint8 click_count; /* Figure out which event to perform */ switch (state) { @@ -358,25 +356,28 @@ SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 } mouse->buttonstate = buttonstate; - if (clickstate) { - if (state == SDL_PRESSED) { - Uint32 now = SDL_GetTicks(); + if (clicks < 0) { + SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button); + if (clickstate) { + if (state == SDL_PRESSED) { + Uint32 now = SDL_GetTicks(); - if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) || - SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius || - SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) { - clickstate->click_count = 0; - } - clickstate->last_timestamp = now; - clickstate->last_x = mouse->x; - clickstate->last_y = mouse->y; - if (clickstate->click_count < 255) { - ++clickstate->click_count; + if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) || + SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius || + SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) { + clickstate->click_count = 0; + } + clickstate->last_timestamp = now; + clickstate->last_x = mouse->x; + clickstate->last_y = mouse->y; + if (clickstate->click_count < 255) { + ++clickstate->click_count; + } } + clicks = clickstate->click_count; + } else { + clicks = 1; } - click_count = clickstate->click_count; - } else { - click_count = 1; } /* Post the event, if desired */ @@ -388,7 +389,7 @@ SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 event.button.which = mouseID; event.button.state = state; event.button.button = button; - event.button.clicks = click_count; + event.button.clicks = (Uint8) SDL_min(clicks, 255); event.button.x = mouse->x; event.button.y = mouse->y; posted = (SDL_PushEvent(&event) > 0); @@ -398,10 +399,23 @@ SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 if (window && state == SDL_RELEASED) { SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate); } - + return posted; } +int +SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) +{ + clicks = SDL_max(clicks, 0); + return SDL_PrivateSendMouseButton(window, mouseID, state, button, clicks); +} + +int +SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button) +{ + return SDL_PrivateSendMouseButton(window, mouseID, state, button, -1); +} + int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction) { @@ -550,21 +564,11 @@ SDL_WarpMouseGlobal(int x, int y) static SDL_bool ShouldUseRelativeModeWarp(SDL_Mouse *mouse) { - const char *hint; - if (!mouse->SetRelativeMouseMode) { return SDL_TRUE; } - hint = SDL_GetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP); - if (hint) { - if (*hint == '0') { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - return SDL_FALSE; + return SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE); } int diff --git a/Engine/lib/sdl/src/events/SDL_mouse_c.h b/Engine/lib/sdl/src/events/SDL_mouse_c.h index 03aca0a5c..06dc88701 100644 --- a/Engine/lib/sdl/src/events/SDL_mouse_c.h +++ b/Engine/lib/sdl/src/events/SDL_mouse_c.h @@ -119,6 +119,9 @@ extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int rel /* Send a mouse button event */ extern int SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button); +/* Send a mouse button event with a click count */ +extern int SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks); + /* Send a mouse wheel event */ extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction); diff --git a/Engine/lib/sdl/src/events/SDL_quit.c b/Engine/lib/sdl/src/events/SDL_quit.c index 5b7105ef8..3cb6b3d4f 100644 --- a/Engine/lib/sdl/src/events/SDL_quit.c +++ b/Engine/lib/sdl/src/events/SDL_quit.c @@ -91,9 +91,7 @@ SDL_QuitInit_Internal(void) int SDL_QuitInit(void) { - const char *hint = SDL_GetHint(SDL_HINT_NO_SIGNAL_HANDLERS); - disable_signals = hint && (SDL_atoi(hint) == 1); - if (!disable_signals) { + if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) { return SDL_QuitInit_Internal(); } return 0; diff --git a/Engine/lib/sdl/src/events/SDL_windowevents.c b/Engine/lib/sdl/src/events/SDL_windowevents.c index 785ea4e0c..b45015bd0 100644 --- a/Engine/lib/sdl/src/events/SDL_windowevents.c +++ b/Engine/lib/sdl/src/events/SDL_windowevents.c @@ -70,6 +70,20 @@ RemovePendingMoveEvents(void * userdata, SDL_Event *event) return 1; } +static int +RemovePendingExposedEvents(void * userdata, SDL_Event *event) +{ + SDL_Event *new_event = (SDL_Event *)userdata; + + if (event->type == SDL_WINDOWEVENT && + event->window.event == SDL_WINDOWEVENT_EXPOSED && + event->window.windowID == new_event->window.windowID) { + /* We're about to post a new exposed event, drop the old one */ + return 0; + } + return 1; +} + int SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, int data2) @@ -195,7 +209,9 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, if (windowevent == SDL_WINDOWEVENT_MOVED) { SDL_FilterEvents(RemovePendingMoveEvents, &event); } - + if (windowevent == SDL_WINDOWEVENT_EXPOSED) { + SDL_FilterEvents(RemovePendingExposedEvents, &event); + } posted = (SDL_PushEvent(&event) > 0); } diff --git a/Engine/lib/sdl/src/events/scancodes_linux.h b/Engine/lib/sdl/src/events/scancodes_linux.h index 8db37df5b..e197ee3fe 100644 --- a/Engine/lib/sdl/src/events/scancodes_linux.h +++ b/Engine/lib/sdl/src/events/scancodes_linux.h @@ -111,7 +111,7 @@ static SDL_Scancode const linux_scancode_table[] = { /* 82 */ SDL_SCANCODE_KP_0, /* 83 */ SDL_SCANCODE_KP_PERIOD, 0, - /* 85 */ SDL_SCANCODE_UNKNOWN, /* KEY_ZENKAKUHANKAKU */ + /* 85 */ SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU */ /* 86 */ SDL_SCANCODE_NONUSBACKSLASH, /* KEY_102ND */ /* 87 */ SDL_SCANCODE_F11, /* 88 */ SDL_SCANCODE_F12, @@ -153,7 +153,7 @@ static SDL_Scancode const linux_scancode_table[] = { /* 124 */ SDL_SCANCODE_INTERNATIONAL3, /* KEY_YEN */ /* 125 */ SDL_SCANCODE_LGUI, /* 126 */ SDL_SCANCODE_RGUI, - /* 127 */ SDL_SCANCODE_UNKNOWN, /* KEY_COMPOSE */ + /* 127 */ SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE */ /* 128 */ SDL_SCANCODE_STOP, /* 129 */ SDL_SCANCODE_AGAIN, /* 130 */ SDL_SCANCODE_UNKNOWN, /* KEY_PROPS */ @@ -174,9 +174,9 @@ static SDL_Scancode const linux_scancode_table[] = { /* 145 */ SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE */ /* 146 */ SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE */ /* 147 */ SDL_SCANCODE_UNKNOWN, /* KEY_XFER */ - /* 148 */ SDL_SCANCODE_UNKNOWN, /* KEY_PROG1 */ - /* 149 */ SDL_SCANCODE_UNKNOWN, /* KEY_PROG2 */ - /* 150 */ SDL_SCANCODE_UNKNOWN, /* KEY_WWW */ + /* 148 */ SDL_SCANCODE_APP1, /* KEY_PROG1 */ + /* 149 */ SDL_SCANCODE_APP2, /* KEY_PROG2 */ + /* 150 */ SDL_SCANCODE_WWW, /* KEY_WWW */ /* 151 */ SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS */ /* 152 */ SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE */ /* 153 */ SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION */ @@ -192,7 +192,7 @@ static SDL_Scancode const linux_scancode_table[] = { /* 163 */ SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG */ /* 164 */ SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE */ /* 165 */ SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG */ - /* 166 */ SDL_SCANCODE_UNKNOWN, /* KEY_STOPCD */ + /* 166 */ SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD */ /* 167 */ SDL_SCANCODE_UNKNOWN, /* KEY_RECORD */ /* 168 */ SDL_SCANCODE_UNKNOWN, /* KEY_REWIND */ /* 169 */ SDL_SCANCODE_UNKNOWN, /* KEY_PHONE */ @@ -221,7 +221,7 @@ static SDL_Scancode const linux_scancode_table[] = { /* 192 */ SDL_SCANCODE_F22, /* 193 */ SDL_SCANCODE_F23, /* 194 */ SDL_SCANCODE_F24, - 0, 0, 0, 0, + 0, 0, 0, 0, 0, /* 200 */ SDL_SCANCODE_UNKNOWN, /* KEY_PLAYCD */ /* 201 */ SDL_SCANCODE_UNKNOWN, /* KEY_PAUSECD */ /* 202 */ SDL_SCANCODE_UNKNOWN, /* KEY_PROG3 */ diff --git a/Engine/lib/sdl/src/events/scancodes_xfree86.h b/Engine/lib/sdl/src/events/scancodes_xfree86.h index 29d9ef944..804196ca4 100644 --- a/Engine/lib/sdl/src/events/scancodes_xfree86.h +++ b/Engine/lib/sdl/src/events/scancodes_xfree86.h @@ -418,4 +418,89 @@ static const SDL_Scancode xfree86_scancode_table2[] = { /* 238 */ SDL_SCANCODE_UNKNOWN, /* XF86WLAN */ }; +/* Xvnc / Xtightvnc scancodes from xmodmap -pk */ +static const SDL_Scancode xvnc_scancode_table[] = { + /* 0 */ SDL_SCANCODE_LCTRL, + /* 1 */ SDL_SCANCODE_RCTRL, + /* 2 */ SDL_SCANCODE_LSHIFT, + /* 3 */ SDL_SCANCODE_RSHIFT, + /* 4 */ SDL_SCANCODE_UNKNOWN, /* Meta_L */ + /* 5 */ SDL_SCANCODE_UNKNOWN, /* Meta_R */ + /* 6 */ SDL_SCANCODE_LALT, + /* 7 */ SDL_SCANCODE_RALT, + /* 8 */ SDL_SCANCODE_SPACE, + /* 9 */ SDL_SCANCODE_0, + /* 10 */ SDL_SCANCODE_1, + /* 11 */ SDL_SCANCODE_2, + /* 12 */ SDL_SCANCODE_3, + /* 13 */ SDL_SCANCODE_4, + /* 14 */ SDL_SCANCODE_5, + /* 15 */ SDL_SCANCODE_6, + /* 16 */ SDL_SCANCODE_7, + /* 17 */ SDL_SCANCODE_8, + /* 18 */ SDL_SCANCODE_9, + /* 19 */ SDL_SCANCODE_MINUS, + /* 20 */ SDL_SCANCODE_EQUALS, + /* 21 */ SDL_SCANCODE_LEFTBRACKET, + /* 22 */ SDL_SCANCODE_RIGHTBRACKET, + /* 23 */ SDL_SCANCODE_SEMICOLON, + /* 24 */ SDL_SCANCODE_APOSTROPHE, + /* 25 */ SDL_SCANCODE_GRAVE, + /* 26 */ SDL_SCANCODE_COMMA, + /* 27 */ SDL_SCANCODE_PERIOD, + /* 28 */ SDL_SCANCODE_SLASH, + /* 29 */ SDL_SCANCODE_BACKSLASH, + /* 30 */ SDL_SCANCODE_A, + /* 31 */ SDL_SCANCODE_B, + /* 32 */ SDL_SCANCODE_C, + /* 33 */ SDL_SCANCODE_D, + /* 34 */ SDL_SCANCODE_E, + /* 35 */ SDL_SCANCODE_F, + /* 36 */ SDL_SCANCODE_G, + /* 37 */ SDL_SCANCODE_H, + /* 38 */ SDL_SCANCODE_I, + /* 39 */ SDL_SCANCODE_J, + /* 40 */ SDL_SCANCODE_K, + /* 41 */ SDL_SCANCODE_L, + /* 42 */ SDL_SCANCODE_M, + /* 43 */ SDL_SCANCODE_N, + /* 44 */ SDL_SCANCODE_O, + /* 45 */ SDL_SCANCODE_P, + /* 46 */ SDL_SCANCODE_Q, + /* 47 */ SDL_SCANCODE_R, + /* 48 */ SDL_SCANCODE_S, + /* 49 */ SDL_SCANCODE_T, + /* 50 */ SDL_SCANCODE_U, + /* 51 */ SDL_SCANCODE_V, + /* 52 */ SDL_SCANCODE_W, + /* 53 */ SDL_SCANCODE_X, + /* 54 */ SDL_SCANCODE_Y, + /* 55 */ SDL_SCANCODE_Z, + /* 56 */ SDL_SCANCODE_BACKSPACE, + /* 57 */ SDL_SCANCODE_RETURN, + /* 58 */ SDL_SCANCODE_TAB, + /* 59 */ SDL_SCANCODE_ESCAPE, + /* 60 */ SDL_SCANCODE_DELETE, + /* 61 */ SDL_SCANCODE_HOME, + /* 62 */ SDL_SCANCODE_END, + /* 63 */ SDL_SCANCODE_PAGEUP, + /* 64 */ SDL_SCANCODE_PAGEDOWN, + /* 65 */ SDL_SCANCODE_UP, + /* 66 */ SDL_SCANCODE_DOWN, + /* 67 */ SDL_SCANCODE_LEFT, + /* 68 */ SDL_SCANCODE_RIGHT, + /* 69 */ SDL_SCANCODE_F1, + /* 70 */ SDL_SCANCODE_F2, + /* 71 */ SDL_SCANCODE_F3, + /* 72 */ SDL_SCANCODE_F4, + /* 73 */ SDL_SCANCODE_F5, + /* 74 */ SDL_SCANCODE_F6, + /* 75 */ SDL_SCANCODE_F7, + /* 76 */ SDL_SCANCODE_F8, + /* 77 */ SDL_SCANCODE_F9, + /* 78 */ SDL_SCANCODE_F10, + /* 79 */ SDL_SCANCODE_F11, + /* 80 */ SDL_SCANCODE_F12, +}; + /* *INDENT-ON* */ diff --git a/Engine/lib/sdl/src/filesystem/dummy/SDL_sysfilesystem.c b/Engine/lib/sdl/src/filesystem/dummy/SDL_sysfilesystem.c index 45273f24a..2570f4c75 100644 --- a/Engine/lib/sdl/src/filesystem/dummy/SDL_sysfilesystem.c +++ b/Engine/lib/sdl/src/filesystem/dummy/SDL_sysfilesystem.c @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_FILESYSTEM_DUMMY +#if defined(SDL_FILESYSTEM_DUMMY) || defined(SDL_FILESYSTEM_DISABLED) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* System dependent filesystem routines */ @@ -42,6 +42,6 @@ SDL_GetPrefPath(const char *org, const char *app) return NULL; } -#endif /* SDL_FILESYSTEM_DUMMY */ +#endif /* SDL_FILESYSTEM_DUMMY || SDL_FILESYSTEM_DISABLED */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/filesystem/unix/SDL_sysfilesystem.c b/Engine/lib/sdl/src/filesystem/unix/SDL_sysfilesystem.c index fa034a456..bd2e84cd1 100644 --- a/Engine/lib/sdl/src/filesystem/unix/SDL_sysfilesystem.c +++ b/Engine/lib/sdl/src/filesystem/unix/SDL_sysfilesystem.c @@ -33,7 +33,7 @@ #include #include -#ifdef __FREEBSD__ +#if defined(__FREEBSD__) || defined(__OPENBSD__) #include #endif @@ -90,7 +90,26 @@ SDL_GetBasePath(void) return NULL; } } -#elif defined(__SOLARIS__) +#endif +#if defined(__OPENBSD__) + char **retvalargs; + size_t len; + const int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; + if (sysctl(mib, 4, NULL, &len, NULL, 0) != -1) { + retvalargs = SDL_malloc(len); + if (!retvalargs) { + SDL_OutOfMemory(); + return NULL; + } + sysctl(mib, 4, retvalargs, &len, NULL, 0); + retval = SDL_malloc(PATH_MAX + 1); + if (retval) + realpath(retvalargs[0], retval); + + SDL_free(retvalargs); + } +#endif +#if defined(__SOLARIS__) const char *path = getexecname(); if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */ retval = SDL_strdup(path); diff --git a/Engine/lib/sdl/src/haptic/linux/SDL_syshaptic.c b/Engine/lib/sdl/src/haptic/linux/SDL_syshaptic.c index e8d785535..7bd966449 100644 --- a/Engine/lib/sdl/src/haptic/linux/SDL_syshaptic.c +++ b/Engine/lib/sdl/src/haptic/linux/SDL_syshaptic.c @@ -609,7 +609,7 @@ SDL_SYS_HapticQuit(void) /* Opened and not closed haptics are leaked, this is on purpose. * Close your haptic devices after usage. */ SDL_free(item->fname); - item->fname = NULL; + SDL_free(item); } #if SDL_USE_LIBUDEV @@ -690,7 +690,7 @@ SDL_SYS_ToDirection(Uint16 *dest, SDL_HapticDirection * src) else if (!src->dir[0]) *dest = (src->dir[1] >= 0 ? 0x8000 : 0); else { - float f = atan2(src->dir[1], src->dir[0]); /* Ideally we'd use fixed point math instead of floats... */ + float f = SDL_atan2(src->dir[1], src->dir[0]); /* Ideally we'd use fixed point math instead of floats... */ /* atan2 takes the parameters: Y-axis-value and X-axis-value (in that order) - Y-axis-value is the second coordinate (from center to SOUTH) diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c b/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c index c51470dd5..c81432c26 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c +++ b/Engine/lib/sdl/src/haptic/windows/SDL_dinputhaptic.c @@ -325,20 +325,12 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device /* Set data format. */ ret = IDirectInputDevice8_SetDataFormat(haptic->hwdata->device, - &c_dfDIJoystick2); + &SDL_c_dfDIJoystick2); if (FAILED(ret)) { DI_SetError("Setting data format", ret); goto acquire_err; } - /* Get number of axes. */ - ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device, - DI_DeviceObjectCallback, - haptic, DIDFT_AXIS); - if (FAILED(ret)) { - DI_SetError("Getting device axes", ret); - goto acquire_err; - } /* Acquire the device. */ ret = IDirectInputDevice8_Acquire(haptic->hwdata->device); @@ -348,6 +340,15 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device } } + /* Get number of axes. */ + ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device, + DI_DeviceObjectCallback, + haptic, DIDFT_AXIS); + if (FAILED(ret)) { + DI_SetError("Getting device axes", ret); + goto acquire_err; + } + /* Reset all actuators - just in case. */ ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, DISFFC_RESET); diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c index 0c038fb1b..c6bcba1f3 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c +++ b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic.c @@ -255,7 +255,7 @@ SDL_SYS_HapticQuit(void) for (hapticitem = SDL_haptics; hapticitem; hapticitem = hapticitem->next) { if ((hapticitem->hwdata->bXInputHaptic) && (hapticitem->hwdata->thread)) { /* we _have_ to stop the thread before we free the XInput DLL! */ - hapticitem->hwdata->stopThread = 1; + SDL_AtomicSet(&hapticitem->hwdata->stopThread, 1); SDL_WaitThread(hapticitem->hwdata->thread, NULL); hapticitem->hwdata->thread = NULL; } diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h index 89fdd2cb9..f34426442 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h +++ b/Engine/lib/sdl/src/haptic/windows/SDL_windowshaptic_c.h @@ -42,8 +42,8 @@ struct haptic_hwdata Uint8 userid; /* XInput userid index for this joystick */ SDL_Thread *thread; SDL_mutex *mutex; - volatile Uint32 stopTicks; - volatile int stopThread; + Uint32 stopTicks; + SDL_atomic_t stopThread; }; diff --git a/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c b/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c index a46ae5f97..afbab456a 100644 --- a/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c +++ b/Engine/lib/sdl/src/haptic/windows/SDL_xinputhaptic.c @@ -33,6 +33,7 @@ #include "SDL_xinputhaptic_c.h" #include "../../core/windows/SDL_xinput.h" #include "../../joystick/windows/SDL_windowsjoystick_c.h" +#include "../../thread/SDL_systhread.h" /* * Internal stuff. @@ -43,8 +44,7 @@ static SDL_bool loaded_xinput = SDL_FALSE; int SDL_XINPUT_HapticInit(void) { - const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED); - if (!env || SDL_atoi(env)) { + if (SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE)) { loaded_xinput = (WIN_LoadXInputDLL() == 0); } @@ -146,7 +146,7 @@ SDL_RunXInputHaptic(void *arg) { struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg; - while (!hwdata->stopThread) { + while (!SDL_AtomicGet(&hwdata->stopThread)) { SDL_Delay(50); SDL_LockMutex(hwdata->mutex); /* If we're currently running and need to stop... */ @@ -205,17 +205,8 @@ SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid) } SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", (int)userid); + haptic->hwdata->thread = SDL_CreateThreadInternal(SDL_RunXInputHaptic, threadName, 64 * 1024, haptic->hwdata); -#if defined(__WIN32__) && !defined(HAVE_LIBC) /* !!! FIXME: this is nasty. */ -#undef SDL_CreateThread -#if SDL_DYNAMIC_API - haptic->hwdata->thread = SDL_CreateThread_REAL(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL); -#else - haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL); -#endif -#else - haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata); -#endif if (haptic->hwdata->thread == NULL) { SDL_DestroyMutex(haptic->hwdata->mutex); SDL_free(haptic->effects); @@ -261,7 +252,7 @@ SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) void SDL_XINPUT_HapticClose(SDL_Haptic * haptic) { - haptic->hwdata->stopThread = 1; + SDL_AtomicSet(&haptic->hwdata->stopThread, 1); SDL_WaitThread(haptic->hwdata->thread, NULL); SDL_DestroyMutex(haptic->hwdata->mutex); } diff --git a/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c b/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c index 0fd1ef4a7..1d3a4c203 100644 --- a/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c +++ b/Engine/lib/sdl/src/joystick/SDL_gamecontroller.c @@ -45,7 +45,8 @@ struct _SDL_HatMapping Uint8 mask; }; -#define k_nMaxReverseEntries 20 +/* We need 36 entries for Android (as of SDL v2.0.4) */ +#define k_nMaxReverseEntries 48 /** * We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask @@ -105,6 +106,35 @@ struct _SDL_GameController int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value); int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state); +/* + * If there is an existing add event in the queue, it needs to be modified + * to have the right value for which, because the number of controllers in + * the system is now one less. + */ +static void UpdateEventsForDeviceRemoval() +{ + int i, num_events; + SDL_Event *events; + + num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED); + if (num_events <= 0) { + return; + } + + events = SDL_stack_alloc(SDL_Event, num_events); + if (!events) { + return; + } + + num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED); + for (i = 0; i < num_events; ++i) { + --events[i].cdevice.which; + } + SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0); + + SDL_stack_free(events); +} + /* * Event filter to fire controller events from joystick ones */ @@ -115,7 +145,11 @@ int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) { SDL_GameController *controllerlist; - if (event->jaxis.axis >= k_nMaxReverseEntries) break; + if (event->jaxis.axis >= k_nMaxReverseEntries) + { + SDL_SetError("SDL_GameControllerEventWatcher: Axis index %d too large, ignoring motion", (int)event->jaxis.axis); + break; + } controllerlist = SDL_gamecontrollers; while (controllerlist) { @@ -126,8 +160,8 @@ int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) switch (axis) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - /* Shift it to be 0 - 32767. */ value = value / 2 + 16384; + break; default: break; } @@ -146,7 +180,11 @@ int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) { SDL_GameController *controllerlist; - if (event->jbutton.button >= k_nMaxReverseEntries) break; + if (event->jbutton.button >= k_nMaxReverseEntries) + { + SDL_SetError("SDL_GameControllerEventWatcher: Button index %d too large, ignoring update", (int)event->jbutton.button); + break; + } controllerlist = SDL_gamecontrollers; while (controllerlist) { @@ -223,9 +261,12 @@ int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) while (controllerlist) { if (controllerlist->joystick->instance_id == event->jdevice.which) { SDL_Event deviceevent; + deviceevent.type = SDL_CONTROLLERDEVICEREMOVED; deviceevent.cdevice.which = event->jdevice.which; SDL_PushEvent(&deviceevent); + + UpdateEventsForDeviceRemoval(); break; } controllerlist = controllerlist->next; @@ -861,7 +902,6 @@ SDL_GameControllerInit(void) { int i = 0; const char *pMappingString = NULL; - s_pSupportedControllers = NULL; pMappingString = s_ControllerMappings[i]; while (pMappingString) { SDL_GameControllerAddMapping(pMappingString); @@ -971,6 +1011,20 @@ SDL_GameControllerOpen(int device_index) SDL_PrivateLoadButtonMapping(&gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping); + /* The triggers are mapped from -32768 to 32767, where -32768 is the 'unpressed' value */ + { + int leftTriggerMapping = gamecontroller->mapping.axes[SDL_CONTROLLER_AXIS_TRIGGERLEFT]; + int rightTriggerMapping = gamecontroller->mapping.axes[SDL_CONTROLLER_AXIS_TRIGGERRIGHT]; + if (leftTriggerMapping >= 0) { + gamecontroller->joystick->axes[leftTriggerMapping] = + gamecontroller->joystick->axes_zero[leftTriggerMapping] = (Sint16)-32768; + } + if (rightTriggerMapping >= 0) { + gamecontroller->joystick->axes[rightTriggerMapping] = + gamecontroller->joystick->axes_zero[rightTriggerMapping] = (Sint16)-32768; + } + } + /* Add joystick to list */ ++gamecontroller->ref_count; /* Link the joystick in the list */ @@ -1007,7 +1061,7 @@ SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControlle switch (axis) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - /* Shift it to be 0 - 32767. */ + /* Shift it to be 0 - 32767 */ value = value / 2 + 16384; default: break; diff --git a/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h b/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h index 211d00d01..1e623cbb8 100644 --- a/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h +++ b/Engine/lib/sdl/src/joystick/SDL_gamecontrollerdb.h @@ -35,6 +35,7 @@ static const char *s_ControllerMappings [] = "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", #endif #if SDL_JOYSTICK_DINPUT + "10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "e8206058000000000000504944564944,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", @@ -48,6 +49,7 @@ static const char *s_ControllerMappings [] = "4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", #endif #if defined(__MACOSX__) + "10280000000000000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", "830500000000000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */ @@ -56,11 +58,14 @@ static const char *s_ControllerMappings [] = "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */ "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", "4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", "11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,", "11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,", "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", #endif #if defined(__LINUX__) + "05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", + "03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", @@ -71,6 +76,12 @@ static const char *s_ControllerMappings [] = "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */ "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "050000003620000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,", @@ -78,12 +89,15 @@ static const char *s_ControllerMappings [] = "03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", #endif #if defined(__ANDROID__) diff --git a/Engine/lib/sdl/src/joystick/SDL_joystick.c b/Engine/lib/sdl/src/joystick/SDL_joystick.c index dc910a82b..c426a39e5 100644 --- a/Engine/lib/sdl/src/joystick/SDL_joystick.c +++ b/Engine/lib/sdl/src/joystick/SDL_joystick.c @@ -142,8 +142,8 @@ SDL_JoystickOpen(int device_index) joystick->name = NULL; if (joystick->naxes > 0) { - joystick->axes = (Sint16 *) SDL_malloc - (joystick->naxes * sizeof(Sint16)); + joystick->axes = (Sint16 *) SDL_malloc(joystick->naxes * sizeof(Sint16)); + joystick->axes_zero = (Sint16 *) SDL_malloc(joystick->naxes * sizeof(Sint16)); } if (joystick->nhats > 0) { joystick->hats = (Uint8 *) SDL_malloc @@ -167,6 +167,7 @@ SDL_JoystickOpen(int device_index) } if (joystick->axes) { SDL_memset(joystick->axes, 0, joystick->naxes * sizeof(Sint16)); + SDL_memset(joystick->axes_zero, 0, joystick->naxes * sizeof(Sint16)); } if (joystick->hats) { SDL_memset(joystick->hats, 0, joystick->nhats * sizeof(Uint8)); @@ -497,6 +498,71 @@ SDL_PrivateJoystickShouldIgnoreEvent() /* These are global for SDL_sysjoystick.c and SDL_events.c */ +void SDL_PrivateJoystickAdded(int device_index) +{ +#if !SDL_EVENTS_DISABLED + SDL_Event event; + + event.type = SDL_JOYDEVICEADDED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_index; + if ( (SDL_EventOK == NULL) || + (*SDL_EventOK) (SDL_EventOKParam, &event) ) { + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ +} + +/* + * If there is an existing add event in the queue, it needs to be modified + * to have the right value for which, because the number of controllers in + * the system is now one less. + */ +static void UpdateEventsForDeviceRemoval() +{ + int i, num_events; + SDL_Event *events; + + num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED); + if (num_events <= 0) { + return; + } + + events = SDL_stack_alloc(SDL_Event, num_events); + if (!events) { + return; + } + + num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED); + for (i = 0; i < num_events; ++i) { + --events[i].jdevice.which; + } + SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0); + + SDL_stack_free(events); +} + +void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) +{ +#if !SDL_EVENTS_DISABLED + SDL_Event event; + + event.type = SDL_JOYDEVICEREMOVED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_instance; + if ( (SDL_EventOK == NULL) || + (*SDL_EventOK) (SDL_EventOKParam, &event) ) { + SDL_PushEvent(&event); + } + } + + UpdateEventsForDeviceRemoval(); +#endif /* !SDL_EVENTS_DISABLED */ +} + int SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) { @@ -514,8 +580,8 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) * events. */ if (SDL_PrivateJoystickShouldIgnoreEvent()) { - if ((value > 0 && value >= joystick->axes[axis]) || - (value < 0 && value <= joystick->axes[axis])) { + if ((value > joystick->axes_zero[axis] && value >= joystick->axes[axis]) || + (value < joystick->axes_zero[axis] && value <= joystick->axes[axis])) { return 0; } } @@ -688,7 +754,7 @@ SDL_JoystickUpdate(void) /* Tell the app that everything is centered/unpressed... */ for (i = 0; i < joystick->naxes; i++) { - SDL_PrivateJoystickAxis(joystick, i, 0); + SDL_PrivateJoystickAxis(joystick, i, joystick->axes_zero[i]); } for (i = 0; i < joystick->nbuttons; i++) { diff --git a/Engine/lib/sdl/src/joystick/SDL_joystick_c.h b/Engine/lib/sdl/src/joystick/SDL_joystick_c.h index 4a076f6d6..cb9c92544 100644 --- a/Engine/lib/sdl/src/joystick/SDL_joystick_c.h +++ b/Engine/lib/sdl/src/joystick/SDL_joystick_c.h @@ -33,6 +33,8 @@ extern void SDL_GameControllerQuit(void); /* Internal event queueing functions */ +extern void SDL_PrivateJoystickAdded(int device_index); +extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance); extern int SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value); extern int SDL_PrivateJoystickBall(SDL_Joystick * joystick, @@ -41,8 +43,8 @@ extern int SDL_PrivateJoystickHat(SDL_Joystick * joystick, Uint8 hat, Uint8 value); extern int SDL_PrivateJoystickButton(SDL_Joystick * joystick, Uint8 button, Uint8 state); -extern void SDL_PrivateJoystickBatteryLevel( SDL_Joystick * joystick, - SDL_JoystickPowerLevel ePowerLevel ); +extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick, + SDL_JoystickPowerLevel ePowerLevel); /* Internal sanity checking functions */ extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick); diff --git a/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h b/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h index 1015840af..f4cad05ec 100644 --- a/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h +++ b/Engine/lib/sdl/src/joystick/SDL_sysjoystick.h @@ -36,6 +36,7 @@ struct _SDL_Joystick int naxes; /* Number of axis controls on the joystick */ Sint16 *axes; /* Current axis states */ + Sint16 *axes_zero; /* Zero point on the axis (-32768 for triggers) */ int nhats; /* Number of hats on the joystick */ Uint8 *hats; /* Current hat states */ diff --git a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c index 8656a5322..a09e9a12c 100644 --- a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick.c @@ -27,10 +27,6 @@ #include "SDL_error.h" #include "SDL_events.h" -#if !SDL_EVENTS_DISABLED -#include "../../events/SDL_events_c.h" -#endif - #include "SDL_joystick.h" #include "SDL_hints.h" #include "SDL_assert.h" @@ -191,8 +187,8 @@ Android_OnPadDown(int device_id, int keycode) item = JoystickByDeviceId(device_id); if (item && item->joystick) { SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED); - return 0; } + return 0; } return -1; @@ -207,8 +203,8 @@ Android_OnPadUp(int device_id, int keycode) item = JoystickByDeviceId(device_id); if (item && item->joystick) { SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED); - return 0; } + return 0; } return -1; @@ -252,9 +248,6 @@ Android_AddJoystick(int device_id, const char *name, SDL_bool is_accelerometer, { SDL_JoystickGUID guid; SDL_joylist_item *item; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif if(JoystickByDeviceId(device_id) != NULL || name == NULL) { return -1; @@ -299,17 +292,7 @@ Android_AddJoystick(int device_id, const char *name, SDL_bool is_accelerometer, /* Need to increment the joystick count before we post the event */ ++numjoysticks; -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEADDED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = (numjoysticks - 1); - if ( (SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event) ) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickAdded(numjoysticks - 1); #ifdef DEBUG_JOYSTICK SDL_Log("Added joystick %s with device_id %d", name, device_id); @@ -323,9 +306,6 @@ Android_RemoveJoystick(int device_id) { SDL_joylist_item *item = SDL_joylist; SDL_joylist_item *prev = NULL; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif /* Don't call JoystickByDeviceId here or there'll be an infinite loop! */ while (item != NULL) { @@ -340,7 +320,6 @@ Android_RemoveJoystick(int device_id) return -1; } - const int retval = item->device_instance; if (item->joystick) { item->joystick->hwdata = NULL; } @@ -358,17 +337,7 @@ Android_RemoveJoystick(int device_id) /* Need to decrement the joystick count before we post the event */ --numjoysticks; -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEREMOVED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = item->device_instance; - if ( (SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event) ) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickRemoved(item->device_instance); #ifdef DEBUG_JOYSTICK SDL_Log("Removed joystick with device_id %d", device_id); @@ -376,18 +345,16 @@ Android_RemoveJoystick(int device_id) SDL_free(item->name); SDL_free(item); - return retval; + return numjoysticks; } int SDL_SYS_JoystickInit(void) { - const char *hint; SDL_SYS_JoystickDetect(); - hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK); - if (!hint || SDL_atoi(hint)) { + if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) { /* Default behavior, accelerometer as joystick */ Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0); } @@ -539,6 +506,10 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { + SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; + if (item) { + item->joystick = NULL; + } } /* Function to perform any system-specific joystick related cleanup */ diff --git a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h index 49b494c54..51803db35 100644 --- a/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/android/SDL_sysjoystick_c.h @@ -1,23 +1,23 @@ /* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - */ + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ #include "../../SDL_internal.h" diff --git a/Engine/lib/sdl/src/joystick/bsd/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/bsd/SDL_sysjoystick.c index 509d43f75..ddc899f6e 100644 --- a/Engine/lib/sdl/src/joystick/bsd/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/bsd/SDL_sysjoystick.c @@ -179,7 +179,7 @@ SDL_SYS_JoystickInit(void) SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); - joynames[SDL_SYS_numjoysticks] = strdup(s); + joynames[SDL_SYS_numjoysticks] = SDL_strdup(s); if (SDL_SYS_JoystickOpen(&nj, SDL_SYS_numjoysticks) == 0) { SDL_SYS_JoystickClose(&nj); @@ -193,7 +193,7 @@ SDL_SYS_JoystickInit(void) SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); fd = open(s, O_RDONLY); if (fd != -1) { - joynames[SDL_SYS_numjoysticks++] = strdup(s); + joynames[SDL_SYS_numjoysticks++] = SDL_strdup(s); close(fd); } } @@ -304,14 +304,14 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index) } joy->hwdata = hw; hw->fd = fd; - hw->path = strdup(path); + hw->path = SDL_strdup(path); if (!SDL_strncmp(path, "/dev/joy", 8)) { hw->type = BSDJOY_JOY; joy->naxes = 2; joy->nbuttons = 2; joy->nhats = 0; joy->nballs = 0; - joydevnames[device_index] = strdup("Gameport joystick"); + joydevnames[device_index] = SDL_strdup("Gameport joystick"); goto usbend; } else { hw->type = BSDJOY_UHID; @@ -363,7 +363,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joy, int device_index) str[i] = '\0'; asprintf(&new_name, "%s @ %s", str, path); if (new_name != NULL) { - free(joydevnames[SDL_SYS_numjoysticks]); + SDL_free(joydevnames[SDL_SYS_numjoysticks]); joydevnames[SDL_SYS_numjoysticks] = new_name; } } diff --git a/Engine/lib/sdl/src/joystick/darwin/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/darwin/SDL_sysjoystick.c index 6dd306aa8..da10fbac5 100644 --- a/Engine/lib/sdl/src/joystick/darwin/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/darwin/SDL_sysjoystick.c @@ -34,9 +34,6 @@ #include "SDL_sysjoystick_c.h" #include "SDL_events.h" #include "../../haptic/darwin/SDL_syshaptic_c.h" /* For haptic hot plugging */ -#if !SDL_EVENTS_DISABLED -#include "../../events/SDL_events_c.h" -#endif #define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick") @@ -154,21 +151,7 @@ JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender) MacHaptic_MaybeRemoveDevice(device->ffservice); #endif -/* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceRemoved()? */ -#if !SDL_EVENTS_DISABLED - { - SDL_Event event; - event.type = SDL_JOYDEVICEREMOVED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = device->instance_id; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickRemoved(device->instance_id); } @@ -249,6 +232,7 @@ AddHIDElement(const void *value, void *parameter) case kHIDUsage_GD_DPadLeft: case kHIDUsage_GD_Start: case kHIDUsage_GD_Select: + case kHIDUsage_GD_SystemMainMenu: if (!ElementAlreadyAdded(cookie, pDevice->firstButton)) { element = (recElement *) SDL_calloc(1, sizeof (recElement)); if (element) { @@ -422,6 +406,7 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic { recDevice *device; int device_index = 0; + io_service_t ioservice; if (res != kIOReturnSuccess) { return; @@ -451,20 +436,11 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic device->instance_id = ++s_joystick_instance_id; /* We have to do some storage of the io_service_t for SDL_HapticOpenFromJoystick */ - -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (IOHIDDeviceGetService != NULL) { /* weak reference: available in 10.6 and later. */ -#endif - - const io_service_t ioservice = IOHIDDeviceGetService(ioHIDDeviceObject); + ioservice = IOHIDDeviceGetService(ioHIDDeviceObject); #if SDL_HAPTIC_IOKIT - if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) { - device->ffservice = ioservice; - MacHaptic_MaybeAddDevice(ioservice); - } -#endif - -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) { + device->ffservice = ioservice; + MacHaptic_MaybeAddDevice(ioservice); } #endif @@ -483,21 +459,7 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic ++device_index; /* bump by one since we counted by pNext. */ } -/* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceAdded()? */ -#if !SDL_EVENTS_DISABLED - { - SDL_Event event; - event.type = SDL_JOYDEVICEADDED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = device_index; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickAdded(device_index); } static SDL_bool diff --git a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c index e0c5833bf..6b203667a 100644 --- a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick.c @@ -27,10 +27,6 @@ #include "SDL_error.h" #include "SDL_events.h" -#if !SDL_EVENTS_DISABLED -#include "../../events/SDL_events_c.h" -#endif - #include "SDL_joystick.h" #include "SDL_hints.h" #include "SDL_assert.h" @@ -57,10 +53,6 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa return 1; } -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif - item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item)); if (item == NULL) { return 1; @@ -105,20 +97,12 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa } ++numjoysticks; + + SDL_PrivateJoystickAdded(numjoysticks - 1); + #ifdef DEBUG_JOYSTICK SDL_Log("Number of joysticks is %d", numjoysticks); #endif -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEADDED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = numjoysticks - 1; - if ( (SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event) ) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ #ifdef DEBUG_JOYSTICK SDL_Log("Added joystick with index %d", item->index); @@ -132,9 +116,6 @@ Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gam { SDL_joylist_item *item = SDL_joylist; SDL_joylist_item *prev = NULL; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif while (item != NULL) { if (item->index == gamepadEvent->index) { @@ -165,17 +146,7 @@ Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gam /* Need to decrement the joystick count before we post the event */ --numjoysticks; -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEREMOVED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = item->device_instance; - if ( (SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event) ) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickRemoved(item->device_instance); #ifdef DEBUG_JOYSTICK SDL_Log("Removed joystick with id %d", item->device_instance); @@ -377,6 +348,10 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { + SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; + if (item) { + item->joystick = NULL; + } } /* Function to perform any system-specific joystick related cleanup */ diff --git a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h index c7103c56a..41f613e11 100644 --- a/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/emscripten/SDL_sysjoystick_c.h @@ -1,23 +1,23 @@ /* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - */ + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ #include "../../SDL_internal.h" diff --git a/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc b/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc index 3ec9ae107..a680189c7 100644 --- a/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc +++ b/Engine/lib/sdl/src/joystick/haiku/SDL_haikujoystick.cc @@ -74,8 +74,8 @@ extern "C" if (joystick.Open(name) != B_ERROR) { BString stick_name; joystick.GetControllerName(&stick_name); - SDL_joyport[SDL_SYS_numjoysticks] = strdup(name); - SDL_joyname[SDL_SYS_numjoysticks] = strdup(stick_name.String()); + SDL_joyport[SDL_SYS_numjoysticks] = SDL_strdup(name); + SDL_joyname[SDL_SYS_numjoysticks] = SDL_strdup(stick_name.String()); SDL_SYS_numjoysticks++; joystick.Close(); } diff --git a/Engine/lib/sdl/src/joystick/iphoneos/SDL_sysjoystick.m b/Engine/lib/sdl/src/joystick/iphoneos/SDL_sysjoystick.m index c8a42af05..eb7e00032 100644 --- a/Engine/lib/sdl/src/joystick/iphoneos/SDL_sysjoystick.m +++ b/Engine/lib/sdl/src/joystick/iphoneos/SDL_sysjoystick.m @@ -26,6 +26,7 @@ /* needed for SDL_IPHONE_MAX_GFORCE macro */ #include "SDL_config_iphoneos.h" +#include "SDL_events.h" #include "SDL_joystick.h" #include "SDL_hints.h" #include "SDL_stdinc.h" @@ -36,7 +37,9 @@ #include "../../events/SDL_events_c.h" #endif +#if !TARGET_OS_TV #import +#endif #ifdef SDL_JOYSTICK_MFI #import @@ -45,8 +48,10 @@ static id connectObserver = nil; static id disconnectObserver = nil; #endif /* SDL_JOYSTICK_MFI */ +#if !TARGET_OS_TV static const char *accelerometerName = "iOS Accelerometer"; static CMMotionManager *motionManager = nil; +#endif /* !TARGET_OS_TV */ static SDL_JoystickDeviceItem *deviceList = NULL; @@ -105,6 +110,11 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr } else if (controller.gamepad) { device->guid.data[10] = 2; } +#if TARGET_OS_TV + else if (controller.microGamepad) { + device->guid.data[10] = 3; + } +#endif /* TARGET_OS_TV */ if (controller.extendedGamepad) { device->naxes = 6; /* 2 thumbsticks and 2 triggers */ @@ -115,21 +125,27 @@ SDL_SYS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *contr device->nhats = 1; /* d-pad */ device->nbuttons = 7; /* ABXY, shoulder buttons, pause button */ } - /* TODO: Handle micro profiles on tvOS. */ +#if TARGET_OS_TV + else if (controller.microGamepad) { + device->naxes = 2; /* treat the touch surface as two axes */ + device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */ + device->nbuttons = 3; /* AX, pause button */ + + controller.microGamepad.allowsRotation = SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_FALSE); + } +#endif /* TARGET_OS_TV */ /* This will be set when the first button press of the controller is * detected. */ controller.playerIndex = -1; -#endif + +#endif /* SDL_JOYSTICK_MFI */ } static void SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer) { SDL_JoystickDeviceItem *device = deviceList; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif while (device != NULL) { if (device->controller == controller) { @@ -149,6 +165,10 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer) device->instance_id = instancecounter++; if (accelerometer) { +#if TARGET_OS_TV + SDL_free(device); + return; +#else device->name = SDL_strdup(accelerometerName); device->naxes = 3; /* Device acceleration in the x, y, and z axes. */ device->nhats = 0; @@ -156,6 +176,7 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer) /* Use the accelerometer name as a GUID. */ SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name))); +#endif /* TARGET_OS_TV */ } else if (controller) { SDL_SYS_AddMFIJoystickDevice(device, controller); } @@ -172,17 +193,7 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer) ++numjoysticks; -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEADDED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = numjoysticks - 1; - if ((SDL_EventOK == NULL) || - (*SDL_EventOK)(SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickAdded(numjoysticks - 1); } static SDL_JoystickDeviceItem * @@ -191,9 +202,6 @@ SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device) SDL_JoystickDeviceItem *prev = NULL; SDL_JoystickDeviceItem *next = NULL; SDL_JoystickDeviceItem *item = deviceList; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif if (device == NULL) { return NULL; @@ -234,17 +242,7 @@ SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device) --numjoysticks; -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEREMOVED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = device->instance_id; - if ((SDL_EventOK == NULL) || - (*SDL_EventOK)(SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickRemoved(device->instance_id); SDL_free(device->name); SDL_free(device); @@ -252,6 +250,22 @@ SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device) return next; } +#if TARGET_OS_TV +static void +SDL_AppleTVRemoteRotationHintChanged(void *udata, const char *name, const char *oldValue, const char *newValue) +{ + BOOL allowRotation = newValue != NULL && *newValue != '0'; + + @autoreleasepool { + for (GCController *controller in [GCController controllers]) { + if (controller.microGamepad) { + controller.microGamepad.allowsRotation = allowRotation; + } + } + } +} +#endif /* TARGET_OS_TV */ + /* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * It should return 0, or -1 on an unrecoverable fatal error. @@ -261,12 +275,13 @@ SDL_SYS_JoystickInit(void) { @autoreleasepool { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - const char *hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK); - if (!hint || SDL_atoi(hint)) { +#if !TARGET_OS_TV + if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) { /* Default behavior, accelerometer as joystick */ SDL_SYS_AddJoystickDevice(nil, SDL_TRUE); } +#endif /* !TARGET_OS_TV */ #ifdef SDL_JOYSTICK_MFI /* GameController.framework was added in iOS 7. */ @@ -278,6 +293,11 @@ SDL_SYS_JoystickInit(void) SDL_SYS_AddJoystickDevice(controller, SDL_FALSE); } +#if TARGET_OS_TV + SDL_AddHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, + SDL_AppleTVRemoteRotationHintChanged, NULL); +#endif /* TARGET_OS_TV */ + connectObserver = [center addObserverForName:GCControllerDidConnectNotification object:nil queue:nil @@ -355,6 +375,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) @autoreleasepool { if (device->accelerometer) { +#if !TARGET_OS_TV if (motionManager == nil) { motionManager = [[CMMotionManager alloc] init]; } @@ -362,6 +383,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) /* Shorter times between updates can significantly increase CPU usage. */ motionManager.accelerometerUpdateInterval = 0.1; [motionManager startAccelerometerUpdates]; +#endif /* !TARGET_OS_TV */ } else { #ifdef SDL_JOYSTICK_MFI GCController *controller = device->controller; @@ -387,6 +409,7 @@ SDL_SYS_JoystickAttached(SDL_Joystick *joystick) static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick) { +#if !TARGET_OS_TV const float maxgforce = SDL_IPHONE_MAX_GFORCE; const SInt16 maxsint16 = 0x7FFF; CMAcceleration accel; @@ -424,6 +447,7 @@ SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick) SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16); SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16); SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16); +#endif /* !TARGET_OS_TV */ } #ifdef SDL_JOYSTICK_MFI @@ -455,7 +479,7 @@ SDL_SYS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad) static void SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick) { -#ifdef SDL_JOYSTICK_MFI +#if SDL_JOYSTICK_MFI @autoreleasepool { GCController *controller = joystick->hwdata->controller; Uint8 hatstate = SDL_HAT_CENTERED; @@ -517,7 +541,36 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick) SDL_PrivateJoystickButton(joystick, i, buttons[i]); } } - /* TODO: Handle micro profiles on tvOS. */ +#if TARGET_OS_TV + else if (controller.microGamepad) { + GCMicroGamepad *gamepad = controller.microGamepad; + + Sint16 axes[] = { + (Sint16) (gamepad.dpad.xAxis.value * 32767), + (Sint16) (gamepad.dpad.yAxis.value * -32767), + }; + + for (i = 0; i < SDL_arraysize(axes); i++) { + updateplayerindex |= (joystick->axes[i] != axes[i]); + SDL_PrivateJoystickAxis(joystick, i, axes[i]); + } + + /* Apparently the dpad values are not accurate enough to be useful. */ + /* hatstate = SDL_SYS_MFIJoystickHatStateForDPad(gamepad.dpad); */ + + Uint8 buttons[] = { + gamepad.buttonA.isPressed, + gamepad.buttonX.isPressed, + }; + + for (i = 0; i < SDL_arraysize(buttons); i++) { + updateplayerindex |= (joystick->buttons[i] != buttons[i]); + SDL_PrivateJoystickButton(joystick, i, buttons[i]); + } + + /* TODO: Figure out what to do with reportsAbsoluteDpadValues */ + } +#endif /* TARGET_OS_TV */ if (joystick->nhats > 0) { updateplayerindex |= (joystick->hats[0] != hatstate); @@ -557,7 +610,7 @@ SDL_SYS_MFIJoystickUpdate(SDL_Joystick * joystick) } } } -#endif +#endif /* SDL_JOYSTICK_MFI */ } /* Function to update the state of a joystick - called as a device poll. @@ -595,7 +648,9 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick) @autoreleasepool { if (device->accelerometer) { +#if !TARGET_OS_TV [motionManager stopAccelerometerUpdates]; +#endif /* !TARGET_OS_TV */ } else if (device->controller) { #ifdef SDL_JOYSTICK_MFI GCController *controller = device->controller; @@ -623,13 +678,20 @@ SDL_SYS_JoystickQuit(void) [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil]; disconnectObserver = nil; } + +#if TARGET_OS_TV + SDL_DelHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, + SDL_AppleTVRemoteRotationHintChanged, NULL); +#endif /* TARGET_OS_TV */ #endif /* SDL_JOYSTICK_MFI */ while (deviceList != NULL) { SDL_SYS_RemoveJoystickDevice(deviceList); } +#if !TARGET_OS_TV motionManager = nil; +#endif /* !TARGET_OS_TV */ } numjoysticks = 0; diff --git a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c index 8c73859ea..bd52b1808 100644 --- a/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/linux/SDL_sysjoystick.c @@ -42,11 +42,6 @@ #include "../SDL_joystick_c.h" #include "SDL_sysjoystick_c.h" -/* !!! FIXME: move this somewhere else. */ -#if !SDL_EVENTS_DISABLED -#include "../../events/SDL_events_c.h" -#endif - /* This isn't defined in older Linux kernel headers */ #ifndef SYN_DROPPED #define SYN_DROPPED 3 @@ -176,9 +171,6 @@ MaybeAddDevice(const char *path) char namebuf[128]; SDL_JoystickGUID guid; SDL_joylist_item *item; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif if (path == NULL) { return -1; @@ -239,18 +231,7 @@ MaybeAddDevice(const char *path) /* Need to increment the joystick count before we post the event */ ++numjoysticks; - /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceAdded() function? */ -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEADDED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = (numjoysticks - 1); - if ( (SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event) ) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickAdded(numjoysticks - 1); return numjoysticks; } @@ -262,9 +243,6 @@ MaybeRemoveDevice(const char *path) { SDL_joylist_item *item; SDL_joylist_item *prev = NULL; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif if (path == NULL) { return -1; @@ -290,18 +268,7 @@ MaybeRemoveDevice(const char *path) /* Need to decrement the joystick count before we post the event */ --numjoysticks; - /* !!! FIXME: Move this to an SDL_PrivateJoyDeviceRemoved() function? */ -#if !SDL_EVENTS_DISABLED - event.type = SDL_JOYDEVICEREMOVED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = item->device_instance; - if ( (SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event) ) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickRemoved(item->device_instance); SDL_free(item->path); SDL_free(item->name); diff --git a/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c b/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c index e5247254f..352960edf 100644 --- a/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c +++ b/Engine/lib/sdl/src/joystick/psp/SDL_sysjoystick.c @@ -34,9 +34,9 @@ #include "SDL_events.h" #include "SDL_error.h" -#include "SDL_thread.h" #include "SDL_mutex.h" #include "SDL_timer.h" +#include "../../thread/SDL_systhread.h" /* Current pad state */ static SceCtrlData pad = { .Lx = 0, .Ly = 0, .Buttons = 0 }; @@ -116,7 +116,7 @@ int SDL_SYS_JoystickInit(void) return SDL_SetError("Can't create input semaphore"); } running = 1; - if((thread = SDL_CreateThread(JoystickUpdate, "JoySitckThread",NULL)) == NULL) { + if((thread = SDL_CreateThreadInternal(JoystickUpdate, "JoystickThread", 4096, NULL)) == NULL) { return SDL_SetError("Can't create input thread"); } diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c index f6b0cc88d..7166075b1 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_dinputjoystick.c @@ -214,7 +214,7 @@ static DIOBJECTDATAFORMAT dfDIJoystick2[] = { { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, }; -const DIDATAFORMAT c_dfDIJoystick2 = { +const DIDATAFORMAT SDL_c_dfDIJoystick2 = { sizeof(DIDATAFORMAT), sizeof(DIOBJECTDATAFORMAT), DIDF_ABSAXIS, @@ -240,11 +240,23 @@ SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput) static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; static const GUID *s_XInputProductGUID[] = { &IID_ValveStreamingGamepad, - &IID_X360WiredGamepad, /* Microsoft's wired X360 controller for Windows. */ - &IID_X360WirelessGamepad /* Microsoft's wireless X360 controller for Windows. */ + &IID_X360WiredGamepad, /* Microsoft's wired X360 controller for Windows. */ + &IID_X360WirelessGamepad, /* Microsoft's wireless X360 controller for Windows. */ + &IID_XOneWiredGamepad, /* Microsoft's wired Xbox One controller for Windows. */ + &IID_XOneWirelessGamepad, /* Microsoft's wireless Xbox One controller for Windows. */ + &IID_XOneNewWirelessGamepad, /* Microsoft's updated wireless Xbox One controller (w/ 3.5 mm jack) for Windows. */ + &IID_XOneSWirelessGamepad, /* Microsoft's wireless Xbox One S controller for Windows. */ + &IID_XOneSBluetoothGamepad, /* Microsoft's Bluetooth Xbox One S controller for Windows. */ + &IID_XOneEliteWirelessGamepad /* Microsoft's wireless Xbox One Elite controller for Windows. */ }; size_t iDevice; @@ -582,7 +594,7 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde /* Use the extended data structure: DIJOYSTATE2. */ result = IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice, - &c_dfDIJoystick2); + &SDL_c_dfDIJoystick2); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetDataFormat", result); } diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c index 7123c6151..e528afa7f 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick.c @@ -35,16 +35,13 @@ #include "SDL_error.h" #include "SDL_assert.h" #include "SDL_events.h" -#include "SDL_thread.h" #include "SDL_timer.h" #include "SDL_mutex.h" #include "SDL_events.h" #include "SDL_hints.h" #include "SDL_joystick.h" #include "../SDL_sysjoystick.h" -#if !SDL_EVENTS_DISABLED -#include "../../events/SDL_events_c.h" -#endif +#include "../../thread/SDL_systhread.h" #include "../../core/windows/SDL_windows.h" #if !defined(__WINRT__) #include @@ -301,18 +298,9 @@ SDL_SYS_JoystickInit(void) SDL_SYS_JoystickDetect(); if (!s_threadJoystick) { - s_bJoystickThreadQuit = SDL_FALSE; /* spin up the thread to detect hotplug of devices */ -#if defined(__WIN32__) && !defined(HAVE_LIBC) -#undef SDL_CreateThread -#if SDL_DYNAMIC_API - s_threadJoystick= SDL_CreateThread_REAL(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL); -#else - s_threadJoystick= SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL); -#endif -#else - s_threadJoystick = SDL_CreateThread(SDL_JoystickThread, "SDL_joystick", NULL); -#endif + s_bJoystickThreadQuit = SDL_FALSE; + s_threadJoystick = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL); } return SDL_SYS_NumJoysticks(); } @@ -336,9 +324,6 @@ void SDL_SYS_JoystickDetect() { JoyStick_DeviceData *pCurList = NULL; -#if !SDL_EVENTS_DISABLED - SDL_Event event; -#endif /* only enum the devices if the joystick thread told us something changed */ if (!s_bDeviceAdded && !s_bDeviceRemoved) { @@ -370,17 +355,7 @@ SDL_SYS_JoystickDetect() SDL_DINPUT_MaybeRemoveDevice(&pCurList->dxdevice); } -#if !SDL_EVENTS_DISABLED - SDL_zero(event); - event.type = SDL_JOYDEVICEREMOVED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = pCurList->nInstanceID; - if ((!SDL_EventOK) || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ + SDL_PrivateJoystickRemoved(pCurList->nInstanceID); pListNext = pCurList->pNext; SDL_free(pCurList->joystickname); @@ -401,17 +376,8 @@ SDL_SYS_JoystickDetect() SDL_DINPUT_MaybeAddDevice(&pNewJoystick->dxdevice); } -#if !SDL_EVENTS_DISABLED - SDL_zero(event); - event.type = SDL_JOYDEVICEADDED; + SDL_PrivateJoystickAdded(device_index); - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = device_index; - if ((!SDL_EventOK) || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } -#endif /* !SDL_EVENTS_DISABLED */ pNewJoystick->send_add_event = SDL_FALSE; } device_index++; @@ -543,6 +509,9 @@ SDL_SYS_JoystickQuit(void) SDL_DINPUT_JoystickQuit(); SDL_XINPUT_JoystickQuit(); + + s_bDeviceAdded = SDL_FALSE; + s_bDeviceRemoved = SDL_FALSE; } /* return the stable device guid for this device index */ diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h index ab946b4f7..d3c5fcaab 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h +++ b/Engine/lib/sdl/src/joystick/windows/SDL_windowsjoystick_c.h @@ -83,6 +83,10 @@ struct joystick_hwdata DWORD dwPacketNumber; }; +#if SDL_JOYSTICK_DINPUT +extern const DIDATAFORMAT SDL_c_dfDIJoystick2; +#endif + extern void SDL_SYS_AddJoystickDevice(JoyStick_DeviceData *device); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c b/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c index 2f27c47dc..d581d45b9 100644 --- a/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c +++ b/Engine/lib/sdl/src/joystick/windows/SDL_xinputjoystick.c @@ -40,8 +40,7 @@ SDL_XInputUseOldJoystickMapping() { static int s_XInputUseOldJoystickMapping = -1; if (s_XInputUseOldJoystickMapping < 0) { - const char *hint = SDL_GetHint(SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING); - s_XInputUseOldJoystickMapping = (hint && *hint == '1') ? 1 : 0; + s_XInputUseOldJoystickMapping = SDL_GetHintBoolean(SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING, SDL_FALSE); } return (s_XInputUseOldJoystickMapping > 0); } @@ -54,10 +53,7 @@ SDL_bool SDL_XINPUT_Enabled(void) int SDL_XINPUT_JoystickInit(void) { - const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED); - if (env && !SDL_atoi(env)) { - s_bXInputEnabled = SDL_FALSE; - } + s_bXInputEnabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE); if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) { s_bXInputEnabled = SDL_FALSE; /* oh well. */ @@ -376,7 +372,7 @@ SDL_SYS_IsXInputGamepad_DeviceIndex(int device_index) for (index = device_index; index > 0; index--) device = device->pNext; - return (device->SubType == XINPUT_DEVSUBTYPE_GAMEPAD); + return device->bXInputDevice; } #else /* !SDL_JOYSTICK_XINPUT */ diff --git a/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c b/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c index 03ffae129..7b30b7735 100644 --- a/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c +++ b/Engine/lib/sdl/src/loadso/dlopen/SDL_sysloadso.c @@ -30,11 +30,25 @@ #include "SDL_loadso.h" +#if SDL_VIDEO_DRIVER_UIKIT +#include "../../video/uikit/SDL_uikitvideo.h" +#endif + void * SDL_LoadObject(const char *sofile) { - void *handle = dlopen(sofile, RTLD_NOW|RTLD_LOCAL); - const char *loaderror = (char *) dlerror(); + void *handle; + const char *loaderror; + +#if SDL_VIDEO_DRIVER_UIKIT + if (!UIKit_IsSystemVersionAtLeast(8.0)) { + SDL_SetError("SDL_LoadObject requires iOS 8+"); + return NULL; + } +#endif + + handle = dlopen(sofile, RTLD_NOW|RTLD_LOCAL); + loaderror = (char *) dlerror(); if (handle == NULL) { SDL_SetError("Failed loading %s: %s", sofile, loaderror); } diff --git a/Engine/lib/sdl/src/main/android/SDL_android_main.c b/Engine/lib/sdl/src/main/android/SDL_android_main.c index 4173bcb1d..671d9328e 100644 --- a/Engine/lib/sdl/src/main/android/SDL_android_main.c +++ b/Engine/lib/sdl/src/main/android/SDL_android_main.c @@ -16,12 +16,17 @@ /* Called before SDL_main() to initialize JNI bindings in SDL library */ extern void SDL_Android_Init(JNIEnv* env, jclass cls); +/* This prototype is needed to prevent a warning about the missing prototype for global function below */ +JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject array); + /* Start up the SDL app */ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject array) { int i; int argc; int status; + int len; + char** argv; /* This interface could expand with ABI negotiation, callbacks, etc. */ SDL_Android_Init(env, cls); @@ -30,8 +35,8 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc /* Prepare the arguments. */ - int len = (*env)->GetArrayLength(env, array); - char* argv[1 + len + 1]; + len = (*env)->GetArrayLength(env, array); + argv = SDL_stack_alloc(char*, 1 + len + 1); argc = 0; /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works. https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start @@ -66,7 +71,7 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc for (i = 0; i < argc; ++i) { SDL_free(argv[i]); } - + SDL_stack_free(argv); /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ /* exit(status); */ diff --git a/Engine/lib/sdl/src/main/haiku/SDL_BApp.h b/Engine/lib/sdl/src/main/haiku/SDL_BApp.h index 157c23635..9672d462c 100644 --- a/Engine/lib/sdl/src/main/haiku/SDL_BApp.h +++ b/Engine/lib/sdl/src/main/haiku/SDL_BApp.h @@ -193,7 +193,8 @@ public: if(_current_context) _current_context->UnlockGL(); _current_context = newContext; - _current_context->LockGL(); + if (_current_context) + _current_context->LockGL(); } private: /* Event management */ @@ -272,6 +273,17 @@ private: } BE_SetKeyState(scancode, state); SDL_SendKeyboardKey(state, BE_GetScancodeFromBeKey(scancode)); + + if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + const int8 *keyUtf8; + ssize_t count; + if (msg->FindData("key-utf8", B_INT8_TYPE, (const void**)&keyUtf8, &count) == B_OK) { + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + SDL_zero(text); + SDL_memcpy(text, keyUtf8, count); + SDL_SendKeyboardText(text); + } + } } void _HandleMouseFocus(BMessage *msg) { diff --git a/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc b/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc index 36c2a1ab8..4c5df0954 100644 --- a/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc +++ b/Engine/lib/sdl/src/main/haiku/SDL_BeApp.cc @@ -31,7 +31,6 @@ #include "SDL_BApp.h" /* SDL_BApp class definition */ #include "SDL_BeApp.h" -#include "SDL_thread.h" #include "SDL_timer.h" #include "SDL_error.h" @@ -40,6 +39,9 @@ #ifdef __cplusplus extern "C" { #endif + +#include "../../thread/SDL_systhread.h" + /* Flag to tell whether or not the Be application is active or not */ int SDL_BeAppActive = 0; static SDL_Thread *SDL_AppThread = NULL; @@ -62,7 +64,7 @@ SDL_InitBeApp(void) { /* Create the BApplication that handles appserver interaction */ if (SDL_BeAppActive <= 0) { - SDL_AppThread = SDL_CreateThread(StartBeApp, "SDLApplication", NULL); + SDL_AppThread = SDL_CreateThreadInternal(StartBeApp, "SDLApplication", 0, NULL); if (SDL_AppThread == NULL) { return SDL_SetError("Couldn't create BApplication thread"); } diff --git a/Engine/lib/sdl/src/main/windows/SDL_windows_main.c b/Engine/lib/sdl/src/main/windows/SDL_windows_main.c index e6378081f..b502ed50e 100644 --- a/Engine/lib/sdl/src/main/windows/SDL_windows_main.c +++ b/Engine/lib/sdl/src/main/windows/SDL_windows_main.c @@ -126,44 +126,15 @@ main_utf8(int argc, char *argv[]) return SDL_main(argc, argv); } -/* This is where execution begins [console apps, ansi] */ -int -console_ansi_main(int argc, char *argv[]) -{ - /* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */ - return main_utf8(argc, argv); -} - - -#if UNICODE -/* This is where execution begins [console apps, unicode] */ -int -console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) -{ - int retval = 0; - char **argv = SDL_stack_alloc(char*, argc); - int i; - - for (i = 0; i < argc; ++i) { - argv[i] = WIN_StringToUTF8(wargv[i]); - } - - retval = main_utf8(argc, argv); - - /* !!! FIXME: we are leaking all the elements of argv we allocated. */ - SDL_stack_free(argv); - - return retval; -} -#endif - -/* This is where execution begins [windowed apps] */ -int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +/* Gets the arguments with GetCommandLine, converts them to argc and argv + and calls main_utf8 */ +static int +main_getcmdline() { char **argv; int argc; char *cmdline; + int retval = 0; /* Grab the command line */ TCHAR *text = GetCommandLine(); @@ -185,15 +156,50 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) } ParseCommandLine(cmdline, argv); - /* Run the main program */ - main_utf8(argc, argv); + retval = main_utf8(argc, argv); SDL_stack_free(argv); - SDL_free(cmdline); - /* Hush little compiler, don't you cry... */ - return 0; + return retval; +} + +/* This is where execution begins [console apps, ansi] */ +int +console_ansi_main(int argc, char *argv[]) +{ + return main_getcmdline(); +} + + +#if UNICODE +/* This is where execution begins [console apps, unicode] */ +int +console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) +{ + int retval = 0; + char **argv = SDL_stack_alloc(char*, argc + 1); + int i; + + for (i = 0; i < argc; ++i) { + argv[i] = WIN_StringToUTF8(wargv[i]); + } + argv[argc] = NULL; + + retval = main_utf8(argc, argv); + + /* !!! FIXME: we are leaking all the elements of argv we allocated. */ + SDL_stack_free(argv); + + return retval; +} +#endif + +/* This is where execution begins [windowed apps] */ +int WINAPI +WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +{ + return main_getcmdline(); } #endif /* __WIN32__ */ diff --git a/Engine/lib/sdl/src/main/windows/version.rc b/Engine/lib/sdl/src/main/windows/version.rc index 8597154aa..e10443b06 100644 --- a/Engine/lib/sdl/src/main/windows/version.rc +++ b/Engine/lib/sdl/src/main/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,4,0 - PRODUCTVERSION 2,0,4,0 + FILEVERSION 2,0,5,0 + PRODUCTVERSION 2,0,5,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "2, 0, 4, 0\0" + VALUE "FileVersion", "2, 0, 5, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2016 Sam Lantinga\0" VALUE "OriginalFilename", "SDL2.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "2, 0, 4, 0\0" + VALUE "ProductVersion", "2, 0, 5, 0\0" END END BLOCK "VarFileInfo" diff --git a/Engine/lib/sdl/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur b/Engine/lib/sdl/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur new file mode 100644 index 0000000000000000000000000000000000000000..c6556b8a72d272dc9b47f2194b05a1bc022f80a7 GIT binary patch literal 326 zcmc(Zu@L|u2m>F6u%@(h1V?jo3_1k4`wy22aEu6KV;Kx!3QcTLd*wWTxvHpS=06&( HA6jz(2=#;* literal 0 HcmV?d00001 diff --git a/Engine/lib/sdl/src/main/winrt/SDL2-WinRTResources.rc b/Engine/lib/sdl/src/main/winrt/SDL2-WinRTResources.rc new file mode 100644 index 000000000..988a8d57d --- /dev/null +++ b/Engine/lib/sdl/src/main/winrt/SDL2-WinRTResources.rc @@ -0,0 +1,3 @@ +#include "winres.h" +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +5000 CURSOR "SDL2-WinRTResource_BlankCursor.cur" diff --git a/Engine/lib/sdl/src/power/uikit/SDL_syspower.m b/Engine/lib/sdl/src/power/uikit/SDL_syspower.m index 14ce3576a..7186b219c 100644 --- a/Engine/lib/sdl/src/power/uikit/SDL_syspower.m +++ b/Engine/lib/sdl/src/power/uikit/SDL_syspower.m @@ -30,6 +30,7 @@ #include "SDL_assert.h" #include "SDL_syspower.h" +#if !TARGET_OS_TV /* turn off the battery monitor if it's been more than X ms since last check. */ static const int BATTERY_MONITORING_TIMEOUT = 3000; static Uint32 SDL_UIKitLastPowerInfoQuery = 0; @@ -46,10 +47,22 @@ SDL_UIKit_UpdateBatteryMonitoring(void) } } } +#else +void +SDL_UIKit_UpdateBatteryMonitoring(void) +{ + /* Do nothing. */ +} +#endif /* !TARGET_OS_TV */ SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent) { +#if TARGET_OS_TV + *state = SDL_POWERSTATE_NO_BATTERY; + *seconds = -1; + *percent = -1; +#else /* TARGET_OS_TV */ @autoreleasepool { UIDevice *uidev = [UIDevice currentDevice]; @@ -88,8 +101,10 @@ SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent) const float level = uidev.batteryLevel; *percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) ); - return SDL_TRUE; /* always the definitive answer on iOS. */ } +#endif /* TARGET_OS_TV */ + + return SDL_TRUE; /* always the definitive answer on iOS. */ } #endif /* SDL_POWER_UIKIT */ diff --git a/Engine/lib/sdl/src/render/SDL_render.c b/Engine/lib/sdl/src/render/SDL_render.c index 923973ec7..94750810d 100644 --- a/Engine/lib/sdl/src/render/SDL_render.c +++ b/Engine/lib/sdl/src/render/SDL_render.c @@ -234,12 +234,11 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags) return NULL; } - hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC); - if (hint) { - if (*hint == '0') { - flags &= ~SDL_RENDERER_PRESENTVSYNC; - } else { + if (SDL_GetHint(SDL_HINT_RENDER_VSYNC)) { + if (SDL_GetHintBoolean(SDL_HINT_RENDER_VSYNC, SDL_TRUE)) { flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + flags &= ~SDL_RENDERER_PRESENTVSYNC; } } @@ -1106,6 +1105,8 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) renderer->viewport.y = 0; renderer->viewport.w = texture->w; renderer->viewport.h = texture->h; + SDL_zero(renderer->clip_rect); + renderer->clipping_enabled = SDL_FALSE; renderer->scale.x = 1.0f; renderer->scale.y = 1.0f; renderer->logical_w = texture->w; @@ -1144,6 +1145,9 @@ UpdateLogicalSize(SDL_Renderer *renderer) float scale; SDL_Rect viewport; + if (!renderer->logical_w || !renderer->logical_h) { + return 0; + } if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) { return -1; } @@ -1154,7 +1158,19 @@ UpdateLogicalSize(SDL_Renderer *renderer) /* Clear the scale because we're setting viewport in output coordinates */ SDL_RenderSetScale(renderer, 1.0f, 1.0f); - if (SDL_fabs(want_aspect-real_aspect) < 0.0001) { + if (renderer->integer_scale) { + if (want_aspect > real_aspect) { + scale = (float)(w / renderer->logical_w); + } else { + scale = (float)(h / renderer->logical_h); + } + viewport.w = (int)SDL_ceil(renderer->logical_w * scale); + viewport.x = (w - viewport.w) / 2; + viewport.h = (int)SDL_ceil(renderer->logical_h * scale); + viewport.y = (h - viewport.h) / 2; + + SDL_RenderSetViewport(renderer, &viewport); + } else if (SDL_fabs(want_aspect-real_aspect) < 0.0001) { /* The aspect ratios are the same, just scale appropriately */ scale = (float)w / renderer->logical_w; SDL_RenderSetViewport(renderer, NULL); @@ -1215,6 +1231,24 @@ SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h) } } +int +SDL_RenderSetIntegerScale(SDL_Renderer * renderer, SDL_bool enable) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + renderer->integer_scale = enable; + + return UpdateLogicalSize(renderer); +} + +SDL_bool +SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer) +{ + CHECK_RENDERER_MAGIC(renderer, SDL_FALSE); + + return renderer->integer_scale; +} + int SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect) { @@ -1425,6 +1459,7 @@ SDL_RenderDrawPoints(SDL_Renderer * renderer, if (count < 1) { return 0; } + /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; @@ -1534,6 +1569,7 @@ SDL_RenderDrawLines(SDL_Renderer * renderer, if (count < 2) { return 0; } + /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; @@ -1607,6 +1643,7 @@ SDL_RenderDrawRects(SDL_Renderer * renderer, if (renderer->hidden) { return 0; } + for (i = 0; i < count; ++i) { if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) { return -1; @@ -1648,6 +1685,7 @@ SDL_RenderFillRects(SDL_Renderer * renderer, if (count < 1) { return 0; } + /* Don't draw while we're hidden */ if (renderer->hidden) { return 0; @@ -1686,6 +1724,11 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, return SDL_SetError("Texture was not created with this renderer"); } + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } + real_srcrect.x = 0; real_srcrect.y = 0; real_srcrect.w = texture->w; @@ -1710,11 +1753,6 @@ SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, texture = texture->native; } - /* Don't draw while we're hidden */ - if (renderer->hidden) { - return 0; - } - frect.x = real_dstrect.x * renderer->scale.x; frect.y = real_dstrect.y * renderer->scale.y; frect.w = real_dstrect.w * renderer->scale.x; @@ -1735,7 +1773,7 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, SDL_FRect frect; SDL_FPoint fcenter; - if (flip == SDL_FLIP_NONE && angle == 0) { /* fast path when we don't need rotation or flipping */ + if (flip == SDL_FLIP_NONE && (int)(angle/360) == angle/360) { /* fast path when we don't need rotation or flipping */ return SDL_RenderCopy(renderer, texture, srcrect, dstrect); } @@ -1749,6 +1787,11 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, return SDL_SetError("Renderer does not support RenderCopyEx"); } + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } + real_srcrect.x = 0; real_srcrect.y = 0; real_srcrect.w = texture->w; @@ -1772,8 +1815,9 @@ SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, texture = texture->native; } - if(center) real_center = *center; - else { + if (center) { + real_center = *center; + } else { real_center.x = real_dstrect.w/2; real_center.y = real_dstrect.h/2; } diff --git a/Engine/lib/sdl/src/render/SDL_sysrender.h b/Engine/lib/sdl/src/render/SDL_sysrender.h index 19dfe8e64..378fc4d97 100644 --- a/Engine/lib/sdl/src/render/SDL_sysrender.h +++ b/Engine/lib/sdl/src/render/SDL_sysrender.h @@ -135,6 +135,9 @@ struct SDL_Renderer int logical_w_backup; int logical_h_backup; + /* Whether or not to force the viewport to even integer intervals */ + SDL_bool integer_scale; + /* The drawable area within the window */ SDL_Rect viewport; SDL_Rect viewport_backup; diff --git a/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c b/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c index 9d7564224..151dbbf04 100644 --- a/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c +++ b/Engine/lib/sdl/src/render/direct3d/SDL_render_d3d.c @@ -512,7 +512,6 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) D3D_RenderData *data; SDL_SysWMinfo windowinfo; HRESULT result; - const char *hint; D3DPRESENT_PARAMETERS pparams; IDirect3DSwapChain9 *chain; D3DCAPS9 caps; @@ -607,8 +606,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) device_flags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } - hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D_THREADSAFE); - if (hint && SDL_atoi(hint)) { + if (SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_FALSE)) { device_flags |= D3DCREATE_MULTITHREADED; } @@ -1004,6 +1002,10 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; + if (!texturedata) { + return 0; + } + if (D3D_RecreateTextureRep(data->device, &texturedata->texture, texture->format, texture->w, texture->h) < 0) { return -1; } @@ -1307,6 +1309,10 @@ D3D_RenderClear(SDL_Renderer * renderer) BackBufferHeight = data->pparams.BackBufferHeight; } + if (renderer->clipping_enabled) { + IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE); + } + /* Don't reset the viewport if we don't have to! */ if (!renderer->viewport.x && !renderer->viewport.y && renderer->viewport.w == BackBufferWidth && @@ -1336,6 +1342,10 @@ D3D_RenderClear(SDL_Renderer * renderer) IDirect3DDevice9_SetViewport(data->device, &viewport); } + if (renderer->clipping_enabled) { + IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, TRUE); + } + if (FAILED(result)) { return D3D_SetError("Clear()", result); } diff --git a/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c b/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c index a48eacee7..df0f1558a 100644 --- a/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c +++ b/Engine/lib/sdl/src/render/direct3d11/SDL_render_d3d11.c @@ -51,6 +51,8 @@ extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNat #endif /* __WINRT__ */ +#define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str + #define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; } @@ -136,14 +138,31 @@ typedef struct } D3D11_RenderData; -/* Defined here so we don't have to include uuid.lib */ -static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; -static const GUID IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; -static const GUID IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } }; -static const GUID IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } }; -static const GUID IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } }; -static const GUID IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } }; -static const GUID IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } }; +/* Define D3D GUIDs here so we don't have to include uuid.lib. +* +* Fix for SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3437: +* The extra 'SDL_' was added to the start of each IID's name, in order +* to prevent build errors on both MinGW-w64 and WinRT/UWP. +* (SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3336 led to +* linker errors in WinRT/UWP builds.) +*/ + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#endif + +static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; +static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; +static const GUID SDL_IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } }; +static const GUID SDL_IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } }; +static const GUID SDL_IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } }; +static const GUID SDL_IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } }; +static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } }; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif /* Direct3D 11.x shaders @@ -961,7 +980,7 @@ D3D11_CreateBlendMode(SDL_Renderer * renderer, blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; result = ID3D11Device_CreateBlendState(data->d3dDevice, &blendDesc, blendStateOutput); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBlendState", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBlendState"), result); return result; } @@ -976,13 +995,11 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc; D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc; - IDXGIAdapter *d3dAdapter = NULL; ID3D11Device *d3dDevice = NULL; ID3D11DeviceContext *d3dContext = NULL; IDXGIDevice1 *dxgiDevice = NULL; HRESULT result = S_OK; UINT creationFlags; - const char *hint; /* This array defines the set of DirectX hardware feature levels this app will support. * Note the ordering should be preserved. @@ -1041,16 +1058,16 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) } #endif /* __WINRT__ */ - result = CreateDXGIFactoryFunc(&IID_IDXGIFactory2, &data->dxgiFactory); + result = CreateDXGIFactoryFunc(&SDL_IID_IDXGIFactory2, (void **)&data->dxgiFactory); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("CreateDXGIFactory"), result); goto done; } /* FIXME: Should we use the default adapter? */ result = IDXGIFactory2_EnumAdapters(data->dxgiFactory, 0, &data->dxgiAdapter); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result); goto done; } @@ -1060,8 +1077,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; /* Make sure Direct3D's debugging feature gets used, if the app requests it. */ - hint = SDL_GetHint(SDL_HINT_RENDER_DIRECT3D11_DEBUG); - if (hint && SDL_atoi(hint) > 0) { + if (SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_FALSE)) { creationFlags |= D3D11_CREATE_DEVICE_DEBUG; } @@ -1079,25 +1095,25 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &d3dContext /* Returns the device immediate context. */ ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", D3D11CreateDevice", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result); goto done; } - result = ID3D11Device_QueryInterface(d3dDevice, &IID_ID3D11Device1, &data->d3dDevice); + result = ID3D11Device_QueryInterface(d3dDevice, &SDL_IID_ID3D11Device1, (void **)&data->d3dDevice); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to ID3D11Device1", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device to ID3D11Device1"), result); goto done; } - result = ID3D11DeviceContext_QueryInterface(d3dContext, &IID_ID3D11DeviceContext1, &data->d3dContext); + result = ID3D11DeviceContext_QueryInterface(d3dContext, &SDL_IID_ID3D11DeviceContext1, (void **)&data->d3dContext); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext to ID3D11DeviceContext1", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext to ID3D11DeviceContext1"), result); goto done; } - result = ID3D11Device_QueryInterface(d3dDevice, &IID_IDXGIDevice1, &dxgiDevice); + result = ID3D11Device_QueryInterface(d3dDevice, &SDL_IID_IDXGIDevice1, (void **)&dxgiDevice); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice1", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device to IDXGIDevice1"), result); goto done; } @@ -1106,7 +1122,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) */ result = IDXGIDevice1_SetMaximumFrameLatency(dxgiDevice, 1); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIDevice1::SetMaximumFrameLatency", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIDevice1::SetMaximumFrameLatency"), result); goto done; } @@ -1135,7 +1151,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) break; default: - SDL_SetError(__FUNCTION__ ", Unexpected feature level: %d", data->featureLevel); + SDL_SetError("%s, Unexpected feature level: %d", __FUNCTION__, data->featureLevel); result = E_FAIL; goto done; } @@ -1148,7 +1164,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->vertexShader ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateVertexShader", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateVertexShader"), result); goto done; } @@ -1161,7 +1177,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->inputLayout ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateInputLayout", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateInputLayout"), result); goto done; } @@ -1173,7 +1189,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->colorPixelShader ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['color' shader]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreatePixelShader ['color' shader]"), result); goto done; } @@ -1184,7 +1200,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->texturePixelShader ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['textures' shader]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreatePixelShader ['textures' shader]"), result); goto done; } @@ -1195,7 +1211,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->yuvPixelShader ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreatePixelShader ['yuv' shader]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreatePixelShader ['yuv' shader]"), result); goto done; } @@ -1210,7 +1226,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->vertexShaderConstants ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex shader constants]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex shader constants]"), result); goto done; } @@ -1230,7 +1246,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->nearestPixelSampler ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [nearest-pixel filter]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [nearest-pixel filter]"), result); goto done; } @@ -1240,7 +1256,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) &data->linearSampler ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateSamplerState [linear filter]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [linear filter]"), result); goto done; } @@ -1258,14 +1274,14 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) rasterDesc.SlopeScaledDepthBias = 0.0f; result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->mainRasterizer); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [main rasterizer]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRasterizerState [main rasterizer]"), result); goto done; } rasterDesc.ScissorEnable = TRUE; result = ID3D11Device_CreateRasterizerState(data->d3dDevice, &rasterDesc, &data->clippedRasterizer); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRasterizerState [clipped rasterizer]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRasterizerState [clipped rasterizer]"), result); goto done; } @@ -1358,7 +1374,6 @@ D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer) static int D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect, BOOL includeViewportOffset) { - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer); switch (rotation) { case DXGI_MODE_ROTATION_IDENTITY: @@ -1444,7 +1459,7 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) &data->swapChain ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForCoreWindow", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForCoreWindow"), result); goto done; } } else if (usingXAML) { @@ -1454,18 +1469,18 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) NULL, &data->swapChain); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForComposition", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForComposition"), result); goto done; } #if WINAPI_FAMILY == WINAPI_FAMILY_APP result = ISwapChainBackgroundPanelNative_SetSwapChain(WINRT_GlobalSwapChainBackgroundPanelNative, (IDXGISwapChain *) data->swapChain); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ISwapChainBackgroundPanelNative::SetSwapChain", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ISwapChainBackgroundPanelNative::SetSwapChain"), result); goto done; } #else - SDL_SetError(__FUNCTION__ ", XAML support is not yet available for Windows Phone"); + SDL_SetError(SDL_COMPOSE_ERROR("XAML support is not yet available for Windows Phone")); result = E_FAIL; goto done; #endif @@ -1484,7 +1499,7 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) &data->swapChain ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIFactory2::CreateSwapChainForHwnd", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForHwnd"), result); goto done; } @@ -1545,7 +1560,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) */ goto done; } else if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::ResizeBuffers", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::ResizeBuffers"), result); goto done; } #endif @@ -1576,7 +1591,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) { result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::SetRotation", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result); goto done; } } @@ -1584,11 +1599,11 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) result = IDXGISwapChain_GetBuffer(data->swapChain, 0, - &IID_ID3D11Texture2D, - &backBuffer + &SDL_IID_ID3D11Texture2D, + (void **)&backBuffer ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::GetBuffer [back-buffer]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::GetBuffer [back-buffer]"), result); goto done; } @@ -1599,7 +1614,7 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) &data->mainRenderTargetView ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device::CreateRenderTargetView", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device::CreateRenderTargetView"), result); goto done; } @@ -1618,14 +1633,12 @@ done: static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) { - D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; return D3D11_CreateWindowSizeDependentResources(renderer); } HRESULT D3D11_HandleDeviceLost(SDL_Renderer * renderer) { - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; HRESULT result = S_OK; D3D11_ReleaseAll(renderer); @@ -1661,7 +1674,7 @@ D3D11_Trim(SDL_Renderer * renderer) HRESULT result = S_OK; IDXGIDevice3 *dxgiDevice = NULL; - result = ID3D11Device_QueryInterface(data->d3dDevice, &IID_IDXGIDevice3, &dxgiDevice); + result = ID3D11Device_QueryInterface(data->d3dDevice, &SDL_IID_IDXGIDevice3, &dxgiDevice); if (FAILED(result)) { //WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result); return; @@ -1702,7 +1715,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) D3D11_TEXTURE2D_DESC textureDesc; D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc; - if (textureFormat == SDL_PIXELFORMAT_UNKNOWN) { + if (textureFormat == DXGI_FORMAT_UNKNOWN) { return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", __FUNCTION__, texture->format); } @@ -1747,7 +1760,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); return -1; } @@ -1765,7 +1778,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); return -1; } @@ -1776,7 +1789,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); return -1; } } @@ -1792,7 +1805,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); return -1; } @@ -1804,7 +1817,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); return -1; } result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice, @@ -1814,7 +1827,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) ); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__ "ID3D11Device1::CreateShaderResourceView", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); return -1; } } @@ -1831,7 +1844,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) &textureData->mainTextureRenderTargetView); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateRenderTargetView", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result); return -1; } } @@ -1887,7 +1900,7 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex NULL, &stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); return -1; } @@ -1900,7 +1913,7 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex &textureMemory ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); SAFE_RELEASE(stagingTexture); return -1; } @@ -2062,7 +2075,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, NULL, &textureData->stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); return -1; } @@ -2075,7 +2088,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, &textureMemory ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); SAFE_RELEASE(textureData->stagingTexture); return -1; } @@ -2359,7 +2372,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, &mappedResource ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [vertex buffer]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result); return -1; } SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes); @@ -2383,7 +2396,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, &rendererData->vertexBuffer ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateBuffer [vertex buffer]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result); return -1; } @@ -2842,18 +2855,18 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, HRESULT result; int status = -1; D3D11_TEXTURE2D_DESC stagingTextureDesc; - D3D11_RECT srcRect; + D3D11_RECT srcRect = {0, 0, 0, 0}; D3D11_BOX srcBox; D3D11_MAPPED_SUBRESOURCE textureMemory; /* Retrieve a pointer to the back buffer: */ result = IDXGISwapChain_GetBuffer(data->swapChain, 0, - &IID_ID3D11Texture2D, - &backBuffer + &SDL_IID_ID3D11Texture2D, + (void **)&backBuffer ); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain1::GetBuffer [get back buffer]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::GetBuffer [get back buffer]"), result); goto done; } @@ -2870,7 +2883,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, NULL, &stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device1::CreateTexture2D [create staging texture]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); goto done; } @@ -2902,7 +2915,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, 0, &textureMemory); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11DeviceContext1::Map [map staging texture]", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); goto done; } @@ -2921,7 +2934,7 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, * Get the error message, and attach some extra data to it. */ char errorMessage[1024]; - SDL_snprintf(errorMessage, sizeof(errorMessage), __FUNCTION__ ", Convert Pixels failed: %s", SDL_GetError()); + SDL_snprintf(errorMessage, sizeof(errorMessage), "%s, Convert Pixels failed: %s", __FUNCTION__, SDL_GetError()); SDL_SetError("%s", errorMessage); goto done; } @@ -2991,7 +3004,7 @@ D3D11_RenderPresent(SDL_Renderer * renderer) /* We probably went through a fullscreen <-> windowed transition */ D3D11_CreateWindowSizeDependentResources(renderer); } else { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGISwapChain::Present", result); + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result); } } } diff --git a/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c b/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c index 6a4fa3ecf..1ca2cb5c4 100644 --- a/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c +++ b/Engine/lib/sdl/src/render/opengl/SDL_render_gl.c @@ -390,7 +390,6 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_Renderer *renderer; GL_RenderData *data; - const char *hint; GLint value; Uint32 window_flags; int profile_mask = 0, major = 0, minor = 0; @@ -450,7 +449,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->GL_BindTexture = GL_BindTexture; renderer->GL_UnbindTexture = GL_UnbindTexture; renderer->info = GL_RenderDriver.info; - renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + renderer->info.flags = SDL_RENDERER_ACCELERATED; renderer->driverdata = data; renderer->window = window; @@ -528,8 +527,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) } /* Check for shader support */ - hint = SDL_GetHint(SDL_HINT_RENDER_OPENGL_SHADERS); - if (!hint || *hint != '0') { + if (SDL_GetHintBoolean(SDL_HINT_RENDER_OPENGL_SHADERS, SDL_TRUE)) { data->shaders = GL_CreateShaderContext(); } SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s", @@ -594,7 +592,6 @@ static int GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) { SDL_GL_GetDrawableSize(renderer->window, w, h); - return 0; } @@ -664,6 +661,11 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_ActivateRenderer(renderer); + if (texture->access == SDL_TEXTUREACCESS_TARGET && + !renderdata->GL_EXT_framebuffer_object_supported) { + return SDL_SetError("Render targets not supported by OpenGL"); + } + if (!convert_format(renderdata, texture->format, &internalFormat, &format, &type)) { return SDL_SetError("Texture format %s not supported by OpenGL", @@ -980,6 +982,10 @@ GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) GL_ActivateRenderer(renderer); + if (!data->GL_EXT_framebuffer_object_supported) { + return SDL_SetError("Render targets not supported by OpenGL"); + } + if (texture == NULL) { data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); return 0; @@ -1013,7 +1019,7 @@ GL_UpdateViewport(SDL_Renderer * renderer) } else { int w, h; - SDL_GetRendererOutputSize(renderer, &w, &h); + SDL_GL_GetDrawableSize(renderer->window, &w, &h); data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h), renderer->viewport.w, renderer->viewport.h); } @@ -1051,7 +1057,7 @@ GL_UpdateClipRect(SDL_Renderer * renderer) } else { int w, h; - SDL_GetRendererOutputSize(renderer, &w, &h); + SDL_GL_GetDrawableSize(renderer->window, &w, &h); data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h); } } else { @@ -1089,21 +1095,17 @@ GL_SetBlendMode(GL_RenderData * data, int blendMode) if (blendMode != data->current.blendMode) { switch (blendMode) { case SDL_BLENDMODE_NONE: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); data->glDisable(GL_BLEND); break; case SDL_BLENDMODE_BLEND: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glEnable(GL_BLEND); data->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); break; case SDL_BLENDMODE_ADD: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glEnable(GL_BLEND); data->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE); break; case SDL_BLENDMODE_MOD: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glEnable(GL_BLEND); data->glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE); break; @@ -1141,8 +1143,16 @@ GL_RenderClear(SDL_Renderer * renderer) (GLfloat) renderer->b * inv255f, (GLfloat) renderer->a * inv255f); + if (renderer->clipping_enabled) { + data->glDisable(GL_SCISSOR_TEST); + } + data->glClear(GL_COLOR_BUFFER_BIT); + if (renderer->clipping_enabled) { + data->glEnable(GL_SCISSOR_TEST); + } + return 0; } @@ -1409,7 +1419,7 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { GL_RenderData *data = (GL_RenderData *) renderer->driverdata; - Uint32 temp_format = SDL_PIXELFORMAT_ARGB8888; + Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888; void *temp_pixels; int temp_pitch; GLint internalFormat; @@ -1426,7 +1436,11 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return SDL_OutOfMemory(); } - convert_format(data, temp_format, &internalFormat, &format, &type); + if (!convert_format(data, temp_format, &internalFormat, &format, &type)) { + SDL_free(temp_pixels); + return SDL_SetError("Texture format %s not supported by OpenGL", + SDL_GetPixelFormatName(temp_format)); + } SDL_GetRendererOutputSize(renderer, &w, &h); @@ -1434,28 +1448,30 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, data->glPixelStorei(GL_PACK_ROW_LENGTH, (temp_pitch / SDL_BYTESPERPIXEL(temp_format))); - data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, - format, type, temp_pixels); + data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + rect->w, rect->h, format, type, temp_pixels); if (GL_CheckError("glReadPixels()", renderer) < 0) { SDL_free(temp_pixels); return -1; } - /* Flip the rows to be top-down */ - length = rect->w * SDL_BYTESPERPIXEL(temp_format); - src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; - dst = (Uint8*)temp_pixels; - tmp = SDL_stack_alloc(Uint8, length); - rows = rect->h / 2; - while (rows--) { - SDL_memcpy(tmp, dst, length); - SDL_memcpy(dst, src, length); - SDL_memcpy(src, tmp, length); - dst += temp_pitch; - src -= temp_pitch; + /* Flip the rows to be top-down if necessary */ + if (!renderer->target) { + length = rect->w * SDL_BYTESPERPIXEL(temp_format); + src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; + dst = (Uint8*)temp_pixels; + tmp = SDL_stack_alloc(Uint8, length); + rows = rect->h / 2; + while (rows--) { + SDL_memcpy(tmp, dst, length); + SDL_memcpy(dst, src, length); + SDL_memcpy(src, tmp, length); + dst += temp_pitch; + src -= temp_pitch; + } + SDL_stack_free(tmp); } - SDL_stack_free(tmp); status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, temp_pitch, diff --git a/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c b/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c index 0d59da360..71f5b3a7a 100644 --- a/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c +++ b/Engine/lib/sdl/src/render/opengles/SDL_render_gles.c @@ -129,8 +129,6 @@ typedef struct GLES_FBOList *framebuffers; GLuint window_framebuffer; - SDL_bool useDrawTexture; - SDL_bool GL_OES_draw_texture_supported; SDL_bool GL_OES_blend_func_separate_supported; } GLES_RenderData; @@ -369,19 +367,6 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } -#if SDL_VIDEO_DRIVER_PANDORA - data->GL_OES_draw_texture_supported = SDL_FALSE; - data->useDrawTexture = SDL_FALSE; -#else - if (SDL_GL_ExtensionSupported("GL_OES_draw_texture")) { - data->GL_OES_draw_texture_supported = SDL_TRUE; - data->useDrawTexture = SDL_TRUE; - } else { - data->GL_OES_draw_texture_supported = SDL_FALSE; - data->useDrawTexture = SDL_FALSE; - } -#endif - value = 0; data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); renderer->info.max_texture_width = value; @@ -605,6 +590,7 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, data->format, data->formattype, src); + renderdata->glDisable(data->type); SDL_free(blob); if (renderdata->glGetError() != GL_NO_ERROR) { @@ -686,18 +672,27 @@ GLES_UpdateViewport(SDL_Renderer * renderer) } else { int w, h; - SDL_GetRendererOutputSize(renderer, &w, &h); + SDL_GL_GetDrawableSize(renderer->window, &w, &h); data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h), renderer->viewport.w, renderer->viewport.h); } + data->glMatrixMode(GL_PROJECTION); + data->glLoadIdentity(); if (renderer->viewport.w && renderer->viewport.h) { - data->glMatrixMode(GL_PROJECTION); - data->glLoadIdentity(); - data->glOrthof((GLfloat) 0, - (GLfloat) renderer->viewport.w, - (GLfloat) renderer->viewport.h, - (GLfloat) 0, 0.0, 1.0); + if (renderer->target) { + data->glOrthof((GLfloat) 0, + (GLfloat) renderer->viewport.w, + (GLfloat) 0, + (GLfloat) renderer->viewport.h, + 0.0, 1.0); + } else { + data->glOrthof((GLfloat) 0, + (GLfloat) renderer->viewport.w, + (GLfloat) renderer->viewport.h, + (GLfloat) 0, + 0.0, 1.0); + } } return 0; } @@ -720,7 +715,7 @@ GLES_UpdateClipRect(SDL_Renderer * renderer) } else { int w, h; - SDL_GetRendererOutputSize(renderer, &w, &h); + SDL_GL_GetDrawableSize(renderer->window, &w, &h); data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h); } } else { @@ -749,11 +744,9 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode) if (blendMode != data->current.blendMode) { switch (blendMode) { case SDL_BLENDMODE_NONE: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); data->glDisable(GL_BLEND); break; case SDL_BLENDMODE_BLEND: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glEnable(GL_BLEND); if (data->GL_OES_blend_func_separate_supported) { data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); @@ -762,7 +755,6 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode) } break; case SDL_BLENDMODE_ADD: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glEnable(GL_BLEND); if (data->GL_OES_blend_func_separate_supported) { data->glBlendFuncSeparateOES(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE); @@ -771,7 +763,6 @@ GLES_SetBlendMode(GLES_RenderData * data, int blendMode) } break; case SDL_BLENDMODE_MOD: - data->glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); data->glEnable(GL_BLEND); if (data->GL_OES_blend_func_separate_supported) { data->glBlendFuncSeparateOES(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE); @@ -825,9 +816,17 @@ GLES_RenderClear(SDL_Renderer * renderer) (GLfloat) renderer->g * inv255f, (GLfloat) renderer->b * inv255f, (GLfloat) renderer->a * inv255f); + + if (renderer->clipping_enabled) { + data->glDisable(GL_SCISSOR_TEST); + } data->glClear(GL_COLOR_BUFFER_BIT); + if (renderer->clipping_enabled) { + data->glEnable(GL_SCISSOR_TEST); + } + return 0; } @@ -952,71 +951,42 @@ GLES_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, GLES_SetTexCoords(data, SDL_TRUE); - if (data->GL_OES_draw_texture_supported && data->useDrawTexture) { - /* this code is a little funny because the viewport is upside down vs SDL's coordinate system */ - GLint cropRect[4]; - int w, h; - SDL_Window *window = renderer->window; + minx = dstrect->x; + miny = dstrect->y; + maxx = dstrect->x + dstrect->w; + maxy = dstrect->y + dstrect->h; - SDL_GetWindowSize(window, &w, &h); - if (renderer->target) { - cropRect[0] = srcrect->x; - cropRect[1] = srcrect->y; - cropRect[2] = srcrect->w; - cropRect[3] = srcrect->h; - data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, - cropRect); - data->glDrawTexfOES(renderer->viewport.x + dstrect->x, renderer->viewport.y + dstrect->y, 0, - dstrect->w, dstrect->h); - } else { - cropRect[0] = srcrect->x; - cropRect[1] = srcrect->y + srcrect->h; - cropRect[2] = srcrect->w; - cropRect[3] = -srcrect->h; - data->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, - cropRect); - data->glDrawTexfOES(renderer->viewport.x + dstrect->x, - h - (renderer->viewport.y + dstrect->y) - dstrect->h, 0, - dstrect->w, dstrect->h); - } - } else { + minu = (GLfloat) srcrect->x / texture->w; + minu *= texturedata->texw; + maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; + maxu *= texturedata->texw; + minv = (GLfloat) srcrect->y / texture->h; + minv *= texturedata->texh; + maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; + maxv *= texturedata->texh; - minx = dstrect->x; - miny = dstrect->y; - maxx = dstrect->x + dstrect->w; - maxy = dstrect->y + dstrect->h; + vertices[0] = minx; + vertices[1] = miny; + vertices[2] = maxx; + vertices[3] = miny; + vertices[4] = minx; + vertices[5] = maxy; + vertices[6] = maxx; + vertices[7] = maxy; - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; + texCoords[0] = minu; + texCoords[1] = minv; + texCoords[2] = maxu; + texCoords[3] = minv; + texCoords[4] = minu; + texCoords[5] = maxv; + texCoords[6] = maxu; + texCoords[7] = maxv; - vertices[0] = minx; - vertices[1] = miny; - vertices[2] = maxx; - vertices[3] = miny; - vertices[4] = minx; - vertices[5] = maxy; - vertices[6] = maxx; - vertices[7] = maxy; + data->glVertexPointer(2, GL_FLOAT, 0, vertices); + data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - texCoords[0] = minu; - texCoords[1] = minv; - texCoords[2] = maxu; - texCoords[3] = minv; - texCoords[4] = minu; - texCoords[5] = maxv; - texCoords[6] = maxu; - texCoords[7] = maxv; - - data->glVertexPointer(2, GL_FLOAT, 0, vertices); - data->glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - } data->glDisable(GL_TEXTURE_2D); return 0; @@ -1117,7 +1087,7 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; + Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888; void *temp_pixels; int temp_pitch; Uint8 *src, *dst, *tmp; @@ -1136,23 +1106,25 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, data->glPixelStorei(GL_PACK_ALIGNMENT, 1); - data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, - GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); + data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); - /* Flip the rows to be top-down */ - length = rect->w * SDL_BYTESPERPIXEL(temp_format); - src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; - dst = (Uint8*)temp_pixels; - tmp = SDL_stack_alloc(Uint8, length); - rows = rect->h / 2; - while (rows--) { - SDL_memcpy(tmp, dst, length); - SDL_memcpy(dst, src, length); - SDL_memcpy(src, tmp, length); - dst += temp_pitch; - src -= temp_pitch; + /* Flip the rows to be top-down if necessary */ + if (!renderer->target) { + length = rect->w * SDL_BYTESPERPIXEL(temp_format); + src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; + dst = (Uint8*)temp_pixels; + tmp = SDL_stack_alloc(Uint8, length); + rows = rect->h / 2; + while (rows--) { + SDL_memcpy(tmp, dst, length); + SDL_memcpy(dst, src, length); + SDL_memcpy(src, tmp, length); + dst += temp_pitch; + src -= temp_pitch; + } + SDL_stack_free(tmp); } - SDL_stack_free(tmp); status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, temp_pitch, diff --git a/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c b/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c index e41ab6231..c846a7b39 100644 --- a/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c +++ b/Engine/lib/sdl/src/render/opengles2/SDL_render_gles2.c @@ -388,7 +388,7 @@ GLES2_UpdateViewport(SDL_Renderer * renderer) } else { int w, h; - SDL_GetRendererOutputSize(renderer, &w, &h); + SDL_GL_GetDrawableSize(renderer->window, &w, &h); data->glViewport(renderer->viewport.x, (h - renderer->viewport.y - renderer->viewport.h), renderer->viewport.w, renderer->viewport.h); } @@ -417,7 +417,7 @@ GLES2_UpdateClipRect(SDL_Renderer * renderer) } else { int w, h; - SDL_GetRendererOutputSize(renderer, &w, &h); + SDL_GL_GetDrawableSize(renderer->window, &w, &h); data->glScissor(renderer->viewport.x + rect->x, h - renderer->viewport.y - rect->y - rect->h, rect->w, rect->h); } } else { @@ -1327,8 +1327,16 @@ GLES2_RenderClear(SDL_Renderer * renderer) data->clear_a = renderer->a; } + if (renderer->clipping_enabled) { + data->glDisable(GL_SCISSOR_TEST); + } + data->glClear(GL_COLOR_BUFFER_BIT); + if (renderer->clipping_enabled) { + data->glEnable(GL_SCISSOR_TEST); + } + return 0; } @@ -1817,7 +1825,7 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata; - Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888; + Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888; void *temp_pixels; int temp_pitch; Uint8 *src, *dst, *tmp; @@ -1834,26 +1842,28 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_GetRendererOutputSize(renderer, &w, &h); - data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, - GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); + data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); if (GL_CheckError("glReadPixels()", renderer) < 0) { return -1; } - /* Flip the rows to be top-down */ - length = rect->w * SDL_BYTESPERPIXEL(temp_format); - src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; - dst = (Uint8*)temp_pixels; - tmp = SDL_stack_alloc(Uint8, length); - rows = rect->h / 2; - while (rows--) { - SDL_memcpy(tmp, dst, length); - SDL_memcpy(dst, src, length); - SDL_memcpy(src, tmp, length); - dst += temp_pitch; - src -= temp_pitch; + /* Flip the rows to be top-down if necessary */ + if (!renderer->target) { + length = rect->w * SDL_BYTESPERPIXEL(temp_format); + src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; + dst = (Uint8*)temp_pixels; + tmp = SDL_stack_alloc(Uint8, length); + rows = rect->h / 2; + while (rows--) { + SDL_memcpy(tmp, dst, length); + SDL_memcpy(dst, src, length); + SDL_memcpy(src, tmp, length); + dst += temp_pitch; + src -= temp_pitch; + } + SDL_stack_free(tmp); } - SDL_stack_free(tmp); status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, temp_pitch, @@ -1959,9 +1969,15 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) int profile_mask = 0, major = 0, minor = 0; SDL_bool changed_window = SDL_FALSE; - SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask); - SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); - SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); + if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask) < 0) { + goto error; + } + if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major) < 0) { + goto error; + } + if (SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor) < 0) { + goto error; + } window_flags = SDL_GetWindowFlags(window); if (!(window_flags & SDL_WINDOW_OPENGL) || diff --git a/Engine/lib/sdl/src/render/psp/SDL_render_psp.c b/Engine/lib/sdl/src/render/psp/SDL_render_psp.c index 8e8c87353..f2851319e 100644 --- a/Engine/lib/sdl/src/render/psp/SDL_render_psp.c +++ b/Engine/lib/sdl/src/render/psp/SDL_render_psp.c @@ -50,6 +50,8 @@ static SDL_Renderer *PSP_CreateRenderer(SDL_Window * window, Uint32 flags); static void PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event); static int PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int PSP_SetTextureColorMod(SDL_Renderer * renderer, + SDL_Texture * texture); static int PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch); @@ -359,6 +361,7 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->WindowEvent = PSP_WindowEvent; renderer->CreateTexture = PSP_CreateTexture; + renderer->SetTextureColorMod = PSP_SetTextureColorMod; renderer->UpdateTexture = PSP_UpdateTexture; renderer->LockTexture = PSP_LockTexture; renderer->UnlockTexture = PSP_UnlockTexture; @@ -501,6 +504,11 @@ PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } +static int +PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) +{ + return SDL_Unsupported(); +} void TextureActivate(SDL_Texture * texture) @@ -853,7 +861,7 @@ PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { - return 0; + return SDL_Unsupported(); } diff --git a/Engine/lib/sdl/src/render/software/SDL_render_sw.c b/Engine/lib/sdl/src/render/software/SDL_render_sw.c index dadd2442f..e7a6cd88d 100644 --- a/Engine/lib/sdl/src/render/software/SDL_render_sw.c +++ b/Engine/lib/sdl/src/render/software/SDL_render_sw.c @@ -677,8 +677,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, } if (!retval) { - SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, -angle, &dstwidth, &dstheight, &cangle, &sangle); - surface_rotated = SDLgfx_rotateSurface(surface_scaled, -angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); + SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle); + surface_rotated = SDLgfx_rotateSurface(surface_scaled, angle, dstwidth/2, dstheight/2, GetScaleQuality(), flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); if(surface_rotated) { /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ abscenterx = final_rect.x + (int)center->x; diff --git a/Engine/lib/sdl/src/render/software/SDL_rotate.c b/Engine/lib/sdl/src/render/software/SDL_rotate.c index 8d92758f8..0141d174d 100644 --- a/Engine/lib/sdl/src/render/software/SDL_rotate.c +++ b/Engine/lib/sdl/src/render/software/SDL_rotate.c @@ -110,31 +110,105 @@ SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle) { - double x, y, cx, cy, sx, sy; - double radangle; - int dstwidthhalf, dstheighthalf; - - /* - * Determine destination width and height by rotating a centered source box - */ - radangle = angle * (M_PI / 180.0); - *sangle = SDL_sin(radangle); - *cangle = SDL_cos(radangle); - x = (double)(width / 2); - y = (double)(height / 2); - cx = *cangle * x; - cy = *cangle * y; - sx = *sangle * x; - sy = *sangle * y; - - dstwidthhalf = MAX((int) - SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1); - dstheighthalf = MAX((int) - SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1); - *dstwidth = 2 * dstwidthhalf; - *dstheight = 2 * dstheighthalf; + /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */ + int angle90 = (int)(angle/90); + if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */ + angle90 %= 4; + if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + if(angle90 & 1) { + *dstwidth = height; + *dstheight = width; + *cangle = 0; + *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */ + } else { + *dstwidth = width; + *dstheight = height; + *cangle = angle90 == 0 ? 1 : -1; + *sangle = 0; + } + } else { + double x, y, cx, cy, sx, sy; + double radangle; + int dstwidthhalf, dstheighthalf; + /* + * Determine destination width and height by rotating a centered source box + */ + radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */ + *sangle = SDL_sin(radangle); + *cangle = SDL_cos(radangle); + x = (double)(width / 2); + y = (double)(height / 2); + cx = *cangle * x; + cy = *cangle * y; + sx = *sangle * x; + sy = *sangle * y; + + dstwidthhalf = MAX((int) + SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1); + dstheighthalf = MAX((int) + SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1); + *dstwidth = 2 * dstwidthhalf; + *dstheight = 2 * dstheighthalf; + } } +/* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */ +static void +computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy, + int *sincx, int *sincy, int *signx, int *signy) +{ + int pitch = flipy ? -src->pitch : src->pitch; + if (flipx) { + bpp = -bpp; + } + switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break; + case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break; + case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break; + case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break; + } + if (flipx) { + *signx = -*signx; + } + if (flipy) { + *signy = -*signy; + } +} + +/* Performs a relatively fast rotation/flip when the angle is a multiple of 90 degrees. */ +#define TRANSFORM_SURFACE_90(pixelType) \ + int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy; \ + Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de; \ + \ + computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \ + if (signx < 0) sp += (src->w-1)*sizeof(pixelType); \ + if (signy < 0) sp += (src->h-1)*src->pitch; \ + \ + for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \ + if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \ + SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \ + sp += dst->w*sizeof(pixelType); \ + dp += dst->w*sizeof(pixelType); \ + } else { \ + for (de = dp + dst->w*sizeof(pixelType); dp != de; sp += sincx, dp += sizeof(pixelType)) { \ + *(pixelType*)dp = *(pixelType*)sp; \ + } \ + } \ + } + +static void +transformSurfaceRGBA90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) +{ + TRANSFORM_SURFACE_90(tColorRGBA); +} + +static void +transformSurfaceY90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) +{ + TRANSFORM_SURFACE_90(tColorY); +} + +#undef TRANSFORM_SURFACE_90 /* ! \brief Internal 32 bit rotozoomer with optional anti-aliasing. @@ -341,9 +415,9 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, { SDL_Surface *rz_src; SDL_Surface *rz_dst; - int is32bit; + int is32bit, angle90; int i; - Uint8 r,g,b; + Uint8 r = 0, g = 0, b = 0; Uint32 colorkey = 0; int colorKeyAvailable = 0; double sangleinv, cangleinv; @@ -370,18 +444,13 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, */ rz_src = src; } else { - Uint32 format = SDL_MasksToPixelFormatEnum(32, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 -#else - 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff -#endif - ); - rz_src = SDL_ConvertSurfaceFormat(src, format, src->flags); + rz_src = SDL_ConvertSurfaceFormat(src, SDL_PIXELFORMAT_ARGB32, src->flags); + if (rz_src == NULL) { + return NULL; + } is32bit = 1; } - /* Determine target size */ /* _rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, &dstwidth, &dstheight, &cangle, &sangle); */ @@ -394,7 +463,6 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, /* * Alloc space to completely contain the rotated surface */ - rz_dst = NULL; if (is32bit) { /* * Target surface is 32bit with source RGBA/ABGR ordering @@ -430,6 +498,18 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, SDL_LockSurface(rz_src); } + /* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce + * the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near + * multiples of 90 degrees. + */ + angle90 = (int)(angle/90); + if (angle90 == angle/90) { + angle90 %= 4; + if (angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + } else { + angle90 = -1; + } + /* * Check which kind of surface we have */ @@ -437,10 +517,11 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, /* * Call the 32bit transformation routine to do the rotation (using alpha) */ - _transformSurfaceRGBA(rz_src, rz_dst, centerx, centery, - (int) (sangleinv), (int) (cangleinv), - flipx, flipy, - smooth); + if (angle90 >= 0) { + transformSurfaceRGBA90(rz_src, rz_dst, angle90, flipx, flipy); + } else { + _transformSurfaceRGBA(rz_src, rz_dst, centerx, centery, (int) (sangleinv), (int) (cangleinv), flipx, flipy, smooth); + } /* * Turn on source-alpha support */ @@ -457,9 +538,11 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, /* * Call the 8bit transformation routine to do the rotation */ - transformSurfaceY(rz_src, rz_dst, centerx, centery, - (int) (sangleinv), (int) (cangleinv), - flipx, flipy); + if(angle90 >= 0) { + transformSurfaceY90(rz_src, rz_dst, angle90, flipx, flipy); + } else { + transformSurfaceY(rz_src, rz_dst, centerx, centery, (int)(sangleinv), (int)(cangleinv), flipx, flipy); + } SDL_SetColorKey(rz_dst, /* SDL_SRCCOLORKEY */ SDL_TRUE | SDL_RLEACCEL, _colorkey(rz_src)); } diff --git a/Engine/lib/sdl/src/stdlib/SDL_iconv.c b/Engine/lib/sdl/src/stdlib/SDL_iconv.c index 8f0403734..34bcd8431 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_iconv.c +++ b/Engine/lib/sdl/src/stdlib/SDL_iconv.c @@ -30,7 +30,8 @@ #include "SDL_stdinc.h" #include "SDL_endian.h" -#ifdef HAVE_ICONV +#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) +#include /* Depending on which standard the iconv() was implemented with, iconv() may or may not use const char ** for the inbuf param. diff --git a/Engine/lib/sdl/src/stdlib/SDL_qsort.c b/Engine/lib/sdl/src/stdlib/SDL_qsort.c index 0d1978424..2ef33b15e 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_qsort.c +++ b/Engine/lib/sdl/src/stdlib/SDL_qsort.c @@ -1,46 +1,23 @@ -/* qsort.c - * (c) 1998 Gareth McCaughan - * - * This is a drop-in replacement for the C library's |qsort()| routine. - * - * Features: - * - Median-of-three pivoting (and more) - * - Truncation and final polishing by a single insertion sort - * - Early truncation when no swaps needed in pivoting step - * - Explicit recursion, guaranteed not to overflow - * - A few little wrinkles stolen from the GNU |qsort()|. - * - separate code for non-aligned / aligned / word-size objects - * - * This code may be reproduced freely provided - * - this file is retained unaltered apart from minor - * changes for portability and efficiency - * - no changes are made to this comment - * - any changes that *are* made are clearly flagged - * - the _ID string below is altered by inserting, after - * the date, the string " altered" followed at your option - * by other material. (Exceptions: you may change the name - * of the exported routine without changing the ID string. - * You may change the values of the macros TRUNC_* and - * PIVOT_THRESHOLD without changing the ID string, provided - * they remain constants with TRUNC_nonaligned, TRUNC_aligned - * and TRUNC_words/WORD_BYTES between 8 and 24, and - * PIVOT_THRESHOLD between 32 and 200.) - * - * You may use it in anything you like; you may make money - * out of it; you may distribute it in object form or as - * part of an executable without including source code; - * you don't have to credit me. (But it would be nice if - * you did.) - * - * If you find problems with this code, or find ways of - * making it significantly faster, please let me know! - * My e-mail address, valid as of early 1998 and certainly - * OK for at least the next 18 months, is - * gjm11@dpmms.cam.ac.uk - * Thanks! - * - * Gareth McCaughan Peterhouse Cambridge 1998 - */ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ #if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) #define SDL_DISABLE_ANALYZE_MACROS 1 @@ -48,11 +25,6 @@ #include "../SDL_internal.h" -/* -#include -#include -#include -*/ #include "SDL_stdinc.h" #include "SDL_assert.h" @@ -62,34 +34,128 @@ SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, c { qsort(base, nmemb, size, compare); } + #else #ifdef assert #undef assert #endif -#define assert(X) SDL_assert(X) +#define assert SDL_assert #ifdef malloc #undef malloc #endif -#define malloc SDL_malloc +#define malloc SDL_malloc #ifdef free #undef free #endif -#define free SDL_free +#define free SDL_free #ifdef memcpy #undef memcpy #endif -#define memcpy SDL_memcpy +#define memcpy SDL_memcpy #ifdef memmove #undef memmove #endif -#define memmove SDL_memmove -#ifdef qsort -#undef qsort +#define memmove SDL_memmove +#ifdef qsortG +#undef qsortG #endif -#define qsort SDL_qsort +#define qsortG SDL_qsort -static const char _ID[] = ""; +/* +This code came from Gareth McCaughan, under the zlib license. +Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.14 + +Everything below this comment until the HAVE_QSORT #endif was from Gareth +(any minor changes will be noted inline). + +Thank you to Gareth for relicensing this code under the zlib license for our +benefit! + +--ryan. +*/ + +/* This is a drop-in replacement for the C library's |qsort()| routine. + * + * It is intended for use where you know or suspect that your + * platform's qsort is bad. If that isn't the case, then you + * should probably use the qsort your system gives you in preference + * to mine -- it will likely have been tested and tuned better. + * + * Features: + * - Median-of-three pivoting (and more) + * - Truncation and final polishing by a single insertion sort + * - Early truncation when no swaps needed in pivoting step + * - Explicit recursion, guaranteed not to overflow + * - A few little wrinkles stolen from the GNU |qsort()|. + * (For the avoidance of doubt, no code was stolen, only + * broad ideas.) + * - separate code for non-aligned / aligned / word-size objects + * + * Earlier releases of this code used an idiosyncratic licence + * I wrote myself, because I'm an idiot. The code is now released + * under the "zlib/libpng licence"; you will find the actual + * terms in the next comment. I request (but do not require) + * that if you make any changes beyond the name of the exported + * routine and reasonable tweaks to the TRUNC_* and + * PIVOT_THRESHOLD values, you modify the _ID string so as + * to make it clear that you have changed the code. + * + * If you find problems with this code, or find ways of + * making it significantly faster, please let me know! + * My e-mail address, valid as of early 2016 and for the + * foreseeable future, is + * gareth.mccaughan@pobox.com + * Thanks! + * + * Gareth McCaughan + */ + +/* Copyright (c) 1998-2016 Gareth McCaughan + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; + * you must not claim that you wrote the original software. + * If you use this software in a product, an acknowledgment + * in the product documentation would be appreciated but + * is not required. + * + * 2. Altered source versions must be plainly marked as such, + * and must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + */ + +/* Revision history since release: + * 1998-03-19 v1.12 First release I have any records of. + * 2007-09-02 v1.13 Fix bug kindly reported by Dan Bodoh + * (premature termination of recursion). + * Add a few clarifying comments. + * Minor improvements to debug output. + * 2016-02-21 v1.14 Replace licence with 2-clause BSD, + * and clarify a couple of things in + * comments. No code changes. + */ + +/* BEGIN SDL CHANGE ... commented this out with an #if 0 block. --ryan. */ +#if 0 +#include +#include +#include + +#define DEBUG_QSORT + +static char _ID[]=""; +#endif +/* END SDL CHANGE ... commented this out with an #if 0 block. --ryan. */ /* How many bytes are there per word? (Must be a power of 2, * and must in fact equal sizeof(int).) @@ -110,7 +176,7 @@ static const char _ID[] = ""; */ #define TRUNC_nonaligned 12 #define TRUNC_aligned 12 -#define TRUNC_words 12*WORD_BYTES /* nb different meaning */ +#define TRUNC_words 12*WORD_BYTES /* nb different meaning */ /* We use a simple pivoting algorithm for shortish sub-arrays * and a more complicated one for larger ones. The threshold @@ -118,11 +184,7 @@ static const char _ID[] = ""; */ #define PIVOT_THRESHOLD 40 -typedef struct -{ - char *first; - char *last; -} stack_entry; +typedef struct { char * first; char * last; } stack_entry; #define pushLeft {stack[stacktop].first=ffirst;stack[stacktop++].last=last;} #define pushRight {stack[stacktop].first=first;stack[stacktop++].last=llast;} #define doLeft {first=ffirst;llast=last;continue;} @@ -197,7 +259,9 @@ typedef struct * 16-bit |int|s and 4096-bit |size_t|s. :-) */ -/* The recursion logic is the same in each case: */ +/* The recursion logic is the same in each case. + * We keep chopping up until we reach subarrays of size + * strictly less than Trunc; we leave these unsorted. */ #define Recurse(Trunc) \ { size_t l=last-ffirst,r=llast-first; \ if (lPIVOT_THRESHOLD*sz) mid=pivot_big(first,mid,last,sz,compare);\ + if (last-first>PIVOT_THRESHOLD*sz) mid=pivot_big(first,mid,last,sz,compare);\ else { \ if (compare(first,mid)<0) { \ if (compare(mid,last)>0) { \ @@ -235,26 +299,28 @@ typedef struct /* and so is the partitioning logic: */ #define Partition(swapper,sz) { \ - int swapped=0; \ do { \ while (compare(first,pivot)<0) first+=sz; \ while (compare(pivot,last)<0) last-=sz; \ if (firstlimit ? limit : nmemb-1)*sz;\ + last=first + ((nmemb>limit ? limit : nmemb)-1)*sz;\ while (last!=base) { \ if (compare(first,last)>0) first=last; \ last-=sz; } \ @@ -294,188 +360,175 @@ typedef struct /* ---------------------------------------------------------------------- */ -static char * -pivot_big(char *first, char *mid, char *last, size_t size, - int compare(const void *, const void *)) -{ - size_t d = (((last - first) / size) >> 3) * size; - char *m1, *m2, *m3; - { - char *a = first, *b = first + d, *c = first + 2 * d; +static char * pivot_big(char *first, char *mid, char *last, size_t size, + int compare(const void *, const void *)) { + int d=(((last-first)/size)>>3)*size; #ifdef DEBUG_QSORT - fprintf(stderr, "< %d %d %d\n", *(int *) a, *(int *) b, *(int *) c); +fprintf(stderr, "pivot_big: first=%p last=%p size=%lu n=%lu\n", first, (unsigned long)last, size, (unsigned long)((last-first+1)/size)); #endif - m1 = compare(a, b) < 0 ? - (compare(b, c) < 0 ? b : (compare(a, c) < 0 ? c : a)) - : (compare(a, c) < 0 ? a : (compare(b, c) < 0 ? c : b)); - } - { - char *a = mid - d, *b = mid, *c = mid + d; + char *m1,*m2,*m3; + { char *a=first, *b=first+d, *c=first+2*d; #ifdef DEBUG_QSORT - fprintf(stderr, ". %d %d %d\n", *(int *) a, *(int *) b, *(int *) c); +fprintf(stderr,"< %d %d %d @ %p %p %p\n",*(int*)a,*(int*)b,*(int*)c, a,b,c); #endif - m2 = compare(a, b) < 0 ? - (compare(b, c) < 0 ? b : (compare(a, c) < 0 ? c : a)) - : (compare(a, c) < 0 ? a : (compare(b, c) < 0 ? c : b)); - } - { - char *a = last - 2 * d, *b = last - d, *c = last; + m1 = compare(a,b)<0 ? + (compare(b,c)<0 ? b : (compare(a,c)<0 ? c : a)) + : (compare(a,c)<0 ? a : (compare(b,c)<0 ? c : b)); + } + { char *a=mid-d, *b=mid, *c=mid+d; #ifdef DEBUG_QSORT - fprintf(stderr, "> %d %d %d\n", *(int *) a, *(int *) b, *(int *) c); +fprintf(stderr,". %d %d %d @ %p %p %p\n",*(int*)a,*(int*)b,*(int*)c, a,b,c); #endif - m3 = compare(a, b) < 0 ? - (compare(b, c) < 0 ? b : (compare(a, c) < 0 ? c : a)) - : (compare(a, c) < 0 ? a : (compare(b, c) < 0 ? c : b)); - } + m2 = compare(a,b)<0 ? + (compare(b,c)<0 ? b : (compare(a,c)<0 ? c : a)) + : (compare(a,c)<0 ? a : (compare(b,c)<0 ? c : b)); + } + { char *a=last-2*d, *b=last-d, *c=last; #ifdef DEBUG_QSORT - fprintf(stderr, "-> %d %d %d\n", *(int *) m1, *(int *) m2, *(int *) m3); +fprintf(stderr,"> %d %d %d @ %p %p %p\n",*(int*)a,*(int*)b,*(int*)c, a,b,c); #endif - return compare(m1, m2) < 0 ? - (compare(m2, m3) < 0 ? m2 : (compare(m1, m3) < 0 ? m3 : m1)) - : (compare(m1, m3) < 0 ? m1 : (compare(m2, m3) < 0 ? m3 : m2)); + m3 = compare(a,b)<0 ? + (compare(b,c)<0 ? b : (compare(a,c)<0 ? c : a)) + : (compare(a,c)<0 ? a : (compare(b,c)<0 ? c : b)); + } +#ifdef DEBUG_QSORT +fprintf(stderr,"-> %d %d %d @ %p %p %p\n",*(int*)m1,*(int*)m2,*(int*)m3, m1,m2,m3); +#endif + return compare(m1,m2)<0 ? + (compare(m2,m3)<0 ? m2 : (compare(m1,m3)<0 ? m3 : m1)) + : (compare(m1,m3)<0 ? m1 : (compare(m2,m3)<0 ? m3 : m2)); } /* ---------------------------------------------------------------------- */ -static void -qsort_nonaligned(void *base, size_t nmemb, size_t size, - int (*compare) (const void *, const void *)) -{ +static void qsort_nonaligned(void *base, size_t nmemb, size_t size, + int (*compare)(const void *, const void *)) { - stack_entry stack[STACK_SIZE]; - int stacktop = 0; - char *first, *last; - char *pivot = malloc(size); - size_t trunc = TRUNC_nonaligned * size; - assert(pivot != 0); + stack_entry stack[STACK_SIZE]; + int stacktop=0; + char *first,*last; + char *pivot=malloc(size); + size_t trunc=TRUNC_nonaligned*size; + assert(pivot!=0); - first = (char *) base; - last = first + (nmemb - 1) * size; + first=(char*)base; last=first+(nmemb-1)*size; - if ((size_t) (last - first) > trunc) { - char *ffirst = first, *llast = last; - while (1) { - /* Select pivot */ - { - char *mid = first + size * ((last - first) / size >> 1); - Pivot(SWAP_nonaligned, size); - memcpy(pivot, mid, size); - } - /* Partition. */ - Partition(SWAP_nonaligned, size); - /* Prepare to recurse/iterate. */ - Recurse(trunc)} + if (last-first>=trunc) { + char *ffirst=first, *llast=last; + while (1) { + /* Select pivot */ + { char * mid=first+size*((last-first)/size >> 1); + Pivot(SWAP_nonaligned,size); + memcpy(pivot,mid,size); + } + /* Partition. */ + Partition(SWAP_nonaligned,size); + /* Prepare to recurse/iterate. */ + Recurse(trunc) } - PreInsertion(SWAP_nonaligned, TRUNC_nonaligned, size); - Insertion(SWAP_nonaligned); - free(pivot); + } + PreInsertion(SWAP_nonaligned,TRUNC_nonaligned,size); + Insertion(SWAP_nonaligned); + free(pivot); } -static void -qsort_aligned(void *base, size_t nmemb, size_t size, - int (*compare) (const void *, const void *)) -{ +static void qsort_aligned(void *base, size_t nmemb, size_t size, + int (*compare)(const void *, const void *)) { - stack_entry stack[STACK_SIZE]; - int stacktop = 0; - char *first, *last; - char *pivot = malloc(size); - size_t trunc = TRUNC_aligned * size; - assert(pivot != 0); + stack_entry stack[STACK_SIZE]; + int stacktop=0; + char *first,*last; + char *pivot=malloc(size); + size_t trunc=TRUNC_aligned*size; + assert(pivot!=0); - first = (char *) base; - last = first + (nmemb - 1) * size; + first=(char*)base; last=first+(nmemb-1)*size; - if ((size_t) (last - first) > trunc) { - char *ffirst = first, *llast = last; - while (1) { - /* Select pivot */ - { - char *mid = first + size * ((last - first) / size >> 1); - Pivot(SWAP_aligned, size); - memcpy(pivot, mid, size); - } - /* Partition. */ - Partition(SWAP_aligned, size); - /* Prepare to recurse/iterate. */ - Recurse(trunc)} + if (last-first>=trunc) { + char *ffirst=first,*llast=last; + while (1) { + /* Select pivot */ + { char * mid=first+size*((last-first)/size >> 1); + Pivot(SWAP_aligned,size); + memcpy(pivot,mid,size); + } + /* Partition. */ + Partition(SWAP_aligned,size); + /* Prepare to recurse/iterate. */ + Recurse(trunc) } - PreInsertion(SWAP_aligned, TRUNC_aligned, size); - Insertion(SWAP_aligned); - free(pivot); + } + PreInsertion(SWAP_aligned,TRUNC_aligned,size); + Insertion(SWAP_aligned); + free(pivot); } -static void -qsort_words(void *base, size_t nmemb, - int (*compare) (const void *, const void *)) -{ +static void qsort_words(void *base, size_t nmemb, + int (*compare)(const void *, const void *)) { - stack_entry stack[STACK_SIZE]; - int stacktop = 0; - char *first, *last; - char *pivot = malloc(WORD_BYTES); - assert(pivot != 0); + stack_entry stack[STACK_SIZE]; + int stacktop=0; + char *first,*last; + char *pivot=malloc(WORD_BYTES); + assert(pivot!=0); - first = (char *) base; - last = first + (nmemb - 1) * WORD_BYTES; + first=(char*)base; last=first+(nmemb-1)*WORD_BYTES; - if (last - first > TRUNC_words) { - char *ffirst = first, *llast = last; - while (1) { + if (last-first>=TRUNC_words) { + char *ffirst=first, *llast=last; + while (1) { #ifdef DEBUG_QSORT - fprintf(stderr, "Doing %d:%d: ", - (first - (char *) base) / WORD_BYTES, - (last - (char *) base) / WORD_BYTES); +fprintf(stderr,"Doing %d:%d: ", + (first-(char*)base)/WORD_BYTES, + (last-(char*)base)/WORD_BYTES); #endif - /* Select pivot */ - { - char *mid = - first + WORD_BYTES * ((last - first) / (2 * WORD_BYTES)); - Pivot(SWAP_words, WORD_BYTES); - *(int *) pivot = *(int *) mid; - } + /* Select pivot */ + { char * mid=first+WORD_BYTES*((last-first) / (2*WORD_BYTES)); + Pivot(SWAP_words,WORD_BYTES); + *(int*)pivot=*(int*)mid; #ifdef DEBUG_QSORT - fprintf(stderr, "pivot=%d\n", *(int *) pivot); +fprintf(stderr,"pivot = %p = #%lu = %d\n", mid, (unsigned long)(((int*)mid)-((int*)base)), *(int*)mid); #endif - /* Partition. */ - Partition(SWAP_words, WORD_BYTES); - /* Prepare to recurse/iterate. */ - Recurse(TRUNC_words)} + } + /* Partition. */ + Partition(SWAP_words,WORD_BYTES); +#ifdef DEBUG_QSORT +fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base)/4lu, (last-(char*)base)/4lu); +#endif + /* Prepare to recurse/iterate. */ + Recurse(TRUNC_words) } - PreInsertion(SWAP_words, (TRUNC_words / WORD_BYTES), WORD_BYTES); - /* Now do insertion sort. */ - last = ((char *) base) + nmemb * WORD_BYTES; - for (first = ((char *) base) + WORD_BYTES; first != last; - first += WORD_BYTES) { - /* Find the right place for |first|. My apologies for var reuse */ - int *pl = (int *) (first - WORD_BYTES), *pr = (int *) first; - *(int *) pivot = *(int *) first; - for (; compare(pl, pivot) > 0; pr = pl, --pl) { - *pr = *pl; - } - if (pr != (int *) first) - *pr = *(int *) pivot; - } - free(pivot); + } + PreInsertion(SWAP_words,(TRUNC_words/WORD_BYTES),WORD_BYTES); + /* Now do insertion sort. */ + last=((char*)base)+nmemb*WORD_BYTES; + for (first=((char*)base)+WORD_BYTES;first!=last;first+=WORD_BYTES) { + /* Find the right place for |first|. My apologies for var reuse */ + int *pl=(int*)(first-WORD_BYTES),*pr=(int*)first; + *(int*)pivot=*(int*)first; + for (;compare(pl,pivot)>0;pr=pl,--pl) { + *pr=*pl; } + if (pr!=(int*)first) *pr=*(int*)pivot; + } + free(pivot); } /* ---------------------------------------------------------------------- */ -void -qsort(void *base, size_t nmemb, size_t size, - int (*compare) (const void *, const void *)) -{ +extern void qsortG(void *base, size_t nmemb, size_t size, + int (*compare)(const void *, const void *)) { - if (nmemb <= 1) - return; - if (((uintptr_t) base | size) & (WORD_BYTES - 1)) - qsort_nonaligned(base, nmemb, size, compare); - else if (size != WORD_BYTES) - qsort_aligned(base, nmemb, size, compare); - else - qsort_words(base, nmemb, compare); + if (nmemb<=1) return; + if (((int)base|size)&(WORD_BYTES-1)) + qsort_nonaligned(base,nmemb,size,compare); + else if (size!=WORD_BYTES) + qsort_aligned(base,nmemb,size,compare); + else + qsort_words(base,nmemb,compare); } -#endif /* !SDL_qsort */ + +#endif /* HAVE_QSORT */ /* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/src/stdlib/SDL_stdlib.c b/Engine/lib/sdl/src/stdlib/SDL_stdlib.c index 6723d4e2c..f5a152b49 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_stdlib.c +++ b/Engine/lib/sdl/src/stdlib/SDL_stdlib.c @@ -34,7 +34,7 @@ double SDL_atan(double x) { -#ifdef HAVE_ATAN +#if defined(HAVE_ATAN) return atan(x); #else return SDL_uclibc_atan(x); @@ -90,7 +90,7 @@ SDL_asin(double val) double SDL_ceil(double x) { -#ifdef HAVE_CEIL +#if defined(HAVE_CEIL) return ceil(x); #else double integer = SDL_floor(x); @@ -127,7 +127,7 @@ SDL_cos(double x) float SDL_cosf(float x) { -#ifdef HAVE_COSF +#if defined(HAVE_COSF) return cosf(x); #else return (float)SDL_cos((double)x); @@ -199,7 +199,7 @@ SDL_sin(double x) float SDL_sinf(float x) { -#ifdef HAVE_SINF +#if defined(HAVE_SINF) return sinf(x); #else return (float)SDL_sin((double)x); @@ -248,14 +248,14 @@ SDL_tanf(float x) int SDL_abs(int x) { -#ifdef HAVE_ABS +#if defined(HAVE_ABS) return abs(x); #else return ((x) < 0 ? -(x) : (x)); #endif } -#ifdef HAVE_CTYPE_H +#if defined(HAVE_CTYPE_H) int SDL_isdigit(int x) { return isdigit(x); } int SDL_isspace(int x) { return isspace(x); } int SDL_toupper(int x) { return toupper(x); } @@ -279,7 +279,7 @@ __declspec(selectany) int _fltused = 1; #endif /* The optimizer on Visual Studio 2005 and later generates memcpy() calls */ -#if (_MSC_VER >= 1400) && defined(_WIN64) && !defined(_DEBUG) +#if (_MSC_VER >= 1400) && defined(_WIN64) && !defined(_DEBUG) && !(_MSC_VER >= 1900 && defined(_MT)) #include #pragma function(memcpy) diff --git a/Engine/lib/sdl/src/stdlib/SDL_string.c b/Engine/lib/sdl/src/stdlib/SDL_string.c index 5debb2285..debbebaed 100644 --- a/Engine/lib/sdl/src/stdlib/SDL_string.c +++ b/Engine/lib/sdl/src/stdlib/SDL_string.c @@ -1315,6 +1315,7 @@ static size_t SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string) { size_t length = 0; + size_t slen; if (info && info->width && (size_t)info->width > SDL_strlen(string)) { char fill = info->pad_zeroes ? '0' : ' '; @@ -1326,7 +1327,8 @@ SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *str } } - length += SDL_strlcpy(text, string, maxlen); + slen = SDL_strlcpy(text, string, maxlen); + length += SDL_min(slen, maxlen); if (info) { if (info->force_case == SDL_CASE_LOWER) { @@ -1402,10 +1404,11 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg) } value = (unsigned long) arg; len = SDL_PrintUnsignedLong(text, left, NULL, value); - text += len; if (len >= left) { + text += (left > 1) ? left - 1 : 0; left = SDL_min(left, 1); } else { + text += len; left -= len; } arg -= value; @@ -1422,10 +1425,11 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg) while (info->precision-- > 0) { value = (unsigned long) (arg * mult); len = SDL_PrintUnsignedLong(text, left, NULL, value); - text += len; if (len >= left) { + text += (left > 1) ? left - 1 : 0; left = SDL_min(left, 1); } else { + text += len; left -= len; } arg -= (double) value / mult; @@ -1458,10 +1462,11 @@ SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg) } } len = (size_t)width; - text += len; if (len >= left) { + text += (left > 1) ? left - 1 : 0; left = SDL_min(left, 1); } else { + text += len; left -= len; } while (len--) { @@ -1637,10 +1642,11 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, } ++fmt; } - text += len; if (len >= left) { + text += (left > 1) ? left - 1 : 0; left = SDL_min(left, 1); } else { + text += len; left -= len; } } else { diff --git a/Engine/lib/sdl/src/test/SDL_test_assert.c b/Engine/lib/sdl/src/test/SDL_test_assert.c index 98a84d386..ee2f13248 100644 --- a/Engine/lib/sdl/src/test/SDL_test_assert.c +++ b/Engine/lib/sdl/src/test/SDL_test_assert.c @@ -30,10 +30,10 @@ #include "SDL_test.h" /* Assert check message format */ -const char *SDLTest_AssertCheckFormat = "Assert '%s': %s"; +#define SDLTEST_ASSERT_CHECK_FORMAT "Assert '%s': %s" /* Assert summary message format */ -const char *SDLTest_AssertSummaryFormat = "Assert Summary: Total=%d Passed=%d Failed=%d"; +#define SDLTEST_ASSERT_SUMMARY_FORMAT "Assert Summary: Total=%d Passed=%d Failed=%d" /* ! \brief counts the failed asserts */ static Uint32 SDLTest_AssertsFailed = 0; @@ -77,12 +77,12 @@ int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char if (assertCondition == ASSERT_FAIL) { SDLTest_AssertsFailed++; - SDLTest_LogError(SDLTest_AssertCheckFormat, logMessage, "Failed"); + SDLTest_LogError(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Failed"); } else { SDLTest_AssertsPassed++; - SDLTest_Log(SDLTest_AssertCheckFormat, logMessage, "Passed"); + SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Passed"); } return assertCondition; @@ -104,7 +104,7 @@ void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, /* Log pass message */ SDLTest_AssertsPassed++; - SDLTest_Log(SDLTest_AssertCheckFormat, logMessage, "Pass"); + SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Pass"); } /* @@ -125,11 +125,11 @@ void SDLTest_LogAssertSummary() Uint32 totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed; if (SDLTest_AssertsFailed == 0) { - SDLTest_Log(SDLTest_AssertSummaryFormat, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); + SDLTest_Log(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); } else { - SDLTest_LogError(SDLTest_AssertSummaryFormat, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); + SDLTest_LogError(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); } } diff --git a/Engine/lib/sdl/src/test/SDL_test_common.c b/Engine/lib/sdl/src/test/SDL_test_common.c index fee249cb9..1d0b005b5 100644 --- a/Engine/lib/sdl/src/test/SDL_test_common.c +++ b/Engine/lib/sdl/src/test/SDL_test_common.c @@ -1064,6 +1064,12 @@ SDLTest_PrintEvent(SDL_Event * event) case SDL_WINDOWEVENT_CLOSE: SDL_Log("SDL EVENT: Window %d closed", event->window.windowID); break; + case SDL_WINDOWEVENT_TAKE_FOCUS: + SDL_Log("SDL EVENT: Window %d take focus", event->window.windowID); + break; + case SDL_WINDOWEVENT_HIT_TEST: + SDL_Log("SDL EVENT: Window %d hit test", event->window.windowID); + break; default: SDL_Log("SDL EVENT: Window %d got unknown event %d", event->window.windowID, event->window.event); @@ -1368,6 +1374,24 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) } } break; + case SDLK_o: + if (withControl) { + /* Ctrl-O (or Ctrl-Shift-O) changes window opacity. */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + float opacity; + if (SDL_GetWindowOpacity(window, &opacity) == 0) { + if (withShift) { + opacity += 0.20f; + } else { + opacity -= 0.20f; + } + SDL_SetWindowOpacity(window, opacity); + } + } + } + break; + case SDLK_c: if (withControl) { /* Ctrl-C copy awesome text! */ diff --git a/Engine/lib/sdl/src/test/SDL_test_compare.c b/Engine/lib/sdl/src/test/SDL_test_compare.c index 45eb3c689..d06ead9f7 100644 --- a/Engine/lib/sdl/src/test/SDL_test_compare.c +++ b/Engine/lib/sdl/src/test/SDL_test_compare.c @@ -43,7 +43,7 @@ int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int bpp, bpp_reference; Uint8 *p, *p_reference; int dist; - int sampleErrorX, sampleErrorY, sampleDist; + int sampleErrorX = 0, sampleErrorY = 0, sampleDist = 0; Uint8 R, G, B, A; Uint8 Rd, Gd, Bd, Ad; char imageFilename[128]; diff --git a/Engine/lib/sdl/src/test/SDL_test_harness.c b/Engine/lib/sdl/src/test/SDL_test_harness.c index fec34164c..4b86c7a0d 100644 --- a/Engine/lib/sdl/src/test/SDL_test_harness.c +++ b/Engine/lib/sdl/src/test/SDL_test_harness.c @@ -29,13 +29,13 @@ #include /* Invalid test name/description message format */ -const char *SDLTest_InvalidNameFormat = "(Invalid)"; +#define SDLTEST_INVALID_NAME_FORMAT "(Invalid)" /* Log summary message format */ -const char *SDLTest_LogSummaryFormat = "%s Summary: Total=%d Passed=%d Failed=%d Skipped=%d"; +#define SDLTEST_LOG_SUMMARY_FORMAT "%s Summary: Total=%d Passed=%d Failed=%d Skipped=%d" /* Final result message format */ -const char *SDLTest_FinalResultFormat = ">>> %s '%s': %s\n"; +#define SDLTEST_FINAL_RESULT_FORMAT ">>> %s '%s': %s\n" /* ! \brief Timeout for single test case execution */ static Uint32 SDLTest_TestCaseTimeout = 3600; @@ -239,7 +239,7 @@ SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, SDLTest_TestCaseReference if (!testCase->enabled && forceTestRun == SDL_FALSE) { - SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Skipped (Disabled)"); + SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Skipped (Disabled)"); return TEST_RESULT_SKIPPED; } @@ -256,7 +256,7 @@ SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, SDLTest_TestCaseReference if (testSuite->testSetUp) { testSuite->testSetUp(0x0); if (SDLTest_AssertSummaryToTestResult() == TEST_RESULT_FAILED) { - SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Suite Setup", testSuite->name, "Failed"); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite Setup", testSuite->name, "Failed"); return TEST_RESULT_SETUP_FAILURE; } } @@ -298,13 +298,13 @@ SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, SDLTest_TestCaseReference /* Final log based on test execution result */ if (testCaseResult == TEST_SKIPPED) { /* Test was programatically skipped */ - SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Skipped (Programmatically)"); + SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Skipped (Programmatically)"); } else if (testCaseResult == TEST_STARTED) { /* Test did not return a TEST_COMPLETED value; assume it failed */ - SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Failed (test started, but did not return TEST_COMPLETED)"); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Failed (test started, but did not return TEST_COMPLETED)"); } else if (testCaseResult == TEST_ABORTED) { /* Test was aborted early; assume it failed */ - SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", testCase->name, "Failed (Aborted)"); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Failed (Aborted)"); } else { SDLTest_LogAssertSummary(); } @@ -326,7 +326,7 @@ void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) testSuite=&testSuites[suiteCounter]; suiteCounter++; SDLTest_Log("Test Suite %i - %s\n", suiteCounter, - (testSuite->name) ? testSuite->name : SDLTest_InvalidNameFormat); + (testSuite->name) ? testSuite->name : SDLTEST_INVALID_NAME_FORMAT); /* Loop over all test cases */ testCounter = 0; @@ -335,8 +335,8 @@ void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; testCounter++; SDLTest_Log(" Test Case %i - %s: %s", testCounter, - (testCase->name) ? testCase->name : SDLTest_InvalidNameFormat, - (testCase->description) ? testCase->description : SDLTest_InvalidNameFormat); + (testCase->name) ? testCase->name : SDLTEST_INVALID_NAME_FORMAT, + (testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT); } } } @@ -396,7 +396,6 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user Uint32 testPassedCount = 0; Uint32 testSkippedCount = 0; Uint32 countSum = 0; - char *logFormat = (char *)SDLTest_LogSummaryFormat; SDLTest_TestCaseReference **failedTests; /* Sanitize test iterations */ @@ -493,7 +492,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user suiteCounter = 0; while(testSuites[suiteCounter]) { testSuite=(SDLTest_TestSuiteReference *)testSuites[suiteCounter]; - currentSuiteName = (char *)((testSuite->name) ? testSuite->name : SDLTest_InvalidNameFormat); + currentSuiteName = (char *)((testSuite->name) ? testSuite->name : SDLTEST_INVALID_NAME_FORMAT); suiteCounter++; /* Filter suite if flag set and we have a name */ @@ -523,7 +522,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user while(testSuite->testCases[testCounter]) { testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; - currentTestName = (char *)((testCase->name) ? testCase->name : SDLTest_InvalidNameFormat); + currentTestName = (char *)((testCase->name) ? testCase->name : SDLTEST_INVALID_NAME_FORMAT); testCounter++; /* Filter tests if flag set and we have a name */ @@ -551,7 +550,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user currentTestName); if (testCase->description != NULL && testCase->description[0] != '\0') { SDLTest_Log("Test Description: '%s'", - (testCase->description) ? testCase->description : SDLTest_InvalidNameFormat); + (testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT); } /* Loop over all iterations */ @@ -598,13 +597,13 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Log final test result */ switch (testResult) { case TEST_RESULT_PASSED: - SDLTest_Log((char *)SDLTest_FinalResultFormat, "Test", currentTestName, "Passed"); + SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, "Passed"); break; case TEST_RESULT_FAILED: - SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Test", currentTestName, "Failed"); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, "Failed"); break; case TEST_RESULT_NO_ASSERT: - SDLTest_LogError((char *)SDLTest_FinalResultFormat,"Test", currentTestName, "No Asserts"); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT,"Test", currentTestName, "No Asserts"); break; } @@ -628,13 +627,13 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user countSum = testPassedCount + testFailedCount + testSkippedCount; if (testFailedCount == 0) { - SDLTest_Log(logFormat, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); - SDLTest_Log((char *)SDLTest_FinalResultFormat, "Suite", currentSuiteName, "Passed"); + SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); + SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, "Passed"); } else { - SDLTest_LogError(logFormat, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); - SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Suite", currentSuiteName, "Failed"); + SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, "Failed"); } } @@ -653,14 +652,14 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user if (totalTestFailedCount == 0) { runResult = 0; - SDLTest_Log(logFormat, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); - SDLTest_Log((char *)SDLTest_FinalResultFormat, "Run /w seed", runSeed, "Passed"); + SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); + SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, "Passed"); } else { runResult = 1; - SDLTest_LogError(logFormat, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); - SDLTest_LogError((char *)SDLTest_FinalResultFormat, "Run /w seed", runSeed, "Failed"); + SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, "Failed"); } /* Print repro steps for failed tests */ diff --git a/Engine/lib/sdl/src/test/SDL_test_log.c b/Engine/lib/sdl/src/test/SDL_test_log.c index 097372e7a..a2f857f26 100644 --- a/Engine/lib/sdl/src/test/SDL_test_log.c +++ b/Engine/lib/sdl/src/test/SDL_test_log.c @@ -55,12 +55,11 @@ char *SDLTest_TimestampToString(const time_t timestamp) time_t copy; static char buffer[64]; struct tm *local; - const char *fmt = "%x %X"; SDL_memset(buffer, 0, sizeof(buffer)); copy = timestamp; local = localtime(©); - strftime(buffer, sizeof(buffer), fmt, local); + strftime(buffer, sizeof(buffer), "%x %X", local); return buffer; } diff --git a/Engine/lib/sdl/src/thread/SDL_systhread.h b/Engine/lib/sdl/src/thread/SDL_systhread.h index f13f3e203..05a012536 100644 --- a/Engine/lib/sdl/src/thread/SDL_systhread.h +++ b/Engine/lib/sdl/src/thread/SDL_systhread.h @@ -60,6 +60,11 @@ extern SDL_TLSData *SDL_SYS_GetTLSData(); /* Set the thread local storage for this thread */ extern int SDL_SYS_SetTLSData(SDL_TLSData *data); +/* This is for internal SDL use, so we don't need #ifdefs everywhere. */ +extern SDL_Thread * +SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name, + const size_t stacksize, void *data); + #endif /* _SDL_systhread_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/thread/SDL_thread.c b/Engine/lib/sdl/src/thread/SDL_thread.c index e66c5819c..ae865790a 100644 --- a/Engine/lib/sdl/src/thread/SDL_thread.c +++ b/Engine/lib/sdl/src/thread/SDL_thread.c @@ -26,6 +26,7 @@ #include "SDL_thread.h" #include "SDL_thread_c.h" #include "SDL_systhread.h" +#include "SDL_hints.h" #include "../SDL_error_c.h" @@ -304,15 +305,15 @@ SDL_RunThread(void *data) #endif #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), - const char *name, void *data, +static SDL_Thread * +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread) #else -DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), - const char *name, void *data) +static SDL_Thread * +SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), + const char *name, const size_t stacksize, void *data) #endif { SDL_Thread *thread; @@ -362,6 +363,8 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), return (NULL); } + thread->stacksize = stacksize; + /* Create the thread and go! */ #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread); @@ -386,6 +389,50 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), return (thread); } +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD +DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(int (SDLCALL * fn) (void *), + const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +#else +DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(int (SDLCALL * fn) (void *), + const char *name, void *data) +#endif +{ + /* !!! FIXME: in 2.1, just make stackhint part of the usual API. */ + const char *stackhint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE); + size_t stacksize = 0; + + /* If the SDL_HINT_THREAD_STACK_SIZE exists, use it */ + if (stackhint != NULL) { + char *endp = NULL; + const Sint64 hintval = SDL_strtoll(stackhint, &endp, 10); + if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */ + if (hintval > 0) { /* reject bogus values. */ + stacksize = (size_t) hintval; + } + } + } + +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD + return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, pfnBeginThread, pfnEndThread); +#else + return SDL_CreateThreadWithStackSize(fn, name, stacksize, data); +#endif +} + +SDL_Thread * +SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name, + const size_t stacksize, void *data) { +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD + return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, NULL, NULL); +#else + return SDL_CreateThreadWithStackSize(fn, name, stacksize, data); +#endif +} + SDL_threadID SDL_GetThreadID(SDL_Thread * thread) { diff --git a/Engine/lib/sdl/src/thread/SDL_thread_c.h b/Engine/lib/sdl/src/thread/SDL_thread_c.h index a283a0e2c..554325d6d 100644 --- a/Engine/lib/sdl/src/thread/SDL_thread_c.h +++ b/Engine/lib/sdl/src/thread/SDL_thread_c.h @@ -59,6 +59,7 @@ struct SDL_Thread SDL_atomic_t state; /* SDL_THREAD_STATE_* */ SDL_error errbuf; char *name; + size_t stacksize; /* 0 for default, >0 for user-specified stack size. */ void *data; }; diff --git a/Engine/lib/sdl/src/thread/psp/SDL_systhread.c b/Engine/lib/sdl/src/thread/psp/SDL_systhread.c index ab8aff376..c6003b8ed 100644 --- a/Engine/lib/sdl/src/thread/psp/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/psp/SDL_systhread.c @@ -52,8 +52,8 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) priority = status.currentPriority; } - thread->handle = sceKernelCreateThread("SDL thread", ThreadEntry, - priority, 0x8000, + thread->handle = sceKernelCreateThread(thread->name, ThreadEntry, + priority, thread->stacksize ? ((int) thread->stacksize) : 0x8000, PSP_THREAD_ATTR_VFPU, NULL); if (thread->handle < 0) { return SDL_SetError("sceKernelCreateThread() failed"); diff --git a/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c b/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c index 22f7bd57b..4958f6fb9 100644 --- a/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/pthread/SDL_systhread.c @@ -45,7 +45,6 @@ #include "SDL_platform.h" #include "SDL_thread.h" -#include "SDL_hints.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" #ifdef __ANDROID__ @@ -87,7 +86,6 @@ int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { pthread_attr_t type; - const char *hint = SDL_GetHint(SDL_HINT_THREAD_STACK_SIZE); /* do this here before any threads exist, so there's no race condition. */ #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) @@ -108,12 +106,9 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) } pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE); - /* If the SDL_HINT_THREAD_STACK_SIZE exists and it seems to be a positive number, use it */ - if (hint && hint[0] >= '0' && hint[0] <= '9') { - const size_t stacksize = (size_t) SDL_atoi(hint); - if (stacksize > 0) { - pthread_attr_setstacksize(&type, stacksize); - } + /* Set caller-requested stack size. Otherwise: use the system default. */ + if (thread->stacksize) { + pthread_attr_setstacksize(&type, (size_t) thread->stacksize); } /* Create the thread and go! */ @@ -127,10 +122,10 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) void SDL_SYS_SetupThread(const char *name) { -#if !defined(__ANDROID__) && !defined(__NACL__) +#if !defined(__NACL__) int i; sigset_t mask; -#endif /* !__ANDROID__ && !__NACL__ */ +#endif /* !__NACL__ */ if (name != NULL) { #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) @@ -160,14 +155,14 @@ SDL_SYS_SetupThread(const char *name) } /* NativeClient does not yet support signals.*/ -#if !defined(__ANDROID__) && !defined(__NACL__) +#if !defined(__NACL__) /* Mask asynchronous signals for this thread */ sigemptyset(&mask); for (i = 0; sig_list[i]; ++i) { sigaddset(&mask, sig_list[i]); } pthread_sigmask(SIG_BLOCK, &mask, 0); -#endif /* !__ANDROID__ && !__NACL__ */ +#endif /* !__NACL__ */ #ifdef PTHREAD_CANCEL_ASYNCHRONOUS @@ -204,6 +199,10 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) if (setpriority(PRIO_PROCESS, syscall(SYS_gettid), value) < 0) { /* Note that this fails if you're trying to set high priority and you don't have root permission. BUT DON'T RUN AS ROOT! + + You can grant the ability to increase thread priority by + running the following command on your application binary: + sudo setcap 'cap_sys_nice=eip' */ return SDL_SetError("setpriority() failed"); } diff --git a/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp b/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp index 219c67e93..6e5ef473e 100644 --- a/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp +++ b/Engine/lib/sdl/src/thread/stdcpp/SDL_systhread.cpp @@ -48,6 +48,7 @@ int SDL_SYS_CreateThread(SDL_Thread * thread, void *args) { try { + // !!! FIXME: no way to set a thread stack size here. std::thread cpp_thread(RunThread, args); thread->handle = (void *) new std::thread(std::move(cpp_thread)); return 0; diff --git a/Engine/lib/sdl/src/thread/windows/SDL_systhread.c b/Engine/lib/sdl/src/thread/windows/SDL_systhread.c index 308145e30..20a4bd6e2 100644 --- a/Engine/lib/sdl/src/thread/windows/SDL_systhread.c +++ b/Engine/lib/sdl/src/thread/windows/SDL_systhread.c @@ -24,6 +24,7 @@ /* Win32 thread management routines for SDL */ +#include "SDL_hints.h" #include "SDL_thread.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" @@ -33,6 +34,10 @@ /* We'll use the C library from this DLL */ #include +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 +#endif + /* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */ #if (defined(__MINGW32__) && (__GNUC__ < 4)) typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, @@ -121,6 +126,7 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) #endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ pThreadStartParms pThreadParms = (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms)); + const DWORD flags = thread->stacksize ? STACK_SIZE_PARAM_IS_A_RESERVATION : 0; if (!pThreadParms) { return SDL_OutOfMemory(); } @@ -129,15 +135,18 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) /* Also save the real parameters we have to pass to thread function */ pThreadParms->args = args; + /* thread->stacksize == 0 means "system default", same as win32 expects */ if (pfnBeginThread) { unsigned threadid = 0; thread->handle = (SYS_ThreadHandle) - ((size_t) pfnBeginThread(NULL, 0, RunThreadViaBeginThreadEx, - pThreadParms, 0, &threadid)); + ((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize, + RunThreadViaBeginThreadEx, + pThreadParms, flags, &threadid)); } else { DWORD threadid = 0; - thread->handle = CreateThread(NULL, 0, RunThreadViaCreateThread, - pThreadParms, 0, &threadid); + thread->handle = CreateThread(NULL, thread->stacksize, + RunThreadViaCreateThread, + pThreadParms, flags, &threadid); } if (thread->handle == NULL) { return SDL_SetError("Not enough resources to create thread"); @@ -145,9 +154,6 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args) return 0; } -#if 0 /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */ -#ifdef _MSC_VER -#pragma warning(disable : 4733) #pragma pack(push,8) typedef struct tagTHREADNAME_INFO { @@ -158,48 +164,26 @@ typedef struct tagTHREADNAME_INFO } THREADNAME_INFO; #pragma pack(pop) -static EXCEPTION_DISPOSITION -ignore_exception(void *a, void *b, void *c, void *d) -{ - return ExceptionContinueExecution; -} -#endif -#endif - void SDL_SYS_SetupThread(const char *name) { - if (name != NULL) { - #if 0 /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */ - #if (defined(_MSC_VER) && defined(_M_IX86)) - /* This magic tells the debugger to name a thread if it's listening. - The inline asm sets up SEH (__try/__except) without C runtime - support. See Microsoft Systems Journal, January 1997: - http://www.microsoft.com/msj/0197/exception/exception.aspx */ - INT_PTR handler = (INT_PTR) ignore_exception; + if ((name != NULL) && IsDebuggerPresent()) { THREADNAME_INFO inf; + /* C# and friends will try to catch this Exception, let's avoid it. */ + if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, SDL_FALSE)) { + return; + } + + /* This magic tells the debugger to name a thread if it's listening. */ + SDL_zero(inf); inf.dwType = 0x1000; inf.szName = name; inf.dwThreadID = (DWORD) -1; inf.dwFlags = 0; - __asm { /* set up SEH */ - push handler - push fs:[0] - mov fs:[0],esp - } - - /* The program itself should ignore this bogus exception. */ - RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf); - - __asm { /* tear down SEH. */ - mov eax,[esp] - mov fs:[0], eax - add esp, 8 - } - #endif - #endif + /* The debugger catches this, renames the thread, continues on. */ + RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf); } } @@ -230,11 +214,7 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) void SDL_SYS_WaitThread(SDL_Thread * thread) { -#if __WINRT__ WaitForSingleObjectEx(thread->handle, INFINITE, FALSE); -#else - WaitForSingleObject(thread->handle, INFINITE); -#endif CloseHandle(thread->handle); } diff --git a/Engine/lib/sdl/src/timer/SDL_timer.c b/Engine/lib/sdl/src/timer/SDL_timer.c index 6189ab8b5..abe968e86 100644 --- a/Engine/lib/sdl/src/timer/SDL_timer.c +++ b/Engine/lib/sdl/src/timer/SDL_timer.c @@ -24,7 +24,7 @@ #include "SDL_timer_c.h" #include "SDL_atomic.h" #include "SDL_cpuinfo.h" -#include "SDL_thread.h" +#include "../thread/SDL_systhread.h" /* #define DEBUG_TIMERS */ @@ -35,7 +35,7 @@ typedef struct _SDL_Timer void *param; Uint32 interval; Uint32 scheduled; - volatile SDL_bool canceled; + SDL_atomic_t canceled; struct _SDL_Timer *next; } SDL_Timer; @@ -60,9 +60,9 @@ typedef struct { /* Data used to communicate with the timer thread */ SDL_SpinLock lock; SDL_sem *sem; - SDL_Timer * volatile pending; - SDL_Timer * volatile freelist; - volatile SDL_bool active; + SDL_Timer *pending; + SDL_Timer *freelist; + SDL_atomic_t active; /* List of timers - this is only touched by the timer thread */ SDL_Timer *timers; @@ -138,7 +138,7 @@ SDL_TimerThread(void *_data) freelist_tail = NULL; /* Check to see if we're still running, after maintenance */ - if (!data->active) { + if (!SDL_AtomicGet(&data->active)) { break; } @@ -160,7 +160,7 @@ SDL_TimerThread(void *_data) /* We're going to do something with this timer */ data->timers = current->next; - if (current->canceled) { + if (SDL_AtomicGet(¤t->canceled)) { interval = 0; } else { interval = current->callback(current->interval, current->param); @@ -179,7 +179,7 @@ SDL_TimerThread(void *_data) } freelist_tail = current; - current->canceled = SDL_TRUE; + SDL_AtomicSet(¤t->canceled, 1); } } @@ -207,7 +207,7 @@ SDL_TimerInit(void) { SDL_TimerData *data = &SDL_timer_data; - if (!data->active) { + if (!SDL_AtomicGet(&data->active)) { const char *name = "SDLTimer"; data->timermap_lock = SDL_CreateMutex(); if (!data->timermap_lock) { @@ -220,18 +220,10 @@ SDL_TimerInit(void) return -1; } - data->active = SDL_TRUE; - /* !!! FIXME: this is nasty. */ -#if defined(__WIN32__) && !defined(HAVE_LIBC) -#undef SDL_CreateThread -#if SDL_DYNAMIC_API - data->thread = SDL_CreateThread_REAL(SDL_TimerThread, name, data, NULL, NULL); -#else - data->thread = SDL_CreateThread(SDL_TimerThread, name, data, NULL, NULL); -#endif -#else - data->thread = SDL_CreateThread(SDL_TimerThread, name, data); -#endif + SDL_AtomicSet(&data->active, 1); + + /* Timer threads use a callback into the app, so we can't set a limited stack size here. */ + data->thread = SDL_CreateThreadInternal(SDL_TimerThread, name, 0, data); if (!data->thread) { SDL_TimerQuit(); return -1; @@ -249,9 +241,7 @@ SDL_TimerQuit(void) SDL_Timer *timer; SDL_TimerMap *entry; - if (data->active) { - data->active = SDL_FALSE; - + if (SDL_AtomicCAS(&data->active, 1, 0)) { /* active? Move to inactive. */ /* Shutdown the timer thread */ if (data->thread) { SDL_SemPost(data->sem); @@ -291,21 +281,14 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param) SDL_Timer *timer; SDL_TimerMap *entry; - if (!data->active) { - int status = 0; - - SDL_AtomicLock(&data->lock); - if (!data->active) { - status = SDL_TimerInit(); - } - SDL_AtomicUnlock(&data->lock); - - if (status < 0) { + SDL_AtomicLock(&data->lock); + if (!SDL_AtomicGet(&data->active)) { + if (SDL_TimerInit() < 0) { + SDL_AtomicUnlock(&data->lock); return 0; } } - SDL_AtomicLock(&data->lock); timer = data->freelist; if (timer) { data->freelist = timer->next; @@ -326,7 +309,7 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param) timer->param = param; timer->interval = interval; timer->scheduled = SDL_GetTicks() + interval; - timer->canceled = SDL_FALSE; + SDL_AtomicSet(&timer->canceled, 0); entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry)); if (!entry) { @@ -377,8 +360,8 @@ SDL_RemoveTimer(SDL_TimerID id) SDL_UnlockMutex(data->timermap_lock); if (entry) { - if (!entry->timer->canceled) { - entry->timer->canceled = SDL_TRUE; + if (!SDL_AtomicGet(&entry->timer->canceled)) { + SDL_AtomicSet(&entry->timer->canceled, 1); canceled = SDL_TRUE; } SDL_free(entry); diff --git a/Engine/lib/sdl/src/timer/windows/SDL_systimer.c b/Engine/lib/sdl/src/timer/windows/SDL_systimer.c index abfbcb99a..5c9121a51 100644 --- a/Engine/lib/sdl/src/timer/windows/SDL_systimer.c +++ b/Engine/lib/sdl/src/timer/windows/SDL_systimer.c @@ -107,10 +107,8 @@ SDL_TicksInit(void) void SDL_TicksQuit(void) { - if (!hires_timer_available) { - SDL_DelHintCallback(SDL_HINT_TIMER_RESOLUTION, - SDL_TimerResolutionChanged, NULL); - } + SDL_DelHintCallback(SDL_HINT_TIMER_RESOLUTION, + SDL_TimerResolutionChanged, NULL); SDL_SetSystemTimerResolution(0); /* always release our timer resolution request. */ @@ -189,6 +187,10 @@ SDL_Delay(Uint32 ms) } WaitForSingleObjectEx(mutex, ms, FALSE); #else + if (!ticks_started) { + SDL_TicksInit(); + } + Sleep(ms); #endif } diff --git a/Engine/lib/sdl/src/video/SDL_blit_copy.c b/Engine/lib/sdl/src/video/SDL_blit_copy.c index 7b9a91ffd..674650dd9 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_copy.c +++ b/Engine/lib/sdl/src/video/SDL_blit_copy.c @@ -109,10 +109,20 @@ SDL_BlitCopy(SDL_BlitInfo * info) overlap = (src < (dst + h*dstskip)); } if (overlap) { - while (h--) { - SDL_memmove(dst, src, w); - src += srcskip; - dst += dstskip; + if ( dst < src ) { + while ( h-- ) { + SDL_memmove(dst, src, w); + src += srcskip; + dst += dstskip; + } + } else { + src += ((h-1) * srcskip); + dst += ((h-1) * dstskip); + while ( h-- ) { + SDL_memmove(dst, src, w); + src -= srcskip; + dst -= dstskip; + } } return; } diff --git a/Engine/lib/sdl/src/video/SDL_blit_slow.c b/Engine/lib/sdl/src/video/SDL_blit_slow.c index 3a462f6e2..02ab41de7 100644 --- a/Engine/lib/sdl/src/video/SDL_blit_slow.c +++ b/Engine/lib/sdl/src/video/SDL_blit_slow.c @@ -46,6 +46,8 @@ SDL_Blit_Slow(SDL_BlitInfo * info) SDL_PixelFormat *dst_fmt = info->dst_fmt; int srcbpp = src_fmt->BytesPerPixel; int dstbpp = dst_fmt->BytesPerPixel; + Uint32 rgbmask = ~src_fmt->Amask; + Uint32 ckey = info->colorkey & rgbmask; srcy = 0; posy = 0; @@ -85,7 +87,7 @@ SDL_Blit_Slow(SDL_BlitInfo * info) srcpixel = (srcR << src_fmt->Rshift) | (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift); } - if (srcpixel == info->colorkey) { + if ((srcpixel & rgbmask) == ckey) { posx += incx; dst += dstbpp; continue; @@ -127,6 +129,7 @@ SDL_Blit_Slow(SDL_BlitInfo * info) dstR = srcR + ((255 - srcA) * dstR) / 255; dstG = srcG + ((255 - srcA) * dstG) / 255; dstB = srcB + ((255 - srcA) * dstB) / 255; + dstA = srcA + ((255 - srcA) * dstA) / 255; break; case SDL_COPY_ADD: dstR = srcR + dstR; diff --git a/Engine/lib/sdl/src/video/SDL_bmp.c b/Engine/lib/sdl/src/video/SDL_bmp.c index f80f93696..2d9cf240b 100644 --- a/Engine/lib/sdl/src/video/SDL_bmp.c +++ b/Engine/lib/sdl/src/video/SDL_bmp.c @@ -32,6 +32,7 @@ This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp. */ +#include "SDL_hints.h" #include "SDL_video.h" #include "SDL_assert.h" #include "SDL_endian.h" @@ -47,6 +48,11 @@ #define BI_BITFIELDS 3 #endif +/* Logical color space values for BMP files */ +#ifndef LCS_WINDOWS_COLOR_SPACE +/* 0x57696E20 == "Win " */ +#define LCS_WINDOWS_COLOR_SPACE 0x57696E20 +#endif static void CorrectAlphaChannel(SDL_Surface *surface) { @@ -457,6 +463,8 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) int i, pad; SDL_Surface *surface; Uint8 *bits; + SDL_bool save32bit = SDL_FALSE; + SDL_bool saveLegacyBMP = SDL_FALSE; /* The Win32 BMP file header (14 bytes) */ char magic[2] = { 'B', 'M' }; @@ -478,14 +486,24 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) Uint32 biClrUsed; Uint32 biClrImportant; + /* The additional header members from the Win32 BITMAPV4HEADER struct (108 bytes in total) */ + Uint32 bV4RedMask = 0; + Uint32 bV4GreenMask = 0; + Uint32 bV4BlueMask = 0; + Uint32 bV4AlphaMask = 0; + Uint32 bV4CSType = 0; + Sint32 bV4Endpoints[3 * 3] = {0}; + Uint32 bV4GammaRed = 0; + Uint32 bV4GammaGreen = 0; + Uint32 bV4GammaBlue = 0; + /* Make sure we have somewhere to save */ surface = NULL; if (dst) { - SDL_bool save32bit = SDL_FALSE; #ifdef SAVE_32BIT_BMP /* We can save alpha information in a 32-bit BMP */ - if (saveme->map->info.flags & SDL_COPY_COLORKEY || - saveme->format->Amask) { + if (saveme->format->BitsPerPixel >= 8 && (saveme->format->Amask || + saveme->map->info.flags & SDL_COPY_COLORKEY)) { save32bit = SDL_TRUE; } #endif /* SAVE_32BIT_BMP */ @@ -497,7 +515,7 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) SDL_SetError("%d bpp BMP files not supported", saveme->format->BitsPerPixel); } - } else if ((saveme->format->BitsPerPixel == 24) && + } else if ((saveme->format->BitsPerPixel == 24) && !save32bit && #if SDL_BYTEORDER == SDL_LIL_ENDIAN (saveme->format->Rmask == 0x00FF0000) && (saveme->format->Gmask == 0x0000FF00) && @@ -515,13 +533,7 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) /* If the surface has a colorkey or alpha channel we'll save a 32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */ if (save32bit) { - SDL_InitFormat(&format, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - SDL_PIXELFORMAT_ARGB8888 -#else - SDL_PIXELFORMAT_BGRA8888 -#endif - ); + SDL_InitFormat(&format, SDL_PIXELFORMAT_BGRA32); } else { SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24); } @@ -537,6 +549,10 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) return -1; } + if (save32bit) { + saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE); + } + if (surface && (SDL_LockSurface(surface) == 0)) { const int bw = surface->w * surface->format->BytesPerPixel; @@ -572,6 +588,21 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) } biClrImportant = 0; + /* Set the BMP info values for the version 4 header */ + if (save32bit && !saveLegacyBMP) { + biSize = 108; + biCompression = BI_BITFIELDS; + /* The BMP format is always little endian, these masks stay the same */ + bV4RedMask = 0x00ff0000; + bV4GreenMask = 0x0000ff00; + bV4BlueMask = 0x000000ff; + bV4AlphaMask = 0xff000000; + bV4CSType = LCS_WINDOWS_COLOR_SPACE; + bV4GammaRed = 0; + bV4GammaGreen = 0; + bV4GammaBlue = 0; + } + /* Write the BMP info values */ SDL_WriteLE32(dst, biSize); SDL_WriteLE32(dst, biWidth); @@ -585,6 +616,21 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) SDL_WriteLE32(dst, biClrUsed); SDL_WriteLE32(dst, biClrImportant); + /* Write the BMP info values for the version 4 header */ + if (save32bit && !saveLegacyBMP) { + SDL_WriteLE32(dst, bV4RedMask); + SDL_WriteLE32(dst, bV4GreenMask); + SDL_WriteLE32(dst, bV4BlueMask); + SDL_WriteLE32(dst, bV4AlphaMask); + SDL_WriteLE32(dst, bV4CSType); + for (i = 0; i < 3 * 3; i++) { + SDL_WriteLE32(dst, bV4Endpoints[i]); + } + SDL_WriteLE32(dst, bV4GammaRed); + SDL_WriteLE32(dst, bV4GammaGreen); + SDL_WriteLE32(dst, bV4GammaBlue); + } + /* Write the palette (in BGR color order) */ if (surface->format->palette) { SDL_Color *colors; diff --git a/Engine/lib/sdl/src/video/SDL_egl.c b/Engine/lib/sdl/src/video/SDL_egl.c index bfd4affb9..c90380566 100644 --- a/Engine/lib/sdl/src/video/SDL_egl.c +++ b/Engine/lib/sdl/src/video/SDL_egl.c @@ -161,7 +161,7 @@ int SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display) { void *dll_handle = NULL, *egl_dll_handle = NULL; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */ - char *path = NULL; + const char *path = NULL; #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT const char *d3dcompiler; #endif @@ -558,7 +558,8 @@ int SDL_EGL_GetSwapInterval(_THIS) { if (!_this->egl_data) { - return SDL_SetError("EGL not initialized"); + SDL_SetError("EGL not initialized"); + return 0; } return _this->egl_data->egl_swapinterval; diff --git a/Engine/lib/sdl/src/video/SDL_surface.c b/Engine/lib/sdl/src/video/SDL_surface.c index dae07f285..9d52e5ca4 100644 --- a/Engine/lib/sdl/src/video/SDL_surface.c +++ b/Engine/lib/sdl/src/video/SDL_surface.c @@ -27,27 +27,20 @@ #include "SDL_pixels_c.h" /* Public routines */ + /* - * Create an empty RGB surface of the appropriate depth + * Create an empty RGB surface of the appropriate depth using the given + * enum SDL_PIXELFORMAT_* format */ SDL_Surface * -SDL_CreateRGBSurface(Uint32 flags, - int width, int height, int depth, - Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, + Uint32 format) { SDL_Surface *surface; - Uint32 format; /* The flags are no longer used, make the compiler happy */ (void)flags; - /* Get the pixel format */ - format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask); - if (format == SDL_PIXELFORMAT_UNKNOWN) { - SDL_SetError("Unknown pixel format"); - return NULL; - } - /* Allocate the surface */ surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface)); if (surface == NULL) { @@ -105,7 +98,7 @@ SDL_CreateRGBSurface(Uint32 flags, } /* By default surface with an alpha mask are set up for blending */ - if (Amask) { + if (surface->format->Amask) { SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND); } @@ -114,6 +107,26 @@ SDL_CreateRGBSurface(Uint32 flags, return surface; } +/* + * Create an empty RGB surface of the appropriate depth + */ +SDL_Surface * +SDL_CreateRGBSurface(Uint32 flags, + int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + Uint32 format; + + /* Get the pixel format */ + format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask); + if (format == SDL_PIXELFORMAT_UNKNOWN) { + SDL_SetError("Unknown pixel format"); + return NULL; + } + + return SDL_CreateRGBSurfaceWithFormat(flags, width, height, depth, format); +} + /* * Create an RGB surface from an existing memory buffer */ @@ -125,8 +138,30 @@ SDL_CreateRGBSurfaceFrom(void *pixels, { SDL_Surface *surface; - surface = - SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask); + surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask); + if (surface != NULL) { + surface->flags |= SDL_PREALLOC; + surface->pixels = pixels; + surface->w = width; + surface->h = height; + surface->pitch = pitch; + SDL_SetClipRect(surface, NULL); + } + return surface; +} + +/* + * Create an RGB surface from an existing memory buffer using the given given + * enum SDL_PIXELFORMAT_* format + */ +SDL_Surface * +SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, + int width, int height, int depth, int pitch, + Uint32 format) +{ + SDL_Surface *surface; + + surface = SDL_CreateRGBSurfaceWithFormat(0, 0, 0, depth, format); if (surface != NULL) { surface->flags |= SDL_PREALLOC; surface->pixels = pixels; diff --git a/Engine/lib/sdl/src/video/SDL_sysvideo.h b/Engine/lib/sdl/src/video/SDL_sysvideo.h index 77426c3eb..cd2ed2a7e 100644 --- a/Engine/lib/sdl/src/video/SDL_sysvideo.h +++ b/Engine/lib/sdl/src/video/SDL_sysvideo.h @@ -86,6 +86,8 @@ struct SDL_Window SDL_DisplayMode fullscreen_mode; + float opacity; + float brightness; Uint16 *gamma; Uint16 *saved_gamma; /* (just offset into gamma) */ @@ -95,6 +97,7 @@ struct SDL_Window SDL_bool is_hiding; SDL_bool is_destroying; + SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */ SDL_WindowShaper *shaper; @@ -175,6 +178,11 @@ struct SDL_VideoDevice */ int (*GetDisplayDPI) (_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); + /* + * Get the usable bounds of a display (bounds minus menubar or whatever) + */ + int (*GetDisplayUsableBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); + /* * Get a list of the available display modes for a display. */ @@ -200,6 +208,10 @@ struct SDL_VideoDevice void (*SetWindowSize) (_THIS, SDL_Window * window); void (*SetWindowMinimumSize) (_THIS, SDL_Window * window); void (*SetWindowMaximumSize) (_THIS, SDL_Window * window); + int (*GetWindowBordersSize) (_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right); + int (*SetWindowOpacity) (_THIS, SDL_Window * window, float opacity); + int (*SetWindowModalFor) (_THIS, SDL_Window * modal_window, SDL_Window * parent_window); + int (*SetWindowInputFocus) (_THIS, SDL_Window * window); void (*ShowWindow) (_THIS, SDL_Window * window); void (*HideWindow) (_THIS, SDL_Window * window); void (*RaiseWindow) (_THIS, SDL_Window * window); @@ -207,6 +219,7 @@ struct SDL_VideoDevice void (*MinimizeWindow) (_THIS, SDL_Window * window); void (*RestoreWindow) (_THIS, SDL_Window * window); void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered); + void (*SetWindowResizable) (_THIS, SDL_Window * window, SDL_bool resizable); void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/Engine/lib/sdl/src/video/SDL_video.c b/Engine/lib/sdl/src/video/SDL_video.c index 511b4c087..0a21ef5fc 100644 --- a/Engine/lib/sdl/src/video/SDL_video.c +++ b/Engine/lib/sdl/src/video/SDL_video.c @@ -55,6 +55,10 @@ #undef CreateWindow #endif +#ifdef __EMSCRIPTEN__ +#include +#endif + /* Available video drivers */ static VideoBootStrap *bootstrap[] = { #if SDL_VIDEO_DRIVER_COCOA @@ -177,7 +181,7 @@ ShouldUseTextureFramebuffer() /* See if the user or application wants a specific behavior */ hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); if (hint) { - if (*hint == '0') { + if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) { return SDL_FALSE; } else { return SDL_TRUE; @@ -254,6 +258,8 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f /* Check to see if there's a specific driver requested */ if (hint && *hint != '0' && *hint != '1' && + SDL_strcasecmp(hint, "true") != 0 && + SDL_strcasecmp(hint, "false") != 0 && SDL_strcasecmp(hint, "software") != 0) { for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { SDL_RendererInfo info; @@ -443,10 +449,8 @@ int SDL_VideoInit(const char *driver_name) { SDL_VideoDevice *video; - const char *hint; int index; int i; - SDL_bool allow_screensaver; /* Check to make sure we don't overwrite '_this' */ if (_this != NULL) { @@ -534,13 +538,7 @@ SDL_VideoInit(const char *driver_name) joystick, or passively watching a movie. Things that use SDL but function more like a normal desktop app should explicitly reenable the screensaver. */ - hint = SDL_GetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER); - if (hint) { - allow_screensaver = SDL_atoi(hint) ? SDL_TRUE : SDL_FALSE; - } else { - allow_screensaver = SDL_FALSE; - } - if (!allow_screensaver) { + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, SDL_FALSE)) { SDL_DisableScreenSaver(); } @@ -684,7 +682,26 @@ SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect) rect->w = display->current_mode.w; rect->h = display->current_mode.h; } - return 0; + return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */ +} + +int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect) +{ + CHECK_DISPLAY_INDEX(displayIndex, -1); + + if (rect) { + SDL_VideoDisplay *display = &_this->displays[displayIndex]; + + if (_this->GetDisplayUsableBounds) { + if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) { + return 0; + } + } + + /* Oh well, just give the entire display bounds. */ + return SDL_GetDisplayBounds(displayIndex, rect); + } + return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */ } int @@ -700,7 +717,9 @@ SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi) if (_this->GetDisplayDPI(_this, display, ddpi, hdpi, vdpi) == 0) { return 0; } - } + } else { + return SDL_Unsupported(); + } return -1; } @@ -1285,16 +1304,11 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) } #define CREATE_FLAGS \ - (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI) + (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP) static void SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) { - window->windowed.x = window->x; - window->windowed.y = window->y; - window->windowed.w = window->w; - window->windowed.h = window->h; - if (flags & SDL_WINDOW_MAXIMIZED) { SDL_MaximizeWindow(window); } @@ -1316,7 +1330,6 @@ SDL_Window * SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) { SDL_Window *window; - const char *hint; if (!_this) { /* Initialize the video system if needed */ @@ -1325,6 +1338,11 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) } } + if ( (((flags & SDL_WINDOW_UTILITY) != 0) + ((flags & SDL_WINDOW_TOOLTIP) != 0) + ((flags & SDL_WINDOW_POPUP_MENU) != 0)) > 1 ) { + SDL_SetError("Conflicting window flags specified"); + return NULL; + } + /* Some platforms can't create zero-sized windows */ if (w < 1) { w = 1; @@ -1341,7 +1359,9 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) /* Some platforms have OpenGL enabled by default */ #if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__ - flags |= SDL_WINDOW_OPENGL; + if (SDL_strcmp(_this->name, "dummy") != 0) { + flags |= SDL_WINDOW_OPENGL; + } #endif if (flags & SDL_WINDOW_OPENGL) { if (!_this->GL_CreateContext) { @@ -1357,8 +1377,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) * SDL_WINDOW_ALLOW_HIGHDPI flag. */ if (flags & SDL_WINDOW_ALLOW_HIGHDPI) { - hint = SDL_GetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED); - if (hint && SDL_atoi(hint) > 0) { + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_HIGHDPI_DISABLED, SDL_FALSE)) { flags &= ~SDL_WINDOW_ALLOW_HIGHDPI; } } @@ -1389,8 +1408,28 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) window->y = bounds.y + (bounds.h - h) / 2; } } + window->windowed.x = window->x; + window->windowed.y = window->y; + window->windowed.w = window->w; + window->windowed.h = window->h; + + if (flags & SDL_WINDOW_FULLSCREEN) { + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + int displayIndex; + SDL_Rect bounds; + + displayIndex = SDL_GetIndexOfDisplay(display); + SDL_GetDisplayBounds(displayIndex, &bounds); + + window->x = bounds.x; + window->y = bounds.y; + window->w = bounds.w; + window->h = bounds.h; + } + window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN); window->last_fullscreen_flags = window->flags; + window->opacity = 1.0f; window->brightness = 1.0f; window->next = _this->windows; window->is_destroying = SDL_FALSE; @@ -1451,6 +1490,7 @@ SDL_CreateWindowFrom(const void *data) window->flags = SDL_WINDOW_FOREIGN; window->last_fullscreen_flags = window->flags; window->is_destroying = SDL_FALSE; + window->opacity = 1.0f; window->brightness = 1.0f; window->next = _this->windows; if (_this->windows) { @@ -1795,6 +1835,24 @@ SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered) } } +void +SDL_SetWindowResizable(SDL_Window * window, SDL_bool resizable) +{ + CHECK_WINDOW_MAGIC(window,); + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + const int want = (resizable != SDL_FALSE); /* normalize the flag. */ + const int have = ((window->flags & SDL_WINDOW_RESIZABLE) != 0); + if ((want != have) && (_this->SetWindowResizable)) { + if (want) { + window->flags |= SDL_WINDOW_RESIZABLE; + } else { + window->flags &= ~SDL_WINDOW_RESIZABLE; + } + _this->SetWindowResizable(_this, window, (SDL_bool) want); + } + } +} + void SDL_SetWindowSize(SDL_Window * window, int w, int h) { @@ -1883,6 +1941,28 @@ SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) } } +int +SDL_GetWindowBordersSize(SDL_Window * window, int *top, int *left, int *bottom, int *right) +{ + int dummy = 0; + + if (!top) { top = &dummy; } + if (!left) { left = &dummy; } + if (!right) { right = &dummy; } + if (!bottom) { bottom = &dummy; } + + /* Always initialize, so applications don't have to care */ + *top = *left = *bottom = *right = 0; + + CHECK_WINDOW_MAGIC(window, -1); + + if (!_this->GetWindowBordersSize) { + return SDL_Unsupported(); + } + + return _this->GetWindowBordersSize(_this, window, top, left, bottom, right); +} + void SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) { @@ -2144,6 +2224,68 @@ SDL_GetWindowBrightness(SDL_Window * window) return window->brightness; } +int +SDL_SetWindowOpacity(SDL_Window * window, float opacity) +{ + int retval; + CHECK_WINDOW_MAGIC(window, -1); + + if (!_this->SetWindowOpacity) { + return SDL_Unsupported(); + } + + if (opacity < 0.0f) { + opacity = 0.0f; + } else if (opacity > 1.0f) { + opacity = 1.0f; + } + + retval = _this->SetWindowOpacity(_this, window, opacity); + if (retval == 0) { + window->opacity = opacity; + } + + return retval; +} + +int +SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (out_opacity) { + *out_opacity = window->opacity; + } + + return 0; +} + +int +SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window) +{ + CHECK_WINDOW_MAGIC(modal_window, -1); + CHECK_WINDOW_MAGIC(parent_window, -1); + + if (!_this->SetWindowModalFor) { + return SDL_Unsupported(); + } + + return _this->SetWindowModalFor(_this, modal_window, parent_window); +} + +int +SDL_SetWindowInputFocus(SDL_Window * window) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (!_this->SetWindowInputFocus) { + return SDL_Unsupported(); + } + + return _this->SetWindowInputFocus(_this, window); +} + + int SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red, const Uint16 * green, @@ -2359,8 +2501,6 @@ SDL_OnWindowFocusGained(SDL_Window * window) static SDL_bool ShouldMinimizeOnFocusLoss(SDL_Window * window) { - const char *hint; - if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) { return SDL_FALSE; } @@ -2371,16 +2511,7 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window) } #endif - hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); - if (hint) { - if (*hint == '0') { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - - return SDL_TRUE; + return SDL_GetHintBoolean(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_TRUE); } void @@ -3596,6 +3727,16 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) int SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window) { +#ifdef __EMSCRIPTEN__ + /* !!! FIXME: propose a browser API for this, get this #ifdef out of here? */ + /* Web browsers don't (currently) have an API for a custom message box + that can block, but for the most common case (SDL_ShowSimpleMessageBox), + we can use the standard Javascript alert() function. */ + EM_ASM_({ + alert(UTF8ToString($0) + "\n\n" + UTF8ToString($1)); + }, title, message); + return 0; +#else SDL_MessageBoxData data; SDL_MessageBoxButtonData button; @@ -3613,20 +3754,13 @@ SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, S button.text = "OK"; return SDL_ShowMessageBox(&data, NULL); +#endif } SDL_bool SDL_ShouldAllowTopmost(void) { - const char *hint = SDL_GetHint(SDL_HINT_ALLOW_TOPMOST); - if (hint) { - if (*hint == '0') { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - return SDL_TRUE; + return SDL_GetHintBoolean(SDL_HINT_ALLOW_TOPMOST, SDL_TRUE); } int diff --git a/Engine/lib/sdl/src/video/android/SDL_androidevents.c b/Engine/lib/sdl/src/video/android/SDL_androidevents.c index 326361af0..c3cd4cc1b 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidevents.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidevents.c @@ -34,11 +34,11 @@ void android_egl_context_backup(); void android_egl_context_restore(); #if SDL_AUDIO_DRIVER_ANDROID -void AndroidAUD_ResumeDevices(void); -void AndroidAUD_PauseDevices(void); +void ANDROIDAUDIO_ResumeDevices(void); +void ANDROIDAUDIO_PauseDevices(void); #else -static void AndroidAUD_ResumeDevices(void) {} -static void AndroidAUD_PauseDevices(void) {} +static void ANDROIDAUDIO_ResumeDevices(void) {} +static void ANDROIDAUDIO_PauseDevices(void) {} #endif void @@ -83,14 +83,14 @@ Android_PumpEvents(_THIS) if (isPaused && !isPausing) { /* Make sure this is the last thing we do before pausing */ android_egl_context_backup(); - AndroidAUD_PauseDevices(); + ANDROIDAUDIO_PauseDevices(); if(SDL_SemWait(Android_ResumeSem) == 0) { #else if (isPaused) { if(SDL_SemTryWait(Android_ResumeSem) == 0) { #endif isPaused = 0; - AndroidAUD_ResumeDevices(); + ANDROIDAUDIO_ResumeDevices(); /* Restore the GL Context from here, as this operation is thread dependent */ if (!SDL_HasEvent(SDL_QUIT)) { android_egl_context_restore(); @@ -113,7 +113,7 @@ Android_PumpEvents(_THIS) #else if(SDL_SemTryWait(Android_PauseSem) == 0) { android_egl_context_backup(); - AndroidAUD_PauseDevices(); + ANDROIDAUDIO_PauseDevices(); isPaused = 1; } #endif diff --git a/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c b/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c index dc8951ff9..652e0cca7 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidkeyboard.c @@ -304,18 +304,22 @@ static SDL_Scancode Android_Keycodes[] = { SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_NEXT */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_IN */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_OUT */ - SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, - SDL_SCANCODE_UNKNOWN, + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_PRIMARY */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_3 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_LEFT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_LEFT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_RIGHT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_RIGHT */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_FORWARD */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_BACKWARD */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_FORWARD */ SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_BACKWARD */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_SLEEP */ + SDL_SCANCODE_CUT, /* AKEYCODE_CUT */ + SDL_SCANCODE_COPY, /* AKEYCODE_COPY */ + SDL_SCANCODE_PASTE, /* AKEYCODE_PASTE */ }; static SDL_Scancode diff --git a/Engine/lib/sdl/src/video/android/SDL_androidmouse.c b/Engine/lib/sdl/src/video/android/SDL_androidmouse.c index 3e9c0aff5..883fa8d22 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidmouse.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidmouse.c @@ -32,15 +32,24 @@ #define ACTION_DOWN 0 #define ACTION_UP 1 +#define ACTION_MOVE 2 #define ACTION_HOVER_MOVE 7 #define ACTION_SCROLL 8 #define BUTTON_PRIMARY 1 #define BUTTON_SECONDARY 2 #define BUTTON_TERTIARY 4 +#define BUTTON_BACK 8 +#define BUTTON_FORWARD 16 + +static Uint8 SDLButton; + +void +Android_InitMouse(void) +{ + SDLButton = 0; +} void Android_OnMouse( int androidButton, int action, float x, float y) { - static Uint8 SDLButton; - if (!Android_Window) { return; } @@ -53,6 +62,10 @@ void Android_OnMouse( int androidButton, int action, float x, float y) { SDLButton = SDL_BUTTON_RIGHT; } else if (androidButton == BUTTON_TERTIARY) { SDLButton = SDL_BUTTON_MIDDLE; + } else if (androidButton == BUTTON_FORWARD) { + SDLButton = SDL_BUTTON_X1; + } else if (androidButton == BUTTON_BACK) { + SDLButton = SDL_BUTTON_X2; } SDL_SendMouseMotion(Android_Window, 0, 0, x, y); SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, SDLButton); @@ -65,6 +78,7 @@ void Android_OnMouse( int androidButton, int action, float x, float y) { SDL_SendMouseButton(Android_Window, 0, SDL_RELEASED, SDLButton); break; + case ACTION_MOVE: case ACTION_HOVER_MOVE: SDL_SendMouseMotion(Android_Window, 0, 0, x, y); break; diff --git a/Engine/lib/sdl/src/video/android/SDL_androidmouse.h b/Engine/lib/sdl/src/video/android/SDL_androidmouse.h index 9b68eed57..a64e06d51 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidmouse.h +++ b/Engine/lib/sdl/src/video/android/SDL_androidmouse.h @@ -24,6 +24,7 @@ #include "SDL_androidvideo.h" +extern void Android_InitMouse(void); extern void Android_OnMouse( int button, int action, float x, float y); #endif /* _SDL_androidmouse_h */ diff --git a/Engine/lib/sdl/src/video/android/SDL_androidtouch.c b/Engine/lib/sdl/src/video/android/SDL_androidtouch.c index a6e0b896a..0ff11ef57 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidtouch.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidtouch.c @@ -50,7 +50,7 @@ static void Android_GetWindowCoordinates(float x, float y, *window_y = (int)(y * window_h); } -static volatile SDL_bool separate_mouse_and_touch = SDL_FALSE; +static SDL_bool separate_mouse_and_touch = SDL_FALSE; static void SeparateEventsHintWatcher(void *userdata, const char *name, diff --git a/Engine/lib/sdl/src/video/android/SDL_androidvideo.c b/Engine/lib/sdl/src/video/android/SDL_androidvideo.c index e14b96641..178a3e691 100644 --- a/Engine/lib/sdl/src/video/android/SDL_androidvideo.c +++ b/Engine/lib/sdl/src/video/android/SDL_androidvideo.c @@ -36,6 +36,7 @@ #include "SDL_androidclipboard.h" #include "SDL_androidevents.h" #include "SDL_androidkeyboard.h" +#include "SDL_androidmouse.h" #include "SDL_androidtouch.h" #include "SDL_androidwindow.h" @@ -181,6 +182,8 @@ Android_VideoInit(_THIS) Android_InitTouch(); + Android_InitMouse(); + /* We're done! */ return 0; } @@ -191,7 +194,6 @@ Android_VideoQuit(_THIS) Android_QuitTouch(); } -/* This function gets called before VideoInit() */ void Android_SetScreenResolution(int width, int height, Uint32 format, float rate) { @@ -200,8 +202,33 @@ Android_SetScreenResolution(int width, int height, Uint32 format, float rate) Android_ScreenFormat = format; Android_ScreenRate = rate; + /* + Update the resolution of the desktop mode, so that the window + can be properly resized. The screen resolution change can for + example happen when the Activity enters or exists immersive mode, + which can happen after VideoInit(). + */ + SDL_VideoDevice* device = SDL_GetVideoDevice(); + if (device && device->num_displays > 0) + { + SDL_VideoDisplay* display = &device->displays[0]; + display->desktop_mode.format = Android_ScreenFormat; + display->desktop_mode.w = Android_ScreenWidth; + display->desktop_mode.h = Android_ScreenHeight; + display->desktop_mode.refresh_rate = Android_ScreenRate; + } + if (Android_Window) { SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESIZED, width, height); + + /* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event + * will fall back to the old mode */ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(Android_Window); + + display->current_mode.format = format; + display->current_mode.w = width; + display->current_mode.h = height; + display->current_mode.refresh_rate = rate; } } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m index 015d77106..fd8680925 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaclipboard.m @@ -25,23 +25,13 @@ #include "SDL_cocoavideo.h" #include "../../events/SDL_clipboardevents_c.h" -static NSString * -GetTextFormat(_THIS) -{ - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) { - return NSPasteboardTypeString; - } else { - return NSStringPboardType; - } -} - int Cocoa_SetClipboardText(_THIS, const char *text) { @autoreleasepool { SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; NSPasteboard *pasteboard; - NSString *format = GetTextFormat(_this); + NSString *format = NSPasteboardTypeString; pasteboard = [NSPasteboard generalPasteboard]; data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil]; @@ -55,12 +45,12 @@ Cocoa_GetClipboardText(_THIS) { @autoreleasepool { NSPasteboard *pasteboard; - NSString *format = GetTextFormat(_this); + NSString *format = NSPasteboardTypeString; NSString *available; char *text; pasteboard = [NSPasteboard generalPasteboard]; - available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:format]]; + available = [pasteboard availableTypeFromArray:[NSArray arrayWithObject:format]]; if ([available isEqualToString:format]) { NSString* string; const char *utf8; diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m index e0da11fd4..17a3183b7 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaevents.m @@ -36,6 +36,7 @@ @interface SDLApplication : NSApplication - (void)terminate:(id)sender; +- (void)sendEvent:(NSEvent *)theEvent; @end @@ -47,6 +48,48 @@ SDL_SendQuit(); } +static SDL_bool s_bShouldHandleEventsInSDLApplication = SDL_FALSE; + +static void Cocoa_DispatchEvent(NSEvent *theEvent) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + + switch ([theEvent type]) { + case NSLeftMouseDown: + case NSOtherMouseDown: + case NSRightMouseDown: + case NSLeftMouseUp: + case NSOtherMouseUp: + case NSRightMouseUp: + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: /* usually middle mouse dragged */ + case NSMouseMoved: + case NSScrollWheel: + Cocoa_HandleMouseEvent(_this, theEvent); + break; + case NSKeyDown: + case NSKeyUp: + case NSFlagsChanged: + Cocoa_HandleKeyEvent(_this, theEvent); + break; + default: + break; + } +} + +// Dispatch events here so that we can handle events caught by +// nextEventMatchingMask in SDL, as well as events caught by other +// processes (such as CEF) that are passed down to NSApp. +- (void)sendEvent:(NSEvent *)theEvent +{ + if (s_bShouldHandleEventsInSDLApplication) { + Cocoa_DispatchEvent(theEvent); + } + + [super sendEvent:theEvent]; +} + @end // SDLApplication /* setAppleMenu disappeared from the headers in 10.4 */ @@ -114,28 +157,23 @@ */ for (NSWindow *window in [NSApp orderedWindows]) { if (window != win && [window canBecomeKeyWindow]) { - if ([window respondsToSelector:@selector(isOnActiveSpace)]) { - if (![window isOnActiveSpace]) { - continue; - } + if (![window isOnActiveSpace]) { + continue; } [window makeKeyAndOrderFront:self]; return; } } - /* If a window wasn't found above, iterate through all visible windows - * (including the 'About' window, if it's shown) and make the first one key. - * Note that +[NSWindow windowNumbersWithOptions:] was added in 10.6. + /* If a window wasn't found above, iterate through all visible windows in + * the active Space in z-order (including the 'About' window, if it's shown) + * and make the first one key. */ - if ([NSWindow respondsToSelector:@selector(windowNumbersWithOptions:)]) { - /* Get all visible windows in the active Space, in z-order. */ - for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) { - NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]]; - if (window && window != win && [window canBecomeKeyWindow]) { - [window makeKeyAndOrderFront:self]; - return; - } + for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) { + NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]]; + if (window && window != win && [window canBecomeKeyWindow]) { + [window makeKeyAndOrderFront:self]; + return; } } } @@ -176,7 +214,7 @@ - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { - return (BOOL)SDL_SendDropFile([filename UTF8String]); + return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL); } @end @@ -291,7 +329,7 @@ CreateApplicationMenus(void) /* Add the fullscreen view toggle menu option, if supported */ - if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) { + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { /* Create the view menu */ viewMenu = [[NSMenu alloc] initWithTitle:@"View"]; @@ -319,18 +357,10 @@ Cocoa_RegisterApp(void) [SDLApplication sharedApplication]; SDL_assert(NSApp != nil); - const char *hint = SDL_GetHint(SDL_HINT_MAC_BACKGROUND_APP); - if (!hint || *hint == '0') { -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 - if ([NSApp respondsToSelector:@selector(setActivationPolicy:)]) { -#endif - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 - } else { - ProcessSerialNumber psn = {0, kCurrentProcess}; - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - } -#endif + s_bShouldHandleEventsInSDLApplication = SDL_TRUE; + + if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, SDL_FALSE)) { + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp activateIgnoringOtherApps:YES]; } @@ -381,29 +411,11 @@ Cocoa_PumpEvents(_THIS) break; } - switch ([event type]) { - case NSLeftMouseDown: - case NSOtherMouseDown: - case NSRightMouseDown: - case NSLeftMouseUp: - case NSOtherMouseUp: - case NSRightMouseUp: - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: /* usually middle mouse dragged */ - case NSMouseMoved: - case NSScrollWheel: - Cocoa_HandleMouseEvent(_this, event); - break; - case NSKeyDown: - case NSKeyUp: - case NSFlagsChanged: - Cocoa_HandleKeyEvent(_this, event); - break; - default: - break; + if (!s_bShouldHandleEventsInSDLApplication) { + Cocoa_DispatchEvent(event); } - /* Pass through to NSApp to make sure everything stays in sync */ + + // Pass events down to SDLApplication to be handled in sendEvent: [NSApp sendEvent:event]; } }} diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m index 7f1d2308f..8b2ed91c2 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoakeyboard.m @@ -29,6 +29,7 @@ #include "../../events/scancodes_darwin.h" #include +#include /*#define DEBUG_IME NSLog */ #define DEBUG_IME(...) @@ -69,14 +70,6 @@ SDL_SendKeyboardText(str); } -- (void)insertText:(id)insertString -{ - /* This method is part of NSTextInput and not NSTextInputClient, but - * apparently it still might be called in OS X 10.5 and can cause beeps if - * the implementation is missing: http://crbug.com/47890 */ - [self insertText:insertString replacementRange:NSMakeRange(0, 0)]; -} - - (void)doCommandBySelector:(SEL)myselector { /* No need to do anything since we are not using Cocoa @@ -102,7 +95,7 @@ - (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange; { - if ([aString isKindOfClass: [NSAttributedString class]]) { + if ([aString isKindOfClass:[NSAttributedString class]]) { aString = [aString string]; } @@ -120,7 +113,7 @@ _markedRange = NSMakeRange(0, [aString length]); SDL_SendEditingText([aString UTF8String], - selectedRange.location, selectedRange.length); + (int) selectedRange.location, (int) selectedRange.length); DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText, selRange.location, selRange.length); @@ -150,10 +143,10 @@ aRange.location, aRange.length, windowHeight, NSStringFromRect(rect)); - if ([[self window] respondsToSelector:@selector(convertRectToScreen:)]) { - rect = [[self window] convertRectToScreen:rect]; + if ([window respondsToSelector:@selector(convertRectToScreen:)]) { + rect = [window convertRectToScreen:rect]; } else { - rect.origin = [[self window] convertBaseToScreen:rect.origin]; + rect.origin = [window convertBaseToScreen:rect.origin]; } return rect; @@ -191,6 +184,116 @@ @end +/*------------------------------------------------------------------------------ +Set up a HID callback to properly detect Caps Lock up/down events. +Derived from: +http://stackoverflow.com/questions/7190852/using-iohidmanager-to-get-modifier-key-events +*/ + +static IOHIDManagerRef s_hidManager = NULL; + +static void +HIDCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value) +{ + if (context != s_hidManager) { + /* An old callback, ignore it (related to bug 2157 below) */ + return; + } + + IOHIDElementRef elem = IOHIDValueGetElement(value); + if (IOHIDElementGetUsagePage(elem) != kHIDPage_KeyboardOrKeypad + || IOHIDElementGetUsage(elem) != kHIDUsage_KeyboardCapsLock) { + return; + } + CFIndex pressed = IOHIDValueGetIntegerValue(value); + SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); +} + +static CFDictionaryRef +CreateHIDDeviceMatchingDictionary(UInt32 usagePage, UInt32 usage) +{ + CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, + 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (dict) { + CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePage); + if (number) { + CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), number); + CFRelease(number); + number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); + if (number) { + CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), number); + CFRelease(number); + return dict; + } + } + CFRelease(dict); + } + return NULL; +} + +static void +QuitHIDCallback() +{ + if (!s_hidManager) { + return; + } + +#if 0 /* Releasing here causes a crash on Mac OS X 10.10 and earlier, + * so just leak it for now. See bug 2157 for details. + */ + IOHIDManagerUnscheduleFromRunLoop(s_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL); + IOHIDManagerClose(s_hidManager, 0); + + CFRelease(s_hidManager); +#endif + s_hidManager = NULL; +} + +static void +InitHIDCallback() +{ + s_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + if (!s_hidManager) { + return; + } + CFDictionaryRef keyboard = NULL, keypad = NULL; + CFArrayRef matches = NULL; + keyboard = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard); + if (!keyboard) { + goto fail; + } + keypad = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad); + if (!keypad) { + goto fail; + } + CFDictionaryRef matchesList[] = { keyboard, keypad }; + matches = CFArrayCreate(kCFAllocatorDefault, (const void **)matchesList, 2, NULL); + if (!matches) { + goto fail; + } + IOHIDManagerSetDeviceMatchingMultiple(s_hidManager, matches); + IOHIDManagerRegisterInputValueCallback(s_hidManager, HIDCallback, s_hidManager); + IOHIDManagerScheduleWithRunLoop(s_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); + if (IOHIDManagerOpen(s_hidManager, kIOHIDOptionsTypeNone) == kIOReturnSuccess) { + goto cleanup; + } + +fail: + QuitHIDCallback(); + +cleanup: + if (matches) { + CFRelease(matches); + } + if (keypad) { + CFRelease(keypad); + } + if (keyboard) { + CFRelease(keyboard); + } +} + /* This is a helper function for HandleModifierSide. This * function reverts back to behavior before the distinction between * sides was made. @@ -328,24 +431,6 @@ ReleaseModifierSide(unsigned int device_independent_mask, } } -/* This is a helper function for DoSidedModifiers. - * This function handles the CapsLock case. - */ -static void -HandleCapsLock(unsigned short scancode, - unsigned int oldMods, unsigned int newMods) -{ - unsigned int oldMask, newMask; - - oldMask = oldMods & NSAlphaShiftKeyMask; - newMask = newMods & NSAlphaShiftKeyMask; - - if (oldMask != newMask) { - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); - } -} - /* This function will handle the modifier keys and also determine the * correct side of the key. */ @@ -374,9 +459,6 @@ DoSidedModifiers(unsigned short scancode, unsigned int i, bit; - /* Handle CAPSLOCK separately because it doesn't have a left/right side */ - HandleCapsLock(scancode, oldMods, newMods); - /* Iterate through the bits, testing each against the old modifiers */ for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) { unsigned int oldMask, newMask; @@ -498,11 +580,10 @@ Cocoa_InitKeyboard(_THIS) SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option"); SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command"); - /* On pre-10.6, you might have the initial capslock key state wrong. */ - if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) { - data->modifierFlags = [NSEvent modifierFlags]; - SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0); - } + data->modifierFlags = [NSEvent modifierFlags]; + SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0); + + InitHIDCallback(); } void @@ -628,6 +709,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event) void Cocoa_QuitKeyboard(_THIS) { + QuitHIDCallback(); } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h index a0a29f501..ce8601cba 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.h @@ -30,12 +30,14 @@ typedef struct typedef struct { - const void *moderef; + CGDisplayModeRef moderef; } SDL_DisplayModeData; extern void Cocoa_InitModes(_THIS); extern int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); +extern int Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); extern void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display); +extern int Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hpdi, float * vdpi); extern int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern void Cocoa_QuitModes(_THIS); diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m index 7d98264a7..6ae9decbc 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamodes.m @@ -19,6 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" +#include "SDL_assert.h" #if SDL_VIDEO_DRIVER_COCOA @@ -55,25 +56,6 @@ Cocoa_ToggleMenuBar(const BOOL show) #endif } - -/* !!! FIXME: clean out the pre-10.6 code when it makes sense to do so. */ -#define FORCE_OLD_API 0 - -#if FORCE_OLD_API -#undef MAC_OS_X_VERSION_MIN_REQUIRED -#define MAC_OS_X_VERSION_MIN_REQUIRED 1050 -#endif - -static BOOL -IS_SNOW_LEOPARD_OR_LATER() -{ -#if FORCE_OLD_API - return NO; -#else - return floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5; -#endif -} - static int CG_SetError(const char *prefix, CGDisplayErr result) { @@ -118,65 +100,46 @@ CG_SetError(const char *prefix, CGDisplayErr result) } static SDL_bool -GetDisplayMode(_THIS, const void *moderef, CVDisplayLinkRef link, SDL_DisplayMode *mode) +GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CVDisplayLinkRef link, SDL_DisplayMode *mode) { SDL_DisplayModeData *data; - long width = 0; - long height = 0; - long bpp = 0; - long refreshRate = 0; + int width = 0; + int height = 0; + int bpp = 0; + int refreshRate = 0; + CFStringRef fmt; data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); if (!data) { return SDL_FALSE; } - data->moderef = moderef; + data->moderef = vidmode; - if (IS_SNOW_LEOPARD_OR_LATER()) { - CGDisplayModeRef vidmode = (CGDisplayModeRef) moderef; - CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode); - width = (long) CGDisplayModeGetWidth(vidmode); - height = (long) CGDisplayModeGetHeight(vidmode); - refreshRate = (long) (CGDisplayModeGetRefreshRate(vidmode) + 0.5); + fmt = CGDisplayModeCopyPixelEncoding(vidmode); + width = (int) CGDisplayModeGetWidth(vidmode); + height = (int) CGDisplayModeGetHeight(vidmode); + refreshRate = (int) (CGDisplayModeGetRefreshRate(vidmode) + 0.5); - if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels), - kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - bpp = 32; - } else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels), - kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - bpp = 16; - } else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels), - kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - bpp = 30; - } else { - bpp = 0; /* ignore 8-bit and such for now. */ - } - - CFRelease(fmt); + if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels), + kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + bpp = 32; + } else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels), + kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + bpp = 16; + } else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels), + kCFCompareCaseInsensitive) == kCFCompareEqualTo) { + bpp = 30; + } else { + bpp = 0; /* ignore 8-bit and such for now. */ } - #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (!IS_SNOW_LEOPARD_OR_LATER()) { - CFNumberRef number; - double refresh; - CFDictionaryRef vidmode = (CFDictionaryRef) moderef; - number = CFDictionaryGetValue(vidmode, kCGDisplayWidth); - CFNumberGetValue(number, kCFNumberLongType, &width); - number = CFDictionaryGetValue(vidmode, kCGDisplayHeight); - CFNumberGetValue(number, kCFNumberLongType, &height); - number = CFDictionaryGetValue(vidmode, kCGDisplayBitsPerPixel); - CFNumberGetValue(number, kCFNumberLongType, &bpp); - number = CFDictionaryGetValue(vidmode, kCGDisplayRefreshRate); - CFNumberGetValue(number, kCFNumberDoubleType, &refresh); - refreshRate = (long) (refresh + 0.5); - } - #endif + CFRelease(fmt); /* CGDisplayModeGetRefreshRate returns 0 for many non-CRT displays. */ if (refreshRate == 0 && link != NULL) { CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link); if ((time.flags & kCVTimeIsIndefinite) == 0 && time.timeValue != 0) { - refreshRate = (long) ((time.timeScale / (double) time.timeValue) + 0.5); + refreshRate = (int) ((time.timeScale / (double) time.timeValue) + 0.5); } } @@ -203,22 +166,6 @@ GetDisplayMode(_THIS, const void *moderef, CVDisplayLinkRef link, SDL_DisplayMod return SDL_TRUE; } -static void -Cocoa_ReleaseDisplayMode(_THIS, const void *moderef) -{ - if (IS_SNOW_LEOPARD_OR_LATER()) { - CGDisplayModeRelease((CGDisplayModeRef) moderef); /* NULL is ok */ - } -} - -static void -Cocoa_ReleaseDisplayModeList(_THIS, CFArrayRef modelist) -{ - if (IS_SNOW_LEOPARD_OR_LATER()) { - CFRelease(modelist); /* NULL is ok */ - } -} - static const char * Cocoa_GetDisplayName(CGDirectDisplayID displayID) { @@ -261,7 +208,7 @@ Cocoa_InitModes(_THIS) SDL_VideoDisplay display; SDL_DisplayData *displaydata; SDL_DisplayMode mode; - const void *moderef = NULL; + CGDisplayModeRef moderef = NULL; CVDisplayLinkRef link = NULL; if (pass == 0) { @@ -278,15 +225,7 @@ Cocoa_InitModes(_THIS) continue; } - if (IS_SNOW_LEOPARD_OR_LATER()) { - moderef = CGDisplayCopyDisplayMode(displays[i]); - } - - #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (!IS_SNOW_LEOPARD_OR_LATER()) { - moderef = CGDisplayCurrentMode(displays[i]); - } - #endif + moderef = CGDisplayCopyDisplayMode(displays[i]); if (!moderef) { continue; @@ -294,7 +233,7 @@ Cocoa_InitModes(_THIS) displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata)); if (!displaydata) { - Cocoa_ReleaseDisplayMode(_this, moderef); + CGDisplayModeRelease(moderef); continue; } displaydata->display = displays[i]; @@ -306,7 +245,7 @@ Cocoa_InitModes(_THIS) display.name = (char *)Cocoa_GetDisplayName(displays[i]); if (!GetDisplayMode(_this, moderef, link, &mode)) { CVDisplayLinkRelease(link); - Cocoa_ReleaseDisplayMode(_this, moderef); + CGDisplayModeRelease(moderef); SDL_free(display.name); SDL_free(displaydata); continue; @@ -338,21 +277,70 @@ Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) return 0; } +int +Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +{ + SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; + const CGDirectDisplayID cgdisplay = displaydata->display; + NSArray *screens = [NSScreen screens]; + NSScreen *screen = nil; + + /* !!! FIXME: maybe track the NSScreen in SDL_DisplayData? */ + for (NSScreen *i in screens) { + const CGDirectDisplayID thisDisplay = (CGDirectDisplayID) [[[i deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue]; + if (thisDisplay == cgdisplay) { + screen = i; + break; + } + } + + SDL_assert(screen != nil); /* didn't find it?! */ + if (screen == nil) { + return -1; + } + + const CGRect cgrect = CGDisplayBounds(cgdisplay); + const NSRect frame = [screen visibleFrame]; + + // !!! FIXME: I assume -[NSScreen visibleFrame] is relative to the origin of the screen in question and not the whole desktop. + // !!! FIXME: The math vs CGDisplayBounds might be incorrect if that's not the case, though. Check this. + rect->x = (int)(cgrect.origin.x + frame.origin.x); + rect->y = (int)(cgrect.origin.y + frame.origin.y); + rect->w = (int)frame.size.width; + rect->h = (int)frame.size.height; + + return 0; +} + +int +Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi) +{ + const float MM_IN_INCH = 25.4f; + + SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; + + CGSize displaySize = CGDisplayScreenSize(data->display); + int pixelWidth = (int) CGDisplayPixelsWide(data->display); + int pixelHeight = (int) CGDisplayPixelsHigh(data->display); + + if (ddpi) { + *ddpi = SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH); + } + if (hdpi) { + *hdpi = pixelWidth * MM_IN_INCH / displaySize.width; + } + if (vdpi) { + *vdpi = pixelHeight * MM_IN_INCH / displaySize.height; + } + + return 0; +} + void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) { SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; - CFArrayRef modes = NULL; - - if (IS_SNOW_LEOPARD_OR_LATER()) { - modes = CGDisplayCopyAllDisplayModes(data->display, NULL); - } - - #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (!IS_SNOW_LEOPARD_OR_LATER()) { - modes = CGDisplayAvailableModes(data->display); - } - #endif + CFArrayRef modes = CGDisplayCopyAllDisplayModes(data->display, NULL); if (modes) { CVDisplayLinkRef link = NULL; @@ -362,37 +350,19 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) CVDisplayLinkCreateWithCGDisplay(data->display, &link); for (i = 0; i < count; i++) { - const void *moderef = CFArrayGetValueAtIndex(modes, i); + CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); SDL_DisplayMode mode; if (GetDisplayMode(_this, moderef, link, &mode)) { - if (IS_SNOW_LEOPARD_OR_LATER()) { - CGDisplayModeRetain((CGDisplayModeRef) moderef); - } + CGDisplayModeRetain(moderef); SDL_AddDisplayMode(display, &mode); } } CVDisplayLinkRelease(link); - Cocoa_ReleaseDisplayModeList(_this, modes); + CFRelease(modes); } } -static CGError -Cocoa_SwitchMode(_THIS, CGDirectDisplayID display, const void *mode) -{ - if (IS_SNOW_LEOPARD_OR_LATER()) { - return CGDisplaySetDisplayMode(display, (CGDisplayModeRef) mode, NULL); - } - - #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (!IS_SNOW_LEOPARD_OR_LATER()) { - return CGDisplaySwitchToMode(display, (CFDictionaryRef) mode); - } - #endif - - return kCGErrorFailure; -} - int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) { @@ -408,7 +378,7 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) if (data == display->desktop_mode.driverdata) { /* Restoring desktop mode */ - Cocoa_SwitchMode(_this, displaydata->display, data->moderef); + CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL); if (CGDisplayIsMain(displaydata->display)) { CGReleaseAllDisplays(); @@ -433,7 +403,7 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) } /* Do the physical switch */ - result = Cocoa_SwitchMode(_this, displaydata->display, data->moderef); + result = CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL); if (result != kCGErrorSuccess) { CG_SetError("CGDisplaySwitchToMode()", result); goto ERR_NO_SWITCH; @@ -478,11 +448,11 @@ Cocoa_QuitModes(_THIS) } mode = (SDL_DisplayModeData *) display->desktop_mode.driverdata; - Cocoa_ReleaseDisplayMode(_this, mode->moderef); + CGDisplayModeRelease(mode->moderef); for (j = 0; j < display->num_display_modes; j++) { mode = (SDL_DisplayModeData*) display->display_modes[j].driverdata; - Cocoa_ReleaseDisplayMode(_this, mode->moderef); + CGDisplayModeRelease(mode->moderef); } } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m index c76833123..0a27549ae 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamouse.m @@ -226,13 +226,15 @@ Cocoa_WarpMouseGlobal(int x, int y) Cocoa_HandleMouseWarp(point.x, point.y); - /* According to the docs, this was deprecated in 10.6, but it's still - * around. The substitute requires a CGEventSource, but I'm not entirely - * sure how we'd procure the right one for this event. - */ - CGSetLocalEventsSuppressionInterval(0.0); CGWarpMouseCursorPosition(point); - CGSetLocalEventsSuppressionInterval(0.25); + + /* CGWarpMouse causes a short delay by default, which is preventable by + * Calling this directly after. CGSetLocalEventsSuppressionInterval can also + * prevent it, but it's deprecated as of OS X 10.6. + */ + if (!mouse->relative_mode) { + CGAssociateMouseAndMouseCursorPosition(YES); + } /* CGWarpMouseCursorPosition doesn't generate a window event, unlike our * other implementations' APIs. Send what's appropriate. @@ -314,7 +316,7 @@ Cocoa_GetGlobalMouseState(int *x, int *y) for (NSScreen *screen in [NSScreen screens]) { NSRect frame = [screen frame]; - if (NSPointInRect(cocoaLocation, frame)) { + if (NSMouseInRect(cocoaLocation, frame, NO)) { *x = (int) cocoaLocation.x; *y = (int) ((frame.origin.y + frame.size.height) - cocoaLocation.y); break; @@ -396,7 +398,7 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event) /* Ignore events that aren't inside the client area (i.e. title bar.) */ if ([event window]) { NSRect windowRect = [[[event window] contentView] frame]; - if (!NSPointInRect([event locationInWindow], windowRect)) { + if (!NSMouseInRect([event locationInWindow], windowRect, NO)) { return; } } @@ -419,8 +421,8 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) { SDL_Mouse *mouse = SDL_GetMouse(); - float x = -[event deltaX]; - float y = [event deltaY]; + CGFloat x = -[event deltaX]; + CGFloat y = [event deltaY]; SDL_MouseWheelDirection direction = SDL_MOUSEWHEEL_NORMAL; if ([event respondsToSelector:@selector(isDirectionInvertedFromDevice)]) { @@ -430,14 +432,14 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) } if (x > 0) { - x += 0.9f; + x = SDL_ceil(x); } else if (x < 0) { - x -= 0.9f; + x = SDL_floor(x); } if (y > 0) { - y += 0.9f; + y = SDL_ceil(y); } else if (y < 0) { - y -= 0.9f; + y = SDL_floor(y); } SDL_SendMouseWheel(window, mouse->mouseID, (int)x, (int)y, direction); } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m index ed70f3ca3..48abbca9c 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoamousetap.m @@ -32,8 +32,8 @@ #if SDL_MAC_NO_SANDBOX #include "SDL_keyboard.h" -#include "SDL_thread.h" #include "SDL_cocoavideo.h" +#include "../../thread/SDL_systhread.h" #include "../../events/SDL_mouse_c.h" @@ -96,7 +96,7 @@ Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event eventLocation = CGEventGetUnflippedLocation(event); windowRect = [nswindow contentRectForFrameRect:[nswindow frame]]; - if (!NSPointInRect(NSPointFromCGPoint(eventLocation), windowRect)) { + if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) { /* This is in CGs global screenspace coordinate system, which has a * flipped Y. @@ -109,15 +109,14 @@ Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event newLocation.x = NSMaxX(windowRect) - 1.0; } - if (eventLocation.y < NSMinY(windowRect)) { + if (eventLocation.y <= NSMinY(windowRect)) { newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1); - } else if (eventLocation.y >= NSMaxY(windowRect)) { - newLocation.y += (eventLocation.y - NSMaxY(windowRect) + 1); + } else if (eventLocation.y > NSMaxY(windowRect)) { + newLocation.y += (eventLocation.y - NSMaxY(windowRect)); } - CGSetLocalEventsSuppressionInterval(0); CGWarpMouseCursorPosition(newLocation); - CGSetLocalEventsSuppressionInterval(0.25); + CGAssociateMouseAndMouseCursorPosition(YES); if ((CGEventMaskBit(type) & movementEventsMask) == 0) { /* For click events, we just constrain the event to the window, so @@ -203,7 +202,7 @@ Cocoa_InitMouseEventTap(SDL_MouseData* driverdata) tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0); if (tapdata->runloopStartedSemaphore) { - tapdata->thread = SDL_CreateThread(&Cocoa_MouseTapThread, "Event Tap Loop", tapdata); + tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata); if (!tapdata->thread) { SDL_DestroySemaphore(tapdata->runloopStartedSemaphore); } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m index aa3609984..645e5ba45 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoaopengl.m @@ -173,6 +173,8 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) return NULL; } + attr[i++] = NSOpenGLPFAAllowOfflineRenderers; + /* specify a profile if we're on Lion (10.7) or later. */ if (lion_or_later) { NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy; diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m index cd5d97b70..fc8a2775c 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoashape.m @@ -35,9 +35,7 @@ Cocoa_CreateShaper(SDL_Window* window) SDL_WindowData* windata = (SDL_WindowData*)window->driverdata; [windata->nswindow setOpaque:NO]; - if ([windata->nswindow respondsToSelector:@selector(setStyleMask:)]) { - [windata->nswindow setStyleMask:NSBorderlessWindowMask]; - } + [windata->nswindow setStyleMask:NSBorderlessWindowMask]; SDL_WindowShaper* result = result = malloc(sizeof(SDL_WindowShaper)); result->window = window; diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m index b8f775ddb..e436e6521 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoavideo.m @@ -73,6 +73,8 @@ Cocoa_CreateDevice(int devindex) device->VideoInit = Cocoa_VideoInit; device->VideoQuit = Cocoa_VideoQuit; device->GetDisplayBounds = Cocoa_GetDisplayBounds; + device->GetDisplayUsableBounds = Cocoa_GetDisplayUsableBounds; + device->GetDisplayDPI = Cocoa_GetDisplayDPI; device->GetDisplayModes = Cocoa_GetDisplayModes; device->SetDisplayMode = Cocoa_SetDisplayMode; device->PumpEvents = Cocoa_PumpEvents; @@ -86,6 +88,7 @@ Cocoa_CreateDevice(int devindex) device->SetWindowSize = Cocoa_SetWindowSize; device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize; device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize; + device->SetWindowOpacity = Cocoa_SetWindowOpacity; device->ShowWindow = Cocoa_ShowWindow; device->HideWindow = Cocoa_HideWindow; device->RaiseWindow = Cocoa_RaiseWindow; @@ -93,6 +96,7 @@ Cocoa_CreateDevice(int devindex) device->MinimizeWindow = Cocoa_MinimizeWindow; device->RestoreWindow = Cocoa_RestoreWindow; device->SetWindowBordered = Cocoa_SetWindowBordered; + device->SetWindowResizable = Cocoa_SetWindowResizable; device->SetWindowFullscreen = Cocoa_SetWindowFullscreen; device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp; device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp; @@ -146,8 +150,7 @@ Cocoa_VideoInit(_THIS) Cocoa_InitKeyboard(_this); Cocoa_InitMouse(_this); - const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES); - data->allow_spaces = ( (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && (!hint || (*hint != '0')) ); + data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE)); /* The IOPM assertion API can disable the screensaver as of 10.7. */ data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6; @@ -173,13 +176,7 @@ Cocoa_CreateImage(SDL_Surface * surface) int i; NSImage *img; - converted = SDL_ConvertSurfaceFormat(surface, -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - SDL_PIXELFORMAT_RGBA8888, -#else - SDL_PIXELFORMAT_ABGR8888, -#endif - 0); + converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0); if (!converted) { return nil; } diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h index 1037badfc..a32de8387 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.h @@ -125,6 +125,7 @@ extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window); extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window); extern void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window); extern void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window); +extern int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity); extern void Cocoa_ShowWindow(_THIS, SDL_Window * window); extern void Cocoa_HideWindow(_THIS, SDL_Window * window); extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window); @@ -132,6 +133,7 @@ extern void Cocoa_MaximizeWindow(_THIS, SDL_Window * window); extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window); extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window); extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m index a4da6cb2d..cfad54854 100644 --- a/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m +++ b/Engine/lib/sdl/src/video/cocoa/SDL_cocoawindow.m @@ -80,20 +80,20 @@ - (void)sendEvent:(NSEvent *)event { - [super sendEvent:event]; + [super sendEvent:event]; - if ([event type] != NSLeftMouseUp) { - return; - } + if ([event type] != NSLeftMouseUp) { + return; + } - id delegate = [self delegate]; - if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) { - return; - } + id delegate = [self delegate]; + if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) { + return; + } - if ([delegate isMoving]) { - [delegate windowDidFinishMoving]; - } + if ([delegate isMoving]) { + [delegate windowDidFinishMoving]; + } } /* We'll respond to selectors by doing nothing so we don't beep. @@ -116,9 +116,12 @@ - (BOOL)performDragOperation:(id )sender { @autoreleasepool { + SDL_VideoDevice *_this = SDL_GetVideoDevice(); NSPasteboard *pasteboard = [sender draggingPasteboard]; NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType]; NSString *desiredType = [pasteboard availableTypeFromArray:types]; + SDL_Window *sdlwindow = nil; + if (desiredType == nil) { return NO; /* can't accept anything that's being dropped here. */ } @@ -132,13 +135,10 @@ NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"]; for (NSString *path in array) { - NSURL *fileURL = [[NSURL fileURLWithPath:path] autorelease]; + NSURL *fileURL = [NSURL fileURLWithPath:path]; NSNumber *isAlias = nil; - /* Functionality for resolving URL aliases was added with OS X 10.6. */ - if ([fileURL respondsToSelector:@selector(getResourceValue:forKey:error:)]) { - [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil]; - } + [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil]; /* If the URL is an alias, resolve it. */ if ([isAlias boolValue]) { @@ -157,11 +157,22 @@ } } - if (!SDL_SendDropFile([[fileURL path] UTF8String])) { + /* !!! FIXME: is there a better way to do this? */ + if (_this) { + for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) { + NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow; + if (nswindow == self) { + break; + } + } + } + + if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) { return NO; } } + SDL_SendDropComplete(sdlwindow); return YES; }} @@ -196,17 +207,17 @@ ScheduleContextUpdates(SDL_WindowData *data) } } +/* !!! FIXME: this should use a hint callback. */ static int GetHintCtrlClickEmulateRightClick() { - const char *hint = SDL_GetHint( SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK ); - return hint != NULL && *hint != '0'; + return SDL_GetHintBoolean(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, SDL_FALSE); } -static unsigned int +static NSUInteger GetWindowStyle(SDL_Window * window) { - unsigned int style; + NSUInteger style = 0; if (window->flags & SDL_WINDOW_FULLSCREEN) { style = NSBorderlessWindowMask; @@ -224,21 +235,17 @@ GetWindowStyle(SDL_Window * window) } static SDL_bool -SetWindowStyle(SDL_Window * window, unsigned int style) +SetWindowStyle(SDL_Window * window, NSUInteger style) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; NSWindow *nswindow = data->nswindow; - if (![nswindow respondsToSelector: @selector(setStyleMask:)]) { - return SDL_FALSE; - } - /* The view responder chain gets messed with during setStyleMask */ if ([[nswindow contentView] nextResponder] == data->listener) { [[nswindow contentView] setNextResponder:nil]; } - [nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)style]; + [nswindow setStyleMask:style]; /* The view responder chain gets messed with during setStyleMask */ if ([[nswindow contentView] nextResponder] != data->listener) { @@ -302,9 +309,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style) [view setNextResponder:self]; - if ([view respondsToSelector:@selector(setAcceptsTouchEvents:)]) { - [view setAcceptsTouchEvents:YES]; - } + [view setAcceptsTouchEvents:YES]; } - (void)observeValueForKeyPath:(NSString *)keyPath @@ -589,12 +594,9 @@ SetWindowStyle(SDL_Window * window, unsigned int style) [NSMenu setMenuBarVisible:NO]; } - /* On pre-10.6, you might have the capslock key state wrong now because we can't check here. */ - if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) { - const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask; - _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags; - SDL_ToggleModState(KMOD_CAPS, newflags != 0); - } + const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask; + _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags; + SDL_ToggleModState(KMOD_CAPS, newflags != 0); } - (void)windowDidResignKey:(NSNotification *)aNotification @@ -820,23 +822,18 @@ SetWindowStyle(SDL_Window * window, unsigned int style) - (void)mouseDown:(NSEvent *)theEvent { int button; + int clicks; /* Ignore events that aren't inside the client area (i.e. title bar.) */ if ([theEvent window]) { NSRect windowRect = [[[theEvent window] contentView] frame]; - - /* add one to size, since NSPointInRect is exclusive of the bottom - edges, which mean it misses the top of the window by one pixel - (as the origin is the bottom left). */ - windowRect.size.width += 1; - windowRect.size.height += 1; - - if (!NSPointInRect([theEvent locationInWindow], windowRect)) { + if (!NSMouseInRect([theEvent locationInWindow], windowRect, NO)) { return; } } if ([self processHitTest:theEvent]) { + SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return; /* dragging, drop event. */ } @@ -858,10 +855,12 @@ SetWindowStyle(SDL_Window * window, unsigned int style) button = SDL_BUTTON_MIDDLE; break; default: - button = [theEvent buttonNumber] + 1; + button = (int) [theEvent buttonNumber] + 1; break; } - SDL_SendMouseButton(_data->window, 0, SDL_PRESSED, button); + + clicks = (int) [theEvent clickCount]; + SDL_SendMouseButtonClicks(_data->window, 0, SDL_PRESSED, button, clicks); } - (void)rightMouseDown:(NSEvent *)theEvent @@ -877,8 +876,10 @@ SetWindowStyle(SDL_Window * window, unsigned int style) - (void)mouseUp:(NSEvent *)theEvent { int button; + int clicks; if ([self processHitTest:theEvent]) { + SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return; /* stopped dragging, drop event. */ } @@ -898,10 +899,12 @@ SetWindowStyle(SDL_Window * window, unsigned int style) button = SDL_BUTTON_MIDDLE; break; default: - button = [theEvent buttonNumber] + 1; + button = (int) [theEvent buttonNumber] + 1; break; } - SDL_SendMouseButton(_data->window, 0, SDL_RELEASED, button); + + clicks = (int) [theEvent clickCount]; + SDL_SendMouseButtonClicks(_data->window, 0, SDL_RELEASED, button, clicks); } - (void)rightMouseUp:(NSEvent *)theEvent @@ -922,6 +925,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style) int x, y; if ([self processHitTest:theEvent]) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return; /* dragging, drop event. */ } @@ -956,13 +960,8 @@ SetWindowStyle(SDL_Window * window, unsigned int style) cgpoint.x = window->x + x; cgpoint.y = window->y + y; - /* According to the docs, this was deprecated in 10.6, but it's still - * around. The substitute requires a CGEventSource, but I'm not entirely - * sure how we'd procure the right one for this event. - */ - CGSetLocalEventsSuppressionInterval(0.0); CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); - CGSetLocalEventsSuppressionInterval(0.25); + CGAssociateMouseAndMouseCursorPosition(YES); Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); #endif @@ -1075,6 +1074,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style) - (void)rightMouseDown:(NSEvent *)theEvent; - (BOOL)mouseDownCanMoveWindow; - (void)drawRect:(NSRect)dirtyRect; +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent; @end @implementation SDLView @@ -1114,6 +1114,15 @@ SetWindowStyle(SDL_Window * window, unsigned int style) cursor:[NSCursor invisibleCursor]]; } } + +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent +{ + if (SDL_GetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH)) { + return SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE); + } else { + return SDL_GetHintBoolean("SDL_MAC_MOUSE_FOCUS_CLICKTHROUGH", SDL_FALSE); + } +} @end static int @@ -1157,7 +1166,7 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created } { - unsigned int style = [nswindow styleMask]; + unsigned long style = [nswindow styleMask]; if (style == NSBorderlessWindowMask) { window->flags |= SDL_WINDOW_BORDERLESS; @@ -1208,7 +1217,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); NSRect rect; SDL_Rect bounds; - unsigned int style; + NSUInteger style; NSArray *screens = [NSScreen screens]; Cocoa_GetDisplayBounds(_this, display, &bounds); @@ -1263,7 +1272,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) } } - [nswindow setContentView: contentView]; + [nswindow setContentView:contentView]; [contentView release]; /* Allow files and folders to be dragged onto the window by users */ @@ -1470,27 +1479,6 @@ Cocoa_RestoreWindow(_THIS, SDL_Window * window) } }} -static NSWindow * -Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style) -{ - if (!data->created) { - /* Don't mess with other people's windows... */ - return nswindow; - } - - [data->listener close]; - data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:NO screen:[nswindow screen]]; - [data->nswindow setContentView:[nswindow contentView]]; - [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]]; - /* See comment in SetupWindowData. */ - [data->nswindow setOneShot:NO]; - [data->listener listen:data]; - - [nswindow close]; - - return data->nswindow; -} - void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { @autoreleasepool @@ -1502,6 +1490,20 @@ Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) } }} +void +Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ @autoreleasepool +{ + /* Don't set this if we're in a space! + * The window will get permanently stuck if resizable is false. + * -flibit + */ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Cocoa_WindowListener *listener = data->listener; + if (![listener isInFullscreenSpace]) { + SetWindowStyle(window, GetWindowStyle(window)); + } +}} void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) @@ -1532,11 +1534,7 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display rect.origin.y += (screenRect.size.height - rect.size.height); } - if ([nswindow respondsToSelector: @selector(setStyleMask:)]) { - [nswindow performSelector: @selector(setStyleMask:) withObject: (id)NSBorderlessWindowMask]; - } else { - nswindow = Cocoa_RebuildWindow(data, nswindow, NSBorderlessWindowMask); - } + [nswindow setStyleMask:NSBorderlessWindowMask]; } else { rect.origin.x = window->windowed.x; rect.origin.y = window->windowed.y; @@ -1544,16 +1542,12 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display rect.size.height = window->windowed.h; ConvertNSRect([nswindow screen], fullscreen, &rect); - if ([nswindow respondsToSelector: @selector(setStyleMask:)]) { - [nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)GetWindowStyle(window)]; + [nswindow setStyleMask:GetWindowStyle(window)]; - /* Hack to restore window decorations on Mac OS X 10.10 */ - NSRect frameRect = [nswindow frame]; - [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; - [nswindow setFrame:frameRect display:NO]; - } else { - nswindow = Cocoa_RebuildWindow(data, nswindow, GetWindowStyle(window)); - } + /* Hack to restore window decorations on Mac OS X 10.10 */ + NSRect frameRect = [nswindow frame]; + [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; + [nswindow setFrame:frameRect display:NO]; } /* The view responder chain gets messed with during setStyleMask */ @@ -1767,6 +1761,14 @@ Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled) return 0; /* just succeed, the real work is done elsewhere. */ } +int +Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + [data->nswindow setAlphaValue:opacity]; + return 0; +} + #endif /* SDL_VIDEO_DRIVER_COCOA */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c index 5579759eb..d339dd78e 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_video.c @@ -121,6 +121,7 @@ DirectFB_CreateDevice(int devindex) device->SetWindowIcon = DirectFB_SetWindowIcon; device->SetWindowPosition = DirectFB_SetWindowPosition; device->SetWindowSize = DirectFB_SetWindowSize; + device->SetWindowOpacity = DirectFB_SetWindowOpacity; device->ShowWindow = DirectFB_ShowWindow; device->HideWindow = DirectFB_HideWindow; device->RaiseWindow = DirectFB_RaiseWindow; diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c index 3b8b45d44..40bbe6aee 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.c @@ -529,4 +529,17 @@ DirectFB_AdjustWindowSurface(SDL_Window * window) return; } +int +DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ + const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f)); + SDL_DFB_WINDOWDATA(window); + SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha)); + windata->opacity = alpha; + return 0; + +error: + return -1; +} + #endif /* SDL_VIDEO_DRIVER_DIRECTFB */ diff --git a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h index 658cc8749..4b9970812 100644 --- a/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h +++ b/Engine/lib/sdl/src/video/directfb/SDL_DirectFB_window.h @@ -75,6 +75,7 @@ extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); extern void DirectFB_AdjustWindowSurface(SDL_Window * window); +extern int DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity); #endif /* _SDL_directfb_window_h */ diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c index 0f915c6f3..a4720e402 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.c @@ -217,16 +217,16 @@ static const SDL_Scancode emscripten_scancode_table[] = { /* 171 */ SDL_SCANCODE_UNKNOWN, /* 172 */ SDL_SCANCODE_UNKNOWN, /* 173 */ SDL_SCANCODE_MINUS, /*FX*/ - /* 174 */ SDL_SCANCODE_UNKNOWN, - /* 175 */ SDL_SCANCODE_UNKNOWN, - /* 176 */ SDL_SCANCODE_UNKNOWN, - /* 177 */ SDL_SCANCODE_UNKNOWN, + /* 174 */ SDL_SCANCODE_VOLUMEDOWN, /*IE, Chrome*/ + /* 175 */ SDL_SCANCODE_VOLUMEUP, /*IE, Chrome*/ + /* 176 */ SDL_SCANCODE_AUDIONEXT, /*IE, Chrome*/ + /* 177 */ SDL_SCANCODE_AUDIOPREV, /*IE, Chrome*/ /* 178 */ SDL_SCANCODE_UNKNOWN, - /* 179 */ SDL_SCANCODE_UNKNOWN, + /* 179 */ SDL_SCANCODE_AUDIOPLAY, /*IE, Chrome*/ /* 180 */ SDL_SCANCODE_UNKNOWN, - /* 181 */ SDL_SCANCODE_UNKNOWN, - /* 182 */ SDL_SCANCODE_UNKNOWN, - /* 183 */ SDL_SCANCODE_UNKNOWN, + /* 181 */ SDL_SCANCODE_AUDIOMUTE, /*FX*/ + /* 182 */ SDL_SCANCODE_VOLUMEDOWN, /*FX*/ + /* 183 */ SDL_SCANCODE_VOLUMEUP, /*FX*/ /* 184 */ SDL_SCANCODE_UNKNOWN, /* 185 */ SDL_SCANCODE_UNKNOWN, /* 186 */ SDL_SCANCODE_SEMICOLON, /*IE, Chrome, D3E legacy*/ @@ -301,25 +301,34 @@ EM_BOOL Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) { SDL_WindowData *window_data = userData; - int mx = mouseEvent->canvasX, my = mouseEvent->canvasY; + int mx, my; + static double residualx = 0, residualy = 0; EmscriptenPointerlockChangeEvent pointerlock_status; - /* check for pointer lock */ - emscripten_get_pointerlock_status(&pointerlock_status); + /* rescale (in case canvas is being scaled)*/ + double client_w, client_h, xscale, yscale; + emscripten_get_element_css_size(NULL, &client_w, &client_h); + xscale = window_data->window->w / client_w; + yscale = window_data->window->h / client_h; - if (pointerlock_status.isActive) { - mx = mouseEvent->movementX; - my = mouseEvent->movementY; + /* check for pointer lock */ + int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status); + int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS ? pointerlock_status.isActive : SDL_FALSE; + + if (isPointerLocked) { + residualx += mouseEvent->movementX * xscale; + residualy += mouseEvent->movementY * yscale; + /* Let slow sub-pixel motion accumulate. Don't lose it. */ + mx = residualx; + residualx -= mx; + my = residualy; + residualy -= my; + } else { + mx = mouseEvent->canvasX * xscale; + my = mouseEvent->canvasY * yscale; } - /* rescale (in case canvas is being scaled)*/ - double client_w, client_h; - emscripten_get_element_css_size(NULL, &client_w, &client_h); - - mx = mx * (window_data->window->w / (client_w * window_data->pixel_ratio)); - my = my * (window_data->window->h / (client_h * window_data->pixel_ratio)); - - SDL_SendMouseMotion(window_data->window, 0, pointerlock_status.isActive, mx, my); + SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my); return 0; } @@ -341,16 +350,36 @@ Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEve default: return 0; } - SDL_SendMouseButton(window_data->window, 0, eventType == EMSCRIPTEN_EVENT_MOUSEDOWN ? SDL_PRESSED : SDL_RELEASED, sdl_button); - return 1; + + SDL_EventType sdl_event_type = (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN ? SDL_PRESSED : SDL_RELEASED); + SDL_SendMouseButton(window_data->window, 0, sdl_event_type, sdl_button); + return SDL_GetEventState(sdl_event_type) == SDL_ENABLE; } EM_BOOL Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) { SDL_WindowData *window_data = userData; - SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? SDL_WINDOWEVENT_ENTER : SDL_WINDOWEVENT_LEAVE, 0, 0); - return 1; + + int mx = mouseEvent->canvasX, my = mouseEvent->canvasY; + EmscriptenPointerlockChangeEvent pointerlock_status; + + /* check for pointer lock */ + int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status); + int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS ? pointerlock_status.isActive : SDL_FALSE; + + if (!isPointerLocked) { + /* rescale (in case canvas is being scaled)*/ + double client_w, client_h; + emscripten_get_element_css_size(NULL, &client_w, &client_h); + + mx = mx * (window_data->window->w / client_w); + my = my * (window_data->window->h / client_h); + SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my); + } + + SDL_SetMouseFocus(eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? window_data->window : NULL); + return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE; } EM_BOOL @@ -358,15 +387,22 @@ Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, vo { SDL_WindowData *window_data = userData; SDL_SendMouseWheel(window_data->window, 0, wheelEvent->deltaX, -wheelEvent->deltaY, SDL_MOUSEWHEEL_NORMAL); - return 1; + return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE; } EM_BOOL Emscripten_HandleFocus(int eventType, const EmscriptenFocusEvent *wheelEvent, void *userData) { SDL_WindowData *window_data = userData; + /* If the user switches away while keys are pressed (such as + * via Alt+Tab), key release events won't be received. */ + if (eventType == EMSCRIPTEN_EVENT_BLUR) { + SDL_ResetKeyboard(); + } + + SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_FOCUS ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); - return 1; + return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE; } EM_BOOL @@ -374,12 +410,16 @@ Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, vo { SDL_WindowData *window_data = userData; int i; + double client_w, client_h; + int preventDefault = 0; SDL_TouchID deviceId = 1; if (SDL_AddTouch(deviceId, "") < 0) { return 0; } + emscripten_get_element_css_size(NULL, &client_w, &client_h); + for (i = 0; i < touchEvent->numTouches; i++) { SDL_FingerID id; float x, y; @@ -388,20 +428,44 @@ Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, vo continue; id = touchEvent->touches[i].identifier; - x = touchEvent->touches[i].canvasX / (float)window_data->windowed_width; - y = touchEvent->touches[i].canvasY / (float)window_data->windowed_height; + x = touchEvent->touches[i].canvasX / client_w; + y = touchEvent->touches[i].canvasY / client_h; - if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) { - SDL_SendTouchMotion(deviceId, id, x, y, 1.0f); - } else if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) { + if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) { + if (!window_data->finger_touching) { + window_data->finger_touching = SDL_TRUE; + window_data->first_finger = id; + SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, x, y); + SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT); + } SDL_SendTouch(deviceId, id, SDL_TRUE, x, y, 1.0f); + + if (!preventDefault && SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) { + preventDefault = 1; + } + } else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) { + if ((window_data->finger_touching) && (window_data->first_finger == id)) { + SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, x, y); + } + SDL_SendTouchMotion(deviceId, id, x, y, 1.0f); + + if (!preventDefault && SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) { + preventDefault = 1; + } } else { + if ((window_data->finger_touching) && (window_data->first_finger == id)) { + SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT); + window_data->finger_touching = SDL_FALSE; + } SDL_SendTouch(deviceId, id, SDL_FALSE, x, y, 1.0f); + + if (!preventDefault && SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) { + preventDefault = 1; + } } } - - return 1; + return preventDefault; } EM_BOOL @@ -431,16 +495,19 @@ Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, voi break; } } - SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? - SDL_PRESSED : SDL_RELEASED, scancode); + SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode); } } - /* if we prevent keydown, we won't get keypress - * also we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX + SDL_bool prevent_default = SDL_GetEventState(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP) == SDL_ENABLE; + + /* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress + * we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX */ - return SDL_GetEventState(SDL_TEXTINPUT) != SDL_ENABLE || eventType != EMSCRIPTEN_EVENT_KEYDOWN - || keyEvent->keyCode == 8 /* backspace */ || keyEvent->keyCode == 9 /* tab */; + if (eventType == EMSCRIPTEN_EVENT_KEYDOWN && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE && keyEvent->keyCode != 8 /* backspace */ && keyEvent->keyCode != 9 /* tab */) + prevent_default = SDL_FALSE; + + return prevent_default; } EM_BOOL @@ -450,65 +517,24 @@ Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) { SDL_SendKeyboardText(text); } - return 1; + return SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE; } EM_BOOL Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData) { - /*make sure this is actually our element going fullscreen*/ - if(SDL_strcmp(fullscreenChangeEvent->id, "SDLFullscreenElement") != 0) - return 0; - SDL_WindowData *window_data = userData; if(fullscreenChangeEvent->isFullscreen) { - SDL_bool is_desktop_fullscreen; window_data->window->flags |= window_data->requested_fullscreen_mode; - if(!window_data->requested_fullscreen_mode) - window_data->window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; /*we didn't reqest fullscreen*/ - window_data->requested_fullscreen_mode = 0; - is_desktop_fullscreen = (window_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; - - /*update size*/ - if(window_data->window->flags & SDL_WINDOW_RESIZABLE || is_desktop_fullscreen) - { - emscripten_set_canvas_size(fullscreenChangeEvent->screenWidth, fullscreenChangeEvent->screenHeight); - SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, fullscreenChangeEvent->screenWidth, fullscreenChangeEvent->screenHeight); - } - else - { - /*preserve ratio*/ - double w = window_data->window->w; - double h = window_data->window->h; - double factor = SDL_min(fullscreenChangeEvent->screenWidth / w, fullscreenChangeEvent->screenHeight / h); - emscripten_set_element_css_size(NULL, w * factor, h * factor); - } + if(!window_data->requested_fullscreen_mode) + window_data->window->flags |= SDL_WINDOW_FULLSCREEN; /*we didn't reqest fullscreen*/ } else { - EM_ASM({ - //un-reparent canvas (similar to Module.requestFullscreen) - var canvas = Module['canvas']; - if(canvas.parentNode.id == "SDLFullscreenElement") { - var canvasContainer = canvas.parentNode; - canvasContainer.parentNode.insertBefore(canvas, canvasContainer); - canvasContainer.parentNode.removeChild(canvasContainer); - } - }); - double unscaled_w = window_data->windowed_width / window_data->pixel_ratio; - double unscaled_h = window_data->windowed_height / window_data->pixel_ratio; - emscripten_set_canvas_size(window_data->windowed_width, window_data->windowed_height); - - if (!window_data->external_size && window_data->pixel_ratio != 1.0f) { - emscripten_set_element_css_size(NULL, unscaled_w, unscaled_h); - } - - SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, unscaled_w, unscaled_h); - window_data->window->flags &= ~FULLSCREEN_MASK; } @@ -519,17 +545,11 @@ EM_BOOL Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) { SDL_WindowData *window_data = userData; - if(window_data->window->flags & FULLSCREEN_MASK) - { - SDL_bool is_desktop_fullscreen = (window_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; - if(window_data->window->flags & SDL_WINDOW_RESIZABLE || is_desktop_fullscreen) - { - emscripten_set_canvas_size(uiEvent->windowInnerWidth * window_data->pixel_ratio, uiEvent->windowInnerHeight * window_data->pixel_ratio); - SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, uiEvent->windowInnerWidth, uiEvent->windowInnerHeight); - } - } - else + /* update pixel ratio */ + window_data->pixel_ratio = emscripten_get_device_pixel_ratio(); + + if(!(window_data->window->flags & FULLSCREEN_MASK)) { /* this will only work if the canvas size is set through css */ if(window_data->window->flags & SDL_WINDOW_RESIZABLE) @@ -555,6 +575,22 @@ Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *u return 0; } +EM_BOOL +Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData) +{ + /*this is used during fullscreen changes*/ + SDL_WindowData *window_data = userData; + + if(window_data->fullscreen_resize) + { + double css_w, css_h; + emscripten_get_element_css_size(NULL, &css_w, &css_h); + SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, css_w, css_h); + } + + return 0; +} + EM_BOOL Emscripten_HandleVisibilityChange(int eventType, const EmscriptenVisibilityChangeEvent *visEvent, void *userData) { @@ -570,15 +606,15 @@ Emscripten_RegisterEventHandlers(SDL_WindowData *data) emscripten_set_mousemove_callback("#canvas", data, 0, Emscripten_HandleMouseMove); emscripten_set_mousedown_callback("#canvas", data, 0, Emscripten_HandleMouseButton); - emscripten_set_mouseup_callback("#canvas", data, 0, Emscripten_HandleMouseButton); + emscripten_set_mouseup_callback("#document", data, 0, Emscripten_HandleMouseButton); emscripten_set_mouseenter_callback("#canvas", data, 0, Emscripten_HandleMouseFocus); emscripten_set_mouseleave_callback("#canvas", data, 0, Emscripten_HandleMouseFocus); emscripten_set_wheel_callback("#canvas", data, 0, Emscripten_HandleWheel); - emscripten_set_focus_callback("#canvas", data, 0, Emscripten_HandleFocus); - emscripten_set_blur_callback("#canvas", data, 0, Emscripten_HandleFocus); + emscripten_set_focus_callback("#window", data, 0, Emscripten_HandleFocus); + emscripten_set_blur_callback("#window", data, 0, Emscripten_HandleFocus); emscripten_set_touchstart_callback("#canvas", data, 0, Emscripten_HandleTouch); emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch); @@ -607,15 +643,15 @@ Emscripten_UnregisterEventHandlers(SDL_WindowData *data) emscripten_set_mousemove_callback("#canvas", NULL, 0, NULL); emscripten_set_mousedown_callback("#canvas", NULL, 0, NULL); - emscripten_set_mouseup_callback("#canvas", NULL, 0, NULL); + emscripten_set_mouseup_callback("#document", NULL, 0, NULL); emscripten_set_mouseenter_callback("#canvas", NULL, 0, NULL); emscripten_set_mouseleave_callback("#canvas", NULL, 0, NULL); emscripten_set_wheel_callback("#canvas", NULL, 0, NULL); - emscripten_set_focus_callback("#canvas", NULL, 0, NULL); - emscripten_set_blur_callback("#canvas", NULL, 0, NULL); + emscripten_set_focus_callback("#window", NULL, 0, NULL); + emscripten_set_blur_callback("#window", NULL, 0, NULL); emscripten_set_touchstart_callback("#canvas", NULL, 0, NULL); emscripten_set_touchend_callback("#canvas", NULL, 0, NULL); diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h index d5b65f854..089ff60da 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenevents.h @@ -30,6 +30,9 @@ Emscripten_RegisterEventHandlers(SDL_WindowData *data); extern void Emscripten_UnregisterEventHandlers(SDL_WindowData *data); + +extern int +Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData); #endif /* _SDL_emscriptenevents_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c index a26e23ae6..8a6a465d9 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenframebuffer.c @@ -69,15 +69,25 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec /* Send the data to the display */ EM_ASM_INT({ - //TODO: don't create context every update - var ctx = Module['canvas'].getContext('2d'); + var w = $0; + var h = $1; + var pixels = $2; - //library_sdl.js SDL_UnlockSurface - var image = ctx.createImageData($0, $1); - var data = image.data; - var src = $2 >> 2; + if (!Module['SDL2']) Module['SDL2'] = {}; + var SDL2 = Module['SDL2']; + if (SDL2.ctxCanvas !== Module['canvas']) { + SDL2.ctx = Module['createContext'](Module['canvas'], false, true); + SDL2.ctxCanvas = Module['canvas']; + } + if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) { + SDL2.image = SDL2.ctx.createImageData(w, h); + SDL2.w = w; + SDL2.h = h; + SDL2.imageCtx = SDL2.ctx; + } + var data = SDL2.image.data; + var src = pixels >> 2; var dst = 0; - var isScreen = true; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { // IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray, @@ -90,26 +100,58 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec data[dst ] = val & 0xff; data[dst+1] = (val >> 8) & 0xff; data[dst+2] = (val >> 16) & 0xff; - data[dst+3] = isScreen ? 0xff : ((val >> 24) & 0xff); + data[dst+3] = 0xff; src++; dst += 4; } } else { - var data32 = new Uint32Array(data.buffer); + if (SDL2.data32Data !== data) { + SDL2.data32 = new Int32Array(data.buffer); + SDL2.data8 = new Uint8Array(data.buffer); + } + var data32 = SDL2.data32; num = data32.length; - if (isScreen) { - while (dst < num) { - // HEAP32[src++] is an optimization. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}}; - data32[dst++] = HEAP32[src++] | 0xff000000; + // logically we need to do + // while (dst < num) { + // data32[dst++] = HEAP32[src++] | 0xff000000 + // } + // the following code is faster though, because + // .set() is almost free - easily 10x faster due to + // native memcpy efficiencies, and the remaining loop + // just stores, not load + store, so it is faster + data32.set(HEAP32.subarray(src, src + num)); + var data8 = SDL2.data8; + var i = 3; + var j = i + 4*num; + if (num % 8 == 0) { + // unrolling gives big speedups + while (i < j) { + data8[i] = 0xff; + i = i + 4 | 0; + data8[i] = 0xff; + i = i + 4 | 0; + data8[i] = 0xff; + i = i + 4 | 0; + data8[i] = 0xff; + i = i + 4 | 0; + data8[i] = 0xff; + i = i + 4 | 0; + data8[i] = 0xff; + i = i + 4 | 0; + data8[i] = 0xff; + i = i + 4 | 0; + data8[i] = 0xff; + i = i + 4 | 0; } - } else { - while (dst < num) { - data32[dst++] = HEAP32[src++]; + } else { + while (i < j) { + data8[i] = 0xff; + i = i + 4 | 0; } } } - ctx.putImageData(image, 0, 0); + SDL2.ctx.putImageData(SDL2.image, 0, 0); return 0; }, surface->w, surface->h, surface->pixels); diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c index 2a68dd95c..512ad2220 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenmouse.c @@ -58,11 +58,13 @@ Emscripten_CreateDefaultCursor() return cursor; } +/* static SDL_Cursor* Emscripten_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y) { return Emscripten_CreateDefaultCursor(); } +*/ static SDL_Cursor* Emscripten_CreateSystemCursor(SDL_SystemCursor id) @@ -200,7 +202,9 @@ Emscripten_InitMouse() { SDL_Mouse* mouse = SDL_GetMouse(); +/* mouse->CreateCursor = Emscripten_CreateCursor; +*/ mouse->ShowCursor = Emscripten_ShowCursor; mouse->FreeCursor = Emscripten_FreeCursor; mouse->WarpMouse = Emscripten_WarpMouse; diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c index 302ca8793..847bb4cf8 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.c @@ -24,6 +24,7 @@ #include "SDL_video.h" #include "SDL_mouse.h" +#include "SDL_hints.h" #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../SDL_egl_c.h" @@ -47,6 +48,7 @@ static void Emscripten_SetWindowSize(_THIS, SDL_Window * window); static void Emscripten_DestroyWindow(_THIS, SDL_Window * window); static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); static void Emscripten_PumpEvents(_THIS); +static void Emscripten_SetWindowTitle(_THIS, SDL_Window * window); /* Emscripten driver bootstrap functions */ @@ -75,6 +77,12 @@ Emscripten_CreateDevice(int devindex) return (0); } + /* Firefox sends blur event which would otherwise prevent full screen + * when the user clicks to allow full screen. + * See https://bugzilla.mozilla.org/show_bug.cgi?id=1144964 + */ + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); + /* Set the function pointers */ device->VideoInit = Emscripten_VideoInit; device->VideoQuit = Emscripten_VideoQuit; @@ -84,9 +92,9 @@ Emscripten_CreateDevice(int devindex) device->PumpEvents = Emscripten_PumpEvents; device->CreateWindow = Emscripten_CreateWindow; - /*device->CreateWindowFrom = Emscripten_CreateWindowFrom; + /*device->CreateWindowFrom = Emscripten_CreateWindowFrom;*/ device->SetWindowTitle = Emscripten_SetWindowTitle; - device->SetWindowIcon = Emscripten_SetWindowIcon; + /*device->SetWindowIcon = Emscripten_SetWindowIcon; device->SetWindowPosition = Emscripten_SetWindowPosition;*/ device->SetWindowSize = Emscripten_SetWindowSize; /*device->ShowWindow = Emscripten_ShowWindow; @@ -129,15 +137,17 @@ int Emscripten_VideoInit(_THIS) { SDL_DisplayMode mode; - double css_w, css_h; /* Use a fake 32-bpp desktop mode */ mode.format = SDL_PIXELFORMAT_RGB888; - emscripten_get_element_css_size(NULL, &css_w, &css_h); + mode.w = EM_ASM_INT_V({ + return screen.width; + }); - mode.w = css_w; - mode.h = css_h; + mode.h = EM_ASM_INT_V({ + return screen.height; + }); mode.refresh_rate = 0; mode.driverdata = NULL; @@ -199,7 +209,7 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window) emscripten_get_element_css_size(NULL, &css_w, &css_h); - wdata->external_size = css_w != scaled_w || css_h != scaled_h; + wdata->external_size = SDL_floor(css_w) != scaled_w || SDL_floor(css_h) != scaled_h; if ((window->flags & SDL_WINDOW_RESIZABLE) && wdata->external_size) { /* external css has resized us */ @@ -218,9 +228,6 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window) } } - wdata->windowed_width = scaled_w; - wdata->windowed_height = scaled_h; - if (window->flags & SDL_WINDOW_OPENGL) { if (!_this->egl_data) { if (SDL_GL_LoadLibrary(NULL) < 0) { @@ -255,6 +262,8 @@ static void Emscripten_SetWindowSize(_THIS, SDL_Window * window) if (window->driverdata) { data = (SDL_WindowData *) window->driverdata; + /* update pixel ratio */ + data->pixel_ratio = emscripten_get_device_pixel_ratio(); emscripten_set_canvas_size(window->w * data->pixel_ratio, window->h * data->pixel_ratio); /*scale canvas down*/ @@ -290,30 +299,49 @@ Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * di data = (SDL_WindowData *) window->driverdata; if(fullscreen) { + EmscriptenFullscreenStrategy strategy; + SDL_bool is_desktop_fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; + int res; + + strategy.scaleMode = is_desktop_fullscreen ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT; + + if(!is_desktop_fullscreen) { + strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE; + } else if(window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF; + } else { + strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; + } + + strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; + + strategy.canvasResizedCallback = Emscripten_HandleCanvasResize; + strategy.canvasResizedCallbackUserData = data; + data->requested_fullscreen_mode = window->flags & (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN); - /*unset the fullscreen flags as we're not actually fullscreen yet*/ - window->flags &= ~(SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN); + data->fullscreen_resize = is_desktop_fullscreen; - EM_ASM({ - //reparent canvas (similar to Module.requestFullscreen) - var canvas = Module['canvas']; - if(canvas.parentNode.id != "SDLFullscreenElement") { - var canvasContainer = document.createElement("div"); - canvasContainer.id = "SDLFullscreenElement"; - canvas.parentNode.insertBefore(canvasContainer, canvas); - canvasContainer.appendChild(canvas); - } - }); - - int is_fullscreen; - emscripten_get_canvas_size(&data->windowed_width, &data->windowed_height, &is_fullscreen); - emscripten_request_fullscreen("SDLFullscreenElement", 1); + res = emscripten_request_fullscreen_strategy(NULL, 1, &strategy); + if(res != EMSCRIPTEN_RESULT_SUCCESS && res != EMSCRIPTEN_RESULT_DEFERRED) { + /* unset flags, fullscreen failed */ + window->flags &= ~(SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN); + } } else emscripten_exit_fullscreen(); } } +static void +Emscripten_SetWindowTitle(_THIS, SDL_Window * window) { + EM_ASM_INT({ + if (typeof Module['setWindowTitle'] !== 'undefined') { + Module['setWindowTitle'](Module['Pointer_stringify']($0)); + } + return 0; + }, window->title); +} + #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h index e824de34f..7618ab6cc 100644 --- a/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h +++ b/Engine/lib/sdl/src/video/emscripten/SDL_emscriptenvideo.h @@ -24,6 +24,7 @@ #define _SDL_emscriptenvideo_h #include "../SDL_sysvideo.h" +#include "../../events/SDL_touch_c.h" #include #include @@ -37,14 +38,15 @@ typedef struct SDL_WindowData SDL_Window *window; SDL_Surface *surface; - int windowed_width; - int windowed_height; - float pixel_ratio; SDL_bool external_size; int requested_fullscreen_mode; + SDL_bool fullscreen_resize; + + SDL_bool finger_touching; /* for mapping touch events to mice */ + SDL_FingerID first_finger; } SDL_WindowData; #endif /* _SDL_emscriptenvideo_h */ diff --git a/Engine/lib/sdl/src/video/haiku/SDL_BWin.h b/Engine/lib/sdl/src/video/haiku/SDL_BWin.h index dade664c3..a353e1aca 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_BWin.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_BWin.h @@ -56,6 +56,7 @@ enum WinCommands { BWIN_RESTORE_WINDOW, BWIN_SET_TITLE, BWIN_SET_BORDERED, + BWIN_SET_RESIZABLE, BWIN_FULLSCREEN }; @@ -336,16 +337,30 @@ class SDL_BWin:public BDirectWindow break; case B_KEY_DOWN: + { + int32 i = 0; + int8 byte; + int8 bytes[4] = { 0, 0, 0, 0 }; + while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) { + bytes[i] = byte; + i++; + } + if (msg->FindInt32("key", &key) == B_OK) { + _KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED); + } + } + break; + case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ if (msg->FindInt32("key", &key) == B_OK) { - _KeyEvent((SDL_Scancode)key, SDL_PRESSED); + _KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED); } break; case B_KEY_UP: case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */ if (msg->FindInt32("key", &key) == B_OK) { - _KeyEvent(key, SDL_RELEASED); + _KeyEvent(key, NULL, 0, SDL_RELEASED); } break; @@ -378,6 +393,9 @@ class SDL_BWin:public BDirectWindow case BWIN_SET_BORDERED: _SetBordered(message); break; + case BWIN_SET_RESIZABLE: + _SetResizable(message); + break; case BWIN_SHOW_WINDOW: Show(); break; @@ -508,13 +526,15 @@ private: _PostWindowEvent(msg); } - void _KeyEvent(int32 keyCode, int32 keyState) { + void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t & len, int32 keyState) { /* Create a message to pass along to the BeApp thread */ BMessage msg(BAPP_KEY); msg.AddInt32("key-state", keyState); msg.AddInt32("key-scancode", keyCode); + if (keyUtf8 != NULL) { + msg.AddData("key-utf8", B_INT8_TYPE, (const void*)keyUtf8, len); + } be_app->PostMessage(&msg); - /* Apparently SDL only uses the scancode */ } void _RepaintEvent() { @@ -568,6 +588,18 @@ private: SetLook(bEnabled ? B_BORDERED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); } + void _SetResizable(BMessage *msg) { + bool bEnabled; + if(msg->FindBool("window-resizable", &bEnabled) != B_OK) { + return; + } + if (bEnabled) { + SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } else { + SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } + } + void _Restore() { if(IsMinimized()) { Minimize(false); diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc b/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc index 8c243b7a0..8986c609c 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bvideo.cc @@ -81,6 +81,7 @@ BE_CreateDevice(int devindex) device->MinimizeWindow = BE_MinimizeWindow; device->RestoreWindow = BE_RestoreWindow; device->SetWindowBordered = BE_SetWindowBordered; + device->SetWindowResizable = BE_SetWindowResizable; device->SetWindowFullscreen = BE_SetWindowFullscreen; device->SetWindowGammaRamp = BE_SetWindowGammaRamp; device->GetWindowGammaRamp = BE_GetWindowGammaRamp; diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc index 287eac965..a35471df5 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc +++ b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.cc @@ -145,6 +145,12 @@ void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { _ToBeWin(window)->PostMessage(&msg); } +void BE_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) { + BMessage msg(BWIN_SET_RESIZABLE); + msg.AddBool("window-resizable", resizable != SDL_FALSE); + _ToBeWin(window)->PostMessage(&msg); +} + void BE_ShowWindow(_THIS, SDL_Window * window) { BMessage msg(BWIN_SHOW_WINDOW); _ToBeWin(window)->PostMessage(&msg); diff --git a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h index f64530ab7..388443dac 100644 --- a/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h +++ b/Engine/lib/sdl/src/video/haiku/SDL_bwindow.h @@ -39,6 +39,7 @@ extern void BE_MaximizeWindow(_THIS, SDL_Window * window); extern void BE_MinimizeWindow(_THIS, SDL_Window * window); extern void BE_RestoreWindow(_THIS, SDL_Window * window); extern void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void BE_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void BE_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirdyn.c b/Engine/lib/sdl/src/video/mir/SDL_mirdyn.c index f9dfc0395..6bbe53759 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirdyn.c +++ b/Engine/lib/sdl/src/video/mir/SDL_mirdyn.c @@ -84,9 +84,8 @@ MIR_GetSym(const char *fnname, int *pHasModule) /* Define all the function pointers and wrappers... */ #define SDL_MIR_MODULE(modname) int SDL_MIR_HAVE_##modname = 0; #define SDL_MIR_SYM(rc,fn,params) SDL_DYNMIRFN_##fn MIR_##fn = NULL; +#define SDL_MIR_SYM_CONST(type,name) SDL_DYMMIRCONST_##name MIR_##name = NULL; #include "SDL_mirsym.h" -#undef SDL_MIR_MODULE -#undef SDL_MIR_SYM static int mir_load_refcount = 0; @@ -103,9 +102,8 @@ SDL_MIR_UnloadSymbols(void) /* set all the function pointers to NULL. */ #define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 0; #define SDL_MIR_SYM(rc,fn,params) MIR_##fn = NULL; +#define SDL_MIR_SYM_CONST(type,name) MIR_##name = NULL; #include "SDL_mirsym.h" -#undef SDL_MIR_MODULE -#undef SDL_MIR_SYM #ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC @@ -138,16 +136,12 @@ SDL_MIR_LoadSymbols(void) } #define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */ -#define SDL_MIR_SYM(rc,fn,params) #include "SDL_mirsym.h" -#undef SDL_MIR_MODULE -#undef SDL_MIR_SYM #define SDL_MIR_MODULE(modname) thismod = &SDL_MIR_HAVE_##modname; #define SDL_MIR_SYM(rc,fn,params) MIR_##fn = (SDL_DYNMIRFN_##fn) MIR_GetSym(#fn,thismod); +#define SDL_MIR_SYM_CONST(type,name) MIR_##name = *(SDL_DYMMIRCONST_##name*) MIR_GetSym(#name,thismod); #include "SDL_mirsym.h" -#undef SDL_MIR_MODULE -#undef SDL_MIR_SYM if ((SDL_MIR_HAVE_MIR_CLIENT) && (SDL_MIR_HAVE_XKBCOMMON)) { /* all required symbols loaded. */ @@ -162,9 +156,8 @@ SDL_MIR_LoadSymbols(void) #define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */ #define SDL_MIR_SYM(rc,fn,params) MIR_##fn = fn; +#define SDL_MIR_SYM_CONST(type,name) MIR_##name = name; #include "SDL_mirsym.h" -#undef SDL_MIR_MODULE -#undef SDL_MIR_SYM #endif } diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirdyn.h b/Engine/lib/sdl/src/video/mir/SDL_mirdyn.h index 48bf489c6..a3638cf05 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirdyn.h +++ b/Engine/lib/sdl/src/video/mir/SDL_mirdyn.h @@ -36,13 +36,13 @@ int SDL_MIR_LoadSymbols(void); void SDL_MIR_UnloadSymbols(void); /* Declare all the function pointers and wrappers... */ -#define SDL_MIR_MODULE(modname) #define SDL_MIR_SYM(rc,fn,params) \ typedef rc (*SDL_DYNMIRFN_##fn) params; \ extern SDL_DYNMIRFN_##fn MIR_##fn; +#define SDL_MIR_SYM_CONST(type, name) \ + typedef type SDL_DYMMIRCONST_##name; \ + extern SDL_DYMMIRCONST_##name MIR_##name; #include "SDL_mirsym.h" -#undef SDL_MIR_MODULE -#undef SDL_MIR_SYM #ifdef __cplusplus } diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirevents.c b/Engine/lib/sdl/src/video/mir/SDL_mirevents.c index 708f8ffde..e36986835 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirevents.c +++ b/Engine/lib/sdl/src/video/mir/SDL_mirevents.c @@ -53,73 +53,79 @@ HandleKeyText(int32_t key_code) } } -static void -CheckKeyboardFocus(SDL_Window* sdl_window) -{ - SDL_Window* keyboard_window = SDL_GetKeyboardFocus(); - - if (keyboard_window != sdl_window) - SDL_SetKeyboardFocus(sdl_window); -} - - /* FIXME Mir still needs to implement its IM API, for now we assume a single key press produces a character. */ static void -HandleKeyEvent(MirKeyEvent const ev, SDL_Window* window) +HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window) { - uint32_t scancode = SDL_SCANCODE_UNKNOWN; - Uint8 key_state = ev.action == mir_key_action_up ? SDL_RELEASED : SDL_PRESSED; + xkb_keysym_t key_code; + Uint8 key_state; + int event_scancode; + uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN; - CheckKeyboardFocus(window); + MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event); - if (ev.scan_code < SDL_arraysize(xfree86_scancode_table2)) - scancode = xfree86_scancode_table2[ev.scan_code]; + key_state = SDL_PRESSED; + key_code = MIR_mir_keyboard_event_key_code(key_event); + event_scancode = MIR_mir_keyboard_event_scan_code(key_event); - if (scancode != SDL_SCANCODE_UNKNOWN) - SDL_SendKeyboardKey(key_state, scancode); + if (action == mir_keyboard_action_up) + key_state = SDL_RELEASED; + + if (event_scancode < SDL_arraysize(xfree86_scancode_table2)) + sdl_scancode = xfree86_scancode_table2[event_scancode]; + + if (sdl_scancode != SDL_SCANCODE_UNKNOWN) + SDL_SendKeyboardKey(key_state, sdl_scancode); if (key_state == SDL_PRESSED) - HandleKeyText(ev.key_code); + HandleKeyText(key_code); } static void -HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirMotionButton button_state) +HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer) { - static uint32_t last_sdl_button; - uint32_t sdl_button; + uint32_t sdl_button = SDL_BUTTON_LEFT; + MirPointerButton button_state = mir_pointer_button_primary; + + static uint32_t old_button_states = 0; + uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer); + + // XOR on our old button states vs our new states to get the newley pressed/released button + button_state = new_button_states ^ old_button_states; switch (button_state) { - case mir_motion_button_primary: + case mir_pointer_button_primary: sdl_button = SDL_BUTTON_LEFT; break; - case mir_motion_button_secondary: + case mir_pointer_button_secondary: sdl_button = SDL_BUTTON_RIGHT; break; - case mir_motion_button_tertiary: + case mir_pointer_button_tertiary: sdl_button = SDL_BUTTON_MIDDLE; break; - case mir_motion_button_forward: + case mir_pointer_button_forward: sdl_button = SDL_BUTTON_X1; break; - case mir_motion_button_back: + case mir_pointer_button_back: sdl_button = SDL_BUTTON_X2; break; default: - sdl_button = last_sdl_button; break; } - last_sdl_button = sdl_button; + old_button_states = new_button_states; + SDL_SendMouseButton(sdl_window, 0, state, sdl_button); } static void HandleMouseMotion(SDL_Window* sdl_window, int x, int y) { - SDL_SendMouseMotion(sdl_window, 0, 0, x, y); + SDL_Mouse* mouse = SDL_GetMouse(); + SDL_SendMouseMotion(sdl_window, 0, mouse->relative_mode, x, y); } static void @@ -148,71 +154,102 @@ AddTouchDevice(int device_id) } static void -HandleTouchEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window) +HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window) { - int device_id = motion.device_id; - int id = motion.pointer_coordinates[cord_index].id; + int i, point_count; + point_count = MIR_mir_touch_event_point_count(touch); - int width = sdl_window->w; - int height = sdl_window->h; - float x = motion.pointer_coordinates[cord_index].x; - float y = motion.pointer_coordinates[cord_index].y; + AddTouchDevice(device_id); - float n_x = x / width; - float n_y = y / height; - float pressure = motion.pointer_coordinates[cord_index].pressure; + for (i = 0; i < point_count; i++) { + int id = MIR_mir_touch_event_id(touch, i); - AddTouchDevice(motion.device_id); + int width = sdl_window->w; + int height = sdl_window->h; - switch (motion.action) { - case mir_motion_action_down: - case mir_motion_action_pointer_down: - HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure); - break; - case mir_motion_action_up: - case mir_motion_action_pointer_up: - HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure); - break; - case mir_motion_action_hover_move: - case mir_motion_action_move: - HandleTouchMotion(device_id, id, n_x, n_y, pressure); - break; - default: - break; + float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x); + float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y); + + float n_x = x / width; + float n_y = y / height; + + float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure); + + switch (MIR_mir_touch_event_action(touch, i)) { + case mir_touch_action_up: + HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure); + break; + case mir_touch_action_down: + HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure); + break; + case mir_touch_action_change: + HandleTouchMotion(device_id, id, n_x, n_y, pressure); + break; + case mir_touch_actions: + break; + } } } static void -HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window) +HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window) { SDL_SetMouseFocus(sdl_window); - switch (motion.action) { - case mir_motion_action_down: - case mir_motion_action_pointer_down: - HandleMouseButton(sdl_window, SDL_PRESSED, motion.button_state); + switch (MIR_mir_pointer_event_action(pointer)) { + case mir_pointer_action_button_down: + HandleMouseButton(sdl_window, SDL_PRESSED, pointer); break; - case mir_motion_action_up: - case mir_motion_action_pointer_up: - HandleMouseButton(sdl_window, SDL_RELEASED, motion.button_state); + case mir_pointer_action_button_up: + HandleMouseButton(sdl_window, SDL_RELEASED, pointer); break; - case mir_motion_action_hover_move: - case mir_motion_action_move: - HandleMouseMotion(sdl_window, - motion.pointer_coordinates[cord_index].x, - motion.pointer_coordinates[cord_index].y); + case mir_pointer_action_motion: { + int x, y; + int hscroll, vscroll; + SDL_Mouse* mouse = SDL_GetMouse(); + x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x); + y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y); + + if (mouse) { + if (mouse->relative_mode) { + int relative_x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_x); + int relative_y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_y); + HandleMouseMotion(sdl_window, relative_x, relative_y); + } + else if (mouse->x != x || mouse->y != y) { + HandleMouseMotion(sdl_window, x, y); + } + } + + hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll); + vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll); + if (vscroll != 0 || hscroll != 0) + HandleMouseScroll(sdl_window, hscroll, vscroll); + } break; - case mir_motion_action_outside: + case mir_pointer_action_leave: SDL_SetMouseFocus(NULL); break; - case mir_motion_action_scroll: - HandleMouseScroll(sdl_window, - motion.pointer_coordinates[cord_index].hscroll, - motion.pointer_coordinates[cord_index].vscroll); + case mir_pointer_action_enter: + default: break; - case mir_motion_action_cancel: - case mir_motion_action_hover_enter: - case mir_motion_action_hover_exit: + } +} + +static void +MIR_HandleInput(MirInputEvent const* input_event, SDL_Window* window) +{ + switch (MIR_mir_input_event_get_type(input_event)) { + case (mir_input_event_type_key): + HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window); + break; + case (mir_input_event_type_pointer): + HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window); + break; + case (mir_input_event_type_touch): + HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event), + MIR_mir_input_event_get_device_id(input_event), + window); break; default: break; @@ -220,32 +257,54 @@ HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_wi } static void -HandleMotionEvent(MirMotionEvent const motion, SDL_Window* sdl_window) +MIR_HandleResize(MirResizeEvent const* resize_event, SDL_Window* window) { - int cord_index; - for (cord_index = 0; cord_index < motion.pointer_count; cord_index++) { - if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_finger) { - HandleTouchEvent(motion, cord_index, sdl_window); + int new_w = MIR_mir_resize_event_get_width (resize_event); + int new_h = MIR_mir_resize_event_get_height(resize_event); + + int old_w = window->w; + int old_h = window->h; + + if (new_w != old_w || new_h != old_h) + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h); +} + +static void +MIR_HandleSurface(MirSurfaceEvent const* surface_event, SDL_Window* window) +{ + MirSurfaceAttrib attrib = MIR_mir_surface_event_get_attribute(surface_event); + int value = MIR_mir_surface_event_get_attribute_value(surface_event); + + if (attrib == mir_surface_attrib_focus) { + if (value == mir_surface_focused) { + SDL_SetKeyboardFocus(window); } - else { - HandleMouseEvent(motion, cord_index, sdl_window); + else if (value == mir_surface_unfocused) { + SDL_SetKeyboardFocus(NULL); } } } void -MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context) +MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context) { - SDL_Window* window = (SDL_Window*)context; - switch (ev->type) { - case (mir_event_type_key): - HandleKeyEvent(ev->key, window); - break; - case (mir_event_type_motion): - HandleMotionEvent(ev->motion, window); - break; - default: - break; + MirEventType event_type = MIR_mir_event_get_type(ev); + SDL_Window* window = (SDL_Window*)context; + + if (window) { + switch (event_type) { + case (mir_event_type_input): + MIR_HandleInput(MIR_mir_event_get_input_event(ev), window); + break; + case (mir_event_type_resize): + MIR_HandleResize(MIR_mir_event_get_resize_event(ev), window); + break; + case (mir_event_type_surface): + MIR_HandleSurface(MIR_mir_event_get_surface_event(ev), window); + break; + default: + break; + } } } diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirevents.h b/Engine/lib/sdl/src/video/mir/SDL_mirevents.h index 3e0d96625..121c4b365 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirevents.h +++ b/Engine/lib/sdl/src/video/mir/SDL_mirevents.h @@ -29,7 +29,7 @@ #include extern void -MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context); +MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context); #endif /* _SDL_mirevents_h */ diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirframebuffer.c b/Engine/lib/sdl/src/video/mir/SDL_mirframebuffer.c index 53e6056ff..775bc0797 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirframebuffer.c +++ b/Engine/lib/sdl/src/video/mir/SDL_mirframebuffer.c @@ -33,39 +33,18 @@ #include "SDL_mirdyn.h" -static const Uint32 mir_pixel_format_to_sdl_format[] = { - SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */ - SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */ - SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */ - SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */ - SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */ - SDL_PIXELFORMAT_BGR24 /* mir_pixel_format_bgr_888 */ -}; - -Uint32 -MIR_GetSDLPixelFormat(MirPixelFormat format) -{ - return mir_pixel_format_to_sdl_format[format]; -} - int MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, void** pixels, int* pitch) { MIR_Data* mir_data = _this->driverdata; - MIR_Window* mir_window; - MirSurfaceParameters surfaceparm; mir_data->software = SDL_TRUE; if (MIR_CreateWindow(_this, window) < 0) return SDL_SetError("Failed to created a mir window."); - mir_window = window->driverdata; - - MIR_mir_surface_get_parameters(mir_window->surface, &surfaceparm); - - *format = MIR_GetSDLPixelFormat(surfaceparm.pixel_format); + *format = MIR_GetSDLPixelFormat(mir_data->pixel_format); if (*format == SDL_PIXELFORMAT_UNKNOWN) return SDL_SetError("Unknown pixel format"); @@ -75,12 +54,6 @@ MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format, if (*pixels == NULL) return SDL_OutOfMemory(); - mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm); - if (!MIR_mir_surface_is_valid(mir_window->surface)) { - const char* error = MIR_mir_surface_get_error_message(mir_window->surface); - return SDL_SetError("Failed to created a mir surface: %s", error); - } - return 0; } @@ -91,12 +64,14 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window, MIR_Window* mir_window = window->driverdata; MirGraphicsRegion region; + MirBufferStream* bs; int i, j, x, y, w, h, start; int bytes_per_pixel, bytes_per_row, s_stride, d_stride; char* s_dest; char* pixels; - MIR_mir_surface_get_graphics_region(mir_window->surface, ®ion); + bs = MIR_mir_surface_get_buffer_stream(mir_window->surface); + MIR_mir_buffer_stream_get_graphics_region(bs, ®ion); s_dest = region.vaddr; pixels = (char*)window->surface->pixels; @@ -138,13 +113,13 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window, bytes_per_row = bytes_per_pixel * w; for (j = 0; j < h; j++) { - memcpy(s_dest, pixels, bytes_per_row); + SDL_memcpy(s_dest, pixels, bytes_per_row); pixels += s_stride; s_dest += d_stride; } } - MIR_mir_surface_swap_buffers_sync(mir_window->surface); + MIR_mir_buffer_stream_swap_buffers_sync(bs); return 0; } diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirmouse.c b/Engine/lib/sdl/src/video/mir/SDL_mirmouse.c index bb8dc6c4e..1a22b28e8 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirmouse.c +++ b/Engine/lib/sdl/src/video/mir/SDL_mirmouse.c @@ -27,13 +27,22 @@ #if SDL_VIDEO_DRIVER_MIR -#include "SDL_mirmouse.h" - #include "../../events/SDL_mouse_c.h" +#include "../SDL_sysvideo.h" #include "SDL_assert.h" #include "SDL_mirdyn.h" +#include "SDL_mirvideo.h" +#include "SDL_mirmouse.h" +#include "SDL_mirwindow.h" + +typedef struct +{ + MirCursorConfiguration* conf; + MirBufferStream* stream; +} MIR_Cursor; + static SDL_Cursor* MIR_CreateDefaultCursor() { @@ -41,6 +50,18 @@ MIR_CreateDefaultCursor() cursor = SDL_calloc(1, sizeof(SDL_Cursor)); if (cursor) { + + MIR_Cursor* mir_cursor = SDL_calloc(1, sizeof(MIR_Cursor)); + if (mir_cursor) { + mir_cursor->conf = NULL; + mir_cursor->stream = NULL; + cursor->driverdata = mir_cursor; + } + else { + SDL_OutOfMemory(); + SDL_free(cursor); + cursor = NULL; + } } else { SDL_OutOfMemory(); @@ -49,58 +70,168 @@ MIR_CreateDefaultCursor() return cursor; } -static SDL_Cursor* -MIR_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y) +static void +CopySurfacePixelsToMirStream(SDL_Surface* surface, MirBufferStream* stream) { - return MIR_CreateDefaultCursor(); + char* dest, *pixels; + int i, s_w, s_h, r_stride, p_stride, bytes_per_pixel, bytes_per_row; + + MirGraphicsRegion region; + MIR_mir_buffer_stream_get_graphics_region(stream, ®ion); + + s_w = surface->w; + s_h = surface->h; + + bytes_per_pixel = surface->format->BytesPerPixel; + bytes_per_row = bytes_per_pixel * s_w; + + dest = region.vaddr; + pixels = (char*)surface->pixels; + + r_stride = region.stride; + p_stride = surface->pitch; + + for (i = 0; i < s_h; i++) + { + SDL_memcpy(dest, pixels, bytes_per_row); + dest += r_stride; + pixels += p_stride; + } +} + +static SDL_Cursor* +MIR_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y) +{ + MirCursorConfiguration* conf; + MirBufferStream* stream; + + int s_w = surface->w; + int s_h = surface->h; + + MIR_Data* mir_data = (MIR_Data*)SDL_GetVideoDevice()->driverdata; + SDL_Cursor* cursor = MIR_CreateDefaultCursor(); + MIR_Cursor* mir_cursor; + + if (!cursor) { + return NULL; + } + + mir_cursor = (MIR_Cursor*)cursor->driverdata; + + stream = MIR_mir_connection_create_buffer_stream_sync(mir_data->connection, + s_w, s_h, mir_data->pixel_format, + mir_buffer_usage_software); + + conf = MIR_mir_cursor_configuration_from_buffer_stream(stream, hot_x, hot_y); + + CopySurfacePixelsToMirStream(surface, stream); + MIR_mir_buffer_stream_swap_buffers_sync(stream); + + mir_cursor->conf = conf; + mir_cursor->stream = stream; + + return cursor; } static SDL_Cursor* MIR_CreateSystemCursor(SDL_SystemCursor id) { + char const* cursor_name = NULL; + SDL_Cursor* cursor = MIR_CreateDefaultCursor(); + MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata; + + if (!cursor) { + return NULL; + } + switch(id) { case SDL_SYSTEM_CURSOR_ARROW: + cursor_name = MIR_mir_arrow_cursor_name; break; case SDL_SYSTEM_CURSOR_IBEAM: + cursor_name = MIR_mir_caret_cursor_name; break; case SDL_SYSTEM_CURSOR_WAIT: + cursor_name = MIR_mir_busy_cursor_name; break; case SDL_SYSTEM_CURSOR_CROSSHAIR: + /* Unsupported */ + cursor_name = MIR_mir_arrow_cursor_name; break; case SDL_SYSTEM_CURSOR_WAITARROW: + cursor_name = MIR_mir_busy_cursor_name; break; case SDL_SYSTEM_CURSOR_SIZENWSE: + cursor_name = MIR_mir_omnidirectional_resize_cursor_name; break; case SDL_SYSTEM_CURSOR_SIZENESW: + cursor_name = MIR_mir_omnidirectional_resize_cursor_name; break; case SDL_SYSTEM_CURSOR_SIZEWE: + cursor_name = MIR_mir_horizontal_resize_cursor_name; break; case SDL_SYSTEM_CURSOR_SIZENS: + cursor_name = MIR_mir_vertical_resize_cursor_name; break; case SDL_SYSTEM_CURSOR_SIZEALL: + cursor_name = MIR_mir_omnidirectional_resize_cursor_name; break; case SDL_SYSTEM_CURSOR_NO: + /* Unsupported */ + cursor_name = MIR_mir_closed_hand_cursor_name; break; case SDL_SYSTEM_CURSOR_HAND: + cursor_name = MIR_mir_open_hand_cursor_name; break; default: SDL_assert(0); return NULL; } - return MIR_CreateDefaultCursor(); + mir_cursor->conf = MIR_mir_cursor_configuration_from_name(cursor_name); + + return cursor; } static void MIR_FreeCursor(SDL_Cursor* cursor) { - if (cursor) - SDL_free(cursor); + if (cursor) { + + if (cursor->driverdata) { + MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata; + + if (mir_cursor->conf) + MIR_mir_cursor_configuration_destroy(mir_cursor->conf); + if (mir_cursor->stream) + MIR_mir_buffer_stream_release_sync(mir_cursor->stream); + + SDL_free(mir_cursor); + } + + SDL_free(cursor); + } } static int MIR_ShowCursor(SDL_Cursor* cursor) { + MIR_Data* mir_data = (MIR_Data*)SDL_GetVideoDevice()->driverdata; + MIR_Window* mir_window = mir_data->current_window; + + if (cursor && cursor->driverdata) { + if (mir_window && MIR_mir_surface_is_valid(mir_window->surface)) { + MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata; + + if (mir_cursor->conf) { + MIR_mir_surface_configure_cursor(mir_window->surface, mir_cursor->conf); + } + } + } + else if(mir_window && MIR_mir_surface_is_valid(mir_window->surface)) { + MIR_mir_surface_configure_cursor(mir_window->surface, NULL); + } + return 0; } @@ -119,7 +250,7 @@ MIR_WarpMouseGlobal(int x, int y) static int MIR_SetRelativeMouseMode(SDL_bool enabled) { - return SDL_Unsupported(); + return 0; } /* TODO Actually implement the cursor, need to wait for mir support */ diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirsym.h b/Engine/lib/sdl/src/video/mir/SDL_mirsym.h index d0aaf70a3..4f97ed96c 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirsym.h +++ b/Engine/lib/sdl/src/video/mir/SDL_mirsym.h @@ -21,29 +21,122 @@ /* *INDENT-OFF* */ +#ifndef SDL_MIR_MODULE +#define SDL_MIR_MODULE(modname) +#endif + +#ifndef SDL_MIR_SYM +#define SDL_MIR_SYM(rc,fn,params) +#endif + +#ifndef SDL_MIR_SYM_CONST +#define SDL_MIR_SYM_CONST(type, name) +#endif + SDL_MIR_MODULE(MIR_CLIENT) -SDL_MIR_SYM(MirDisplayConfiguration*,mir_connection_create_display_config,(MirConnection *connection)) -SDL_MIR_SYM(MirSurface *,mir_connection_create_surface_sync,(MirConnection *connection, MirSurfaceParameters const *params)) +SDL_MIR_SYM(MirSurface *,mir_surface_create_sync,(MirSurfaceSpec* spec)) +SDL_MIR_SYM(MirEGLNativeWindowType,mir_buffer_stream_get_egl_native_window,(MirBufferStream *surface)) +SDL_MIR_SYM(void,mir_buffer_stream_get_graphics_region,(MirBufferStream *stream, MirGraphicsRegion *graphics_region)) +SDL_MIR_SYM(void,mir_buffer_stream_swap_buffers_sync,(MirBufferStream *stream)) +SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, mir_surface_event_callback callback, void* context)) +SDL_MIR_SYM(MirSurfaceSpec*,mir_connection_create_spec_for_normal_surface,(MirConnection *connection, int width, int height, MirPixelFormat format)) +SDL_MIR_SYM(MirSurfaceSpec*,mir_connection_create_spec_for_changes,(MirConnection *connection)) +SDL_MIR_SYM(void,mir_surface_spec_set_buffer_usage,(MirSurfaceSpec *spec, MirBufferUsage usage)) +SDL_MIR_SYM(void,mir_surface_spec_set_name,(MirSurfaceSpec *spec, char const *name)) +SDL_MIR_SYM(void,mir_surface_spec_release,(MirSurfaceSpec *spec)) +SDL_MIR_SYM(void,mir_surface_spec_set_width,(MirSurfaceSpec *spec, unsigned width)) +SDL_MIR_SYM(void,mir_surface_spec_set_height,(MirSurfaceSpec *spec, unsigned height)) +SDL_MIR_SYM(void,mir_surface_spec_set_min_width,(MirSurfaceSpec *spec, unsigned min_width)) +SDL_MIR_SYM(void,mir_surface_spec_set_min_height,(MirSurfaceSpec *spec, unsigned min_height)) +SDL_MIR_SYM(void,mir_surface_spec_set_max_width,(MirSurfaceSpec *spec, unsigned max_width)) +SDL_MIR_SYM(void,mir_surface_spec_set_max_height,(MirSurfaceSpec *spec, unsigned max_height)) +SDL_MIR_SYM(void,mir_surface_spec_set_type,(MirSurfaceSpec *spec, MirSurfaceType type)) +SDL_MIR_SYM(void,mir_surface_spec_set_state,(MirSurfaceSpec *spec, MirSurfaceState state)) +SDL_MIR_SYM(void,mir_surface_spec_set_pointer_confinement,(MirSurfaceSpec *spec, MirPointerConfinementState state)) +SDL_MIR_SYM(void,mir_surface_apply_spec,(MirSurface *surface, MirSurfaceSpec *spec)) +SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *params)) +SDL_MIR_SYM(MirBufferStream*,mir_surface_get_buffer_stream,(MirSurface *surface)) +SDL_MIR_SYM(MirCursorConfiguration*,mir_cursor_configuration_from_buffer_stream,(MirBufferStream const* stream, int hot_x, int hot_y)) +SDL_MIR_SYM(MirBufferStream*,mir_connection_create_buffer_stream_sync,(MirConnection *connection, int w, int h, MirPixelFormat format, MirBufferUsage usage)) +SDL_MIR_SYM(MirKeyboardAction,mir_keyboard_event_action,(MirKeyboardEvent const *event)) +SDL_MIR_SYM(xkb_keysym_t,mir_keyboard_event_key_code,(MirKeyboardEvent const *event)) +SDL_MIR_SYM(int,mir_keyboard_event_scan_code,(MirKeyboardEvent const *event)) +SDL_MIR_SYM(bool,mir_pointer_event_button_state,(MirPointerEvent const *event, MirPointerButton button)) +SDL_MIR_SYM(MirPointerButtons,mir_pointer_event_buttons,(MirPointerEvent const *event)) +SDL_MIR_SYM(MirInputDeviceId,mir_input_event_get_device_id,(MirInputEvent const* ev)) +SDL_MIR_SYM(MirTouchId,mir_touch_event_id,(MirTouchEvent const *event, size_t touch_index)) +SDL_MIR_SYM(float,mir_touch_event_axis_value,(MirTouchEvent const *event, size_t touch_index, MirTouchAxis axis)) +SDL_MIR_SYM(MirTouchAction,mir_touch_event_action,(MirTouchEvent const *event, size_t touch_index)) +SDL_MIR_SYM(MirPointerAction,mir_pointer_event_action,(MirPointerEvent const *event)) +SDL_MIR_SYM(float,mir_pointer_event_axis_value,(MirPointerEvent const *event, MirPointerAxis)) +SDL_MIR_SYM(MirEventType,mir_event_get_type,(MirEvent const *event)) +SDL_MIR_SYM(MirInputEventType,mir_input_event_get_type,(MirInputEvent const *event)) +SDL_MIR_SYM(MirInputEvent const*,mir_event_get_input_event,(MirEvent const *event)) +SDL_MIR_SYM(MirResizeEvent const*,mir_event_get_resize_event,(MirEvent const *event)) +SDL_MIR_SYM(MirKeyboardEvent const*,mir_input_event_get_keyboard_event,(MirInputEvent const *event)) +SDL_MIR_SYM(MirPointerEvent const*,mir_input_event_get_pointer_event,(MirInputEvent const *event)) +SDL_MIR_SYM(MirTouchEvent const*,mir_input_event_get_touch_event,(MirInputEvent const *event)) +SDL_MIR_SYM(MirSurfaceEvent const*,mir_event_get_surface_event,(MirEvent const *event)) +SDL_MIR_SYM(unsigned int,mir_touch_event_point_count,(MirTouchEvent const *event)) SDL_MIR_SYM(void,mir_connection_get_available_surface_formats,(MirConnection* connection, MirPixelFormat* formats, unsigned const int format_size, unsigned int *num_valid_formats)) SDL_MIR_SYM(MirEGLNativeDisplayType,mir_connection_get_egl_native_display,(MirConnection *connection)) -SDL_MIR_SYM(MirBool,mir_connection_is_valid,(MirConnection *connection)) +SDL_MIR_SYM(bool,mir_connection_is_valid,(MirConnection *connection)) SDL_MIR_SYM(void,mir_connection_release,(MirConnection *connection)) +SDL_MIR_SYM(MirPixelFormat,mir_connection_get_egl_pixel_format,(MirConnection* connection, void* egldisplay, void* eglconfig)) SDL_MIR_SYM(MirConnection *,mir_connect_sync,(char const *server, char const *app_name)) -SDL_MIR_SYM(void,mir_display_config_destroy,(MirDisplayConfiguration* display_configuration)) -SDL_MIR_SYM(MirEGLNativeWindowType,mir_surface_get_egl_native_window,(MirSurface *surface)) SDL_MIR_SYM(char const *,mir_surface_get_error_message,(MirSurface *surface)) -SDL_MIR_SYM(void,mir_surface_get_graphics_region,(MirSurface *surface, MirGraphicsRegion *graphics_region)) -SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *parameters)) -SDL_MIR_SYM(MirBool,mir_surface_is_valid,(MirSurface *surface)) +SDL_MIR_SYM(bool,mir_surface_is_valid,(MirSurface *surface)) SDL_MIR_SYM(void,mir_surface_release_sync,(MirSurface *surface)) -SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, MirEventDelegate const *event_handler)) -SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_type,(MirSurface *surface, MirSurfaceType type)) -SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_state,(MirSurface *surface, MirSurfaceState state)) -SDL_MIR_SYM(void,mir_surface_swap_buffers_sync,(MirSurface *surface)) +SDL_MIR_SYM(void,mir_buffer_stream_release_sync,(MirBufferStream *stream)) +SDL_MIR_SYM(MirCursorConfiguration*,mir_cursor_configuration_from_name,(char const* cursor_name)) +SDL_MIR_SYM(MirWaitHandle*,mir_surface_configure_cursor,(MirSurface* surface, MirCursorConfiguration const* conf)) +SDL_MIR_SYM(void,mir_cursor_configuration_destroy,(MirCursorConfiguration* conf)) +SDL_MIR_SYM(int,mir_resize_event_get_width,(MirResizeEvent const* resize_event)) +SDL_MIR_SYM(int,mir_resize_event_get_height,(MirResizeEvent const* resize_event)) +SDL_MIR_SYM(char const*,mir_connection_get_error_message,(MirConnection* connection)) +SDL_MIR_SYM(MirSurfaceAttrib,mir_surface_event_get_attribute,(MirSurfaceEvent const* surface_event)) +SDL_MIR_SYM(int,mir_surface_event_get_attribute_value,(MirSurfaceEvent const* surface_event)) +SDL_MIR_SYM(void,mir_wait_for,(MirWaitHandle* handle)) +SDL_MIR_SYM(MirDisplayConfig*,mir_connection_create_display_configuration,(MirConnection* connection)) +SDL_MIR_SYM(void,mir_display_config_release,(MirDisplayConfig* config)) +SDL_MIR_SYM(int,mir_display_config_get_num_outputs,(MirDisplayConfig const* config)) +SDL_MIR_SYM(MirOutput*,mir_display_config_get_mutable_output,(MirDisplayConfig* config, size_t index)) +SDL_MIR_SYM(int,mir_output_get_num_modes,(MirOutput const* output)) +SDL_MIR_SYM(MirPixelFormat,mir_output_get_current_pixel_format,(MirOutput const* output)) +SDL_MIR_SYM(int,mir_output_get_position_x,(MirOutput const* output)) +SDL_MIR_SYM(int,mir_output_get_position_y,(MirOutput const* output)) +SDL_MIR_SYM(bool,mir_output_is_enabled,(MirOutput const* output)) +SDL_MIR_SYM(MirOutputConnectionState,mir_output_get_connection_state,(MirOutput const* output)) +SDL_MIR_SYM(size_t,mir_output_get_preferred_mode_index,(MirOutput const* output)) +SDL_MIR_SYM(MirOutputType,mir_output_get_type,(MirOutput const* output)) +SDL_MIR_SYM(char const*,mir_output_type_name,(MirOutputType type)) +SDL_MIR_SYM(void,mir_output_set_current_mode,(MirOutput* output, MirOutputMode const* mode)) +SDL_MIR_SYM(MirOutputMode const*,mir_output_get_mode,(MirOutput const* output, size_t index)) +SDL_MIR_SYM(int,mir_output_mode_get_width,(MirOutputMode const* mode)) +SDL_MIR_SYM(int,mir_output_mode_get_height,(MirOutputMode const* mode)) +SDL_MIR_SYM(double,mir_output_mode_get_refresh_rate,(MirOutputMode const* mode)) +SDL_MIR_SYM(MirOutputGammaSupported,mir_output_is_gamma_supported,(MirOutput const* output)) +SDL_MIR_SYM(uint32_t,mir_output_get_gamma_size,(MirOutput const* output)) +SDL_MIR_SYM(void,mir_output_get_gamma,(MirOutput const* output, uint16_t* red, uint16_t* green, uint16_t* blue, uint32_t size)) +SDL_MIR_SYM(void,mir_output_set_gamma,(MirOutput* output, uint16_t const* red, uint16_t const* green, uint16_t const* blue, uint32_t size)) + +SDL_MIR_SYM_CONST(char const*,mir_omnidirectional_resize_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_busy_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_arrow_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_caret_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_vertical_resize_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_horizontal_resize_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_open_hand_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_closed_hand_cursor_name) +SDL_MIR_SYM_CONST(char const*,mir_disabled_cursor_name) SDL_MIR_MODULE(XKBCOMMON) SDL_MIR_SYM(int,xkb_keysym_to_utf8,(xkb_keysym_t keysym, char *buffer, size_t size)) +#undef SDL_MIR_MODULE +#undef SDL_MIR_SYM +#undef SDL_MIR_SYM_CONST + /* *INDENT-ON* */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirvideo.c b/Engine/lib/sdl/src/video/mir/SDL_mirvideo.c index b6160fd92..6a8f9e482 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirvideo.c +++ b/Engine/lib/sdl/src/video/mir/SDL_mirvideo.c @@ -27,18 +27,37 @@ #if SDL_VIDEO_DRIVER_MIR +#include "SDL_mirwindow.h" #include "SDL_video.h" #include "SDL_mirframebuffer.h" #include "SDL_mirmouse.h" #include "SDL_miropengl.h" #include "SDL_mirvideo.h" -#include "SDL_mirwindow.h" #include "SDL_mirdyn.h" #define MIR_DRIVER_NAME "mir" +static const Uint32 mir_pixel_format_to_sdl_format[] = { + SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */ + SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */ + SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */ + SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */ + SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */ + SDL_PIXELFORMAT_BGR24, /* mir_pixel_format_bgr_888 */ + SDL_PIXELFORMAT_RGB24, /* mir_pixel_format_rgb_888 */ + SDL_PIXELFORMAT_RGB565, /* mir_pixel_format_rgb_565 */ + SDL_PIXELFORMAT_RGBA5551, /* mir_pixel_format_rgba_5551 */ + SDL_PIXELFORMAT_RGBA4444 /* mir_pixel_format_rgba_4444 */ +}; + +Uint32 +MIR_GetSDLPixelFormat(MirPixelFormat format) +{ + return mir_pixel_format_to_sdl_format[format]; +} + static int MIR_VideoInit(_THIS); @@ -94,7 +113,7 @@ MIR_DeleteDevice(SDL_VideoDevice* device) SDL_MIR_UnloadSymbols(); } -void +static void MIR_PumpEvents(_THIS) { } @@ -146,29 +165,30 @@ MIR_CreateDevice(int device_index) device->GL_GetProcAddress = MIR_GL_GetProcAddress; /* mirwindow */ - device->CreateWindow = MIR_CreateWindow; - device->DestroyWindow = MIR_DestroyWindow; - device->GetWindowWMInfo = MIR_GetWindowWMInfo; - device->SetWindowFullscreen = MIR_SetWindowFullscreen; - device->MaximizeWindow = MIR_MaximizeWindow; - device->MinimizeWindow = MIR_MinimizeWindow; - device->RestoreWindow = MIR_RestoreWindow; + device->CreateWindow = MIR_CreateWindow; + device->DestroyWindow = MIR_DestroyWindow; + device->GetWindowWMInfo = MIR_GetWindowWMInfo; + device->SetWindowFullscreen = MIR_SetWindowFullscreen; + device->MaximizeWindow = MIR_MaximizeWindow; + device->MinimizeWindow = MIR_MinimizeWindow; + device->RestoreWindow = MIR_RestoreWindow; + device->ShowWindow = MIR_RestoreWindow; + device->HideWindow = MIR_HideWindow; + device->SetWindowSize = MIR_SetWindowSize; + device->SetWindowMinimumSize = MIR_SetWindowMinimumSize; + device->SetWindowMaximumSize = MIR_SetWindowMaximumSize; + device->SetWindowTitle = MIR_SetWindowTitle; + device->SetWindowGrab = MIR_SetWindowGrab; + device->SetWindowGammaRamp = MIR_SetWindowGammaRamp; + device->GetWindowGammaRamp = MIR_GetWindowGammaRamp; device->CreateWindowFrom = NULL; - device->SetWindowTitle = NULL; device->SetWindowIcon = NULL; - device->SetWindowPosition = NULL; - device->SetWindowSize = NULL; - device->SetWindowMinimumSize = NULL; - device->SetWindowMaximumSize = NULL; - device->ShowWindow = NULL; - device->HideWindow = NULL; device->RaiseWindow = NULL; device->SetWindowBordered = NULL; - device->SetWindowGammaRamp = NULL; - device->GetWindowGammaRamp = NULL; - device->SetWindowGrab = NULL; + device->SetWindowResizable = NULL; device->OnWindowEnter = NULL; + device->SetWindowPosition = NULL; /* mirframebuffer */ device->CreateWindowFramebuffer = MIR_CreateWindowFramebuffer; @@ -206,77 +226,88 @@ VideoBootStrap MIR_bootstrap = { MIR_Available, MIR_CreateDevice }; -static void -MIR_SetCurrentDisplayMode(MirDisplayOutput const* out, SDL_VideoDisplay* display) +static SDL_DisplayMode +MIR_ConvertModeToSDLMode(MirOutputMode const* mode, MirPixelFormat format) { - SDL_DisplayMode mode = { - .format = SDL_PIXELFORMAT_RGB888, - .w = out->modes[out->current_mode].horizontal_resolution, - .h = out->modes[out->current_mode].vertical_resolution, - .refresh_rate = out->modes[out->current_mode].refresh_rate, - .driverdata = NULL + SDL_DisplayMode sdl_mode = { + .format = MIR_GetSDLPixelFormat(format), + .w = MIR_mir_output_mode_get_width(mode), + .h = MIR_mir_output_mode_get_height(mode), + .refresh_rate = MIR_mir_output_mode_get_refresh_rate(mode), + .driverdata = NULL }; - display->desktop_mode = mode; - display->current_mode = mode; + return sdl_mode; } static void -MIR_AddAllModesFromDisplay(MirDisplayOutput const* out, SDL_VideoDisplay* display) +MIR_AddModeToDisplay(SDL_VideoDisplay* display, MirOutputMode const* mode, MirPixelFormat format) { - int n_mode; - for (n_mode = 0; n_mode < out->num_modes; ++n_mode) { - SDL_DisplayMode mode = { - .format = SDL_PIXELFORMAT_RGB888, - .w = out->modes[n_mode].horizontal_resolution, - .h = out->modes[n_mode].vertical_resolution, - .refresh_rate = out->modes[n_mode].refresh_rate, - .driverdata = NULL - }; + SDL_DisplayMode sdl_mode = MIR_ConvertModeToSDLMode(mode, format); + SDL_AddDisplayMode(display, &sdl_mode); +} - SDL_AddDisplayMode(display, &mode); +static void +MIR_InitDisplayFromOutput(_THIS, MirOutput* output) +{ + SDL_VideoDisplay display; + int m; + + MirPixelFormat format = MIR_mir_output_get_current_pixel_format(output); + int num_modes = MIR_mir_output_get_num_modes(output); + SDL_DisplayMode current_mode = MIR_ConvertModeToSDLMode(mir_output_get_current_mode(output), format); + + SDL_zero(display); + + // Unfortunate cast, but SDL_AddVideoDisplay will strdup this pointer so its read-only in this case. + display.name = (char*)MIR_mir_output_type_name(MIR_mir_output_get_type(output)); + + for (m = 0; m < num_modes; m++) { + MirOutputMode const* mode = MIR_mir_output_get_mode(output, m); + MIR_AddModeToDisplay(&display, mode, format); } + + display.desktop_mode = current_mode; + display.current_mode = current_mode; + + display.driverdata = output; + SDL_AddVideoDisplay(&display); } static void MIR_InitDisplays(_THIS) { MIR_Data* mir_data = _this->driverdata; + int num_outputs = MIR_mir_display_config_get_num_outputs(mir_data->display_config); int d; - MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection); + for (d = 0; d < num_outputs; d++) { + MirOutput* output = MIR_mir_display_config_get_mutable_output(mir_data->display_config, d); + SDL_bool enabled = MIR_mir_output_is_enabled(output); + MirOutputConnectionState state = MIR_mir_output_get_connection_state(output); - for (d = 0; d < display_config->num_outputs; d++) { - MirDisplayOutput const* out = display_config->outputs + d; - - SDL_VideoDisplay display; - SDL_zero(display); - - if (out->used && - out->connected && - out->num_modes && - out->current_mode < out->num_modes) { - - MIR_SetCurrentDisplayMode(out, &display); - MIR_AddAllModesFromDisplay(out, &display); - - SDL_AddVideoDisplay(&display); + if (enabled && state == mir_output_connection_state_connected) { + MIR_InitDisplayFromOutput(_this, output); } } - - MIR_mir_display_config_destroy(display_config); } -int +static int MIR_VideoInit(_THIS) { MIR_Data* mir_data = _this->driverdata; - mir_data->connection = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__); - mir_data->software = SDL_FALSE; + mir_data->connection = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__); + mir_data->current_window = NULL; + mir_data->software = SDL_FALSE; + mir_data->pixel_format = mir_pixel_format_invalid; - if (!MIR_mir_connection_is_valid(mir_data->connection)) - return SDL_SetError("Failed to connect to the Mir Server"); + if (!MIR_mir_connection_is_valid(mir_data->connection)) { + return SDL_SetError("Failed to connect to the mir server: %s", + MIR_mir_connection_get_error_message(mir_data->connection)); + } + + mir_data->display_config = MIR_mir_connection_create_display_configuration(mir_data->connection); MIR_InitDisplays(_this); MIR_InitMouse(); @@ -284,11 +315,27 @@ MIR_VideoInit(_THIS) return 0; } -void +static void +MIR_CleanUpDisplayConfig(_THIS) +{ + MIR_Data* mir_data = _this->driverdata; + int i; + + // SDL_VideoQuit frees the display driverdata, we own it not them + for (i = 0; i < _this->num_displays; ++i) { + _this->displays[i].driverdata = NULL; + } + + MIR_mir_display_config_release(mir_data->display_config); +} + +static void MIR_VideoQuit(_THIS) { MIR_Data* mir_data = _this->driverdata; + MIR_CleanUpDisplayConfig(_this); + MIR_FiniMouse(); MIR_GL_DeleteContext(_this, NULL); @@ -303,40 +350,48 @@ MIR_VideoQuit(_THIS) static int MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect) { - MIR_Data* mir_data = _this->driverdata; - int d; + MirOutput const* output = display->driverdata; - MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection); - - for (d = 0; d < display_config->num_outputs; d++) { - MirDisplayOutput const* out = display_config->outputs + d; - - if (out->used && - out->connected && - out->num_modes && - out->current_mode < out->num_modes) { - - rect->x = out->position_x; - rect->y = out->position_y; - rect->w = out->modes->horizontal_resolution; - rect->h = out->modes->vertical_resolution; - } - } - - MIR_mir_display_config_destroy(display_config); + rect->x = MIR_mir_output_get_position_x(output); + rect->y = MIR_mir_output_get_position_y(output); + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; return 0; } static void -MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display) +MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* display) { } static int -MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode) +MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* display, SDL_DisplayMode* mode) { - return 0; + int m; + MirOutput* output = display->driverdata; + int num_modes = MIR_mir_output_get_num_modes(output); + Uint32 sdl_format = MIR_GetSDLPixelFormat( + MIR_mir_output_get_current_pixel_format(output)); + + for (m = 0; m < num_modes; m++) { + MirOutputMode const* mir_mode = MIR_mir_output_get_mode(output, m); + int width = MIR_mir_output_mode_get_width(mir_mode); + int height = MIR_mir_output_mode_get_height(mir_mode); + double refresh_rate = MIR_mir_output_mode_get_refresh_rate(mir_mode); + + if (mode->format == sdl_format && + mode->w == width && + mode->h == height && + mode->refresh_rate == refresh_rate) { + + // FIXME Currently wont actually *set* anything. Need to wait for applying display changes + MIR_mir_output_set_current_mode(output, mir_mode); + return 0; + } + } + + return -1; } #endif /* SDL_VIDEO_DRIVER_MIR */ diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirvideo.h b/Engine/lib/sdl/src/video/mir/SDL_mirvideo.h index c5ef4758d..71ef4ecc1 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirvideo.h +++ b/Engine/lib/sdl/src/video/mir/SDL_mirvideo.h @@ -29,13 +29,20 @@ #include #include +typedef struct MIR_Window MIR_Window; + typedef struct { - MirConnection* connection; - SDL_bool software; - + MirConnection* connection; + MirDisplayConfig* display_config; + MIR_Window* current_window; + SDL_bool software; + MirPixelFormat pixel_format; } MIR_Data; +extern Uint32 +MIR_GetSDLPixelFormat(MirPixelFormat format); + #endif /* _SDL_mirvideo_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirwindow.c b/Engine/lib/sdl/src/video/mir/SDL_mirwindow.c index 0eb54be01..1bf9016a0 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirwindow.c +++ b/Engine/lib/sdl/src/video/mir/SDL_mirwindow.c @@ -29,6 +29,7 @@ #include "../SDL_egl_c.h" #include "../SDL_sysvideo.h" +#include "../../events/SDL_keyboard_c.h" #include "SDL_mirevents.h" #include "SDL_mirwindow.h" @@ -55,7 +56,7 @@ FindValidPixelFormat(MIR_Data* mir_data) MirPixelFormat formats[pf_size]; MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats, - pf_size, &valid_formats); + pf_size, &valid_formats); for (f = 0; f < valid_formats; f++) { MirPixelFormat cur_pf = formats[f]; @@ -77,21 +78,10 @@ MIR_CreateWindow(_THIS, SDL_Window* window) { MIR_Window* mir_window; MIR_Data* mir_data; + MirPixelFormat pixel_format; + MirBufferUsage buffer_usage; - MirSurfaceParameters surfaceparm = - { - .name = "MirSurface", - .width = window->w, - .height = window->h, - .pixel_format = mir_pixel_format_invalid, - .buffer_usage = mir_buffer_usage_hardware, - .output_id = mir_display_output_id_invalid - }; - - MirEventDelegate delegate = { - MIR_HandleInput, - window - }; + MirSurfaceSpec* spec; mir_window = SDL_calloc(1, sizeof(MIR_Window)); if (!mir_window) @@ -100,9 +90,6 @@ MIR_CreateWindow(_THIS, SDL_Window* window) mir_data = _this->driverdata; window->driverdata = mir_window; - if (mir_data->software) - surfaceparm.buffer_usage = mir_buffer_usage_software; - if (window->x == SDL_WINDOWPOS_UNDEFINED) window->x = 0; @@ -112,20 +99,49 @@ MIR_CreateWindow(_THIS, SDL_Window* window) mir_window->mir_data = mir_data; mir_window->sdl_window = window; - surfaceparm.pixel_format = FindValidPixelFormat(mir_data); - if (surfaceparm.pixel_format == mir_pixel_format_invalid) { + if (window->flags & SDL_WINDOW_OPENGL) { + pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection, + _this->egl_data->egl_display, + _this->egl_data->egl_config); + } + else { + pixel_format = FindValidPixelFormat(mir_data); + } + + mir_data->pixel_format = pixel_format; + if (pixel_format == mir_pixel_format_invalid) { return SDL_SetError("Failed to find a valid pixel format."); } - mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm); + buffer_usage = mir_buffer_usage_hardware; + if (mir_data->software) + buffer_usage = mir_buffer_usage_software; + + spec = MIR_mir_connection_create_spec_for_normal_surface(mir_data->connection, + window->w, + window->h, + pixel_format); + + MIR_mir_surface_spec_set_buffer_usage(spec, buffer_usage); + MIR_mir_surface_spec_set_name(spec, "Mir surface"); + + if (window->flags & SDL_WINDOW_INPUT_FOCUS) + SDL_SetKeyboardFocus(window); + + mir_window->surface = MIR_mir_surface_create_sync(spec); + MIR_mir_surface_set_event_handler(mir_window->surface, MIR_HandleEvent, window); + + MIR_mir_surface_spec_release(spec); + if (!MIR_mir_surface_is_valid(mir_window->surface)) { - const char* error = MIR_mir_surface_get_error_message(mir_window->surface); - return SDL_SetError("Failed to created a mir surface: %s", error); + return SDL_SetError("Failed to created a mir surface: %s", + MIR_mir_surface_get_error_message(mir_window->surface)); } if (window->flags & SDL_WINDOW_OPENGL) { EGLNativeWindowType egl_native_window = - (EGLNativeWindowType)MIR_mir_surface_get_egl_native_window(mir_window->surface); + (EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window( + MIR_mir_surface_get_buffer_stream(mir_window->surface)); mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window); @@ -138,7 +154,7 @@ MIR_CreateWindow(_THIS, SDL_Window* window) mir_window->egl_surface = EGL_NO_SURFACE; } - MIR_mir_surface_set_event_handler(mir_window->surface, &delegate); + mir_data->current_window = mir_window; return 0; } @@ -146,13 +162,15 @@ MIR_CreateWindow(_THIS, SDL_Window* window) void MIR_DestroyWindow(_THIS, SDL_Window* window) { - MIR_Data* mir_data = _this->driverdata; + MIR_Data* mir_data = _this->driverdata; MIR_Window* mir_window = window->driverdata; if (mir_data) { SDL_EGL_DestroySurface(_this, mir_window->egl_surface); MIR_mir_surface_release_sync(mir_window->surface); + mir_data->current_window = NULL; + SDL_free(mir_window); } window->driverdata = NULL; @@ -180,49 +198,223 @@ MIR_SetWindowFullscreen(_THIS, SDL_Window* window, SDL_VideoDisplay* display, SDL_bool fullscreen) { + MIR_Data* mir_data = _this->driverdata; MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; + MirSurfaceState state; if (IsSurfaceValid(mir_window) < 0) return; if (fullscreen) { - MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_fullscreen); + state = mir_surface_state_fullscreen; } else { - MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored); + state = mir_surface_state_restored; } + + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_state(spec, state); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); } void MIR_MaximizeWindow(_THIS, SDL_Window* window) { + MIR_Data* mir_data = _this->driverdata; MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; if (IsSurfaceValid(mir_window) < 0) return; - MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_maximized); + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_state(spec, mir_surface_state_maximized); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); } void MIR_MinimizeWindow(_THIS, SDL_Window* window) { + MIR_Data* mir_data = _this->driverdata; MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; if (IsSurfaceValid(mir_window) < 0) return; - MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_minimized); + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_state(spec, mir_surface_state_minimized); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); } void MIR_RestoreWindow(_THIS, SDL_Window * window) { + MIR_Data* mir_data = _this->driverdata; MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; if (IsSurfaceValid(mir_window) < 0) return; - MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored); + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_state(spec, mir_surface_state_restored); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); +} + +void +MIR_HideWindow(_THIS, SDL_Window* window) +{ + MIR_Data* mir_data = _this->driverdata; + MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; + + if (IsSurfaceValid(mir_window) < 0) + return; + + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_state(spec, mir_surface_state_hidden); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); +} + +void +MIR_SetWindowSize(_THIS, SDL_Window* window) +{ + MIR_Data* mir_data = _this->driverdata; + MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; + + if (IsSurfaceValid(mir_window) < 0) + return; + + /* You cannot set the x/y of a mir window! So only update w/h */ + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_width (spec, window->w); + MIR_mir_surface_spec_set_height(spec, window->h); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); +} + +void +MIR_SetWindowMinimumSize(_THIS, SDL_Window* window) +{ + MIR_Data* mir_data = _this->driverdata; + MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; + + if (IsSurfaceValid(mir_window) < 0) + return; + + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_min_width (spec, window->min_w); + MIR_mir_surface_spec_set_min_height(spec, window->min_h); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); +} + +void +MIR_SetWindowMaximumSize(_THIS, SDL_Window* window) +{ + MIR_Data* mir_data = _this->driverdata; + MIR_Window* mir_window = window->driverdata; + MirSurfaceSpec* spec; + + if (IsSurfaceValid(mir_window) < 0) + return; + + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_max_width (spec, window->max_w); + MIR_mir_surface_spec_set_max_height(spec, window->max_h); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); +} + +void +MIR_SetWindowTitle(_THIS, SDL_Window* window) +{ + MIR_Data* mir_data = _this->driverdata; + MIR_Window* mir_window = window->driverdata; + char const* title = window->title ? window->title : ""; + MirSurfaceSpec* spec; + + if (IsSurfaceValid(mir_window) < 0) + return; + + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_name(spec, title); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); +} + +void +MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed) +{ + MIR_Data* mir_data = _this->driverdata; + MIR_Window* mir_window = window->driverdata; + MirPointerConfinementState confined = mir_pointer_unconfined; + MirSurfaceSpec* spec; + + if (grabbed) + confined = mir_pointer_confined_to_surface; + + spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection); + MIR_mir_surface_spec_set_pointer_confinement(spec, confined); + + MIR_mir_surface_apply_spec(mir_window->surface, spec); + MIR_mir_surface_spec_release(spec); +} + +int +MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp) +{ + MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata; + Uint32 ramp_size = 256; + + // FIXME Need to apply the changes to the output, once that public API function is around + if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) { + MIR_mir_output_set_gamma(output, + ramp + ramp_size * 0, + ramp + ramp_size * 1, + ramp + ramp_size * 2, + ramp_size); + return 0; + } + + return -1; +} + +int +MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp) +{ + MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata; + Uint32 ramp_size = 256; + + if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) { + if (MIR_mir_output_get_gamma_size(output) == ramp_size) { + MIR_mir_output_get_gamma(output, + ramp + ramp_size * 0, + ramp + ramp_size * 1, + ramp + ramp_size * 2, + ramp_size); + return 0; + } + } + + return -1; } #endif /* SDL_VIDEO_DRIVER_MIR */ diff --git a/Engine/lib/sdl/src/video/mir/SDL_mirwindow.h b/Engine/lib/sdl/src/video/mir/SDL_mirwindow.h index c21fc9292..c4084aa4e 100644 --- a/Engine/lib/sdl/src/video/mir/SDL_mirwindow.h +++ b/Engine/lib/sdl/src/video/mir/SDL_mirwindow.h @@ -31,13 +31,13 @@ #include "SDL_mirvideo.h" -typedef struct { +struct MIR_Window { SDL_Window* sdl_window; - MIR_Data* mir_data; + MIR_Data* mir_data; MirSurface* surface; - EGLSurface egl_surface; -} MIR_Window; + EGLSurface egl_surface; +}; extern int @@ -60,9 +60,33 @@ MIR_MinimizeWindow(_THIS, SDL_Window* window); extern void MIR_RestoreWindow(_THIS, SDL_Window* window); +extern void +MIR_HideWindow(_THIS, SDL_Window* window); + extern SDL_bool MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info); +extern void +MIR_SetWindowSize(_THIS, SDL_Window* window); + +extern void +MIR_SetWindowMinimumSize(_THIS, SDL_Window* window); + +extern void +MIR_SetWindowMaximumSize(_THIS, SDL_Window* window); + +extern void +MIR_SetWindowTitle(_THIS, SDL_Window* window); + +extern void +MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed); + +extern int +MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp); + +extern int +MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp); + #endif /* _SDL_mirwindow_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/pandora/SDL_pandora.c b/Engine/lib/sdl/src/video/pandora/SDL_pandora.c index d1c35a705..7afa54306 100644 --- a/Engine/lib/sdl/src/video/pandora/SDL_pandora.c +++ b/Engine/lib/sdl/src/video/pandora/SDL_pandora.c @@ -41,8 +41,6 @@ static NativeWindowType hNativeWnd = 0; /* A handle to the window we will create. */ #endif -static SDL_bool PND_initialized = SDL_FALSE; - static int PND_available(void) { @@ -52,11 +50,11 @@ PND_available(void) static void PND_destroy(SDL_VideoDevice * device) { - SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; - if (device->driverdata != NULL) { + SDL_free(device->driverdata); device->driverdata = NULL; } + SDL_free(device); } static SDL_VideoDevice * @@ -93,9 +91,8 @@ PND_create() phdata->egl_initialized = SDL_TRUE; - /* Setup amount of available displays and current display */ + /* Setup amount of available displays */ device->num_displays = 0; - device->current_display = 0; /* Set device free function */ device->free = PND_destroy; @@ -204,10 +201,6 @@ PND_createwindow(_THIS, SDL_Window * window) SDL_WindowData *wdata; - uint32_t winargc = 0; - int32_t status; - - /* Allocate window internal data */ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); if (wdata == NULL) { @@ -292,7 +285,7 @@ PND_restorewindow(_THIS, SDL_Window * window) { } void -PND_setwindowgrab(_THIS, SDL_Window * window) +PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed) { } void @@ -326,8 +319,6 @@ PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) int PND_gl_loadlibrary(_THIS, const char *path) { - SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; - /* Check if OpenGL ES library is specified for GF driver */ if (path == NULL) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); @@ -365,7 +356,6 @@ PND_gl_loadlibrary(_THIS, const char *path) void * PND_gl_getprocaddres(_THIS, const char *proc) { - SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; void *function_address; /* Try to get function address through the egl interface */ @@ -409,10 +399,7 @@ PND_gl_createcontext(_THIS, SDL_Window * window) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *didata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; EGLBoolean status; - int32_t gfstatus; EGLint configs; uint32_t attr_pos; EGLint attr_value; @@ -629,12 +616,12 @@ PND_gl_createcontext(_THIS, SDL_Window * window) hNativeWnd = (NativeWindowType)malloc(16*1024); if(!hNativeWnd) - printf( "Error : Wiz framebuffer allocatation failed\n" ); + printf( "Error: Wiz framebuffer allocatation failed\n" ); else - printf( "SDL13: Wiz framebuffer allocated: %X\n", hNativeWnd ); + printf( "SDL: Wiz framebuffer allocated: %X\n", hNativeWnd ); } else { - printf( "SDL13: Wiz framebuffer already allocated: %X\n", hNativeWnd ); + printf( "SDL: Wiz framebuffer already allocated: %X\n", hNativeWnd ); } wdata->gles_surface = @@ -792,9 +779,6 @@ PND_gl_swapwindow(_THIS, SDL_Window * window) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *didata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - if (phdata->egl_initialized != SDL_TRUE) { SDL_SetError("PND: GLES initialization failed, no OpenGL ES support"); @@ -838,7 +822,7 @@ PND_gl_deletecontext(_THIS, SDL_GLContext context) { free(hNativeWnd); hNativeWnd = 0; - printf( "SDL13: Wiz framebuffer released\n" ); + printf( "SDL: Wiz framebuffer released\n" ); } #endif diff --git a/Engine/lib/sdl/src/video/pandora/SDL_pandora.h b/Engine/lib/sdl/src/video/pandora/SDL_pandora.h index b95cd10b1..859b7ee5d 100644 --- a/Engine/lib/sdl/src/video/pandora/SDL_pandora.h +++ b/Engine/lib/sdl/src/video/pandora/SDL_pandora.h @@ -77,7 +77,7 @@ void PND_raisewindow(_THIS, SDL_Window * window); void PND_maximizewindow(_THIS, SDL_Window * window); void PND_minimizewindow(_THIS, SDL_Window * window); void PND_restorewindow(_THIS, SDL_Window * window); -void PND_setwindowgrab(_THIS, SDL_Window * window); +void PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed); void PND_destroywindow(_THIS, SDL_Window * window); /* Window manager function */ diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspevents.c b/Engine/lib/sdl/src/video/psp/SDL_pspevents.c index c1a095dbb..71267272d 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspevents.c +++ b/Engine/lib/sdl/src/video/psp/SDL_pspevents.c @@ -31,8 +31,8 @@ #include "../../events/SDL_keyboard_c.h" #include "SDL_pspvideo.h" #include "SDL_pspevents_c.h" -#include "SDL_thread.h" #include "SDL_keyboard.h" +#include "../../thread/SDL_systhread.h" #include #ifdef PSPIRKEYB @@ -264,7 +264,7 @@ void PSP_EventInit(_THIS) return; } running = 1; - if((thread = SDL_CreateThread(EventUpdate, "PSPInputThread",NULL)) == NULL) { + if((thread = SDL_CreateThreadInternal(EventUpdate, "PSPInputThread", 4096, NULL)) == NULL) { SDL_SetError("Can't create input thread\n"); return; } diff --git a/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c b/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c index 955666877..381e4899e 100644 --- a/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c +++ b/Engine/lib/sdl/src/video/psp/SDL_pspvideo.c @@ -92,6 +92,7 @@ PSP_Create() if (gldata == NULL) { SDL_OutOfMemory(); SDL_free(device); + SDL_free(phdata); return NULL; } device->gl_data = gldata; @@ -101,7 +102,7 @@ PSP_Create() phdata->egl_initialized = SDL_TRUE; - /* Setup amount of available displays and current display */ + /* Setup amount of available displays */ device->num_displays = 0; /* Set device free function */ @@ -234,7 +235,7 @@ PSP_CreateWindow(_THIS, SDL_Window * window) int PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { - return -1; + return SDL_Unsupported(); } void diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c b/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c index 0d1482c04..ae9bdfd5c 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpimouse.c @@ -24,6 +24,7 @@ #include "SDL_assert.h" #include "SDL_surface.h" +#include "SDL_hints.h" #include "SDL_rpivideo.h" #include "SDL_rpimouse.h" @@ -70,7 +71,16 @@ RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) SDL_assert(surface->pitch == surface->w * 4); cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + if (cursor == NULL) { + SDL_OutOfMemory(); + return NULL; + } curdata = (RPI_CursorData *) SDL_calloc(1, sizeof(*curdata)); + if (curdata == NULL) { + SDL_OutOfMemory(); + SDL_free(cursor); + return NULL; + } curdata->hot_x = hot_x; curdata->hot_y = hot_y; @@ -78,17 +88,17 @@ RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) curdata->h = surface->h; /* This usage is inspired by Wayland/Weston RPI code, how they figured this out is anyone's guess */ - curdata->resource = vc_dispmanx_resource_create( VC_IMAGE_ARGB8888, surface->w | (surface->pitch << 16), surface->h | (surface->h << 16), &dummy ); + curdata->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, surface->w | (surface->pitch << 16), surface->h | (surface->h << 16), &dummy); SDL_assert(curdata->resource); - vc_dispmanx_rect_set( &dst_rect, 0, 0, curdata->w, curdata->h); + vc_dispmanx_rect_set(&dst_rect, 0, 0, curdata->w, curdata->h); /* A note from Weston: * vc_dispmanx_resource_write_data() ignores ifmt, * rect.x, rect.width, and uses stride only for computing * the size of the transfer as rect.height * stride. * Therefore we can only write rows starting at x=0. */ - ret = vc_dispmanx_resource_write_data( curdata->resource, VC_IMAGE_ARGB8888, surface->pitch, surface->pixels, &dst_rect ); - SDL_assert ( ret == DISPMANX_SUCCESS ); + ret = vc_dispmanx_resource_write_data(curdata->resource, VC_IMAGE_ARGB8888, surface->pitch, surface->pixels, &dst_rect); + SDL_assert (ret == DISPMANX_SUCCESS); cursor->driverdata = curdata; @@ -108,7 +118,9 @@ RPI_ShowCursor(SDL_Cursor * cursor) SDL_VideoDisplay *display; SDL_DisplayData *data; VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE /* flags */ , 255 /*opacity 0->255*/, 0 /* mask */ }; - + uint32_t layer = SDL_RPI_MOUSELAYER; + const char *env; + mouse = SDL_GetMouse(); if (mouse == NULL) { return -1; @@ -117,15 +129,15 @@ RPI_ShowCursor(SDL_Cursor * cursor) if (cursor == NULL) { /* FIXME: We hide the current mouse's cursor, what we actually need is *_HideCursor */ - if ( mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) { + if (mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) { curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata; if (curdata->element > DISPMANX_NO_HANDLE) { - update = vc_dispmanx_update_start( 10 ); - SDL_assert( update ); - ret = vc_dispmanx_element_remove( update, curdata->element ); - SDL_assert( ret == DISPMANX_SUCCESS ); - ret = vc_dispmanx_update_submit_sync( update ); - SDL_assert( ret == DISPMANX_SUCCESS ); + update = vc_dispmanx_update_start(10); + SDL_assert(update); + ret = vc_dispmanx_element_remove(update, curdata->element); + SDL_assert(ret == DISPMANX_SUCCESS); + ret = vc_dispmanx_update_submit_sync(update); + SDL_assert(ret == DISPMANX_SUCCESS); curdata->element = DISPMANX_NO_HANDLE; } } @@ -152,25 +164,30 @@ RPI_ShowCursor(SDL_Cursor * cursor) } if (curdata->element == DISPMANX_NO_HANDLE) { - vc_dispmanx_rect_set( &src_rect, 0, 0, curdata->w << 16, curdata->h << 16 ); - vc_dispmanx_rect_set( &dst_rect, 0, 0, curdata->w, curdata->h); + vc_dispmanx_rect_set(&src_rect, 0, 0, curdata->w << 16, curdata->h << 16); + vc_dispmanx_rect_set(&dst_rect, 0, 0, curdata->w, curdata->h); - update = vc_dispmanx_update_start( 10 ); - SDL_assert( update ); + update = vc_dispmanx_update_start(10); + SDL_assert(update); - curdata->element = vc_dispmanx_element_add( update, + env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER); + if (env) { + layer = SDL_atoi(env) + 1; + } + + curdata->element = vc_dispmanx_element_add(update, data->dispman_display, - SDL_RPI_MOUSELAYER, // layer + layer, &dst_rect, curdata->resource, &src_rect, DISPMANX_PROTECTION_NONE, &alpha, DISPMANX_NO_HANDLE, // clamp - VC_IMAGE_ROT0 ); - SDL_assert( curdata->element > DISPMANX_NO_HANDLE); - ret = vc_dispmanx_update_submit_sync( update ); - SDL_assert( ret == DISPMANX_SUCCESS ); + VC_IMAGE_ROT0); + SDL_assert(curdata->element > DISPMANX_NO_HANDLE); + ret = vc_dispmanx_update_submit_sync(update); + SDL_assert(ret == DISPMANX_SUCCESS); } return 0; @@ -189,17 +206,17 @@ RPI_FreeCursor(SDL_Cursor * cursor) if (curdata != NULL) { if (curdata->element != DISPMANX_NO_HANDLE) { - update = vc_dispmanx_update_start( 10 ); - SDL_assert( update ); - ret = vc_dispmanx_element_remove( update, curdata->element ); - SDL_assert( ret == DISPMANX_SUCCESS ); - ret = vc_dispmanx_update_submit_sync( update ); - SDL_assert( ret == DISPMANX_SUCCESS ); + update = vc_dispmanx_update_start(10); + SDL_assert(update); + ret = vc_dispmanx_element_remove(update, curdata->element); + SDL_assert(ret == DISPMANX_SUCCESS); + ret = vc_dispmanx_update_submit_sync(update); + SDL_assert(ret == DISPMANX_SUCCESS); } if (curdata->resource != DISPMANX_NO_HANDLE) { - ret = vc_dispmanx_resource_delete( curdata->resource ); - SDL_assert( ret == DISPMANX_SUCCESS ); + ret = vc_dispmanx_resource_delete(curdata->resource); + SDL_assert(ret == DISPMANX_SUCCESS); } SDL_free(cursor->driverdata); @@ -221,35 +238,54 @@ RPI_WarpMouseGlobal(int x, int y) { RPI_CursorData *curdata; DISPMANX_UPDATE_HANDLE_T update; + int ret; VC_RECT_T dst_rect; + VC_RECT_T src_rect; SDL_Mouse *mouse = SDL_GetMouse(); - if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) { - curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata; - if (curdata->element != DISPMANX_NO_HANDLE) { - int ret; - update = vc_dispmanx_update_start( 10 ); - SDL_assert( update ); - vc_dispmanx_rect_set( &dst_rect, x, y, curdata->w, curdata->h); - ret = vc_dispmanx_element_change_attributes( - update, - curdata->element, - ELEMENT_CHANGE_DEST_RECT, - 0, - 0, - &dst_rect, - NULL, - DISPMANX_NO_HANDLE, - DISPMANX_NO_ROTATE); - SDL_assert( ret == DISPMANX_SUCCESS ); - /* Submit asynchronously, otherwise the peformance suffers a lot */ - ret = vc_dispmanx_update_submit( update, 0, NULL ); - SDL_assert( ret == DISPMANX_SUCCESS ); - return (ret == DISPMANX_SUCCESS) ? 0 : -1; - } - } + if (mouse == NULL || mouse->cur_cursor == NULL || mouse->cur_cursor->driverdata == NULL) { + return 0; + } - return -1; /* !!! FIXME: this should SDL_SetError() somewhere. */ + curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata; + if (curdata->element == DISPMANX_NO_HANDLE) { + return 0; + } + + update = vc_dispmanx_update_start(10); + if (!update) { + return 0; + } + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = curdata->w << 16; + src_rect.height = curdata->h << 16; + dst_rect.x = x; + dst_rect.y = y; + dst_rect.width = curdata->w; + dst_rect.height = curdata->h; + + ret = vc_dispmanx_element_change_attributes( + update, + curdata->element, + 0, + 0, + 0, + &dst_rect, + &src_rect, + DISPMANX_NO_HANDLE, + DISPMANX_NO_ROTATE); + if (ret != DISPMANX_SUCCESS) { + return SDL_SetError("vc_dispmanx_element_change_attributes() failed"); + } + + /* Submit asynchronously, otherwise the peformance suffers a lot */ + ret = vc_dispmanx_update_submit(update, 0, NULL); + if (ret != DISPMANX_SUCCESS) { + return SDL_SetError("vc_dispmanx_update_submit() failed"); + } + return 0; } void diff --git a/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c b/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c index 539c88c9b..67dc77b1c 100644 --- a/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c +++ b/Engine/lib/sdl/src/video/raspberry/SDL_rpivideo.c @@ -38,6 +38,7 @@ #include "SDL_events.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_keyboard_c.h" +#include "SDL_hints.h" #ifdef SDL_INPUT_LINUXEV #include "../../core/linux/SDL_evdev.h" @@ -88,7 +89,7 @@ RPI_Create() device->driverdata = phdata; - /* Setup amount of available displays and current display */ + /* Setup amount of available displays */ device->num_displays = 0; /* Set device free function */ @@ -221,6 +222,8 @@ RPI_CreateWindow(_THIS, SDL_Window * window) VC_RECT_T src_rect; VC_DISPMANX_ALPHA_T dispman_alpha; DISPMANX_UPDATE_HANDLE_T dispman_update; + uint32_t layer = SDL_RPI_VIDEOLAYER; + const char *env; /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */ dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; @@ -253,11 +256,25 @@ RPI_CreateWindow(_THIS, SDL_Window * window) src_rect.width = window->w << 16; src_rect.height = window->h << 16; + env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER); + if (env) { + layer = SDL_atoi(env); + } + dispman_update = vc_dispmanx_update_start( 0 ); - wdata->dispman_window.element = vc_dispmanx_element_add ( dispman_update, displaydata->dispman_display, SDL_RPI_VIDEOLAYER /* layer */, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha*/, 0/*clamp*/, 0/*transform*/); + wdata->dispman_window.element = vc_dispmanx_element_add (dispman_update, + displaydata->dispman_display, + layer /* layer */, + &dst_rect, + 0 /*src*/, + &src_rect, + DISPMANX_PROTECTION_NONE, + &dispman_alpha /*alpha*/, + 0 /*clamp*/, + 0 /*transform*/); wdata->dispman_window.width = window->w; wdata->dispman_window.height = window->h; - vc_dispmanx_update_submit_sync( dispman_update ); + vc_dispmanx_update_submit_sync(dispman_update); if (!_this->egl_data) { if (SDL_GL_LoadLibrary(NULL) < 0) { diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h index 1879f0b3a..edf09f50f 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.h @@ -24,8 +24,8 @@ @interface SDLLaunchScreenController : UIViewController - (instancetype)init; +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil; - (void)loadView; -- (NSUInteger)supportedInterfaceOrientations; @end diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m index 971b438b0..c94c78a41 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitappdelegate.m @@ -76,6 +76,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa [UIApplication sharedApplication].idleTimerDisabled = disable; } +#if !TARGET_OS_TV /* Load a launch image using the old UILaunchImageFile-era naming rules. */ static UIImage * SDL_LoadLaunchImageNamed(NSString *name, int screenh) @@ -114,17 +115,31 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) return image; } +#endif /* !TARGET_OS_TV */ + +@interface SDLLaunchScreenController () + +#if !TARGET_OS_TV +- (NSUInteger)supportedInterfaceOrientations; +#endif + +@end @implementation SDLLaunchScreenController - (instancetype)init +{ + return [self initWithNibName:nil bundle:[NSBundle mainBundle]]; +} + +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { if (!(self = [super initWithNibName:nil bundle:nil])) { return nil; } - NSBundle *bundle = [NSBundle mainBundle]; - NSString *screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"]; + NSString *screenname = nibNameOrNil; + NSBundle *bundle = nibBundleOrNil; BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0); /* Launch screens were added in iOS 8. Otherwise we use launch images. */ @@ -141,27 +156,28 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) if (!self.view) { NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"]; - UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation; NSString *imagename = nil; UIImage *image = nil; int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5); int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5); +#if !TARGET_OS_TV + UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation; + /* We always want portrait-oriented size, to match UILaunchImageSize. */ if (screenw > screenh) { int width = screenw; screenw = screenh; screenh = width; } +#endif /* Xcode 5 introduced a dictionary of launch images in Info.plist. */ if (launchimages) { for (NSDictionary *dict in launchimages) { - UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; - NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"]; - NSString *sizestring = dict[@"UILaunchImageSize"]; - NSString *orientstring = dict[@"UILaunchImageOrientation"]; + NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"]; + NSString *sizestring = dict[@"UILaunchImageSize"]; /* Ignore this image if the current version is too low. */ if (minversion && !UIKit_IsSystemVersionAtLeast(minversion.doubleValue)) { @@ -176,6 +192,10 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) } } +#if !TARGET_OS_TV + UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; + NSString *orientstring = dict[@"UILaunchImageOrientation"]; + if (orientstring) { if ([orientstring isEqualToString:@"PortraitUpsideDown"]) { orientmask = UIInterfaceOrientationMaskPortraitUpsideDown; @@ -192,6 +212,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) if ((orientmask & (1 << curorient)) == 0) { continue; } +#endif imagename = dict[@"UILaunchImageName"]; } @@ -199,7 +220,9 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) if (imagename) { image = [UIImage imageNamed:imagename]; } - } else { + } +#if !TARGET_OS_TV + else { imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"]; if (imagename) { @@ -210,11 +233,13 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) image = SDL_LoadLaunchImageNamed(@"Default", screenh); } } +#endif if (image) { UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIImageOrientation imageorient = UIImageOrientationUp; +#if !TARGET_OS_TV /* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */ if (UIInterfaceOrientationIsLandscape(curorient)) { if (atleastiOS8 && image.size.width < image.size.height) { @@ -238,6 +263,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) } } } +#endif /* Create the properly oriented image. */ view.image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:imageorient]; @@ -254,6 +280,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) /* Do nothing. */ } +#if !TARGET_OS_TV - (BOOL)shouldAutorotate { /* If YES, the launch image will be incorrectly rotated in some cases. */ @@ -267,6 +294,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) * the ones set here (it will cause an exception in that case.) */ return UIInterfaceOrientationMaskAll; } +#endif /* !TARGET_OS_TV */ @end @@ -333,7 +361,6 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSBundle *bundle = [NSBundle mainBundle]; - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; #if SDL_IPHONE_LAUNCHSCREEN /* The normal launch screen is displayed until didFinishLaunching returns, @@ -342,9 +369,32 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) * displayed (e.g. if resources are loaded before SDL_GL_SwapWindow is * called), so we show the launch screen programmatically until the first * time events are pumped. */ - UIViewController *viewcontroller = [[SDLLaunchScreenController alloc] init]; + UIViewController *vc = nil; + NSString *screenname = nil; - if (viewcontroller.view) { + /* tvOS only uses a plain launch image. */ +#if !TARGET_OS_TV + screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"]; + + if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) { + @try { + /* The launch storyboard is actually a nib in some older versions of + * Xcode. We'll try to load it as a storyboard first, as it's more + * modern. */ + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:screenname bundle:bundle]; + vc = [storyboard instantiateInitialViewController]; + } + @catch (NSException *exception) { + /* Do nothing (there's more code to execute below). */ + } + } +#endif + + if (vc == nil) { + vc = [[SDLLaunchScreenController alloc] initWithNibName:screenname bundle:bundle]; + } + + if (vc.view) { launchWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; /* We don't want the launch window immediately hidden when a real SDL @@ -355,7 +405,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) * other windows when possible. */ launchWindow.hidden = NO; - launchWindow.rootViewController = viewcontroller; + launchWindow.rootViewController = vc; } #endif @@ -382,6 +432,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) SDL_SendAppEvent(SDL_APP_LOWMEMORY); } +#if !TARGET_OS_TV - (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation { BOOL isLandscape = UIInterfaceOrientationIsLandscape(application.statusBarOrientation); @@ -409,6 +460,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) } } } +#endif - (void)applicationWillResignActive:(UIApplication*)application { @@ -447,16 +499,34 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) } } -- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +- (void)sendDropFileForURL:(NSURL *)url { NSURL *fileURL = url.filePathURL; if (fileURL != nil) { - SDL_SendDropFile([fileURL.path UTF8String]); + SDL_SendDropFile(NULL, fileURL.path.UTF8String); } else { - SDL_SendDropFile([url.absoluteString UTF8String]); + SDL_SendDropFile(NULL, url.absoluteString.UTF8String); } + SDL_SendDropComplete(NULL); +} + +#if TARGET_OS_TV +/* TODO: Use this on iOS 9+ as well? */ +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options +{ + /* TODO: Handle options */ + [self sendDropFileForURL:url]; return YES; } +#endif /* TARGET_OS_TV */ + +#if !TARGET_OS_TV +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +{ + [self sendDropFileForURL:url]; + return YES; +} +#endif /* !TARGET_OS_TV */ @end diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h new file mode 100644 index 000000000..7d1c35f99 --- /dev/null +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef _SDL_uikitclipboard_h +#define _SDL_uikitclipboard_h + +#include "../SDL_sysvideo.h" + +extern int UIKit_SetClipboardText(_THIS, const char *text); +extern char *UIKit_GetClipboardText(_THIS); +extern SDL_bool UIKit_HasClipboardText(_THIS); + +extern void UIKit_InitClipboard(_THIS); +extern void UIKit_QuitClipboard(_THIS); + +#endif /* _SDL_uikitclipboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m new file mode 100644 index 000000000..050d5885f --- /dev/null +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m @@ -0,0 +1,111 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_UIKIT + +#include "SDL_uikitvideo.h" +#include "../../events/SDL_clipboardevents_c.h" + +#import + +int +UIKit_SetClipboardText(_THIS, const char *text) +{ +#if TARGET_OS_TV + return SDL_SetError("The clipboard is not available on tvOS"); +#else + @autoreleasepool { + [UIPasteboard generalPasteboard].string = @(text); + return 0; + } +#endif +} + +char * +UIKit_GetClipboardText(_THIS) +{ +#if TARGET_OS_TV + return SDL_strdup(""); // Unsupported. +#else + @autoreleasepool { + UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; + NSString *string = pasteboard.string; + + if (string != nil) { + return SDL_strdup(string.UTF8String); + } else { + return SDL_strdup(""); + } + } +#endif +} + +SDL_bool +UIKit_HasClipboardText(_THIS) +{ + @autoreleasepool { +#if !TARGET_OS_TV + if ([UIPasteboard generalPasteboard].string != nil) { + return SDL_TRUE; + } +#endif + return SDL_FALSE; + } +} + +void +UIKit_InitClipboard(_THIS) +{ +#if !TARGET_OS_TV + @autoreleasepool { + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + id observer = [center addObserverForName:UIPasteboardChangedNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + SDL_SendClipboardUpdate(); + }]; + + data.pasteboardObserver = observer; + } +#endif +} + +void +UIKit_QuitClipboard(_THIS) +{ + @autoreleasepool { + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; + + if (data.pasteboardObserver != nil) { + [[NSNotificationCenter defaultCenter] removeObserver:data.pasteboardObserver]; + } + + data.pasteboardObserver = nil; + } +} + +#endif /* SDL_VIDEO_DRIVER_UIKIT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m index 1d7044d88..7083e204b 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitevents.m @@ -26,6 +26,7 @@ #include "SDL_uikitvideo.h" #include "SDL_uikitevents.h" +#include "SDL_uikitopengles.h" #import @@ -62,6 +63,9 @@ UIKit_PumpEvents(_THIS) do { result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE); } while(result == kCFRunLoopRunHandledSource); + + /* See the comment in the function definition. */ + UIKit_GL_RestoreCurrentContext(); } #endif /* SDL_VIDEO_DRIVER_UIKIT */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h index 027cf7aa0..b936df616 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.h @@ -43,6 +43,7 @@ extern int UIKit_InitModes(_THIS); extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); extern void UIKit_QuitModes(_THIS); +extern int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); #endif /* _SDL_uikitmodes_h */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m index 98d031484..cd3b8d08e 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitmodes.m @@ -156,9 +156,12 @@ UIKit_AddDisplay(UIScreen *uiscreen) SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen) { +#if !TARGET_OS_TV if (uiscreen == [UIScreen mainScreen]) { return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation); - } else { + } else +#endif /* !TARGET_OS_TV */ + { CGSize size = uiscreen.bounds.size; return (size.width > size.height); } @@ -187,6 +190,14 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen); SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]); CGFloat scale = data.uiscreen.scale; + NSArray *availableModes = nil; + +#if TARGET_OS_TV + addRotation = SDL_FALSE; + availableModes = @[data.uiscreen.currentMode]; +#else + availableModes = data.uiscreen.availableModes; +#endif #ifdef __IPHONE_8_0 /* The UIScreenMode of an iPhone 6 Plus should be 1080x1920 rather than @@ -196,7 +207,7 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) } #endif - for (UIScreenMode *uimode in data.uiscreen.availableModes) { + for (UIScreenMode *uimode in availableModes) { /* The size of a UIScreenMode is in pixels, but we deal exclusively * in points (except in SDL_GL_GetDrawableSize.) */ int w = (int)(uimode.size.width / scale); @@ -219,9 +230,11 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) { @autoreleasepool { SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; - SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata; +#if !TARGET_OS_TV + SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata; [data.uiscreen setCurrentMode:modedata.uiscreenmode]; +#endif if (data.uiscreen == [UIScreen mainScreen]) { /* [UIApplication setStatusBarOrientation:] no longer works reliably @@ -242,6 +255,36 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) return 0; } +int +UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +{ + @autoreleasepool { + int displayIndex = (int) (display - _this->displays); + SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; + + /* the default function iterates displays to make a fake offset, + as if all the displays were side-by-side, which is fine for iOS. */ + if (SDL_GetDisplayBounds(displayIndex, rect) < 0) { + return -1; + } + + CGRect frame = data.uiscreen.bounds; + +#if !TARGET_OS_TV + if (!UIKit_IsSystemVersionAtLeast(7.0)) { + frame = [data.uiscreen applicationFrame]; + } +#endif + + rect->x += frame.origin.x; + rect->y += frame.origin.y; + rect->w = frame.size.width; + rect->h = frame.size.height; + } + + return 0; +} + void UIKit_QuitModes(_THIS) { diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h index 10697610d..b52e42913 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.h @@ -33,6 +33,8 @@ extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context); extern void *UIKit_GL_GetProcAddress(_THIS, const char *proc); extern int UIKit_GL_LoadLibrary(_THIS, const char *path); +extern void UIKit_GL_RestoreCurrentContext(); + #endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m index a2ea4ab67..461ff9b80 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitopengles.m @@ -140,10 +140,19 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window) EAGLSharegroup *sharegroup = nil; CGFloat scale = 1.0; int samples = 0; + int major = _this->gl_config.major_version; + int minor = _this->gl_config.minor_version; /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES * versions. */ - EAGLRenderingAPI api = _this->gl_config.major_version; + EAGLRenderingAPI api = major; + + /* iOS currently doesn't support GLES >3.0. iOS 6 also only supports up + * to GLES 2.0. */ + if (major > 3 || (major == 3 && (minor > 0 || !UIKit_IsSystemVersionAtLeast(7.0)))) { + SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor); + return NULL; + } if (_this->gl_config.multisamplebuffers > 0) { samples = _this->gl_config.multisamplesamples; @@ -217,6 +226,24 @@ UIKit_GL_DeleteContext(_THIS, SDL_GLContext context) } } +void +UIKit_GL_RestoreCurrentContext() +{ + @autoreleasepool { + /* Some iOS system functionality (such as Dictation on the on-screen + keyboard) uses its own OpenGL ES context but doesn't restore the + previous one when it's done. This is a workaround to make sure the + expected SDL-created OpenGL ES context is active after the OS is + finished running its own code for the frame. If this isn't done, the + app may crash or have other nasty symptoms when Dictation is used. + */ + EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext(); + if (context != NULL && [EAGLContext currentContext] != context) { + [EAGLContext setCurrentContext:context]; + } + } +} + #endif /* SDL_VIDEO_DRIVER_UIKIT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m index 60c247e6a..aae7ee8f2 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitopenglview.m @@ -239,7 +239,7 @@ if (msaaRenderbuffer != 0) { glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, backingWidth, backingHeight); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight); } if (depthRenderbuffer != 0) { diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h index 3fbaf92f1..aafb714d7 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.h @@ -21,14 +21,25 @@ #ifndef _SDL_uikitvideo_h #define _SDL_uikitvideo_h +#include "../SDL_sysvideo.h" + +#ifdef __OBJC__ + #include -#include "../SDL_sysvideo.h" +@interface SDL_VideoData : NSObject + +@property (nonatomic) id pasteboardObserver; + +@end + +CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen); + +#endif /* __OBJC__ */ void UIKit_SuspendScreenSaver(_THIS); -BOOL UIKit_IsSystemVersionAtLeast(double version); -CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen); +SDL_bool UIKit_IsSystemVersionAtLeast(double version); #endif /* _SDL_uikitvideo_h */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m index 4f3c7dc43..88d461751 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitvideo.m @@ -36,9 +36,14 @@ #include "SDL_uikitmodes.h" #include "SDL_uikitwindow.h" #include "SDL_uikitopengles.h" +#include "SDL_uikitclipboard.h" #define UIKITVID_DRIVER_NAME "uikit" +@implementation SDL_VideoData + +@end + /* Initialization/Query functions */ static int UIKit_VideoInit(_THIS); static void UIKit_VideoQuit(_THIS); @@ -53,60 +58,75 @@ UIKit_Available(void) static void UIKit_DeleteDevice(SDL_VideoDevice * device) { - SDL_free(device); + @autoreleasepool { + CFRelease(device->driverdata); + SDL_free(device); + } } static SDL_VideoDevice * UIKit_CreateDevice(int devindex) { - SDL_VideoDevice *device; + @autoreleasepool { + SDL_VideoDevice *device; + SDL_VideoData *data; - /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (!device) { - SDL_free(device); - SDL_OutOfMemory(); - return (0); + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device) { + data = [SDL_VideoData new]; + } else { + SDL_free(device); + SDL_OutOfMemory(); + return (0); + } + + device->driverdata = (void *) CFBridgingRetain(data); + + /* Set the function pointers */ + device->VideoInit = UIKit_VideoInit; + device->VideoQuit = UIKit_VideoQuit; + device->GetDisplayModes = UIKit_GetDisplayModes; + device->SetDisplayMode = UIKit_SetDisplayMode; + device->PumpEvents = UIKit_PumpEvents; + device->SuspendScreenSaver = UIKit_SuspendScreenSaver; + device->CreateWindow = UIKit_CreateWindow; + device->SetWindowTitle = UIKit_SetWindowTitle; + device->ShowWindow = UIKit_ShowWindow; + device->HideWindow = UIKit_HideWindow; + device->RaiseWindow = UIKit_RaiseWindow; + device->SetWindowBordered = UIKit_SetWindowBordered; + device->SetWindowFullscreen = UIKit_SetWindowFullscreen; + device->DestroyWindow = UIKit_DestroyWindow; + device->GetWindowWMInfo = UIKit_GetWindowWMInfo; + device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds; + + #if SDL_IPHONE_KEYBOARD + device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard; + device->HideScreenKeyboard = UIKit_HideScreenKeyboard; + device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown; + device->SetTextInputRect = UIKit_SetTextInputRect; + #endif + + device->SetClipboardText = UIKit_SetClipboardText; + device->GetClipboardText = UIKit_GetClipboardText; + device->HasClipboardText = UIKit_HasClipboardText; + + /* OpenGL (ES) functions */ + device->GL_MakeCurrent = UIKit_GL_MakeCurrent; + device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize; + device->GL_SwapWindow = UIKit_GL_SwapWindow; + device->GL_CreateContext = UIKit_GL_CreateContext; + device->GL_DeleteContext = UIKit_GL_DeleteContext; + device->GL_GetProcAddress = UIKit_GL_GetProcAddress; + device->GL_LoadLibrary = UIKit_GL_LoadLibrary; + device->free = UIKit_DeleteDevice; + + device->gl_config.accelerated = 1; + + return device; } - - /* Set the function pointers */ - device->VideoInit = UIKit_VideoInit; - device->VideoQuit = UIKit_VideoQuit; - device->GetDisplayModes = UIKit_GetDisplayModes; - device->SetDisplayMode = UIKit_SetDisplayMode; - device->PumpEvents = UIKit_PumpEvents; - device->SuspendScreenSaver = UIKit_SuspendScreenSaver; - device->CreateWindow = UIKit_CreateWindow; - device->SetWindowTitle = UIKit_SetWindowTitle; - device->ShowWindow = UIKit_ShowWindow; - device->HideWindow = UIKit_HideWindow; - device->RaiseWindow = UIKit_RaiseWindow; - device->SetWindowBordered = UIKit_SetWindowBordered; - device->SetWindowFullscreen = UIKit_SetWindowFullscreen; - device->DestroyWindow = UIKit_DestroyWindow; - device->GetWindowWMInfo = UIKit_GetWindowWMInfo; - -#if SDL_IPHONE_KEYBOARD - device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport; - device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard; - device->HideScreenKeyboard = UIKit_HideScreenKeyboard; - device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown; - device->SetTextInputRect = UIKit_SetTextInputRect; -#endif - - /* OpenGL (ES) functions */ - device->GL_MakeCurrent = UIKit_GL_MakeCurrent; - device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize; - device->GL_SwapWindow = UIKit_GL_SwapWindow; - device->GL_CreateContext = UIKit_GL_CreateContext; - device->GL_DeleteContext = UIKit_GL_DeleteContext; - device->GL_GetProcAddress = UIKit_GL_GetProcAddress; - device->GL_LoadLibrary = UIKit_GL_LoadLibrary; - device->free = UIKit_DeleteDevice; - - device->gl_config.accelerated = 1; - - return device; } VideoBootStrap UIKIT_bootstrap = { @@ -138,7 +158,7 @@ UIKit_SuspendScreenSaver(_THIS) @autoreleasepool { /* Ignore ScreenSaver API calls if the idle timer hint has been set. */ /* FIXME: The idle timer hint should be deprecated for SDL 2.1. */ - if (SDL_GetHint(SDL_HINT_IDLE_TIMER_DISABLED) == NULL) { + if (!SDL_GetHintBoolean(SDL_HINT_IDLE_TIMER_DISABLED, SDL_FALSE)) { UIApplication *app = [UIApplication sharedApplication]; /* Prevent the display from dimming and going to sleep. */ @@ -147,7 +167,7 @@ UIKit_SuspendScreenSaver(_THIS) } } -BOOL +SDL_bool UIKit_IsSystemVersionAtLeast(double version) { return [[UIDevice currentDevice].systemVersion doubleValue] >= version; @@ -156,6 +176,7 @@ UIKit_IsSystemVersionAtLeast(double version) CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) { +#if !TARGET_OS_TV && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0) BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(7.0); if (hasiOS7 || (window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) { @@ -164,6 +185,9 @@ UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) } else { return screen.applicationFrame; } +#else + return screen.bounds; +#endif } /* diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m index 1ccda98ff..c7d9f51d9 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitview.m @@ -45,7 +45,9 @@ self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.autoresizesSubviews = YES; +#if !TARGET_OS_TV self.multipleTouchEnabled = YES; +#endif touchId = 1; SDL_AddTouch(touchId, ""); @@ -141,12 +143,13 @@ if (!firstFingerDown) { CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO]; + int clicks = (int) touch.tapCount; /* send mouse moved event */ SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y); /* send mouse down event */ - SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT); + SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT, clicks); firstFingerDown = touch; } @@ -164,7 +167,8 @@ if (touch == firstFingerDown) { /* send mouse up */ - SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT); + int clicks = (int) touch.tapCount; + SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT, clicks); firstFingerDown = nil; } @@ -197,6 +201,69 @@ } } +#if TARGET_OS_TV || defined(__IPHONE_9_1) +- (SDL_Scancode)scancodeFromPressType:(UIPressType)presstype +{ + switch (presstype) { + case UIPressTypeUpArrow: + return SDL_SCANCODE_UP; + case UIPressTypeDownArrow: + return SDL_SCANCODE_DOWN; + case UIPressTypeLeftArrow: + return SDL_SCANCODE_LEFT; + case UIPressTypeRightArrow: + return SDL_SCANCODE_RIGHT; + case UIPressTypeSelect: + /* HIG says: "primary button behavior" */ + return SDL_SCANCODE_SELECT; + case UIPressTypeMenu: + /* HIG says: "returns to previous screen" */ + return SDL_SCANCODE_MENU; + case UIPressTypePlayPause: + /* HIG says: "secondary button behavior" */ + return SDL_SCANCODE_PAUSE; + default: + return SDL_SCANCODE_UNKNOWN; + } +} + +- (void)pressesBegan:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPressType:press.type]; + SDL_SendKeyboardKey(SDL_PRESSED, scancode); + } + + [super pressesBegan:presses withEvent:event]; +} + +- (void)pressesEnded:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPressType:press.type]; + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + + [super pressesEnded:presses withEvent:event]; +} + +- (void)pressesCancelled:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPressType:press.type]; + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + + [super pressesCancelled:presses withEvent:event]; +} + +- (void)pressesChanged:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + /* This is only called when the force of a press changes. */ + [super pressesChanged:presses withEvent:event]; +} +#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */ + @end #endif /* SDL_VIDEO_DRIVER_UIKIT */ diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h index c78396802..860852441 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.h @@ -1,23 +1,24 @@ /* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - */ + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" #import @@ -25,10 +26,17 @@ #include "SDL_touch.h" -#if SDL_IPHONE_KEYBOARD -@interface SDL_uikitviewcontroller : UIViewController +#if TARGET_OS_TV +#import +#define SDLRootViewController GCEventViewController #else -@interface SDL_uikitviewcontroller : UIViewController +#define SDLRootViewController UIViewController +#endif + +#if SDL_IPHONE_KEYBOARD +@interface SDL_uikitviewcontroller : SDLRootViewController +#else +@interface SDL_uikitviewcontroller : SDLRootViewController #endif @property (nonatomic, assign) SDL_Window *window; @@ -46,8 +54,11 @@ - (void)loadView; - (void)viewDidLayoutSubviews; + +#if !TARGET_OS_TV - (NSUInteger)supportedInterfaceOrientations; - (BOOL)prefersStatusBarHidden; +#endif #if SDL_IPHONE_KEYBOARD - (void)showKeyboard; diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m index 58cdf1ac5..e6e903ee4 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitviewcontroller.m @@ -33,11 +33,23 @@ #include "SDL_uikitvideo.h" #include "SDL_uikitmodes.h" #include "SDL_uikitwindow.h" +#include "SDL_uikitopengles.h" #if SDL_IPHONE_KEYBOARD #include "keyinfotable.h" #endif +#if TARGET_OS_TV +static void +SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + @autoreleasepool { + SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata; + viewcontroller.controllerUserInteractionEnabled = hint && (*hint != '0'); + } +} +#endif + @implementation SDL_uikitviewcontroller { CADisplayLink *displayLink; int animationInterval; @@ -59,6 +71,12 @@ #if SDL_IPHONE_KEYBOARD [self initKeyboard]; #endif + +#if TARGET_OS_TV + SDL_AddHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS, + SDL_AppleTVControllerUIHintChanged, + (__bridge void *) self); +#endif } return self; } @@ -68,6 +86,12 @@ #if SDL_IPHONE_KEYBOARD [self deinitKeyboard]; #endif + +#if TARGET_OS_TV + SDL_DelHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS, + SDL_AppleTVControllerUIHintChanged, + (__bridge void *) self); +#endif } - (void)setAnimationCallback:(int)interval @@ -102,6 +126,9 @@ { /* Don't run the game loop while a messagebox is up */ if (!UIKit_ShowingMessageBox()) { + /* See the comment in the function definition. */ + UIKit_GL_RestoreCurrentContext(); + animationCallback(animationCallbackParam); } } @@ -120,6 +147,7 @@ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h); } +#if !TARGET_OS_TV - (NSUInteger)supportedInterfaceOrientations { return UIKit_GetSupportedOrientations(window); @@ -134,6 +162,7 @@ { return (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0; } +#endif /* ---- Keyboard related functionality below this line ---- @@ -164,9 +193,11 @@ textField.hidden = YES; keyboardVisible = NO; +#if !TARGET_OS_TV NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; +#endif } - (void)setView:(UIView *)view @@ -182,9 +213,11 @@ - (void)deinitKeyboard { +#if !TARGET_OS_TV NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [center removeObserver:self name:UIKeyboardWillHideNotification object:nil]; +#endif } /* reveal onscreen virtual keyboard */ @@ -205,6 +238,7 @@ - (void)keyboardWillShow:(NSNotification *)notification { +#if !TARGET_OS_TV CGRect kbrect = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue]; /* The keyboard rect is in the coordinate space of the screen/window, but we @@ -212,10 +246,12 @@ kbrect = [self.view convertRect:kbrect fromView:nil]; [self setKeyboardHeight:(int)kbrect.size.height]; +#endif } - (void)keyboardWillHide:(NSNotification *)notification { + SDL_StopTextInput(); [self setKeyboardHeight:0]; } diff --git a/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m b/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m index c5f385b8c..35c549b43 100644 --- a/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m +++ b/Engine/lib/sdl/src/video/uikit/SDL_uikitwindow.m @@ -99,14 +99,13 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo /* only one window on iOS, always shown */ window->flags &= ~SDL_WINDOW_HIDDEN; - if (displaydata.uiscreen == [UIScreen mainScreen]) { - window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */ - } else { + if (displaydata.uiscreen != [UIScreen mainScreen]) { window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizable */ window->flags &= ~SDL_WINDOW_INPUT_FOCUS; /* never has input focus */ window->flags |= SDL_WINDOW_BORDERLESS; /* never has a status bar. */ } +#if !TARGET_OS_TV if (displaydata.uiscreen == [UIScreen mainScreen]) { NSUInteger orients = UIKit_GetSupportedOrientations(window); BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0; @@ -119,6 +118,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo height = temp; } } +#endif /* !TARGET_OS_TV */ window->x = 0; window->y = 0; @@ -152,7 +152,6 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) @autoreleasepool { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; - const CGSize origsize = data.uiscreen.currentMode.size; /* SDL currently puts this window at the start of display's linked list. We rely on this. */ SDL_assert(_this->windows == window); @@ -165,6 +164,8 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the * user, so it's in standby), try to force the display to a resolution * that most closely matches the desired window size. */ +#if !TARGET_OS_TV + const CGSize origsize = data.uiscreen.currentMode.size; if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) { if (display->num_display_modes == 0) { _this->GetDisplayModes(_this, display); @@ -197,6 +198,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) [UIApplication sharedApplication].statusBarHidden = NO; } } +#endif /* !TARGET_OS_TV */ /* ignore the size user requested, and make a fullscreen window */ /* !!! FIXME: can we have a smaller view? */ @@ -258,6 +260,7 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; SDL_uikitviewcontroller *viewcontroller = data.viewcontroller; +#if !TARGET_OS_TV if (data.uiwindow.screen == [UIScreen mainScreen]) { if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) { [UIApplication sharedApplication].statusBarHidden = YES; @@ -273,6 +276,7 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) /* Update the view's frame to account for the status bar change. */ viewcontroller.view.frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen); +#endif /* !TARGET_OS_TV */ #ifdef SDL_IPHONE_KEYBOARD /* Make sure the view is offset correctly when the keyboard is visible. */ @@ -363,6 +367,7 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) } } +#if !TARGET_OS_TV NSUInteger UIKit_GetSupportedOrientations(SDL_Window * window) { @@ -428,6 +433,7 @@ UIKit_GetSupportedOrientations(SDL_Window * window) return orientationMask; } +#endif /* !TARGET_OS_TV */ int SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam) diff --git a/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c b/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c index fe4ea089d..0372de5c3 100644 --- a/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c +++ b/Engine/lib/sdl/src/video/vivante/SDL_vivantevideo.c @@ -77,7 +77,7 @@ VIVANTE_Create() device->driverdata = data; - /* Setup amount of available displays and current display */ + /* Setup amount of available displays */ device->num_displays = 0; /* Set device free function */ @@ -366,12 +366,13 @@ VIVANTE_HideWindow(_THIS, SDL_Window * window) SDL_bool VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { -/* SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0); if (info->version.major == SDL_MAJOR_VERSION && info->version.minor == SDL_MINOR_VERSION) { info->subsystem = SDL_SYSWM_VIVANTE; + info->info.vivante.display = displaydata->native_display; info->info.vivante.window = data->native_window; return SDL_TRUE; } else { @@ -379,9 +380,6 @@ VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) SDL_MAJOR_VERSION, SDL_MINOR_VERSION); return SDL_FALSE; } -*/ - SDL_Unsupported(); - return SDL_FALSE; } /*****************************************************************************/ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c index bc1d06e46..14674fbe2 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.c @@ -94,9 +94,6 @@ WAYLAND_GetSym(const char *fnname, int *pHasModule) #define SDL_WAYLAND_SYM(rc,fn,params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL; #define SDL_WAYLAND_INTERFACE(iface) const struct wl_interface *WAYLAND_##iface = NULL; #include "SDL_waylandsym.h" -#undef SDL_WAYLAND_MODULE -#undef SDL_WAYLAND_SYM -#undef SDL_WAYLAND_INTERFACE static int wayland_load_refcount = 0; @@ -115,9 +112,6 @@ SDL_WAYLAND_UnloadSymbols(void) #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = NULL; #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = NULL; #include "SDL_waylandsym.h" -#undef SDL_WAYLAND_MODULE -#undef SDL_WAYLAND_SYM -#undef SDL_WAYLAND_INTERFACE #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC @@ -150,20 +144,12 @@ SDL_WAYLAND_LoadSymbols(void) } #define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */ -#define SDL_WAYLAND_SYM(rc,fn,params) -#define SDL_WAYLAND_INTERFACE(iface) #include "SDL_waylandsym.h" -#undef SDL_WAYLAND_MODULE -#undef SDL_WAYLAND_SYM -#undef SDL_WAYLAND_INTERFACE #define SDL_WAYLAND_MODULE(modname) thismod = &SDL_WAYLAND_HAVE_##modname; #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn) WAYLAND_GetSym(#fn,thismod); #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = (struct wl_interface *) WAYLAND_GetSym(#iface,thismod); #include "SDL_waylandsym.h" -#undef SDL_WAYLAND_MODULE -#undef SDL_WAYLAND_SYM -#undef SDL_WAYLAND_INTERFACE if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT) { /* all required symbols loaded. */ @@ -180,9 +166,6 @@ SDL_WAYLAND_LoadSymbols(void) #define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = fn; #define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = &iface; #include "SDL_waylandsym.h" -#undef SDL_WAYLAND_MODULE -#undef SDL_WAYLAND_SYM -#undef SDL_WAYLAND_INTERFACE #endif } diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h index b3ff9d8e9..f1f652566 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylanddyn.h @@ -53,10 +53,7 @@ void SDL_WAYLAND_UnloadSymbols(void); extern SDL_DYNWAYLANDFN_##fn WAYLAND_##fn; #define SDL_WAYLAND_INTERFACE(iface) extern const struct wl_interface *WAYLAND_##iface; #include "SDL_waylandsym.h" -#undef SDL_WAYLAND_MODULE -#undef SDL_WAYLAND_SYM -#undef SDL_WAYLAND_INTERFACE - + #ifdef __cplusplus } @@ -79,6 +76,7 @@ void SDL_WAYLAND_UnloadSymbols(void); #define wl_proxy_get_user_data (*WAYLAND_wl_proxy_get_user_data) #define wl_proxy_add_listener (*WAYLAND_wl_proxy_add_listener) #define wl_proxy_marshal_constructor (*WAYLAND_wl_proxy_marshal_constructor) +#define wl_proxy_marshal_constructor_versioned (*WAYLAND_wl_proxy_marshal_constructor_versioned) #define wl_seat_interface (*WAYLAND_wl_seat_interface) #define wl_surface_interface (*WAYLAND_wl_surface_interface) @@ -96,7 +94,8 @@ void SDL_WAYLAND_UnloadSymbols(void); #endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ -#include "wayland-client.h" +#include "wayland-client-core.h" +#include "wayland-client-protocol.h" #include "wayland-egl.h" #endif /* !defined _SDL_waylanddyn_h */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c index 53b0ac907..2443aef7a 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents.c @@ -25,6 +25,7 @@ #include "SDL_stdinc.h" #include "SDL_assert.h" +#include "SDL_log.h" #include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" @@ -36,11 +37,13 @@ #include "SDL_waylanddyn.h" +#include "pointer-constraints-unstable-v1-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" + #include #include #include #include -#include #include #include @@ -49,13 +52,17 @@ struct SDL_WaylandInput { struct wl_seat *seat; struct wl_pointer *pointer; struct wl_keyboard *keyboard; + struct zwp_relative_pointer_v1 *relative_pointer; SDL_WindowData *pointer_focus; SDL_WindowData *keyboard_focus; /* Last motion location */ wl_fixed_t sx_w; wl_fixed_t sy_w; - + + double dx_frac; + double dy_frac; + struct { struct xkb_keymap *keymap; struct xkb_state *state; @@ -171,10 +178,9 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) } static void -pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, - uint32_t time, uint32_t button, uint32_t state_w) +pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state_w) { - struct SDL_WaylandInput *input = data; SDL_WindowData *window = input->pointer_focus; enum wl_pointer_button_state state = state_w; uint32_t sdl_button; @@ -183,7 +189,7 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, switch (button) { case BTN_LEFT: sdl_button = SDL_BUTTON_LEFT; - if (ProcessHitTest(data, serial)) { + if (ProcessHitTest(input, serial)) { return; /* don't pass this event on to app. */ } break; @@ -209,10 +215,18 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, } static void -pointer_handle_axis(void *data, struct wl_pointer *pointer, - uint32_t time, uint32_t axis, wl_fixed_t value) +pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state_w) { struct SDL_WaylandInput *input = data; + + pointer_handle_button_common(input, serial, time, button, state_w); +} + +static void +pointer_handle_axis_common(struct SDL_WaylandInput *input, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ SDL_WindowData *window = input->pointer_focus; enum wl_pointer_axis a = axis; int x, y; @@ -235,6 +249,15 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer, } } +static void +pointer_handle_axis(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ + struct SDL_WaylandInput *input = data; + + pointer_handle_axis_common(input, time, axis, value); +} + static const struct wl_pointer_listener pointer_listener = { pointer_handle_enter, pointer_handle_leave, @@ -302,9 +325,9 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, window = wl_surface_get_user_data(surface); - input->keyboard_focus = window; - window->keyboard_device = input; if (window) { + input->keyboard_focus = window; + window->keyboard_device = input; SDL_SetKeyboardFocus(window->sdlwindow); } } @@ -454,6 +477,164 @@ void Wayland_display_destroy_input(SDL_VideoData *d) d->input = NULL; } +void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id) +{ + d->relative_pointer_manager = + wl_registry_bind(d->registry, id, + &zwp_relative_pointer_manager_v1_interface, 1); +} + +void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d) +{ + if (d->relative_pointer_manager) + zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager); +} + +void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id) +{ + d->pointer_constraints = + wl_registry_bind(d->registry, id, + &zwp_pointer_constraints_v1_interface, 1); +} + +void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d) +{ + if (d->pointer_constraints) + zwp_pointer_constraints_v1_destroy(d->pointer_constraints); +} + +static void +relative_pointer_handle_relative_motion(void *data, + struct zwp_relative_pointer_v1 *pointer, + uint32_t time_hi, + uint32_t time_lo, + wl_fixed_t dx_w, + wl_fixed_t dy_w, + wl_fixed_t dx_unaccel_w, + wl_fixed_t dy_unaccel_w) +{ + struct SDL_WaylandInput *input = data; + SDL_VideoData *d = input->display; + SDL_WindowData *window = input->pointer_focus; + double dx_unaccel; + double dy_unaccel; + double dx; + double dy; + + dx_unaccel = wl_fixed_to_double(dx_unaccel_w); + dy_unaccel = wl_fixed_to_double(dy_unaccel_w); + + /* Add left over fraction from last event. */ + dx_unaccel += input->dx_frac; + dy_unaccel += input->dy_frac; + + input->dx_frac = modf(dx_unaccel, &dx); + input->dy_frac = modf(dy_unaccel, &dy); + + if (input->pointer_focus && d->relative_mouse_mode) { + SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy); + } +} + +static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = { + relative_pointer_handle_relative_motion, +}; + +static void +locked_pointer_locked(void *data, + struct zwp_locked_pointer_v1 *locked_pointer) +{ +} + +static void +locked_pointer_unlocked(void *data, + struct zwp_locked_pointer_v1 *locked_pointer) +{ +} + +static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = { + locked_pointer_locked, + locked_pointer_unlocked, +}; + +static void +lock_pointer_to_window(SDL_Window *window, + struct SDL_WaylandInput *input) +{ + SDL_WindowData *w = window->driverdata; + SDL_VideoData *d = input->display; + struct zwp_locked_pointer_v1 *locked_pointer; + + if (w->locked_pointer) + return; + + locked_pointer = + zwp_pointer_constraints_v1_lock_pointer(d->pointer_constraints, + w->surface, + input->pointer, + NULL, + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + zwp_locked_pointer_v1_add_listener(locked_pointer, + &locked_pointer_listener, + window); + + w->locked_pointer = locked_pointer; +} + +int Wayland_input_lock_pointer(struct SDL_WaylandInput *input) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *d = input->display; + SDL_Window *window; + struct zwp_relative_pointer_v1 *relative_pointer; + + if (!d->relative_pointer_manager) + return -1; + + if (!d->pointer_constraints) + return -1; + + if (!input->relative_pointer) { + relative_pointer = + zwp_relative_pointer_manager_v1_get_relative_pointer( + d->relative_pointer_manager, + input->pointer); + zwp_relative_pointer_v1_add_listener(relative_pointer, + &relative_pointer_listener, + input); + input->relative_pointer = relative_pointer; + } + + for (window = vd->windows; window; window = window->next) + lock_pointer_to_window(window, input); + + d->relative_mouse_mode = 1; + + return 0; +} + +int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *d = input->display; + SDL_Window *window; + SDL_WindowData *w; + + for (window = vd->windows; window; window = window->next) { + w = window->driverdata; + if (w->locked_pointer) + zwp_locked_pointer_v1_destroy(w->locked_pointer); + w->locked_pointer = NULL; + } + + zwp_relative_pointer_v1_destroy(input->relative_pointer); + input->relative_pointer = NULL; + + d->relative_mouse_mode = 0; + + return 0; +} + #endif /* SDL_VIDEO_DRIVER_WAYLAND */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h index 62b163bf6..56d12ec27 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandevents_c.h @@ -32,6 +32,15 @@ extern void Wayland_PumpEvents(_THIS); extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id); extern void Wayland_display_destroy_input(SDL_VideoData *d); +extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id); +extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d); + +extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input); +extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input); + +extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id); +extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d); + #endif /* _SDL_waylandevents_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c index b810f7784..8dfc9eea3 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandmouse.c @@ -27,7 +27,6 @@ #define _GNU_SOURCE #endif -#include #include #include #include @@ -70,7 +69,6 @@ wayland_create_tmp_file(off_t size) xdg_path = SDL_getenv("XDG_RUNTIME_DIR"); if (!xdg_path) { - errno = ENOENT; return -1; } @@ -116,8 +114,7 @@ create_buffer_from_shm(Wayland_CursorData *d, shm_fd = wayland_create_tmp_file(size); if (shm_fd < 0) { - fprintf(stderr, "creating mouse cursor buffer failed!\n"); - return -1; + return SDL_SetError("Creating mouse cursor buffer failed."); } d->shm_data = mmap(NULL, @@ -128,8 +125,8 @@ create_buffer_from_shm(Wayland_CursorData *d, 0); if (d->shm_data == MAP_FAILED) { d->shm_data = NULL; - fprintf (stderr, "mmap () failed\n"); close (shm_fd); + return SDL_SetError("mmap() failed."); } shm_pool = wl_shm_create_pool(data->shm, shm_fd, size); @@ -159,6 +156,11 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) SDL_VideoDevice *vd = SDL_GetVideoDevice (); SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata; Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData)); + if (!data) { + SDL_OutOfMemory(); + free(cursor); + return NULL; + } cursor->driverdata = (void *) data; /* Assume ARGB8888 */ @@ -169,7 +171,7 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) if (create_buffer_from_shm (data, surface->w, surface->h, - WL_SHM_FORMAT_XRGB8888) < 0) + WL_SHM_FORMAT_ARGB8888) < 0) { free (cursor->driverdata); free (cursor); @@ -187,6 +189,8 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) data->hot_y = hot_y; data->w = surface->w; data->h = surface->h; + } else { + SDL_OutOfMemory(); } return cursor; @@ -200,6 +204,11 @@ CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor) cursor = calloc(1, sizeof (*cursor)); if (cursor) { Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData)); + if (!data) { + SDL_OutOfMemory(); + free(cursor); + return NULL; + } cursor->driverdata = (void *) data; data->buffer = WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]); @@ -322,13 +331,13 @@ Wayland_ShowCursor(SDL_Cursor *cursor) { Wayland_CursorData *data = cursor->driverdata; - wl_surface_attach(data->surface, data->buffer, 0, 0); - wl_surface_damage(data->surface, 0, 0, data->w, data->h); - wl_surface_commit(data->surface); wl_pointer_set_cursor (pointer, 0, data->surface, data->hot_x, data->hot_y); + wl_surface_attach(data->surface, data->buffer, 0, 0); + wl_surface_damage(data->surface, 0, 0, data->w, data->h); + wl_surface_commit(data->surface); } else { @@ -356,7 +365,13 @@ Wayland_WarpMouseGlobal(int x, int y) static int Wayland_SetRelativeMouseMode(SDL_bool enabled) { - return SDL_Unsupported(); + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *data = (SDL_VideoData *) vd->driverdata; + + if (enabled) + return Wayland_input_lock_pointer(data->input); + else + return Wayland_input_unlock_pointer(data->input); } void diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h index b093d9db1..aea3cb129 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandsym.h @@ -21,6 +21,18 @@ /* *INDENT-OFF* */ +#ifndef SDL_WAYLAND_MODULE +#define SDL_WAYLAND_MODULE(modname) +#endif + +#ifndef SDL_WAYLAND_SYM +#define SDL_WAYLAND_SYM(rc,fn,params) +#endif + +#ifndef SDL_WAYLAND_INTERFACE +#define SDL_WAYLAND_INTERFACE(iface) +#endif + SDL_WAYLAND_MODULE(WAYLAND_CLIENT) SDL_WAYLAND_SYM(void, wl_proxy_marshal, (struct wl_proxy *, uint32_t, ...)) SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_create, (struct wl_proxy *, const struct wl_interface *)) @@ -55,6 +67,9 @@ SDL_WAYLAND_SYM(void, wl_list_insert_list, (struct wl_list *, struct wl_list *)) SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_4) SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_proxy *, uint32_t opcode, const struct wl_interface *interface, ...)) +SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10) +SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...)) + SDL_WAYLAND_INTERFACE(wl_seat_interface) SDL_WAYLAND_INTERFACE(wl_surface_interface) SDL_WAYLAND_INTERFACE(wl_shm_pool_interface) @@ -99,8 +114,10 @@ SDL_WAYLAND_SYM(enum xkb_state_component, xkb_state_update_mask, (struct xkb_sta xkb_layout_index_t latched_layout,\ xkb_layout_index_t locked_layout) ) +#undef SDL_WAYLAND_MODULE +#undef SDL_WAYLAND_SYM +#undef SDL_WAYLAND_INTERFACE /* *INDENT-ON* */ /* vi: set ts=4 sw=4 expandtab: */ -//SDL_WAYLAND_SYM(ret, fn, params) diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c index b47ec29be..554b0ecad 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.c @@ -35,6 +35,8 @@ #include "SDL_waylandmouse.h" #include "SDL_waylandtouch.h" +#include +#include #include #include @@ -55,6 +57,56 @@ Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); static void Wayland_VideoQuit(_THIS); +/* Find out what class name we should use + * Based on src/video/x11/SDL_x11video.c */ +static char * +get_classname() +{ + char *spot; +#if defined(__LINUX__) || defined(__FREEBSD__) + char procfile[1024]; + char linkfile[1024]; + int linksize; +#endif + + /* First allow environment variable override */ + spot = SDL_getenv("SDL_VIDEO_WAYLAND_WMCLASS"); + if (spot) { + return SDL_strdup(spot); + } else { + /* Fallback to the "old" envvar */ + spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS"); + if (spot) { + return SDL_strdup(spot); + } + } + + /* Next look at the application's executable name */ +#if defined(__LINUX__) || defined(__FREEBSD__) +#if defined(__LINUX__) + SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid()); +#elif defined(__FREEBSD__) + SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", + getpid()); +#else +#error Where can we find the executable name? +#endif + linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1); + if (linksize > 0) { + linkfile[linksize] = '\0'; + spot = SDL_strrchr(linkfile, '/'); + if (spot) { + return SDL_strdup(spot + 1); + } else { + return SDL_strdup(linkfile); + } + } +#endif /* __LINUX__ || __FREEBSD__ */ + + /* Finally use the default we've used forever */ + return SDL_strdup("SDL_App"); +} + /* Wayland driver bootstrap functions */ static int Wayland_Available(void) @@ -117,7 +169,10 @@ Wayland_CreateDevice(int devindex) device->CreateWindow = Wayland_CreateWindow; device->ShowWindow = Wayland_ShowWindow; device->SetWindowFullscreen = Wayland_SetWindowFullscreen; + device->MaximizeWindow = Wayland_MaximizeWindow; + device->RestoreWindow = Wayland_RestoreWindow; device->SetWindowSize = Wayland_SetWindowSize; + device->SetWindowTitle = Wayland_SetWindowTitle; device->DestroyWindow = Wayland_DestroyWindow; device->SetWindowHitTest = Wayland_SetWindowHitTest; @@ -145,7 +200,7 @@ display_handle_geometry(void *data, { SDL_VideoDisplay *display = data; - display->name = strdup(model); + display->name = SDL_strdup(model); display->driverdata = output; } @@ -253,8 +308,10 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, } else if (strcmp(interface, "wl_shm") == 0) { d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm); - d->default_cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr"); - + } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) { + Wayland_display_add_relative_pointer_manager(d, id); + } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) { + Wayland_display_add_pointer_constraints(d, id); #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH } else if (strcmp(interface, "qt_touch_extension") == 0) { Wayland_touch_create(d, id); @@ -283,6 +340,11 @@ Wayland_VideoInit(_THIS) _this->driverdata = data; + data->xkb_context = WAYLAND_xkb_context_new(0); + if (!data->xkb_context) { + return SDL_SetError("Failed to create XKB context"); + } + data->display = WAYLAND_wl_display_connect(NULL); if (data->display == NULL) { return SDL_SetError("Failed to connect to a Wayland display"); @@ -301,13 +363,11 @@ Wayland_VideoInit(_THIS) // Second roundtrip to receive all output events. WAYLAND_wl_display_roundtrip(data->display); - data->xkb_context = WAYLAND_xkb_context_new(0); - if (!data->xkb_context) { - return SDL_SetError("Failed to create XKB context"); - } - Wayland_InitMouse(); + /* Get the surface class name, usually the name of the application */ + data->classname = get_classname(); + WAYLAND_wl_display_flush(data->display); return 0; @@ -341,6 +401,8 @@ Wayland_VideoQuit(_THIS) } Wayland_display_destroy_input(data); + Wayland_display_destroy_pointer_constraints(data); + Wayland_display_destroy_relative_pointer_manager(data); if (data->xkb_context) { WAYLAND_xkb_context_unref(data->xkb_context); @@ -376,6 +438,7 @@ Wayland_VideoQuit(_THIS) WAYLAND_wl_display_disconnect(data->display); } + SDL_free(data->classname); free(data); _this->driverdata = NULL; } diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h index 8111bf153..ccd7ecf92 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandvideo.h @@ -42,9 +42,10 @@ typedef struct { struct wl_compositor *compositor; struct wl_shm *shm; struct wl_cursor_theme *cursor_theme; - struct wl_cursor *default_cursor; struct wl_pointer *pointer; struct wl_shell *shell; + struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; + struct zwp_pointer_constraints_v1 *pointer_constraints; EGLDisplay edpy; EGLContext context; @@ -58,6 +59,10 @@ typedef struct { struct qt_surface_extension *surface_extension; struct qt_windowmanager *windowmanager; #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + + char *classname; + + int relative_mouse_mode; } SDL_VideoData; #endif /* _SDL_waylandvideo_h */ diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c index b59759a7c..85fca8de6 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.c @@ -26,6 +26,7 @@ #include "../SDL_sysvideo.h" #include "../../events/SDL_windowevents_c.h" #include "../SDL_egl_c.h" +#include "SDL_waylandevents_c.h" #include "SDL_waylandwindow.h" #include "SDL_waylandvideo.h" #include "SDL_waylandtouch.h" @@ -46,6 +47,33 @@ handle_configure(void *data, struct wl_shell_surface *shell_surface, SDL_Window *window = wind->sdlwindow; struct wl_region *region; + /* wl_shell_surface spec states that this is a suggestion. + Ignore if less than or greater than max/min size. */ + + if (width == 0 || height == 0) { + return; + } + + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + if ((window->flags & SDL_WINDOW_RESIZABLE)) { + if (window->max_w > 0) { + width = SDL_min(width, window->max_w); + } + width = SDL_max(width, window->min_w); + + if (window->max_h > 0) { + height = SDL_min(height, window->max_h); + } + height = SDL_max(height, window->min_h); + } else { + return; + } + } + + if (width == window->w && height == window->h) { + return; + } + window->w = width; window->h = height; WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0); @@ -145,6 +173,26 @@ Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); } +void +Wayland_RestoreWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + + wl_shell_surface_set_toplevel(wind->shell_surface); + + WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); +} + +void +Wayland_MaximizeWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + + wl_shell_surface_set_maximized(wind->shell_surface, NULL); + + WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); +} + int Wayland_CreateWindow(_THIS, SDL_Window *window) { SDL_WindowData *data; @@ -178,6 +226,7 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) wl_surface_set_user_data(data->surface, data); data->shell_surface = wl_shell_get_shell_surface(c->shell, data->surface); + wl_shell_surface_set_class (data->shell_surface, c->classname); #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH if (c->surface_extension) { data->extended_surface = qt_surface_extension_get_extended_surface( @@ -214,6 +263,10 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) wl_surface_set_opaque_region(data->surface, region); wl_region_destroy(region); + if (c->relative_mouse_mode) { + Wayland_input_lock_pointer(c->input); + } + WAYLAND_wl_display_flush(c->display); return 0; @@ -233,6 +286,17 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window) wl_region_destroy(region); } +void Wayland_SetWindowTitle(_THIS, SDL_Window * window) +{ + SDL_WindowData *wind = window->driverdata; + + if (window->title != NULL) { + wl_shell_surface_set_title(wind->shell_surface, window->title); + } + + WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display ); +} + void Wayland_DestroyWindow(_THIS, SDL_Window *window) { SDL_VideoData *data = _this->driverdata; diff --git a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h index 053b1281f..319a573dc 100644 --- a/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h +++ b/Engine/lib/sdl/src/video/wayland/SDL_waylandwindow.h @@ -39,6 +39,7 @@ typedef struct { struct wl_egl_window *egl_window; struct SDL_WaylandInput *keyboard_device; EGLSurface egl_surface; + struct zwp_locked_pointer_v1 *locked_pointer; #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH struct qt_extended_surface *extended_surface; @@ -49,8 +50,11 @@ extern void Wayland_ShowWindow(_THIS, SDL_Window *window); extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen); +extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window); +extern void Wayland_RestoreWindow(_THIS, SDL_Window * window); extern int Wayland_CreateWindow(_THIS, SDL_Window *window); extern void Wayland_SetWindowSize(_THIS, SDL_Window * window); +extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window); extern void Wayland_DestroyWindow(_THIS, SDL_Window *window); extern SDL_bool diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c index 61420894f..02768fb68 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsevents.c @@ -198,13 +198,26 @@ WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam) return code; } +static SDL_bool +WIN_ShouldIgnoreFocusClick() +{ + return !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE); +} void WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID) { - if (data->focus_click_pending && button == SDL_BUTTON_LEFT && !bwParamMousePressed) { - data->focus_click_pending = SDL_FALSE; - WIN_UpdateClipCursor(data->window); + if (data->focus_click_pending & SDL_BUTTON(button)) { + /* Ignore the button click for activation */ + if (!bwParamMousePressed) { + data->focus_click_pending &= ~SDL_BUTTON(button); + if (!data->focus_click_pending) { + WIN_UpdateClipCursor(data->window); + } + } + if (WIN_ShouldIgnoreFocusClick()) { + return; + } } if (bwParamMousePressed && !bSDLMousePressed) { @@ -326,17 +339,7 @@ WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text) static SDL_bool ShouldGenerateWindowCloseOnAltF4(void) { - const char *hint; - - hint = SDL_GetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4); - if (hint) { - if (*hint == '0') { - return SDL_TRUE; - } else { - return SDL_FALSE; - } - } - return SDL_TRUE; + return !SDL_GetHintBoolean(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, SDL_FALSE); } LRESULT CALLBACK @@ -398,8 +401,24 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) minimized = HIWORD(wParam); if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) { - data->focus_click_pending = (GetAsyncKeyState(VK_LBUTTON) != 0); - + if (LOWORD(wParam) == WA_CLICKACTIVE) { + if (GetAsyncKeyState(VK_LBUTTON)) { + data->focus_click_pending |= SDL_BUTTON_LMASK; + } + if (GetAsyncKeyState(VK_RBUTTON)) { + data->focus_click_pending |= SDL_BUTTON_RMASK; + } + if (GetAsyncKeyState(VK_MBUTTON)) { + data->focus_click_pending |= SDL_BUTTON_MMASK; + } + if (GetAsyncKeyState(VK_XBUTTON1)) { + data->focus_click_pending |= SDL_BUTTON_X1MASK; + } + if (GetAsyncKeyState(VK_XBUTTON2)) { + data->focus_click_pending |= SDL_BUTTON_X2MASK; + } + } + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); if (SDL_GetKeyboardFocus() != data->window) { SDL_SetKeyboardFocus(data->window); @@ -423,6 +442,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (SDL_GetKeyboardFocus() == data->window) { SDL_SetKeyboardFocus(NULL); + WIN_ResetDeadKeys(); } ClipCursor(NULL); @@ -737,6 +757,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; #endif /* WM_GETMINMAXINFO */ + case WM_WINDOWPOSCHANGING: + + if (data->expected_resize) { + returnCode = 0; + } + break; + case WM_WINDOWPOSCHANGED: { RECT rect; @@ -763,6 +790,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) h = rect.bottom - rect.top; SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w, h); + + /* Forces a WM_PAINT event */ + InvalidateRect(hwnd, NULL, FALSE); } break; @@ -907,12 +937,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (buffer) { if (DragQueryFile(drop, i, buffer, size)) { char *file = WIN_StringToUTF8(buffer); - SDL_SendDropFile(file); + SDL_SendDropFile(data->window, file); SDL_free(file); } SDL_stack_free(buffer); } } + SDL_SendDropComplete(data->window); DragFinish(drop); return 0; } @@ -927,15 +958,17 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) const SDL_Point point = { (int) winpoint.x, (int) winpoint.y }; const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); switch (rc) { - case SDL_HITTEST_DRAGGABLE: return HTCAPTION; - case SDL_HITTEST_RESIZE_TOPLEFT: return HTTOPLEFT; - case SDL_HITTEST_RESIZE_TOP: return HTTOP; - case SDL_HITTEST_RESIZE_TOPRIGHT: return HTTOPRIGHT; - case SDL_HITTEST_RESIZE_RIGHT: return HTRIGHT; - case SDL_HITTEST_RESIZE_BOTTOMRIGHT: return HTBOTTOMRIGHT; - case SDL_HITTEST_RESIZE_BOTTOM: return HTBOTTOM; - case SDL_HITTEST_RESIZE_BOTTOMLEFT: return HTBOTTOMLEFT; - case SDL_HITTEST_RESIZE_LEFT: return HTLEFT; + #define POST_HIT_TEST(ret) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return ret; } + case SDL_HITTEST_DRAGGABLE: POST_HIT_TEST(HTCAPTION); + case SDL_HITTEST_RESIZE_TOPLEFT: POST_HIT_TEST(HTTOPLEFT); + case SDL_HITTEST_RESIZE_TOP: POST_HIT_TEST(HTTOP); + case SDL_HITTEST_RESIZE_TOPRIGHT: POST_HIT_TEST(HTTOPRIGHT); + case SDL_HITTEST_RESIZE_RIGHT: POST_HIT_TEST(HTRIGHT); + case SDL_HITTEST_RESIZE_BOTTOMRIGHT: POST_HIT_TEST(HTBOTTOMRIGHT); + case SDL_HITTEST_RESIZE_BOTTOM: POST_HIT_TEST(HTBOTTOM); + case SDL_HITTEST_RESIZE_BOTTOMLEFT: POST_HIT_TEST(HTBOTTOMLEFT); + case SDL_HITTEST_RESIZE_LEFT: POST_HIT_TEST(HTLEFT); + #undef POST_HIT_TEST case SDL_HITTEST_NORMAL: return HTCLIENT; } } @@ -1012,7 +1045,8 @@ HINSTANCE SDL_Instance = NULL; int SDL_RegisterApp(char *name, Uint32 style, void *hInst) { - WNDCLASS class; + WNDCLASSEX wcex; + TCHAR path[MAX_PATH]; /* Only do this once... */ if (app_registered) { @@ -1034,19 +1068,24 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst) } /* Register the application class */ - class.hCursor = NULL; - class.hIcon = - LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0, - LR_DEFAULTCOLOR); - class.lpszMenuName = NULL; - class.lpszClassName = SDL_Appname; - class.hbrBackground = NULL; - class.hInstance = SDL_Instance; - class.style = SDL_Appstyle; - class.lpfnWndProc = WIN_WindowProc; - class.cbWndExtra = 0; - class.cbClsExtra = 0; - if (!RegisterClass(&class)) { + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.hCursor = NULL; + wcex.hIcon = NULL; + wcex.hIconSm = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = SDL_Appname; + wcex.style = SDL_Appstyle; + wcex.hbrBackground = NULL; + wcex.lpfnWndProc = WIN_WindowProc; + wcex.hInstance = SDL_Instance; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + + /* Use the first icon as a default icon, like in the Explorer */ + GetModuleFileName(SDL_Instance, path, MAX_PATH); + ExtractIconEx(path, 0, &wcex.hIcon, &wcex.hIconSm, 1); + + if (!RegisterClassEx(&wcex)) { return SDL_SetError("Couldn't register application class"); } @@ -1058,7 +1097,7 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst) void SDL_UnregisterApp() { - WNDCLASS class; + WNDCLASSEX wcex; /* SDL_RegisterApp might not have been called before */ if (!app_registered) { @@ -1067,8 +1106,10 @@ SDL_UnregisterApp() --app_registered; if (app_registered == 0) { /* Check for any registered window classes. */ - if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) { + if (GetClassInfoEx(SDL_Instance, SDL_Appname, &wcex)) { UnregisterClass(SDL_Appname, SDL_Instance); + if (wcex.hIcon) DestroyIcon(wcex.hIcon); + if (wcex.hIconSm) DestroyIcon(wcex.hIconSm); } SDL_free(SDL_Appname); SDL_Appname = NULL; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c index d3e16c8bf..8271b0421 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.c @@ -157,11 +157,47 @@ WIN_QuitKeyboard(_THIS) #endif } +void +WIN_ResetDeadKeys() +{ + /* + if a deadkey has been typed, but not the next character (which the deadkey might modify), + this tries to undo the effect pressing the deadkey. + see: http://archives.miloush.net/michkap/archive/2006/09/10/748775.html + */ + BYTE keyboardState[256]; + WCHAR buffer[16]; + int keycode, scancode, result, i; + + GetKeyboardState(keyboardState); + + keycode = VK_SPACE; + scancode = MapVirtualKey(keycode, MAPVK_VK_TO_VSC); + if (scancode == 0) { + /* the keyboard doesn't have this key */ + return; + } + + for (i = 0; i < 5; i++) { + result = ToUnicode(keycode, scancode, keyboardState, (LPWSTR)buffer, 16, 0); + if (result > 0) { + /* success */ + return; + } + } +} + void WIN_StartTextInput(_THIS) { #ifndef SDL_DISABLE_WINDOWS_IME - SDL_Window *window = SDL_GetKeyboardFocus(); + SDL_Window *window; +#endif + + WIN_ResetDeadKeys(); + +#ifndef SDL_DISABLE_WINDOWS_IME + window = SDL_GetKeyboardFocus(); if (window) { HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; @@ -176,7 +212,13 @@ void WIN_StopTextInput(_THIS) { #ifndef SDL_DISABLE_WINDOWS_IME - SDL_Window *window = SDL_GetKeyboardFocus(); + SDL_Window *window; +#endif + + WIN_ResetDeadKeys(); + +#ifndef SDL_DISABLE_WINDOWS_IME + window = SDL_GetKeyboardFocus(); if (window) { HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h index d330d3871..84654d7b8 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowskeyboard.h @@ -27,6 +27,8 @@ extern void WIN_InitKeyboard(_THIS); extern void WIN_UpdateKeymap(void); extern void WIN_QuitKeyboard(_THIS); +extern void WIN_ResetDeadKeys(void); + extern void WIN_StartTextInput(_THIS); extern void WIN_StopTextInput(_THIS); extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c b/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c index b39df32fc..689e5bbc3 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmessagebox.c @@ -452,9 +452,9 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } /* Align the buttons to the right/bottom. */ - x = Size.cx - ButtonWidth - ButtonMargin; + x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons; y = Size.cy - ButtonHeight - ButtonMargin; - for (i = 0; i < messageboxdata->numbuttons; ++i) { + for (i = messageboxdata->numbuttons - 1; i >= 0; --i) { SDL_bool isDefault; if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { @@ -466,7 +466,7 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) FreeDialogData(dialog); return -1; } - x -= ButtonWidth + ButtonMargin; + x += ButtonWidth + ButtonMargin; } /* FIXME: If we have a parent window, get the Instance and HWND for them */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c index 91ed67f87..f172f9a3d 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.c @@ -23,6 +23,7 @@ #if SDL_VIDEO_DRIVER_WINDOWS #include "SDL_windowsvideo.h" +#include "../../../include/SDL_assert.h" /* Windows CE compatibility */ #ifndef CDS_FULLSCREEN @@ -69,40 +70,16 @@ WIN_GetMonitorDPI(HMONITOR hMonitor, return TRUE; } -static SDL_bool -WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) +static void +WIN_UpdateDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) { SDL_VideoData *vid_data = (SDL_VideoData *) _this->driverdata; - SDL_DisplayModeData *data; - DEVMODE devmode; + SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata; HDC hdc; - devmode.dmSize = sizeof(devmode); - devmode.dmDriverExtra = 0; - if (!EnumDisplaySettings(deviceName, index, &devmode)) { - return SDL_FALSE; - } - - data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); - if (!data) { - return SDL_FALSE; - } - data->DeviceMode = devmode; data->DeviceMode.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS); - data->ScaleX = 1.0f; - data->ScaleY = 1.0f; - data->DiagDPI = 0.0f; - data->HorzDPI = 0.0f; - data->VertDPI = 0.0f; - - /* Fill in the mode information */ - mode->format = SDL_PIXELFORMAT_UNKNOWN; - mode->w = devmode.dmPelsWidth; - mode->h = devmode.dmPelsHeight; - mode->refresh_rate = devmode.dmDisplayFrequency; - mode->driverdata = data; if (index == ENUM_CURRENT_SETTINGS && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) { @@ -112,8 +89,8 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod int logical_width = GetDeviceCaps( hdc, HORZRES ); int logical_height = GetDeviceCaps( hdc, VERTRES ); - data->ScaleX = (float)logical_width / devmode.dmPelsWidth; - data->ScaleY = (float)logical_height / devmode.dmPelsHeight; + data->ScaleX = (float)logical_width / data->DeviceMode.dmPelsWidth; + data->ScaleY = (float)logical_height / data->DeviceMode.dmPelsHeight; mode->w = logical_width; mode->h = logical_height; @@ -126,8 +103,8 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod dpi_data.vid_data = vid_data; dpi_data.mode = mode; dpi_data.mode_data = data; - monitor_rect.left = devmode.dmPosition.x; - monitor_rect.top = devmode.dmPosition.y; + monitor_rect.left = data->DeviceMode.dmPosition.x; + monitor_rect.top = data->DeviceMode.dmPosition.y; monitor_rect.right = monitor_rect.left + 1; monitor_rect.bottom = monitor_rect.top + 1; EnumDisplayMonitors(NULL, &monitor_rect, WIN_GetMonitorDPI, (LPARAM)&dpi_data); @@ -175,10 +152,10 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod } else if (bmi->bmiHeader.biBitCount == 4) { mode->format = SDL_PIXELFORMAT_INDEX4LSB; } - } else { + } else if (mode->format == SDL_PIXELFORMAT_UNKNOWN) { /* FIXME: Can we tell what this will be? */ - if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) { - switch (devmode.dmBitsPerPel) { + if ((data->DeviceMode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) { + switch (data->DeviceMode.dmBitsPerPel) { case 32: mode->format = SDL_PIXELFORMAT_RGB888; break; @@ -200,6 +177,42 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod } } } +} + +static SDL_bool +WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode) +{ + SDL_DisplayModeData *data; + DEVMODE devmode; + + devmode.dmSize = sizeof(devmode); + devmode.dmDriverExtra = 0; + if (!EnumDisplaySettings(deviceName, index, &devmode)) { + return SDL_FALSE; + } + + data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); + if (!data) { + return SDL_FALSE; + } + + mode->driverdata = data; + data->DeviceMode = devmode; + + /* Default basic information */ + data->ScaleX = 1.0f; + data->ScaleY = 1.0f; + data->DiagDPI = 0.0f; + data->HorzDPI = 0.0f; + data->VertDPI = 0.0f; + + mode->format = SDL_PIXELFORMAT_UNKNOWN; + mode->w = data->DeviceMode.dmPelsWidth; + mode->h = data->DeviceMode.dmPelsHeight; + mode->refresh_rate = data->DeviceMode.dmDisplayFrequency; + + /* Fill in the mode information */ + WIN_UpdateDisplayMode(_this, deviceName, index, mode); return SDL_TRUE; } @@ -329,7 +342,44 @@ WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, *vdpi = data->VertDPI; } - return data->DiagDPI != 0.0f ? 0 : -1; + return data->DiagDPI != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); +} + +int +WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +{ + const SDL_DisplayModeData *data = (const SDL_DisplayModeData *) display->current_mode.driverdata; + const DEVMODE *pDevMode = &data->DeviceMode; + POINT pt = { + /* !!! FIXME: no scale, right? */ + (LONG) (pDevMode->dmPosition.x + (pDevMode->dmPelsWidth / 2)), + (LONG) (pDevMode->dmPosition.y + (pDevMode->dmPelsHeight / 2)) + }; + HMONITOR hmon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); + MONITORINFO minfo; + const RECT *work; + BOOL rc = FALSE; + + SDL_assert(hmon != NULL); + + if (hmon != NULL) { + SDL_zero(minfo); + minfo.cbSize = sizeof (MONITORINFO); + rc = GetMonitorInfo(hmon, &minfo); + SDL_assert(rc); + } + + if (!rc) { + return SDL_SetError("Couldn't find monitor data"); + } + + work = &minfo.rcWork; + rect->x = (int)SDL_ceil(work->left * data->ScaleX); + rect->y = (int)SDL_ceil(work->top * data->ScaleY); + rect->w = (int)SDL_ceil((work->right - work->left) * data->ScaleX); + rect->h = (int)SDL_ceil((work->bottom - work->top) * data->ScaleY); + + return 0; } void @@ -366,7 +416,7 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) LONG status; if (mode->driverdata == display->desktop_mode.driverdata) { - status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL, 0, NULL); + status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL, CDS_FULLSCREEN, NULL); } else { status = ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode, NULL, CDS_FULLSCREEN, NULL); } @@ -389,6 +439,7 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason); } EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode); + WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode); return 0; } diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h index e725848b2..6aa293d21 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsmodes.h @@ -40,6 +40,7 @@ typedef struct extern int WIN_InitModes(_THIS); extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); +extern int WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); extern int WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c b/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c index 37199805b..21f63a018 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowsvideo.c @@ -124,6 +124,7 @@ WIN_CreateDevice(int devindex) device->VideoInit = WIN_VideoInit; device->VideoQuit = WIN_VideoQuit; device->GetDisplayBounds = WIN_GetDisplayBounds; + device->GetDisplayUsableBounds = WIN_GetDisplayUsableBounds; device->GetDisplayDPI = WIN_GetDisplayDPI; device->GetDisplayModes = WIN_GetDisplayModes; device->SetDisplayMode = WIN_SetDisplayMode; @@ -136,6 +137,7 @@ WIN_CreateDevice(int devindex) device->SetWindowIcon = WIN_SetWindowIcon; device->SetWindowPosition = WIN_SetWindowPosition; device->SetWindowSize = WIN_SetWindowSize; + device->SetWindowOpacity = WIN_SetWindowOpacity; device->ShowWindow = WIN_ShowWindow; device->HideWindow = WIN_HideWindow; device->RaiseWindow = WIN_RaiseWindow; @@ -143,6 +145,7 @@ WIN_CreateDevice(int devindex) device->MinimizeWindow = WIN_MinimizeWindow; device->RestoreWindow = WIN_RestoreWindow; device->SetWindowBordered = WIN_SetWindowBordered; + device->SetWindowResizable = WIN_SetWindowResizable; device->SetWindowFullscreen = WIN_SetWindowFullscreen; device->SetWindowGammaRamp = WIN_SetWindowGammaRamp; device->GetWindowGammaRamp = WIN_GetWindowGammaRamp; diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c index 26683a0ed..5ce40e6ba 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c +++ b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.c @@ -478,7 +478,8 @@ WIN_HideWindow(_THIS, SDL_Window * window) void WIN_RaiseWindow(_THIS, SDL_Window * window) { - WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE); + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + SetForegroundWindow(hwnd); } void @@ -519,6 +520,22 @@ WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) data->in_border_change = SDL_FALSE; } +void +WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + DWORD style = GetWindowLong(hwnd, GWL_STYLE); + + if (resizable) { + style |= STYLE_RESIZABLE; + } else { + style &= ~STYLE_RESIZABLE; + } + + SetWindowLong(hwnd, GWL_STYLE, style); +} + void WIN_RestoreWindow(_THIS, SDL_Window * window) { @@ -826,6 +843,39 @@ WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) return 0; /* just succeed, the real work is done elsewhere. */ } +int +WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ + const SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + const HWND hwnd = data->hwnd; + const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE); + + SDL_assert(style != 0); + + if (opacity == 1.0f) { + /* want it fully opaque, just mark it unlayered if necessary. */ + if (style & WS_EX_LAYERED) { + if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) { + return WIN_SetError("SetWindowLong()"); + } + } + } else { + const BYTE alpha = (BYTE) ((int) (opacity * 255.0f)); + /* want it transparent, mark it layered if necessary. */ + if ((style & WS_EX_LAYERED) == 0) { + if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) { + return WIN_SetError("SetWindowLong()"); + } + } + + if (SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA) == 0) { + return WIN_SetError("SetLayeredWindowAttributes()"); + } + } + + return 0; +} + #endif /* SDL_VIDEO_DRIVER_WINDOWS */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h index f91aa0ed2..7d50ba66e 100644 --- a/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h +++ b/Engine/lib/sdl/src/video/windows/SDL_windowswindow.h @@ -41,7 +41,7 @@ typedef struct SDL_bool expected_resize; SDL_bool in_border_change; SDL_bool in_title_click; - SDL_bool focus_click_pending; + Uint8 focus_click_pending; SDL_bool windowed_mode_was_maximized; SDL_bool in_window_deactivation; struct SDL_VideoData *videodata; @@ -56,6 +56,7 @@ extern void WIN_SetWindowTitle(_THIS, SDL_Window * window); extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void WIN_SetWindowPosition(_THIS, SDL_Window * window); extern void WIN_SetWindowSize(_THIS, SDL_Window * window); +extern int WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity); extern void WIN_ShowWindow(_THIS, SDL_Window * window); extern void WIN_HideWindow(_THIS, SDL_Window * window); extern void WIN_RaiseWindow(_THIS, SDL_Window * window); @@ -63,6 +64,7 @@ extern void WIN_MaximizeWindow(_THIS, SDL_Window * window); extern void WIN_MinimizeWindow(_THIS, SDL_Window * window); extern void WIN_RestoreWindow(_THIS, SDL_Window * window); extern void WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp index e9df726d4..30cf01633 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents.cpp @@ -40,6 +40,7 @@ using Windows::UI::Core::CoreCursor; #include "SDL_system.h" extern "C" { +#include "../../thread/SDL_systhread.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" } @@ -113,7 +114,7 @@ WINRT_CycleXAMLThread() _mutex = SDL_CreateMutex(); _threadState = ThreadState_Running; - _XAMLThread = SDL_CreateThread(WINRT_XAMLThreadMain, "SDL/XAML App Thread", nullptr); + _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr); SDL_LockMutex(_mutex); while (_threadState != ThreadState_Yielding) { diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h index dc94526bb..05a90a3bf 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtevents_c.h @@ -67,6 +67,13 @@ extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args); extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args); extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args); +#if NTDDI_VERSION >= NTDDI_WIN10 +extern SDL_bool WINRT_HasScreenKeyboardSupport(_THIS); +extern void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window); +extern void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window); +extern SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window); +#endif // NTDDI_VERSION >= ... + /* XAML Thread Management */ extern void WINRT_CycleXAMLThread(); diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp new file mode 100644 index 000000000..215dfcc83 --- /dev/null +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp @@ -0,0 +1,196 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_DRIVER_WINRT + +/* Windows includes */ +#include +#include +#include + + +/* SDL includes */ +extern "C" { +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +} +#include "SDL_winrtvideo_cpp.h" + + +/* Game Bar events can come in off the main thread. Use the following + WinRT CoreDispatcher to deal with them on SDL's thread. +*/ +static Platform::WeakReference WINRT_MainThreadDispatcher; + + +/* Win10's initial SDK (the 10.0.10240.0 release) does not include references + to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0. + + Declare its WinRT/COM interface here, to allow compilation with earlier + Windows SDKs. +*/ +MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7") +IGameBarStatics_ : public IInspectable +{ +public: + virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( + __FIEventHandler_1_IInspectable *handler, + Windows::Foundation::EventRegistrationToken *token) = 0; + + virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( + Windows::Foundation::EventRegistrationToken token) = 0; + + virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged( + __FIEventHandler_1_IInspectable *handler, + Windows::Foundation::EventRegistrationToken *token) = 0; + + virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged( + Windows::Foundation::EventRegistrationToken token) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Visible( + boolean *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected( + boolean *value) = 0; +}; + +/* Declare the game bar's COM GUID */ +static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } }; + +/* Retrieves a pointer to the game bar, or NULL if it is not available. + If a pointer is returned, it's ->Release() method must be called + after the caller has finished using it. +*/ +static IGameBarStatics_ * +WINRT_GetGameBar() +{ + wchar_t *wClassName = L"Windows.Gaming.UI.GameBar"; + HSTRING hClassName; + IActivationFactory *pActivationFactory = NULL; + IGameBarStatics_ *pGameBar = NULL; + HRESULT hr; + + hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); + if (FAILED(hr)) { + goto done; + } + + hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory); + if (FAILED(hr)) { + goto done; + } + + pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar); + +done: + if (pActivationFactory) { + pActivationFactory->Release(); + } + if (hClassName) { + ::WindowsDeleteString(hClassName); + } + return pGameBar; +} + +static void +WINRT_HandleGameBarIsInputRedirected_MainThread() +{ + IGameBarStatics_ *gameBar; + boolean isInputRedirected = 0; + if (!WINRT_MainThreadDispatcher) { + /* The game bar event handler has been deregistered! */ + return; + } + gameBar = WINRT_GetGameBar(); + if (!gameBar) { + /* Shouldn't happen, but just in case... */ + return; + } + if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) { + if ( ! isInputRedirected) { + /* Input-control is now back to the SDL app. Restore the cursor, + in case Windows does not (it does not in either Win10 + 10.0.10240.0 or 10.0.10586.0, maybe later version(s) too. + */ + SDL_Cursor *cursor = SDL_GetCursor(); + SDL_SetCursor(cursor); + } + } + gameBar->Release(); +} + +static void +WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2) +{ + Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve(); + if (dispatcher) { + dispatcher->RunAsync( + Windows::UI::Core::CoreDispatcherPriority::Normal, + ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread)); + } +} + +void +WINRT_InitGameBar(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + IGameBarStatics_ *gameBar = WINRT_GetGameBar(); + if (gameBar) { + /* GameBar.IsInputRedirected events can come in via something other than + the main/SDL thread. + + Get a WinRT 'CoreDispatcher' that can be used to call back into the + SDL thread. + */ + WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher; + Windows::Foundation::EventHandler ^handler = \ + ref new Windows::Foundation::EventHandler(&WINRT_HandleGameBarIsInputRedirected_NonMainThread); + __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler); + gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken); + gameBar->Release(); + } +} + +void +WINRT_QuitGameBar(_THIS) +{ + SDL_VideoData *driverdata; + IGameBarStatics_ *gameBar; + if (!_this || !_this->driverdata) { + return; + } + gameBar = WINRT_GetGameBar(); + if (!gameBar) { + return; + } + driverdata = (SDL_VideoData *)_this->driverdata; + if (driverdata->gameBarIsInputRedirectedToken.Value) { + gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken); + driverdata->gameBarIsInputRedirectedToken.Value = 0; + } + WINRT_MainThreadDispatcher = nullptr; + gameBar->Release(); +} + +#endif /* SDL_VIDEO_DRIVER_WINRT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h new file mode 100644 index 000000000..afcef37b2 --- /dev/null +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +#ifndef _SDL_winrtgamebar_h +#define _SDL_winrtgamebar_h + +#ifdef __cplusplus +/* These are exported as C++ functions, rather than C, to fix a compilation + bug with MSVC 2013, for Windows 8.x builds. */ +extern void WINRT_InitGameBar(_THIS); +extern void WINRT_QuitGameBar(_THIS); +#endif + +#endif /* _SDL_winrtmouse_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp index 7477cdeeb..affcae62b 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtkeyboard.cpp @@ -383,4 +383,48 @@ WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArg } } + +#if NTDDI_VERSION >= NTDDI_WIN10 + +SDL_bool WINRT_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + using namespace Windows::UI::ViewManagement; + InputPane ^ inputPane = InputPane::GetForCurrentView(); + if (inputPane) { + inputPane->TryShow(); + } +} + +void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window) +{ + using namespace Windows::UI::ViewManagement; + InputPane ^ inputPane = InputPane::GetForCurrentView(); + if (inputPane) { + inputPane->TryHide(); + } +} + +SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ + using namespace Windows::UI::ViewManagement; + InputPane ^ inputPane = InputPane::GetForCurrentView(); + if (inputPane) { + // dludwig@pobox.com: checking inputPane->Visible doesn't seem to detect visibility, + // at least not on the Windows Phone 10.0.10240.0 emulator. Checking + // the size of inputPane->OccludedRect, however, does seem to work. + Windows::Foundation::Rect rect = inputPane->OccludedRect; + if (rect.Width > 0 && rect.Height > 0) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +#endif // NTDDI_VERSION >= ... + #endif // SDL_VIDEO_DRIVER_WINRT diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp index d3140a4a4..9997d6ea4 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtmouse.cpp @@ -26,6 +26,7 @@ * Windows includes: */ #include +#include using namespace Windows::UI::Core; using Windows::UI::Core::CoreCursor; @@ -116,11 +117,69 @@ WINRT_ShowCursor(SDL_Cursor * cursor) return 0; } + CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread(); if (cursor) { CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata; - CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor; + coreWindow->PointerCursor = *theCursor; } else { - CoreWindow::GetForCurrentThread()->PointerCursor = nullptr; + // HACK ALERT: TL;DR - Hiding the cursor in WinRT/UWP apps is weird, and + // a Win32-style cursor resource file must be directly included in apps, + // otherwise hiding the cursor will cause mouse-motion data to never be + // received. + // + // Here's the lengthy explanation: + // + // There are two ways to hide a cursor in WinRT/UWP apps. + // Both involve setting the WinRT CoreWindow's (which is somewhat analogous + // to a Win32 HWND) 'PointerCursor' property. + // + // The first way to hide a cursor sets PointerCursor to nullptr. This + // is, arguably, the easiest to implement for an app. It does have an + // unfortunate side-effect: it'll prevent mouse-motion events from being + // sent to the app (via CoreWindow). + // + // The second way to hide a cursor sets PointerCursor to a transparent + // cursor. This allows mouse-motion events to be sent to the app, but is + // more difficult to set up, as: + // 1. WinRT/UWP, while providing a few stock cursors, does not provide + // a completely transparent cursor. + // 2. WinRT/UWP allows apps to provide custom-built cursors, but *ONLY* + // if they are linked directly inside the app, via Win32-style + // cursor resource files. APIs to create cursors at runtime are + // not provided to apps, and attempting to link-to or use Win32 + // cursor-creation APIs could cause an app to fail Windows Store + // certification. + // + // SDL can use either means of hiding the cursor. It provides a Win32-style + // set of cursor resource files in its source distribution, inside + // src/main/winrt/. If those files are linked to an SDL-for-WinRT/UWP app + // (by including them in a MSVC project, for example), SDL will attempt to + // use those, if and when the cursor is hidden via SDL APIs. If those + // files are not linked in, SDL will attempt to hide the cursor via the + // 'set PointerCursor to nullptr' means (which, if you recall, causes + // mouse-motion data to NOT be sent to the app!). + // + // Tech notes: + // - SDL's blank cursor resource uses a resource ID of 5000. + // - SDL's cursor resources consist of the following two files: + // - src/main/winrt/SDL2-WinRTResource_BlankCursor.cur -- cursor pixel data + // - src/main/winrt/SDL2-WinRTResources.rc -- declares the cursor resource, and its ID (of 5000) + // + + const unsigned int win32CursorResourceID = 5000; + CoreCursor ^ blankCursor = ref new CoreCursor(CoreCursorType::Custom, win32CursorResourceID); + + // Set 'PointerCursor' to 'blankCursor' in a way that shouldn't throw + // an exception if the app hasn't loaded that resource. + ABI::Windows::UI::Core::ICoreCursor * iblankCursor = reinterpret_cast(blankCursor); + ABI::Windows::UI::Core::ICoreWindow * icoreWindow = reinterpret_cast(coreWindow); + HRESULT hr = icoreWindow->put_PointerCursor(iblankCursor); + if (FAILED(hr)) { + // The app doesn't contain the cursor resource, or some other error + // occurred. Just use the other, but mouse-motion-preventing, means of + // hiding the cursor. + coreWindow->PointerCursor = nullptr; + } } return 0; } diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp index 9d7c1ccee..9a26705ad 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo.cpp @@ -31,6 +31,7 @@ /* Windows includes */ #include #include +#include #include #include using namespace Windows::ApplicationModel::Core; @@ -41,7 +42,8 @@ using namespace Windows::UI::ViewManagement; /* [re]declare Windows GUIDs locally, to limit the amount of external lib(s) SDL has to link to */ -static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48,{ 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; +static const GUID IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } }; +static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; /* SDL includes */ @@ -61,6 +63,7 @@ extern "C" { #include "../../core/winrt/SDL_winrtapp_xaml.h" #include "SDL_winrtvideo_cpp.h" #include "SDL_winrtevents_c.h" +#include "SDL_winrtgamebar_cpp.h" #include "SDL_winrtmouse_c.h" #include "SDL_main.h" #include "SDL_system.h" @@ -82,6 +85,11 @@ static void WINRT_DestroyWindow(_THIS, SDL_Window * window); static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info); +/* Misc functions */ +static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(_THIS); +extern void WINRT_SuspendScreenSaver(_THIS); + + /* SDL-internal globals: */ SDL_Window * WINRT_GlobalSDLWindow = NULL; @@ -118,18 +126,15 @@ WINRT_CreateDevice(int devindex) device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); - if (device) { - SDL_free(device); - } return (0); } data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); if (!data) { SDL_OutOfMemory(); + SDL_free(device); return (0); } - SDL_zerop(data); device->driverdata = data; /* Set the function pointers */ @@ -142,6 +147,15 @@ WINRT_CreateDevice(int devindex) device->SetDisplayMode = WINRT_SetDisplayMode; device->PumpEvents = WINRT_PumpEvents; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; + device->SuspendScreenSaver = WINRT_SuspendScreenSaver; + +#if NTDDI_VERSION >= NTDDI_WIN10 + device->HasScreenKeyboardSupport = WINRT_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard; + device->HideScreenKeyboard = WINRT_HideScreenKeyboard; + device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown; +#endif + #ifdef SDL_VIDEO_OPENGL_EGL device->GL_LoadLibrary = WINRT_GLES_LoadLibrary; device->GL_GetProcAddress = WINRT_GLES_GetProcAddress; @@ -167,12 +181,17 @@ VideoBootStrap WINRT_bootstrap = { int WINRT_VideoInit(_THIS) { + SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata; if (WINRT_InitModes(_this) < 0) { return -1; } WINRT_InitMouse(_this); WINRT_InitTouch(_this); - + WINRT_InitGameBar(_this); + if (driverdata) { + /* Initialize screensaver-disabling support */ + driverdata->displayRequest = WINRT_CreateDisplayRequest(_this); + } return 0; } @@ -414,6 +433,12 @@ WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) void WINRT_VideoQuit(_THIS) { + SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata; + if (driverdata && driverdata->displayRequest) { + driverdata->displayRequest->Release(); + driverdata->displayRequest = NULL; + } + WINRT_QuitGameBar(_this); WINRT_QuitMouse(_this); } @@ -483,7 +508,7 @@ WINRT_DetectWindowFlags(SDL_Window * window) // data->coreWindow->PointerPosition is not supported on WinPhone 8.0 latestFlags |= SDL_WINDOW_MOUSE_FOCUS; #else - if (data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) { + if (data->coreWindow->Visible && data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) { latestFlags |= SDL_WINDOW_MOUSE_FOCUS; } #endif @@ -753,6 +778,65 @@ WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) return SDL_FALSE; } +static ABI::Windows::System::Display::IDisplayRequest * +WINRT_CreateDisplayRequest(_THIS) +{ + /* Setup a WinRT DisplayRequest object, usable for enabling/disabling screensaver requests */ + wchar_t *wClassName = L"Windows.System.Display.DisplayRequest"; + HSTRING hClassName; + IActivationFactory *pActivationFactory = NULL; + IInspectable * pDisplayRequestRaw = nullptr; + ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest = nullptr; + HRESULT hr; + + hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); + if (FAILED(hr)) { + goto done; + } + + hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory); + if (FAILED(hr)) { + goto done; + } + + hr = pActivationFactory->ActivateInstance(&pDisplayRequestRaw); + if (FAILED(hr)) { + goto done; + } + + hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (void **) &pDisplayRequest); + if (FAILED(hr)) { + goto done; + } + +done: + if (pDisplayRequestRaw) { + pDisplayRequestRaw->Release(); + } + if (pActivationFactory) { + pActivationFactory->Release(); + } + if (hClassName) { + ::WindowsDeleteString(hClassName); + } + + return pDisplayRequest; +} + +void +WINRT_SuspendScreenSaver(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + if (driverdata && driverdata->displayRequest) { + ABI::Windows::System::Display::IDisplayRequest * displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->displayRequest; + if (_this->suspend_screensaver) { + displayRequest->RequestActive(); + } else { + displayRequest->RequestRelease(); + } + } +} + #endif /* SDL_VIDEO_DRIVER_WINRT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h index 26eb008d4..7d5ce13e0 100644 --- a/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/Engine/lib/sdl/src/video/winrt/SDL_winrtvideo_cpp.h @@ -46,6 +46,17 @@ typedef struct SDL_VideoData { * passed to eglGetDisplay and eglCreateWindowSurface: */ IUnknown *winrtEglWindow; + + /* Event token(s), for unregistering WinRT event handler(s). + These are just a struct with a 64-bit integer inside them + */ + Windows::Foundation::EventRegistrationToken gameBarIsInputRedirectedToken; + + /* A WinRT DisplayRequest, used for implementing SDL_*ScreenSaver() functions. + * This is really a pointer to a 'ABI::Windows::System::Display::IDisplayRequest *', + * It's casted to 'IUnknown *', to help with building SDL. + */ + IUnknown *displayRequest; } SDL_VideoData; /* The global, WinRT, SDL Window. diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c index 7cbfa3e97..d07fda740 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.c @@ -106,11 +106,8 @@ X11_GetSym(const char *fnname, int *pHasModule) #endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */ /* Define all the function pointers and wrappers... */ -#define SDL_X11_MODULE(modname) #define SDL_X11_SYM(rc,fn,params,args,ret) SDL_DYNX11FN_##fn X11_##fn = NULL; #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM /* Annoying varargs entry point... */ #ifdef X_HAVE_UTF8_STRING @@ -120,10 +117,7 @@ SDL_DYNX11FN_XGetICValues X11_XGetICValues = NULL; /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 0; -#define SDL_X11_SYM(rc,fn,params,args,ret) #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM static int x11_load_refcount = 0; @@ -139,8 +133,6 @@ SDL_X11_UnloadSymbols(void) #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0; #define SDL_X11_SYM(rc,fn,params,args,ret) X11_##fn = NULL; #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM #ifdef X_HAVE_UTF8_STRING X11_XCreateIC = NULL; @@ -177,16 +169,11 @@ SDL_X11_LoadSymbols(void) } #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */ -#define SDL_X11_SYM(a,fn,x,y,z) #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname; #define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod); #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM #ifdef X_HAVE_UTF8_STRING X11_XCreateIC = (SDL_DYNX11FN_XCreateIC) @@ -209,8 +196,6 @@ SDL_X11_LoadSymbols(void) #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */ #define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) fn; #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM #ifdef X_HAVE_UTF8_STRING X11_XCreateIC = XCreateIC; diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h index 136609b85..be1ddaa1c 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11dyn.h @@ -86,13 +86,10 @@ int SDL_X11_LoadSymbols(void); void SDL_X11_UnloadSymbols(void); /* Declare all the function pointers and wrappers... */ -#define SDL_X11_MODULE(modname) #define SDL_X11_SYM(rc,fn,params,args,ret) \ typedef rc (*SDL_DYNX11FN_##fn) params; \ extern SDL_DYNX11FN_##fn X11_##fn; #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM /* Annoying varargs entry point... */ #ifdef X_HAVE_UTF8_STRING @@ -104,10 +101,7 @@ extern SDL_DYNX11FN_XGetICValues X11_XGetICValues; /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */ #define SDL_X11_MODULE(modname) extern int SDL_X11_HAVE_##modname; -#define SDL_X11_SYM(rc,fn,params,args,ret) #include "SDL_x11sym.h" -#undef SDL_X11_MODULE -#undef SDL_X11_SYM #ifdef __cplusplus } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11events.c b/Engine/lib/sdl/src/video/x11/SDL_x11events.c index 208009607..56d2368a0 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11events.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11events.c @@ -35,6 +35,7 @@ #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_touch_c.h" +#include "SDL_hints.h" #include "SDL_timer.h" #include "SDL_syswm.h" @@ -117,7 +118,9 @@ static Atom X11_PickTarget(Display *disp, Atom list[], int list_count) int i; for (i=0; i < list_count && request == None; i++) { name = X11_XGetAtomName(disp, list[i]); - if (strcmp("text/uri-list", name)==0) request = list[i]; + if ((SDL_strcmp("text/uri-list", name) == 0) || (SDL_strcmp("text/plain", name) == 0)) { + request = list[i]; + } X11_XFree(name); } return request; @@ -377,8 +380,8 @@ X11_DispatchFocusIn(_THIS, SDL_WindowData *data) X11_XSetICFocus(data->ic); } #endif -#ifdef SDL_USE_IBUS - SDL_IBus_SetFocus(SDL_TRUE); +#ifdef SDL_USE_IME + SDL_IME_SetFocus(SDL_TRUE); #endif } @@ -400,8 +403,8 @@ X11_DispatchFocusOut(_THIS, SDL_WindowData *data) X11_XUnsetICFocus(data->ic); } #endif -#ifdef SDL_USE_IBUS - SDL_IBus_SetFocus(SDL_FALSE); +#ifdef SDL_USE_IME + SDL_IME_SetFocus(SDL_FALSE); #endif } @@ -512,11 +515,28 @@ ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev) return SDL_FALSE; } +static void +X11_UpdateUserTime(SDL_WindowData *data, const unsigned long latest) +{ + if (latest && (latest != data->user_time)) { + SDL_VideoData *videodata = data->videodata; + Display *display = videodata->display; + X11_XChangeProperty(display, data->xwindow, videodata->_NET_WM_USER_TIME, + XA_CARDINAL, 32, PropModeReplace, + (const unsigned char *) &latest, 1); +#ifdef DEBUG_XEVENTS + printf("window %p: updating _NET_WM_USER_TIME to %lu\n", data, latest); +#endif + data->user_time = latest; + } +} + + static void X11_DispatchEvent(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - Display *display = videodata->display; + Display *display; SDL_WindowData *data; XEvent xevent; int orig_event_type; @@ -524,6 +544,11 @@ X11_DispatchEvent(_THIS) XClientMessageEvent m; int i; + if (!videodata) { + return; + } + display = videodata->display; + SDL_zero(xevent); /* valgrind fix. --ryan. */ X11_XNextEvent(display, &xevent); @@ -545,15 +570,12 @@ X11_DispatchEvent(_THIS) #endif if (orig_keycode) { /* Make sure dead key press/release events are sent */ - /* Actually, don't do this because it causes double-delivery - of some keys on Ubuntu 14.04 (bug 2526) SDL_Scancode scancode = videodata->key_layout[orig_keycode]; if (orig_event_type == KeyPress) { SDL_SendKeyboardKey(SDL_PRESSED, scancode); } else { SDL_SendKeyboardKey(SDL_RELEASED, scancode); } - */ } return; } @@ -617,6 +639,7 @@ X11_DispatchEvent(_THIS) /* Gaining mouse coverage? */ case EnterNotify:{ + SDL_Mouse *mouse = SDL_GetMouse(); #ifdef DEBUG_XEVENTS printf("window %p: EnterNotify! (%d,%d,%d)\n", data, xevent.xcrossing.x, @@ -629,7 +652,10 @@ X11_DispatchEvent(_THIS) #endif SDL_SetMouseFocus(data->window); - if (!SDL_GetMouse()->relative_mode) { + mouse->last_x = xevent.xcrossing.x; + mouse->last_y = xevent.xcrossing.y; + + if (!mouse->relative_mode) { SDL_SendMouseMotion(data->window, 0, 0, xevent.xcrossing.x, xevent.xcrossing.y); } } @@ -688,6 +714,7 @@ X11_DispatchEvent(_THIS) data->pending_focus = PENDING_FOCUS_IN; data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME; } + data->last_focus_event_time = SDL_GetTicks(); } break; @@ -739,11 +766,7 @@ X11_DispatchEvent(_THIS) if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) { int min_keycode, max_keycode; X11_XDisplayKeycodes(display, &min_keycode, &max_keycode); -#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM - keysym = X11_XkbKeycodeToKeysym(display, keycode, 0, 0); -#else - keysym = X11_XKeycodeToKeysym(display, keycode, 0); -#endif + keysym = X11_KeyCodeToSym(_this, keycode, xevent.xkey.state >> 13); fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n", keycode, keycode - min_keycode, keysym, @@ -756,14 +779,16 @@ X11_DispatchEvent(_THIS) if (data->ic) { X11_Xutf8LookupString(data->ic, &xevent.xkey, text, sizeof(text), &keysym, &status); + } else { + X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL); } #else X11_XLookupString(&xevent.xkey, text, sizeof(text), &keysym, NULL); #endif -#ifdef SDL_USE_IBUS +#ifdef SDL_USE_IME if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ - handled_by_ime = SDL_IBus_ProcessKeyEvent(keysym, keycode); + handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode); } #endif if (!handled_by_ime) { @@ -773,6 +798,7 @@ X11_DispatchEvent(_THIS) } } + X11_UpdateUserTime(data, xevent.xkey.time); } break; @@ -816,36 +842,28 @@ X11_DispatchEvent(_THIS) xevent.xconfigure.x, xevent.xconfigure.y, xevent.xconfigure.width, xevent.xconfigure.height); #endif - long border_left = 0; - long border_top = 0; - if (data->xwindow) { - Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0); - Atom type; - int format; - unsigned long nitems, bytes_after; - unsigned char *property; - if (X11_XGetWindowProperty(display, data->xwindow, - _net_frame_extents, 0, 16, 0, - XA_CARDINAL, &type, &format, - &nitems, &bytes_after, &property) == Success) { - if (type != None && nitems == 4) - { - border_left = ((long*)property)[0]; - border_top = ((long*)property)[2]; - } - X11_XFree(property); - } + /* Real configure notify events are relative to the parent, synthetic events are absolute. */ + if (!xevent.xconfigure.send_event) { + unsigned int NumChildren; + Window ChildReturn, Root, Parent; + Window * Children; + /* Translate these coodinates back to relative to root */ + X11_XQueryTree(data->videodata->display, xevent.xconfigure.window, &Root, &Parent, &Children, &NumChildren); + X11_XTranslateCoordinates(xevent.xconfigure.display, + Parent, DefaultRootWindow(xevent.xconfigure.display), + xevent.xconfigure.x, xevent.xconfigure.y, + &xevent.xconfigure.x, &xevent.xconfigure.y, + &ChildReturn); } - + if (xevent.xconfigure.x != data->last_xconfigure.x || xevent.xconfigure.y != data->last_xconfigure.y) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, - xevent.xconfigure.x - border_left, - xevent.xconfigure.y - border_top); -#ifdef SDL_USE_IBUS + xevent.xconfigure.x, xevent.xconfigure.y); +#ifdef SDL_USE_IME if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ - /* Update IBus candidate list position */ - SDL_IBus_UpdateTextRect(NULL); + /* Update IME candidate list position */ + SDL_IME_UpdateTextRect(NULL); } #endif } @@ -959,6 +977,16 @@ X11_DispatchEvent(_THIS) SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); break; } + else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent.xclient.format == 32) && + (xevent.xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) { + +#ifdef DEBUG_XEVENTS + printf("window %p: WM_TAKE_FOCUS\n", data); +#endif + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_TAKE_FOCUS, 0, 0); + break; + } } break; @@ -975,7 +1003,7 @@ X11_DispatchEvent(_THIS) SDL_Mouse *mouse = SDL_GetMouse(); if(!mouse->relative_mode || mouse->relative_mode_warp) { #ifdef DEBUG_MOTION - printf("window %p: X11 motion: %d,%d\n", xevent.xmotion.x, xevent.xmotion.y); + printf("window %p: X11 motion: %d,%d\n", data, xevent.xmotion.x, xevent.xmotion.y); #endif SDL_SendMouseMotion(data->window, 0, 0, xevent.xmotion.x, xevent.xmotion.y); @@ -985,12 +1013,17 @@ X11_DispatchEvent(_THIS) case ButtonPress:{ int xticks = 0, yticks = 0; +#ifdef DEBUG_XEVENTS + printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent.xbutton.button); +#endif if (X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) { SDL_SendMouseWheel(data->window, 0, xticks, yticks, SDL_MOUSEWHEEL_NORMAL); } else { + SDL_bool ignore_click = SDL_FALSE; int button = xevent.xbutton.button; if(button == Button1) { if (ProcessHitTest(_this, data, &xevent)) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); break; /* don't pass this event on to app. */ } } @@ -999,8 +1032,18 @@ X11_DispatchEvent(_THIS) => subtract (8-SDL_BUTTON_X1) to get value SDL expects */ button -= (8-SDL_BUTTON_X1); } - SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button); + if (data->last_focus_event_time) { + const int X11_FOCUS_CLICK_TIMEOUT = 10; + if (!SDL_TICKS_PASSED(SDL_GetTicks(), data->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) { + ignore_click = !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE); + } + data->last_focus_event_time = 0; + } + if (!ignore_click) { + SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button); + } } + X11_UpdateUserTime(data, xevent.xbutton.time); } break; @@ -1008,7 +1051,10 @@ X11_DispatchEvent(_THIS) int button = xevent.xbutton.button; /* The X server sends a Release event for each Press for wheels. Ignore them. */ int xticks = 0, yticks = 0; - if (!X11_IsWheelEvent(display,&xevent,&xticks, &yticks)) { +#ifdef DEBUG_XEVENTS + printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent.xbutton.button); +#endif + if (!X11_IsWheelEvent(display, &xevent, &xticks, &yticks)) { if (button > 7) { /* see explanation at case ButtonPress */ button -= (8-SDL_BUTTON_X1); @@ -1027,7 +1073,7 @@ X11_DispatchEvent(_THIS) char *name = X11_XGetAtomName(display, xevent.xproperty.atom); if (name) { - printf("window %p: PropertyNotify: %s %s\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed"); + printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent.xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent.xproperty.time); X11_XFree(name); } @@ -1095,6 +1141,17 @@ X11_DispatchEvent(_THIS) } #endif /* DEBUG_XEVENTS */ + /* Take advantage of this moment to make sure user_time has a + valid timestamp from the X server, so if we later try to + raise/restore this window, _NET_ACTIVE_WINDOW can have a + non-zero timestamp, even if there's never been a mouse or + key press to this window so far. Note that we don't try to + set _NET_WM_USER_TIME here, though. That's only for legit + user interaction with the window. */ + if (!data->user_time) { + data->user_time = xevent.xproperty.time; + } + if (xevent.xproperty.atom == data->videodata->_NET_WM_STATE) { /* Get the new state from the window manager. Compositing window managers can alter visibility of windows @@ -1128,6 +1185,24 @@ X11_DispatchEvent(_THIS) right approach, but it seems to work. */ X11_UpdateKeymap(_this); SDL_SendKeymapChangedEvent(); + } else if (xevent.xproperty.atom == videodata->_NET_FRAME_EXTENTS) { + Atom type; + int format; + unsigned long nitems, bytes_after; + unsigned char *property; + if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) { + if (type != None && nitems == 4) { + data->border_left = (int) ((long*)property)[0]; + data->border_right = (int) ((long*)property)[1]; + data->border_top = (int) ((long*)property)[2]; + data->border_bottom = (int) ((long*)property)[3]; + } + X11_XFree(property); + + #ifdef DEBUG_XEVENTS + printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom); + #endif + } } } break; @@ -1182,51 +1257,33 @@ X11_DispatchEvent(_THIS) break; case SelectionNotify: { + Atom target = xevent.xselection.target; #ifdef DEBUG_XEVENTS printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data, xevent.xselection.requestor, xevent.xselection.target); #endif - Atom target = xevent.xselection.target; if (target == data->xdnd_req) { /* read data */ SDL_x11Prop p; X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY); if (p.format == 8) { - SDL_bool expect_lf = SDL_FALSE; - char *start = NULL; - char *scan = (char*)p.data; - char *fn; - char *uri; - int length = 0; - while (p.count--) { - if (!expect_lf) { - if (*scan == 0x0D) { - expect_lf = SDL_TRUE; + /* !!! FIXME: don't use strtok here. It's not reentrant and not in SDL_stdinc. */ + char* name = X11_XGetAtomName(display, target); + char *token = strtok((char *) p.data, "\r\n"); + while (token != NULL) { + if (SDL_strcmp("text/plain", name)==0) { + SDL_SendDropText(data->window, token); + } else if (SDL_strcmp("text/uri-list", name)==0) { + char *fn = X11_URIToLocal(token); + if (fn) { + SDL_SendDropFile(data->window, fn); } - if (start == NULL) { - start = scan; - length = 0; - } - length++; - } else { - if (*scan == 0x0A && length > 0) { - uri = SDL_malloc(length--); - SDL_memcpy(uri, start, length); - uri[length] = '\0'; - fn = X11_URIToLocal(uri); - if (fn) { - SDL_SendDropFile(fn); - } - SDL_free(uri); - } - expect_lf = SDL_FALSE; - start = NULL; } - scan++; + token = strtok(NULL, "\r\n"); } + SDL_SendDropComplete(data->window); } - X11_XFree(p.data); /* send reply */ @@ -1350,9 +1407,9 @@ X11_PumpEvents(_THIS) X11_DispatchEvent(_this); } -#ifdef SDL_USE_IBUS +#ifdef SDL_USE_IME if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ - SDL_IBus_PumpEvents(); + SDL_IME_PumpEvents(); } #endif diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c index 2c3acdadd..b888bff35 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.c @@ -129,9 +129,21 @@ static const struct { { XK_Control_R, SDL_SCANCODE_RCTRL }, { XK_Shift_R, SDL_SCANCODE_RSHIFT }, { XK_Alt_R, SDL_SCANCODE_RALT }, + { XK_ISO_Level3_Shift, SDL_SCANCODE_RALT }, { XK_Meta_R, SDL_SCANCODE_RGUI }, { XK_Super_R, SDL_SCANCODE_RGUI }, { XK_Mode_switch, SDL_SCANCODE_MODE }, + { XK_period, SDL_SCANCODE_PERIOD }, + { XK_comma, SDL_SCANCODE_COMMA }, + { XK_slash, SDL_SCANCODE_SLASH }, + { XK_backslash, SDL_SCANCODE_BACKSLASH }, + { XK_minus, SDL_SCANCODE_MINUS }, + { XK_equal, SDL_SCANCODE_EQUALS }, + { XK_space, SDL_SCANCODE_SPACE }, + { XK_grave, SDL_SCANCODE_GRAVE }, + { XK_apostrophe, SDL_SCANCODE_APOSTROPHE }, + { XK_bracketleft, SDL_SCANCODE_LEFTBRACKET }, + { XK_bracketright, SDL_SCANCODE_RIGHTBRACKET }, }; static const struct @@ -142,31 +154,34 @@ static const struct { darwin_scancode_table, SDL_arraysize(darwin_scancode_table) }, { xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table) }, { xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) }, + { xvnc_scancode_table, SDL_arraysize(xvnc_scancode_table) }, }; /* *INDENT-OFF* */ /* This function only works for keyboards in US QWERTY layout */ static SDL_Scancode -X11_KeyCodeToSDLScancode(Display *display, KeyCode keycode) +X11_KeyCodeToSDLScancode(_THIS, KeyCode keycode) { KeySym keysym; int i; -#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM - keysym = X11_XkbKeycodeToKeysym(display, keycode, 0, 0); -#else - keysym = X11_XKeycodeToKeysym(display, keycode, 0); -#endif + keysym = X11_KeyCodeToSym(_this, keycode, 0); if (keysym == NoSymbol) { return SDL_SCANCODE_UNKNOWN; } + if (keysym >= XK_a && keysym <= XK_z) { + return SDL_SCANCODE_A + (keysym - XK_a); + } if (keysym >= XK_A && keysym <= XK_Z) { return SDL_SCANCODE_A + (keysym - XK_A); } - if (keysym >= XK_0 && keysym <= XK_9) { - return SDL_SCANCODE_0 + (keysym - XK_0); + if (keysym == XK_0) { + return SDL_SCANCODE_0; + } + if (keysym >= XK_1 && keysym <= XK_9) { + return SDL_SCANCODE_1 + (keysym - XK_1); } for (i = 0; i < SDL_arraysize(KeySymToSDLScancode); ++i) { @@ -178,15 +193,10 @@ X11_KeyCodeToSDLScancode(Display *display, KeyCode keycode) } static Uint32 -X11_KeyCodeToUcs4(Display *display, KeyCode keycode, unsigned char group) +X11_KeyCodeToUcs4(_THIS, KeyCode keycode, unsigned char group) { - KeySym keysym; + KeySym keysym = X11_KeyCodeToSym(_this, keycode, group); -#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM - keysym = X11_XkbKeycodeToKeysym(display, keycode, group, 0); -#else - keysym = X11_XKeycodeToKeysym(display, keycode, 0); -#endif if (keysym == NoSymbol) { return 0; } @@ -194,6 +204,42 @@ X11_KeyCodeToUcs4(Display *display, KeyCode keycode, unsigned char group) return X11_KeySymToUcs4(keysym); } +KeySym +X11_KeyCodeToSym(_THIS, KeyCode keycode, unsigned char group) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + KeySym keysym; + +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + if (data->xkb) { + int num_groups = XkbKeyNumGroups(data->xkb, keycode); + unsigned char info = XkbKeyGroupInfo(data->xkb, keycode); + + if (num_groups && group >= num_groups) { + + int action = XkbOutOfRangeGroupAction(info); + + if (action == XkbRedirectIntoRange) { + if ((group = XkbOutOfRangeGroupNumber(info)) >= num_groups) { + group = 0; + } + } else if (action == XkbClampIntoRange) { + group = num_groups - 1; + } else { + group %= num_groups; + } + } + keysym = X11_XkbKeycodeToKeysym(data->display, keycode, group, 0); + } else { + keysym = X11_XKeycodeToKeysym(data->display, keycode, 0); + } +#else + keysym = X11_XKeycodeToKeysym(data->display, keycode, 0); +#endif + + return keysym; +} + int X11_InitKeyboard(_THIS) { @@ -219,6 +265,16 @@ X11_InitKeyboard(_THIS) X11_XAutoRepeatOn(data->display); +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + { + int xkb_major = XkbMajorVersion; + int xkb_minor = XkbMinorVersion; + if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) { + data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd); + } + } +#endif + /* Try to determine which scancodes are being used based on fingerprint */ best_distance = SDL_arraysize(fingerprint) + 1; best_index = -1; @@ -263,16 +319,12 @@ X11_InitKeyboard(_THIS) SDL_GetDefaultKeymap(keymap); for (i = min_keycode; i <= max_keycode; ++i) { KeySym sym; -#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM - sym = X11_XkbKeycodeToKeysym(data->display, i, 0, 0); -#else - sym = X11_XKeycodeToKeysym(data->display, i, 0); -#endif + sym = X11_KeyCodeToSym(_this, (KeyCode) i, 0); if (sym != NoSymbol) { SDL_Scancode scancode; printf("code = %d, sym = 0x%X (%s) ", i - min_keycode, (unsigned int) sym, X11_XKeysymToString(sym)); - scancode = X11_KeyCodeToSDLScancode(data->display, i); + scancode = X11_KeyCodeToSDLScancode(_this, i); data->key_layout[i] = scancode; if (scancode == SDL_SCANCODE_UNKNOWN) { printf("scancode not found\n"); @@ -287,8 +339,8 @@ X11_InitKeyboard(_THIS) SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); -#ifdef SDL_USE_IBUS - SDL_IBus_Init(); +#ifdef SDL_USE_IME + SDL_IME_Init(); #endif return 0; @@ -304,10 +356,12 @@ X11_UpdateKeymap(_THIS) unsigned char group = 0; SDL_GetDefaultKeymap(keymap); - + #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM - { + if (data->xkb) { XkbStateRec state; + X11_XkbGetUpdatedMap(data->display, XkbAllClientInfoMask, data->xkb); + if (X11_XkbGetState(data->display, XkbUseCoreKbd, &state) == Success) { group = state.group; } @@ -325,11 +379,11 @@ X11_UpdateKeymap(_THIS) } /* See if there is a UCS keycode for this scancode */ - key = X11_KeyCodeToUcs4(data->display, (KeyCode)i, group); + key = X11_KeyCodeToUcs4(_this, (KeyCode)i, group); if (key) { keymap[scancode] = key; } else { - SDL_Scancode keyScancode = X11_KeyCodeToSDLScancode(data->display, (KeyCode)i); + SDL_Scancode keyScancode = X11_KeyCodeToSDLScancode(_this, (KeyCode)i); switch (keyScancode) { case SDL_SCANCODE_RETURN: @@ -359,22 +413,54 @@ X11_UpdateKeymap(_THIS) void X11_QuitKeyboard(_THIS) { -#ifdef SDL_USE_IBUS - SDL_IBus_Quit(); + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + if (data->xkb) { + X11_XkbFreeClientMap(data->xkb, 0, True); + data->xkb = NULL; + } +#endif + +#ifdef SDL_USE_IME + SDL_IME_Quit(); +#endif +} + +static void +X11_ResetXIM(_THIS) +{ +#ifdef X_HAVE_UTF8_STRING + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + int i; + + if (videodata && videodata->windowlist) { + for (i = 0; i < videodata->numwindows; ++i) { + SDL_WindowData *data = videodata->windowlist[i]; + if (data && data->ic) { + /* Clear any partially entered dead keys */ + char *contents = X11_Xutf8ResetIC(data->ic); + if (contents) { + X11_XFree(contents); + } + } + } + } #endif } void X11_StartTextInput(_THIS) { - + X11_ResetXIM(_this); } void X11_StopTextInput(_THIS) { -#ifdef SDL_USE_IBUS - SDL_IBus_Reset(); + X11_ResetXIM(_this); +#ifdef SDL_USE_IME + SDL_IME_Reset(); #endif } @@ -386,8 +472,8 @@ X11_SetTextInputRect(_THIS, SDL_Rect *rect) return; } -#ifdef SDL_USE_IBUS - SDL_IBus_UpdateTextRect(rect); +#ifdef SDL_USE_IME + SDL_IME_UpdateTextRect(rect); #endif } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h index a1102ed75..6ce3c9cce 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11keyboard.h @@ -29,6 +29,7 @@ extern void X11_QuitKeyboard(_THIS); extern void X11_StartTextInput(_THIS); extern void X11_StopTextInput(_THIS); extern void X11_SetTextInputRect(_THIS, SDL_Rect *rect); +extern KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group); #endif /* _SDL_x11keyboard_h */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11modes.c b/Engine/lib/sdl/src/video/x11/SDL_x11modes.c index 446da2b64..29307b3a6 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11modes.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11modes.c @@ -157,14 +157,12 @@ CheckXinerama(Display * display, int *major, int *minor) { int event_base = 0; int error_base = 0; - const char *env; /* Default the extension not available */ *major = *minor = 0; /* Allow environment override */ - env = SDL_GetHint(SDL_HINT_VIDEO_X11_XINERAMA); - if (env && !SDL_atoi(env)) { + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XINERAMA, SDL_TRUE)) { #ifdef X11MODES_DEBUG printf("Xinerama disabled due to hint\n"); #endif @@ -213,22 +211,19 @@ X11_XineramaFailed(Display * d, XErrorEvent * e) static SDL_bool CheckXRandR(Display * display, int *major, int *minor) { - const char *env; - /* Default the extension not available */ *major = *minor = 0; /* Allow environment override */ - env = SDL_GetHint(SDL_HINT_VIDEO_X11_XRANDR); #ifdef XRANDR_DISABLED_BY_DEFAULT - if (!env || !SDL_atoi(env)) { + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_FALSE)) { #ifdef X11MODES_DEBUG printf("XRandR disabled by default due to window manager issues\n"); #endif return SDL_FALSE; } #else - if (env && !SDL_atoi(env)) { + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_TRUE)) { #ifdef X11MODES_DEBUG printf("XRandR disabled due to hint\n"); #endif @@ -264,8 +259,8 @@ CheckXRandR(Display * display, int *major, int *minor) static int CalculateXRandRRefreshRate(const XRRModeInfo *info) { - return (info->hTotal - && info->vTotal) ? (info->dotClock / (info->hTotal * info->vTotal)) : 0; + return (info->hTotal && info->vTotal) ? + round(((double)info->dotClock / (double)(info->hTotal * info->vTotal))) : 0; } static SDL_bool @@ -342,7 +337,7 @@ SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, X11_XFree(props); } - inches = (int)((SDL_sqrt(widthmm * widthmm + heightmm * heightmm) / 25.4f) + 0.5f); + inches = (int)((SDL_sqrtf(widthmm * widthmm + heightmm * heightmm) / 25.4f) + 0.5f); if (*name && inches) { const size_t len = SDL_strlen(name); SDL_snprintf(&name[len], namelen-len, " %d\"", inches); @@ -507,14 +502,11 @@ X11_InitModes_XRandR(_THIS) static SDL_bool CheckVidMode(Display * display, int *major, int *minor) { - const char *env; - /* Default the extension not available */ *major = *minor = 0; /* Allow environment override */ - env = SDL_GetHint(SDL_HINT_VIDEO_X11_XVIDMODE); - if (env && !SDL_atoi(env)) { + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XVIDMODE, SDL_TRUE)) { #ifdef X11MODES_DEBUG printf("XVidMode disabled due to hint\n"); #endif @@ -618,6 +610,19 @@ X11_InitModes(_THIS) /* !!! FIXME: eventually remove support for Xinerama and XVidMode (everything below here). */ + /* This is a workaround for some apps (UnrealEngine4, for example) until + we sort out the ramifications of removing XVidMode support outright. + This block should be removed with the XVidMode support. */ + { + if (SDL_GetHintBoolean("SDL_VIDEO_X11_REQUIRE_XRANDR", SDL_FALSE)) { + #if SDL_VIDEO_DRIVER_X11_XRANDR + return SDL_SetError("XRandR support is required but not available"); + #else + return SDL_SetError("XRandR support is required but not built into SDL!"); + #endif + } + } + #if SDL_VIDEO_DRIVER_X11_XINERAMA /* Query Xinerama extention * NOTE: This works with Nvidia Twinview correctly, but you need version 302.17 (released on June 2012) @@ -1056,7 +1061,44 @@ X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * h *vdpi = data->vdpi; } - return data->ddpi != 0.0f ? 0 : -1; + return data->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); +} + +int +X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + Display *display = data->display; + Atom _NET_WORKAREA; + int status, real_format; + int retval = -1; + Atom real_type; + unsigned long items_read = 0, items_left = 0; + unsigned char *propdata = NULL; + + if (X11_GetDisplayBounds(_this, sdl_display, rect) < 0) { + return -1; + } + + _NET_WORKAREA = X11_XInternAtom(display, "_NET_WORKAREA", False); + status = X11_XGetWindowProperty(display, DefaultRootWindow(display), + _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL, + &real_type, &real_format, &items_read, + &items_left, &propdata); + if ((status == Success) && (items_read >= 4)) { + const long *p = (long*) propdata; + const SDL_Rect usable = { (int)p[0], (int)p[1], (int)p[2], (int)p[3] }; + retval = 0; + if (!SDL_IntersectRect(rect, &usable, rect)) { + SDL_zerop(rect); + } + } + + if (propdata) { + X11_XFree(propdata); + } + + return retval; } #endif /* SDL_VIDEO_DRIVER_X11 */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11modes.h b/Engine/lib/sdl/src/video/x11/SDL_x11modes.h index a68286ab1..4f47f3b5c 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11modes.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11modes.h @@ -77,6 +77,7 @@ extern int X11_GetVisualInfoFromVisual(Display * display, Visual * visual, extern Uint32 X11_GetPixelFormatFromVisualInfo(Display * display, XVisualInfo * vinfo); extern int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect); +extern int X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect); extern int X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi); #endif /* _SDL_x11modes_h */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c b/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c index 245b116ea..e1a16c225 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11mouse.c @@ -366,39 +366,52 @@ X11_CaptureMouse(SDL_Window *window) static Uint32 X11_GetGlobalMouseState(int *x, int *y) { + SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata; Display *display = GetDisplay(); const int num_screens = SDL_GetNumVideoDisplays(); int i; /* !!! FIXME: should we XSync() here first? */ - for (i = 0; i < num_screens; i++) { - SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i); - if (data != NULL) { - Window root, child; - int rootx, rooty, winx, winy; - unsigned int mask; - if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) { - XWindowAttributes root_attrs; - Uint32 retval = 0; - retval |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0; - retval |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0; - retval |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0; - /* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing - * (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right). - * - * Adding root position to root-relative coordinates seems to be a better way to get absolute position. */ - X11_XGetWindowAttributes(display, root, &root_attrs); - *x = root_attrs.x + rootx; - *y = root_attrs.y + rooty; - return retval; +#if !SDL_VIDEO_DRIVER_X11_XINPUT2 + videodata->global_mouse_changed = SDL_TRUE; +#endif + + /* check if we have this cached since XInput last saw the mouse move. */ + /* !!! FIXME: can we just calculate this from XInput's events? */ + if (videodata->global_mouse_changed) { + for (i = 0; i < num_screens; i++) { + SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i); + if (data != NULL) { + Window root, child; + int rootx, rooty, winx, winy; + unsigned int mask; + if (X11_XQueryPointer(display, RootWindow(display, data->screen), &root, &child, &rootx, &rooty, &winx, &winy, &mask)) { + XWindowAttributes root_attrs; + Uint32 buttons = 0; + buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0; + buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0; + buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0; + /* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing + * (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right). + * + * Adding root position to root-relative coordinates seems to be a better way to get absolute position. */ + X11_XGetWindowAttributes(display, root, &root_attrs); + videodata->global_mouse_position.x = root_attrs.x + rootx; + videodata->global_mouse_position.y = root_attrs.y + rooty; + videodata->global_mouse_buttons = buttons; + videodata->global_mouse_changed = SDL_FALSE; + break; + } } } } - SDL_assert(0 && "The pointer wasn't on any X11 screen?!"); + SDL_assert(!videodata->global_mouse_changed); /* The pointer wasn't on any X11 screen?! */ - return 0; + *x = videodata->global_mouse_position.x; + *y = videodata->global_mouse_position.y; + return videodata->global_mouse_buttons; } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c index 8b634be3d..abc699dd4 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11opengl.c @@ -695,7 +695,7 @@ X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) if (errorCode != Success) { /* uhoh, an X error was thrown! */ return -1; /* the error handler called SDL_SetError() already. */ - } else if (!rc) { /* glxMakeCurrent() failed without throwing an X error */ + } else if (!rc) { /* glXMakeCurrent() failed without throwing an X error */ return SDL_SetError("Unable to make GL context current"); } @@ -703,14 +703,14 @@ X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) } /* - 0 is a valid argument to glxSwapInterval(MESA|EXT) and setting it to 0 + 0 is a valid argument to glXSwapInterval(MESA|EXT) and setting it to 0 will undo the effect of a previous call with a value that is greater than zero (or at least that is what the docs say). OTOH, 0 is an invalid - argument to glxSwapIntervalSGI and it returns an error if you call it + argument to glXSwapIntervalSGI and it returns an error if you call it with 0 as an argument. */ -static int swapinterval = -1; +static int swapinterval = 0; int X11_GL_SetSwapInterval(_THIS, int interval) { @@ -742,14 +742,14 @@ X11_GL_SetSwapInterval(_THIS, int interval) } else if (_this->gl_data->glXSwapIntervalMESA) { status = _this->gl_data->glXSwapIntervalMESA(interval); if (status != 0) { - SDL_SetError("glxSwapIntervalMESA failed"); + SDL_SetError("glXSwapIntervalMESA failed"); } else { swapinterval = interval; } } else if (_this->gl_data->glXSwapIntervalSGI) { status = _this->gl_data->glXSwapIntervalSGI(interval); if (status != 0) { - SDL_SetError("glxSwapIntervalSGI failed"); + SDL_SetError("glXSwapIntervalSGI failed"); } else { swapinterval = interval; } diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11sym.h b/Engine/lib/sdl/src/video/x11/SDL_x11sym.h index 3683ac0a5..7290412b7 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11sym.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11sym.h @@ -21,6 +21,14 @@ /* *INDENT-OFF* */ +#ifndef SDL_X11_MODULE +#define SDL_X11_MODULE(modname) +#endif + +#ifndef SDL_X11_SYM +#define SDL_X11_SYM(rc,fn,params,args,ret) +#endif + SDL_X11_MODULE(BASEXLIB) SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return) SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return) @@ -153,6 +161,7 @@ SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),r SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,SDL_X11_XESetWireToEventRetType c),(a,b,c),return) SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return) SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),) +SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return) #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return) @@ -160,12 +169,16 @@ SDL_X11_SYM(void,XFreeEventData,(Display* a,XGenericEventCookie* b),(a,b),) #endif #if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +SDL_X11_SYM(Bool,XkbQueryExtension,(Display* a,int * b,int * c,int * d,int * e, int *f),(a,b,c,d,e,f),return) #if NeedWidePrototypes SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,unsigned int b,int c,int d),(a,b,c,d),return) #else SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,KeyCode b,int c,int d),(a,b,c,d),return) #endif SDL_X11_SYM(Status,XkbGetState,(Display* a,unsigned int b,XkbStatePtr c),(a,b,c),return) +SDL_X11_SYM(Status,XkbGetUpdatedMap,(Display* a,unsigned int b,XkbDescPtr c),(a,b,c),return) +SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b,c),return) +SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),) #endif #if NeedWidePrototypes @@ -187,6 +200,8 @@ SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d) SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return) SDL_X11_SYM(void,Xutf8DrawString,(Display *a, Drawable b, XFontSet c, GC d, int e, int f, _Xconst char *g, int h),(a,b,c,d,e,f,g,h),) SDL_X11_SYM(int,Xutf8TextExtents,(XFontSet a, _Xconst char* b, int c, XRectangle* d, XRectangle* e),(a,b,c,d,e),return) +SDL_X11_SYM(char*,XSetLocaleModifiers,(const char *a),(a),return) +SDL_X11_SYM(char*,Xutf8ResetIC,(XIC a),(a),return) #endif #ifndef NO_SHARED_MEMORY @@ -311,6 +326,9 @@ SDL_X11_SYM(Bool,XF86VidModeSwitchToMode,(Display *a,int b,XF86VidModeModeInfo * SDL_X11_SYM(Bool,XF86VidModeLockModeSwitch,(Display *a,int b,int c),(a,b,c),return) #endif +#undef SDL_X11_MODULE +#undef SDL_X11_SYM + /* *INDENT-ON* */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11video.c b/Engine/lib/sdl/src/video/x11/SDL_x11video.c index 01f8ae60f..38b34de34 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11video.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11video.c @@ -39,6 +39,10 @@ #include "SDL_x11opengles.h" #endif +#ifdef X_HAVE_UTF8_STRING +#include +#endif + /* Initialization/Query functions */ static int X11_VideoInit(_THIS); static void X11_VideoQuit(_THIS); @@ -175,6 +179,8 @@ X11_CreateDevice(int devindex) } device->driverdata = data; + data->global_mouse_changed = SDL_TRUE; + /* FIXME: Do we need this? if ( (SDL_strncmp(X11_XDisplayName(display), ":", 1) == 0) || (SDL_strncmp(X11_XDisplayName(display), "unix:", 5) == 0) ) { @@ -216,6 +222,7 @@ X11_CreateDevice(int devindex) device->VideoQuit = X11_VideoQuit; device->GetDisplayModes = X11_GetDisplayModes; device->GetDisplayBounds = X11_GetDisplayBounds; + device->GetDisplayUsableBounds = X11_GetDisplayUsableBounds; device->GetDisplayDPI = X11_GetDisplayDPI; device->SetDisplayMode = X11_SetDisplayMode; device->SuspendScreenSaver = X11_SuspendScreenSaver; @@ -229,6 +236,10 @@ X11_CreateDevice(int devindex) device->SetWindowSize = X11_SetWindowSize; device->SetWindowMinimumSize = X11_SetWindowMinimumSize; device->SetWindowMaximumSize = X11_SetWindowMaximumSize; + device->GetWindowBordersSize = X11_GetWindowBordersSize; + device->SetWindowOpacity = X11_SetWindowOpacity; + device->SetWindowModalFor = X11_SetWindowModalFor; + device->SetWindowInputFocus = X11_SetWindowInputFocus; device->ShowWindow = X11_ShowWindow; device->HideWindow = X11_HideWindow; device->RaiseWindow = X11_RaiseWindow; @@ -236,6 +247,7 @@ X11_CreateDevice(int devindex) device->MinimizeWindow = X11_MinimizeWindow; device->RestoreWindow = X11_RestoreWindow; device->SetWindowBordered = X11_SetWindowBordered; + device->SetWindowResizable = X11_SetWindowResizable; device->SetWindowFullscreen = X11_SetWindowFullscreen; device->SetWindowGammaRamp = X11_SetWindowGammaRamp; device->SetWindowGrab = X11_SetWindowGrab; @@ -278,7 +290,7 @@ X11_CreateDevice(int devindex) device->StartTextInput = X11_StartTextInput; device->StopTextInput = X11_StopTextInput; device->SetTextInputRect = X11_SetTextInputRect; - + device->free = X11_DeleteDevice; return device; @@ -373,11 +385,65 @@ X11_VideoInit(_THIS) /* Get the process PID to be associated to the window */ data->pid = getpid(); + /* I have no idea how random this actually is, or has to be. */ + data->window_group = (XID) (((size_t) data->pid) ^ ((size_t) _this)); + /* Open a connection to the X input manager */ #ifdef X_HAVE_UTF8_STRING if (SDL_X11_HAVE_UTF8) { - data->im = - X11_XOpenIM(data->display, NULL, data->classname, data->classname); + /* Set the locale, and call XSetLocaleModifiers before XOpenIM so that + Compose keys will work correctly. */ + char *prev_locale = setlocale(LC_ALL, NULL); + char *prev_xmods = X11_XSetLocaleModifiers(NULL); + const char *new_xmods = ""; +#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX_FRONTEND_H) + const char *env_xmods = SDL_getenv("XMODIFIERS"); +#endif + SDL_bool has_dbus_ime_support = SDL_FALSE; + + if (prev_locale) { + prev_locale = SDL_strdup(prev_locale); + } + + if (prev_xmods) { + prev_xmods = SDL_strdup(prev_xmods); + } + + /* IBus resends some key events that were filtered by XFilterEvents + when it is used via XIM which causes issues. Prevent this by forcing + @im=none if XMODIFIERS contains @im=ibus. IBus can still be used via + the DBus implementation, which also has support for pre-editing. */ +#ifdef HAVE_IBUS_IBUS_H + if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) { + has_dbus_ime_support = SDL_TRUE; + } +#endif +#ifdef HAVE_FCITX_FRONTEND_H + if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) { + has_dbus_ime_support = SDL_TRUE; + } +#endif + if (has_dbus_ime_support) { + new_xmods = "@im=none"; + } + + setlocale(LC_ALL, ""); + X11_XSetLocaleModifiers(new_xmods); + + data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname); + + /* Reset the locale + X locale modifiers back to how they were, + locale first because the X locale modifiers depend on it. */ + setlocale(LC_ALL, prev_locale); + X11_XSetLocaleModifiers(prev_xmods); + + if (prev_locale) { + SDL_free(prev_locale); + } + + if (prev_xmods) { + SDL_free(prev_xmods); + } } #endif @@ -385,19 +451,26 @@ X11_VideoInit(_THIS) #define GET_ATOM(X) data->X = X11_XInternAtom(data->display, #X, False) GET_ATOM(WM_PROTOCOLS); GET_ATOM(WM_DELETE_WINDOW); + GET_ATOM(WM_TAKE_FOCUS); GET_ATOM(_NET_WM_STATE); GET_ATOM(_NET_WM_STATE_HIDDEN); GET_ATOM(_NET_WM_STATE_FOCUSED); GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); GET_ATOM(_NET_WM_STATE_FULLSCREEN); + GET_ATOM(_NET_WM_STATE_ABOVE); + GET_ATOM(_NET_WM_STATE_SKIP_TASKBAR); + GET_ATOM(_NET_WM_STATE_SKIP_PAGER); GET_ATOM(_NET_WM_ALLOWED_ACTIONS); GET_ATOM(_NET_WM_ACTION_FULLSCREEN); GET_ATOM(_NET_WM_NAME); GET_ATOM(_NET_WM_ICON_NAME); GET_ATOM(_NET_WM_ICON); GET_ATOM(_NET_WM_PING); + GET_ATOM(_NET_WM_WINDOW_OPACITY); + GET_ATOM(_NET_WM_USER_TIME); GET_ATOM(_NET_ACTIVE_WINDOW); + GET_ATOM(_NET_FRAME_EXTENTS); GET_ATOM(UTF8_STRING); GET_ATOM(PRIMARY); GET_ATOM(XdndEnter); diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11video.h b/Engine/lib/sdl/src/video/x11/SDL_x11video.h index 2083defd2..a3324ff53 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11video.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11video.h @@ -57,7 +57,7 @@ #endif #include "../../core/linux/SDL_dbus.h" -#include "../../core/linux/SDL_ibus.h" +#include "../../core/linux/SDL_ime.h" #include "SDL_x11dyn.h" @@ -81,6 +81,7 @@ typedef struct SDL_VideoData int numwindows; SDL_WindowData **windowlist; int windowlistlength; + XID window_group; /* This is true for ICCCM2.0-compliant window managers */ SDL_bool net_wm; @@ -88,19 +89,26 @@ typedef struct SDL_VideoData /* Useful atoms */ Atom WM_PROTOCOLS; Atom WM_DELETE_WINDOW; + Atom WM_TAKE_FOCUS; Atom _NET_WM_STATE; Atom _NET_WM_STATE_HIDDEN; Atom _NET_WM_STATE_FOCUSED; Atom _NET_WM_STATE_MAXIMIZED_VERT; Atom _NET_WM_STATE_MAXIMIZED_HORZ; Atom _NET_WM_STATE_FULLSCREEN; + Atom _NET_WM_STATE_ABOVE; + Atom _NET_WM_STATE_SKIP_TASKBAR; + Atom _NET_WM_STATE_SKIP_PAGER; Atom _NET_WM_ALLOWED_ACTIONS; Atom _NET_WM_ACTION_FULLSCREEN; Atom _NET_WM_NAME; Atom _NET_WM_ICON_NAME; Atom _NET_WM_ICON; Atom _NET_WM_PING; + Atom _NET_WM_WINDOW_OPACITY; + Atom _NET_WM_USER_TIME; Atom _NET_ACTIVE_WINDOW; + Atom _NET_FRAME_EXTENTS; Atom UTF8_STRING; Atom PRIMARY; Atom XdndEnter; @@ -117,6 +125,14 @@ typedef struct SDL_VideoData SDL_bool selection_waiting; Uint32 last_mode_change_deadline; + + SDL_bool global_mouse_changed; + SDL_Point global_mouse_position; + Uint32 global_mouse_buttons; + +#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + XkbDescPtr xkb; +#endif } SDL_VideoData; extern SDL_bool X11_UseDirectColorVisuals(void); diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11window.c b/Engine/lib/sdl/src/video/x11/SDL_x11window.c index afc802198..668bce225 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11window.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11window.c @@ -130,13 +130,17 @@ X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; Display *display = videodata->display; + /* !!! FIXME: just dereference videodata below instead of copying to locals. */ Atom _NET_WM_STATE = videodata->_NET_WM_STATE; /* Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; */ Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED; Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT; Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ; Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN; - Atom atoms[5]; + Atom _NET_WM_STATE_ABOVE = videodata->_NET_WM_STATE_ABOVE; + Atom _NET_WM_STATE_SKIP_TASKBAR = videodata->_NET_WM_STATE_SKIP_TASKBAR; + Atom _NET_WM_STATE_SKIP_PAGER = videodata->_NET_WM_STATE_SKIP_PAGER; + Atom atoms[16]; int count = 0; /* The window manager sets this property, we shouldn't set it. @@ -147,6 +151,14 @@ X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags) atoms[count++] = _NET_WM_STATE_HIDDEN; } */ + + if (flags & SDL_WINDOW_ALWAYS_ON_TOP) { + atoms[count++] = _NET_WM_STATE_ABOVE; + } + if (flags & SDL_WINDOW_SKIP_TASKBAR) { + atoms[count++] = _NET_WM_STATE_SKIP_TASKBAR; + atoms[count++] = _NET_WM_STATE_SKIP_PAGER; + } if (flags & SDL_WINDOW_INPUT_FOCUS) { atoms[count++] = _NET_WM_STATE_FOCUSED; } @@ -157,6 +169,9 @@ X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags) if (flags & SDL_WINDOW_FULLSCREEN) { atoms[count++] = _NET_WM_STATE_FULLSCREEN; } + + SDL_assert(count <= SDL_arraysize(atoms)); + if (count > 0) { X11_XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, count); @@ -206,7 +221,9 @@ X11_GetNetWMState(_THIS, Window xwindow) } if (maximized == 3) { flags |= SDL_WINDOW_MAXIMIZED; - } else if (fullscreen == 1) { + } + + if (fullscreen == 1) { flags |= SDL_WINDOW_FULLSCREEN; } X11_XFree(propertyValue); @@ -355,10 +372,11 @@ X11_CreateWindow(_THIS, SDL_Window * window) XSizeHints *sizehints; XWMHints *wmhints; XClassHint *classhints; - const long _NET_WM_BYPASS_COMPOSITOR_HINT_ON = 1; Atom _NET_WM_BYPASS_COMPOSITOR; Atom _NET_WM_WINDOW_TYPE; - Atom _NET_WM_WINDOW_TYPE_NORMAL; + Atom wintype; + const char *wintype_name = NULL; + int compositor = 1; Atom _NET_WM_PID; Atom XdndAware, xdnd_version = 5; long fevent = 0; @@ -396,7 +414,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) depth = displaydata->depth; } - xattr.override_redirect = False; + xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU)) ? True : False; xattr.background_pixmap = None; xattr.border_pixel = 0; @@ -506,7 +524,8 @@ X11_CreateWindow(_THIS, SDL_Window * window) /* Setup the input hints so we get keyboard input */ wmhints = X11_XAllocWMHints(); wmhints->input = True; - wmhints->flags = InputHint; + wmhints->window_group = data->window_group; + wmhints->flags = InputHint | WindowGroupHint; /* Setup the class hints so we can get an icon (AfterStep) */ classhints = X11_XAllocClassHint(); @@ -521,39 +540,49 @@ X11_CreateWindow(_THIS, SDL_Window * window) X11_XFree(classhints); /* Set the PID related to the window for the given hostname, if possible */ if (data->pid > 0) { + long pid = (long) data->pid; _NET_WM_PID = X11_XInternAtom(display, "_NET_WM_PID", False); X11_XChangeProperty(display, w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)&data->pid, 1); + (unsigned char *) &pid, 1); } /* Set the window manager state */ X11_SetNetWMState(_this, w, window->flags); - /* Let the window manager know we're a "normal" window */ + compositor = 2; /* don't disable compositing except for "normal" windows */ + + if (window->flags & SDL_WINDOW_UTILITY) { + wintype_name = "_NET_WM_WINDOW_TYPE_UTILITY"; + } else if (window->flags & SDL_WINDOW_TOOLTIP) { + wintype_name = "_NET_WM_WINDOW_TYPE_TOOLTIP"; + } else if (window->flags & SDL_WINDOW_POPUP_MENU) { + wintype_name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; + } else { + wintype_name = "_NET_WM_WINDOW_TYPE_NORMAL"; + compositor = 1; /* disable compositing for "normal" windows */ + } + + /* Let the window manager know what type of window we are. */ _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); - _NET_WM_WINDOW_TYPE_NORMAL = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", False); + wintype = X11_XInternAtom(display, wintype_name, False); X11_XChangeProperty(display, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, - PropModeReplace, - (unsigned char *)&_NET_WM_WINDOW_TYPE_NORMAL, 1); + PropModeReplace, (unsigned char *)&wintype, 1); _NET_WM_BYPASS_COMPOSITOR = X11_XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False); X11_XChangeProperty(display, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)&_NET_WM_BYPASS_COMPOSITOR_HINT_ON, 1); + (unsigned char *)&compositor, 1); { - Atom protocols[2]; + Atom protocols[3]; int proto_count = 0; - const char *ping_hint; - protocols[proto_count] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */ - proto_count++; - - ping_hint = SDL_GetHint(SDL_HINT_VIDEO_X11_NET_WM_PING); + protocols[proto_count++] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */ + protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */ + /* Default to using ping if there is no hint */ - if (!ping_hint || SDL_atoi(ping_hint)) { - protocols[proto_count] = data->_NET_WM_PING; /* Respond so WM knows we're alive */ - proto_count++; + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_PING, SDL_TRUE)) { + protocols[proto_count++] = data->_NET_WM_PING; /* Respond so WM knows we're alive */ } SDL_assert(proto_count <= sizeof(protocols) / sizeof(protocols[0])); @@ -750,7 +779,7 @@ X11_SetWindowPosition(_THIS, SDL_Window * window) SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; - X11_XMoveWindow(display, data->xwindow, window->x, window->y); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); X11_XFlush(display); } @@ -776,7 +805,7 @@ X11_SetWindowMinimumSize(_THIS, SDL_Window * window) /* See comment in X11_SetWindowSize. */ X11_XResizeWindow(display, data->xwindow, window->w, window->h); - X11_XMoveWindow(display, data->xwindow, window->x, window->y); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); X11_XRaiseWindow(display, data->xwindow); } @@ -805,7 +834,7 @@ X11_SetWindowMaximumSize(_THIS, SDL_Window * window) /* See comment in X11_SetWindowSize. */ X11_XResizeWindow(display, data->xwindow, window->w, window->h); - X11_XMoveWindow(display, data->xwindow, window->x, window->y); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); X11_XRaiseWindow(display, data->xwindow); } @@ -854,7 +883,7 @@ X11_SetWindowSize(_THIS, SDL_Window * window) and transitioning from windowed to fullscreen in Unity. */ X11_XResizeWindow(display, data->xwindow, window->w, window->h); - X11_XMoveWindow(display, data->xwindow, window->x, window->y); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); X11_XRaiseWindow(display, data->xwindow); } else { X11_XResizeWindow(display, data->xwindow, window->w, window->h); @@ -863,6 +892,61 @@ X11_SetWindowSize(_THIS, SDL_Window * window) X11_XFlush(display); } +int +X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + *left = data->border_left; + *right = data->border_right; + *top = data->border_top; + *bottom = data->border_bottom; + + return 0; +} + +int +X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_WINDOW_OPACITY = data->videodata->_NET_WM_WINDOW_OPACITY; + + if (opacity == 1.0f) { + X11_XDeleteProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY); + } else { + const Uint32 FullyOpaque = 0xFFFFFFFF; + const long alpha = (long) ((double)opacity * (double)FullyOpaque); + X11_XChangeProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&alpha, 1); + } + + return 0; +} + +int +X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window) { + SDL_WindowData *data = (SDL_WindowData *) modal_window->driverdata; + SDL_WindowData *parent_data = (SDL_WindowData *) parent_window->driverdata; + Display *display = data->videodata->display; + + X11_XSetTransientForHint(display, data->xwindow, parent_data->xwindow); + return 0; +} + +int +X11_SetWindowInputFocus(_THIS, SDL_Window * window) +{ + if (X11_IsWindowMapped(_this, window)) { + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); + X11_XFlush(display); + return 0; + } + return -1; +} + void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { @@ -895,6 +979,44 @@ X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); } +void +X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; + + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + + if (resizable) { + /* FIXME: Is there a better way to get max window size from X? -flibit */ + const int maxsize = 0x7FFFFFFF; + sizehints->min_width = window->min_w; + sizehints->min_height = window->min_h; + sizehints->max_width = (window->max_w == 0) ? maxsize : window->max_w; + sizehints->max_height = (window->max_h == 0) ? maxsize : window->max_h; + } else { + sizehints->min_width = window->w; + sizehints->min_height = window->h; + sizehints->max_width = window->w; + sizehints->max_height = window->h; + } + sizehints->flags |= PMinSize | PMaxSize; + + X11_XSetWMNormalHints(display, data->xwindow, sizehints); + + X11_XFree(sizehints); + + /* See comment in X11_SetWindowSize. */ + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); + X11_XRaiseWindow(display, data->xwindow); + + X11_XFlush(display); +} + void X11_ShowWindow(_THIS, SDL_Window * window) { @@ -946,13 +1068,15 @@ SetWindowActive(_THIS, SDL_Window * window) if (X11_IsWindowMapped(_this, window)) { XEvent e; + /*printf("SDL Window %p: sending _NET_ACTIVE_WINDOW with timestamp %lu\n", window, data->user_time);*/ + SDL_zero(e); e.xany.type = ClientMessage; e.xclient.message_type = _NET_ACTIVE_WINDOW; e.xclient.format = 32; e.xclient.window = data->xwindow; e.xclient.data.l[0] = 1; /* source indication. 1 = application */ - e.xclient.data.l[1] = CurrentTime; + e.xclient.data.l[1] = data->user_time; e.xclient.data.l[2] = 0; X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, @@ -1038,7 +1162,7 @@ X11_RestoreWindow(_THIS, SDL_Window * window) SetWindowActive(_this, window); } -/* This asks the Window Manager to handle fullscreen for us. Most don't do it right, though. */ +/* This asks the Window Manager to handle fullscreen for us. This is the modern way. */ static void X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) { @@ -1083,6 +1207,22 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, SubstructureNotifyMask | SubstructureRedirectMask, &e); + + /* Fullscreen windows sometimes end up being marked maximized by + window managers. Force it back to how we expect it to be. */ + if (!fullscreen && ((window->flags & SDL_WINDOW_MAXIMIZED) == 0)) { + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; + e.xclient.data.l[2] = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; + e.xclient.data.l[3] = 0l; + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + } } else { Uint32 flags; @@ -1335,7 +1475,6 @@ X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) Display *display = data->videodata->display; SDL_bool oldstyle_fullscreen; SDL_bool grab_keyboard; - const char *hint; /* ICCCM2.0-compliant window managers can handle fullscreen windows If we're using XVidMode to change resolution we need to confine @@ -1359,8 +1498,7 @@ X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) X11_XRaiseWindow(display, data->xwindow); /* Now grab the keyboard */ - hint = SDL_GetHint(SDL_HINT_GRAB_KEYBOARD); - if (hint && SDL_atoi(hint)) { + if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { grab_keyboard = SDL_TRUE; } else { /* We need to do this with the old style override_redirect diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11window.h b/Engine/lib/sdl/src/video/x11/SDL_x11window.h index efe7ec0f0..50a739dad 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11window.h +++ b/Engine/lib/sdl/src/video/x11/SDL_x11window.h @@ -56,10 +56,16 @@ typedef struct GC gc; XIC ic; SDL_bool created; + int border_left; + int border_right; + int border_top; + int border_bottom; + Uint32 last_focus_event_time; PendingFocusEnum pending_focus; Uint32 pending_focus_time; XConfigureEvent last_xconfigure; struct SDL_VideoData *videodata; + unsigned long user_time; Atom xdnd_req; Window xdnd_source; #if SDL_VIDEO_OPENGL_EGL @@ -78,6 +84,10 @@ extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void X11_SetWindowPosition(_THIS, SDL_Window * window); extern void X11_SetWindowMinimumSize(_THIS, SDL_Window * window); extern void X11_SetWindowMaximumSize(_THIS, SDL_Window * window); +extern int X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right); +extern int X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity); +extern int X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window); +extern int X11_SetWindowInputFocus(_THIS, SDL_Window * window); extern void X11_SetWindowSize(_THIS, SDL_Window * window); extern void X11_ShowWindow(_THIS, SDL_Window * window); extern void X11_HideWindow(_THIS, SDL_Window * window); @@ -86,6 +96,7 @@ extern void X11_MaximizeWindow(_THIS, SDL_Window * window); extern void X11_MinimizeWindow(_THIS, SDL_Window * window); extern void X11_RestoreWindow(_THIS, SDL_Window * window); extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); +extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); diff --git a/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c b/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c index 57132fe9e..bed4234f0 100644 --- a/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c +++ b/Engine/lib/sdl/src/video/x11/SDL_x11xinput2.c @@ -118,6 +118,8 @@ X11_InitXinput2(_THIS) eventmask.mask = mask; XISetMask(mask, XI_RawMotion); + XISetMask(mask, XI_RawButtonPress); + XISetMask(mask, XI_RawButtonRelease); if (X11_XISelectEvents(data->display,DefaultRootWindow(data->display),&eventmask,1) != Success) { return; @@ -140,6 +142,8 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) static Time prev_time = 0; static double prev_rel_coords[2]; + videodata->global_mouse_changed = SDL_TRUE; + if (!mouse->relative_mode || mouse->relative_mode_warp) { return 0; } @@ -158,6 +162,12 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) return 1; } break; + + case XI_RawButtonPress: + case XI_RawButtonRelease: + videodata->global_mouse_changed = SDL_TRUE; + break; + #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH case XI_TouchBegin: { const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; diff --git a/Engine/lib/sdl/src/video/x11/edid-parse.c b/Engine/lib/sdl/src/video/x11/edid-parse.c index 2c145e23c..57f225b85 100644 --- a/Engine/lib/sdl/src/video/x11/edid-parse.c +++ b/Engine/lib/sdl/src/video/x11/edid-parse.c @@ -21,6 +21,8 @@ */ /* Author: Soren Sandmann */ +#include "../../SDL_internal.h" +#include "SDL_stdinc.h" #include "edid.h" #include @@ -247,7 +249,7 @@ decode_fraction (int high, int low) high = (high << 2) | low; for (i = 0; i < 10; ++i) - result += get_bit (high, i) * pow (2, i - 10); + result += get_bit (high, i) * SDL_pow (2, i - 10); return result; } diff --git a/Engine/lib/sdl/src/video/x11/imKStoUCS.c b/Engine/lib/sdl/src/video/x11/imKStoUCS.c index e4f086464..40e224243 100644 --- a/Engine/lib/sdl/src/video/x11/imKStoUCS.c +++ b/Engine/lib/sdl/src/video/x11/imKStoUCS.c @@ -1,297 +1,296 @@ -/* Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved. +/* +Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett +Copyright © 2009 Red Hat, Inc. +Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates. +All rights reserved. -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 fur- -nished to do so, subject to the following conditions: +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 above copyright notice and this permission notice (including the next +paragraph) 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, FIT- -NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- -NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the XFree86 Project shall not -be used in advertising or otherwise to promote the sale, use or other deal- -ings in this Software without prior written authorization from the XFree86 -Project. +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. */ + #include "../../SDL_internal.h" #if SDL_VIDEO_DRIVER_X11 - -/* $XFree86: xc/lib/X11/imKStoUCS.c,v 1.4 2003/04/29 11:29:18 pascal Exp $ */ - #include #include "imKStoUCS.h" static unsigned short const keysym_to_unicode_1a1_1ff[] = { - 0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */ - 0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */ - 0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */ - 0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */ - 0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */ - 0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */ - 0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */ - 0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */ - 0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */ - 0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */ - 0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */ - 0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */ + 0x0104, 0x02d8, 0x0141, 0x0000, 0x013d, 0x015a, 0x0000, /* 0x01a0-0x01a7 */ + 0x0000, 0x0160, 0x015e, 0x0164, 0x0179, 0x0000, 0x017d, 0x017b, /* 0x01a8-0x01af */ + 0x0000, 0x0105, 0x02db, 0x0142, 0x0000, 0x013e, 0x015b, 0x02c7, /* 0x01b0-0x01b7 */ + 0x0000, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* 0x01b8-0x01bf */ + 0x0154, 0x0000, 0x0000, 0x0102, 0x0000, 0x0139, 0x0106, 0x0000, /* 0x01c0-0x01c7 */ + 0x010c, 0x0000, 0x0118, 0x0000, 0x011a, 0x0000, 0x0000, 0x010e, /* 0x01c8-0x01cf */ + 0x0110, 0x0143, 0x0147, 0x0000, 0x0000, 0x0150, 0x0000, 0x0000, /* 0x01d0-0x01d7 */ + 0x0158, 0x016e, 0x0000, 0x0170, 0x0000, 0x0000, 0x0162, 0x0000, /* 0x01d8-0x01df */ + 0x0155, 0x0000, 0x0000, 0x0103, 0x0000, 0x013a, 0x0107, 0x0000, /* 0x01e0-0x01e7 */ + 0x010d, 0x0000, 0x0119, 0x0000, 0x011b, 0x0000, 0x0000, 0x010f, /* 0x01e8-0x01ef */ + 0x0111, 0x0144, 0x0148, 0x0000, 0x0000, 0x0151, 0x0000, 0x0000, /* 0x01f0-0x01f7 */ + 0x0159, 0x016f, 0x0000, 0x0171, 0x0000, 0x0000, 0x0163, 0x02d9 /* 0x01f8-0x01ff */ }; static unsigned short const keysym_to_unicode_2a1_2fe[] = { - 0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */ - 0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */ - 0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */ - 0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */ - 0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */ - 0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */ + 0x0126, 0x0000, 0x0000, 0x0000, 0x0000, 0x0124, 0x0000, /* 0x02a0-0x02a7 */ + 0x0000, 0x0130, 0x0000, 0x011e, 0x0134, 0x0000, 0x0000, 0x0000, /* 0x02a8-0x02af */ + 0x0000, 0x0127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0125, 0x0000, /* 0x02b0-0x02b7 */ + 0x0000, 0x0131, 0x0000, 0x011f, 0x0135, 0x0000, 0x0000, 0x0000, /* 0x02b8-0x02bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010a, 0x0108, 0x0000, /* 0x02c0-0x02c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02c8-0x02cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0120, 0x0000, 0x0000, /* 0x02d0-0x02d7 */ + 0x011c, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x015c, 0x0000, /* 0x02d8-0x02df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x010b, 0x0109, 0x0000, /* 0x02e0-0x02e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x02e8-0x02ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0121, 0x0000, 0x0000, /* 0x02f0-0x02f7 */ + 0x011d, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x015d /* 0x02f8-0x02ff */ }; static unsigned short const keysym_to_unicode_3a2_3fe[] = { - 0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */ - 0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */ - 0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */ - 0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */ - 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */ - 0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */ - 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */ - 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */ - 0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */ - 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */ + 0x0138, 0x0156, 0x0000, 0x0128, 0x013b, 0x0000, /* 0x03a0-0x03a7 */ + 0x0000, 0x0000, 0x0112, 0x0122, 0x0166, 0x0000, 0x0000, 0x0000, /* 0x03a8-0x03af */ + 0x0000, 0x0000, 0x0000, 0x0157, 0x0000, 0x0129, 0x013c, 0x0000, /* 0x03b0-0x03b7 */ + 0x0000, 0x0000, 0x0113, 0x0123, 0x0167, 0x014a, 0x0000, 0x014b, /* 0x03b8-0x03bf */ + 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012e, /* 0x03c0-0x03c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0116, 0x0000, 0x0000, 0x012a, /* 0x03c8-0x03cf */ + 0x0000, 0x0145, 0x014c, 0x0136, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03d0-0x03d7 */ + 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0168, 0x016a, 0x0000, /* 0x03d8-0x03df */ + 0x0101, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x012f, /* 0x03e0-0x03e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0117, 0x0000, 0x0000, 0x012b, /* 0x03e8-0x03ef */ + 0x0000, 0x0146, 0x014d, 0x0137, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x03f0-0x03f7 */ + 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0169, 0x016b /* 0x03f8-0x03ff */ }; static unsigned short const keysym_to_unicode_4a1_4df[] = { - 0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */ - 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */ - 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */ - 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */ - 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */ - 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */ - 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */ - 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */ + 0x3002, 0x3008, 0x3009, 0x3001, 0x30fb, 0x30f2, 0x30a1, /* 0x04a0-0x04a7 */ + 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30e3, 0x30e5, 0x30e7, 0x30c3, /* 0x04a8-0x04af */ + 0x30fc, 0x30a2, 0x30a4, 0x30a6, 0x30a8, 0x30aa, 0x30ab, 0x30ad, /* 0x04b0-0x04b7 */ + 0x30af, 0x30b1, 0x30b3, 0x30b5, 0x30b7, 0x30b9, 0x30bb, 0x30bd, /* 0x04b8-0x04bf */ + 0x30bf, 0x30c1, 0x30c4, 0x30c6, 0x30c8, 0x30ca, 0x30cb, 0x30cc, /* 0x04c0-0x04c7 */ + 0x30cd, 0x30ce, 0x30cf, 0x30d2, 0x30d5, 0x30d8, 0x30db, 0x30de, /* 0x04c8-0x04cf */ + 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e4, 0x30e6, 0x30e8, 0x30e9, /* 0x04d0-0x04d7 */ + 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ef, 0x30f3, 0x309b, 0x309c /* 0x04d8-0x04df */ }; static unsigned short const keysym_to_unicode_590_5fe[] = { - 0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */ - 0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */ + 0x06f0, 0x06f1, 0x06f2, 0x06f3, 0x06f4, 0x06f5, 0x06f6, 0x06f7, /* 0x0590-0x0597 */ + 0x06f8, 0x06f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x0598-0x059f */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x066a, 0x0670, 0x0679, /* 0x05a0-0x05a7 */ - 0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */ - 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */ - 0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */ - 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */ - 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */ - 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */ - 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */ - 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */ - 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */ - 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */ - 0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */ + 0x067e, 0x0686, 0x0688, 0x0691, 0x060c, 0x0000, 0x06d4, 0x0000, /* 0x05ac-0x05af */ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, /* 0x05b0-0x05b7 */ + 0x0668, 0x0669, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f, /* 0x05b8-0x05bf */ + 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, /* 0x05c0-0x05c7 */ + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, /* 0x05c8-0x05cf */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, /* 0x05d0-0x05d7 */ + 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x05d8-0x05df */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, /* 0x05e0-0x05e7 */ + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, /* 0x05e8-0x05ef */ + 0x0650, 0x0651, 0x0652, 0x0653, 0x0654, 0x0655, 0x0698, 0x06a4, /* 0x05f0-0x05f7 */ + 0x06a9, 0x06af, 0x06ba, 0x06be, 0x06cc, 0x06d2, 0x06c1 /* 0x05f8-0x05fe */ }; -static unsigned short const keysym_to_unicode_680_6ff[] = { - 0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */ - 0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */ - 0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */ - 0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */ - 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */ - 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */ - 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */ - 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */ - 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */ - 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */ - 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */ - 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */ - 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */ - 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */ - 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */ - 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */ +static unsigned short keysym_to_unicode_680_6ff[] = { + 0x0492, 0x0496, 0x049a, 0x049c, 0x04a2, 0x04ae, 0x04b0, 0x04b2, /* 0x0680-0x0687 */ + 0x04b6, 0x04b8, 0x04ba, 0x0000, 0x04d8, 0x04e2, 0x04e8, 0x04ee, /* 0x0688-0x068f */ + 0x0493, 0x0497, 0x049b, 0x049d, 0x04a3, 0x04af, 0x04b1, 0x04b3, /* 0x0690-0x0697 */ + 0x04b7, 0x04b9, 0x04bb, 0x0000, 0x04d9, 0x04e3, 0x04e9, 0x04ef, /* 0x0698-0x069f */ + 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, /* 0x06a0-0x06a7 */ + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0491, 0x045e, 0x045f, /* 0x06a8-0x06af */ + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, /* 0x06b0-0x06b7 */ + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0490, 0x040e, 0x040f, /* 0x06b8-0x06bf */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, /* 0x06c0-0x06c7 */ + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, /* 0x06c8-0x06cf */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, /* 0x06d0-0x06d7 */ + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, /* 0x06d8-0x06df */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, /* 0x06e0-0x06e7 */ + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, /* 0x06e8-0x06ef */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, /* 0x06f0-0x06f7 */ + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a /* 0x06f8-0x06ff */ }; static unsigned short const keysym_to_unicode_7a1_7f9[] = { - 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */ - 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */ - 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */ - 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */ - 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */ - 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */ - 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */ - 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */ - 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */ - 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */ - 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */ - 0x03c8, 0x03c9 /* 0x07f8-0x07ff */ + 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c, /* 0x07a0-0x07a7 */ + 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015, /* 0x07a8-0x07af */ + 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, /* 0x07b0-0x07b7 */ + 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07b8-0x07bf */ + 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, /* 0x07c0-0x07c7 */ + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, /* 0x07c8-0x07cf */ + 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7, /* 0x07d0-0x07d7 */ + 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x07d8-0x07df */ + 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, /* 0x07e0-0x07e7 */ + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, /* 0x07e8-0x07ef */ + 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, /* 0x07f0-0x07f7 */ + 0x03c8, 0x03c9 /* 0x07f8-0x07ff */ }; static unsigned short const keysym_to_unicode_8a4_8fe[] = { - 0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */ - 0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */ - 0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */ - 0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x22a2, 0x0000, /* 0x08c8-0x08cf */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */ - 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e8-0x08ef */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */ - 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */ + 0x2320, 0x2321, 0x0000, 0x231c, /* 0x08a0-0x08a7 */ + 0x231d, 0x231e, 0x231f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08a8-0x08af */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08b0-0x08b7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222b, /* 0x08b8-0x08bf */ + 0x2234, 0x0000, 0x221e, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000, /* 0x08c0-0x08c7 */ + 0x2245, 0x2246, 0x0000, 0x0000, 0x0000, 0x0000, 0x21d2, 0x0000, /* 0x08c8-0x08cf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221a, 0x0000, /* 0x08d0-0x08d7 */ + 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222a, 0x2227, 0x2228, /* 0x08d8-0x08df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x08e0-0x08e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202, /* 0x08e8-0x08ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000, /* 0x08f0-0x08f7 */ + 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193 /* 0x08f8-0x08ff */ }; static unsigned short const keysym_to_unicode_9df_9f8[] = { - 0x2422, /* 0x09d8-0x09df */ - 0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */ - 0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */ - 0x2502 /* 0x09f8-0x09ff */ + 0x2422, /* 0x09d8-0x09df */ + 0x2666, 0x25a6, 0x2409, 0x240c, 0x240d, 0x240a, 0x0000, 0x0000, /* 0x09e0-0x09e7 */ + 0x240a, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x2500, /* 0x09e8-0x09ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x251c, 0x2524, 0x2534, 0x252c, /* 0x09f0-0x09f7 */ + 0x2502 /* 0x09f8-0x09ff */ }; static unsigned short const keysym_to_unicode_aa1_afe[] = { - 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */ - 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */ - 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */ - 0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */ - 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */ - 0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */ - 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */ - 0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */ - 0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */ - 0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */ - 0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */ - 0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */ + 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009, /* 0x0aa0-0x0aa7 */ + 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025, /* 0x0aa8-0x0aaf */ + 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, /* 0x0ab0-0x0ab7 */ + 0x2105, 0x0000, 0x0000, 0x2012, 0x2039, 0x2024, 0x203a, 0x0000, /* 0x0ab8-0x0abf */ + 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000, /* 0x0ac0-0x0ac7 */ + 0x0000, 0x2122, 0x2120, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25ad, /* 0x0ac8-0x0acf */ + 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x2030, 0x2032, 0x2033, /* 0x0ad0-0x0ad7 */ + 0x0000, 0x271d, 0x0000, 0x220e, 0x25c2, 0x2023, 0x25cf, 0x25ac, /* 0x0ad8-0x0adf */ + 0x25e6, 0x25ab, 0x25ae, 0x25b5, 0x25bf, 0x2606, 0x2022, 0x25aa, /* 0x0ae0-0x0ae7 */ + 0x25b4, 0x25be, 0x261a, 0x261b, 0x2663, 0x2666, 0x2665, 0x0000, /* 0x0ae8-0x0aef */ + 0x2720, 0x2020, 0x2021, 0x2713, 0x2612, 0x266f, 0x266d, 0x2642, /* 0x0af0-0x0af7 */ + 0x2640, 0x2121, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e /* 0x0af8-0x0aff */ }; /* none of the APL keysyms match the Unicode characters */ static unsigned short const keysym_to_unicode_cdf_cfa[] = { - 0x2017, /* 0x0cd8-0x0cdf */ - 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */ - 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */ - 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */ - 0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */ + 0x2017, /* 0x0cd8-0x0cdf */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, /* 0x0ce0-0x0ce7 */ + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, /* 0x0ce8-0x0cef */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, /* 0x0cf0-0x0cf7 */ + 0x05e8, 0x05e9, 0x05ea /* 0x0cf8-0x0cff */ }; static unsigned short const keysym_to_unicode_da1_df9[] = { - 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */ - 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */ - 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */ - 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */ - 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */ - 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */ - 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */ - 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */ - 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */ - 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */ - 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */ - 0x0e58, 0x0e59 /* 0x0df8-0x0dff */ + 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, /* 0x0da0-0x0da7 */ + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, /* 0x0da8-0x0daf */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, /* 0x0db0-0x0db7 */ + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, /* 0x0db8-0x0dbf */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, /* 0x0dc0-0x0dc7 */ + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, /* 0x0dc8-0x0dcf */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, /* 0x0dd0-0x0dd7 */ + 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0e3e, 0x0e3f, /* 0x0dd8-0x0ddf */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, /* 0x0de0-0x0de7 */ + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0000, 0x0000, /* 0x0de8-0x0def */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, /* 0x0df0-0x0df7 */ + 0x0e58, 0x0e59 /* 0x0df8-0x0dff */ }; static unsigned short const keysym_to_unicode_ea0_eff[] = { - 0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */ - 0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */ - 0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */ - 0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */ - 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */ - 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */ - 0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */ - 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */ - 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */ - 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */ - 0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */ - 0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */ + 0x0000, 0x1101, 0x1101, 0x11aa, 0x1102, 0x11ac, 0x11ad, 0x1103, /* 0x0ea0-0x0ea7 */ + 0x1104, 0x1105, 0x11b0, 0x11b1, 0x11b2, 0x11b3, 0x11b4, 0x11b5, /* 0x0ea8-0x0eaf */ + 0x11b6, 0x1106, 0x1107, 0x1108, 0x11b9, 0x1109, 0x110a, 0x110b, /* 0x0eb0-0x0eb7 */ + 0x110c, 0x110d, 0x110e, 0x110f, 0x1110, 0x1111, 0x1112, 0x1161, /* 0x0eb8-0x0ebf */ + 0x1162, 0x1163, 0x1164, 0x1165, 0x1166, 0x1167, 0x1168, 0x1169, /* 0x0ec0-0x0ec7 */ + 0x116a, 0x116b, 0x116c, 0x116d, 0x116e, 0x116f, 0x1170, 0x1171, /* 0x0ec8-0x0ecf */ + 0x1172, 0x1173, 0x1174, 0x1175, 0x11a8, 0x11a9, 0x11aa, 0x11ab, /* 0x0ed0-0x0ed7 */ + 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3, /* 0x0ed8-0x0edf */ + 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb, /* 0x0ee0-0x0ee7 */ + 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x0000, /* 0x0ee8-0x0eef */ + 0x0000, 0x0000, 0x1140, 0x0000, 0x0000, 0x1159, 0x119e, 0x0000, /* 0x0ef0-0x0ef7 */ + 0x11eb, 0x0000, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9, /* 0x0ef8-0x0eff */ }; -static unsigned short const keysym_to_unicode_12a1_12fe[] = { - 0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */ - 0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */ - 0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */ - 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */ - 0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */ - 0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */ +static unsigned short keysym_to_unicode_12a1_12fe[] = { + 0x1e02, 0x1e03, 0x0000, 0x0000, 0x0000, 0x1e0a, 0x0000, /* 0x12a0-0x12a7 */ + 0x1e80, 0x0000, 0x1e82, 0x1e0b, 0x1ef2, 0x0000, 0x0000, 0x0000, /* 0x12a8-0x12af */ + 0x1e1e, 0x1e1f, 0x0000, 0x0000, 0x1e40, 0x1e41, 0x0000, 0x1e56, /* 0x12b0-0x12b7 */ + 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, /* 0x12b8-0x12bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c0-0x12c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12c8-0x12cf */ + 0x0174, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6a, /* 0x12d0-0x12d7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0176, 0x0000, /* 0x12d8-0x12df */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e0-0x12e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x12e8-0x12ef */ + 0x0175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1e6b, /* 0x12f0-0x12f7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0177 /* 0x12f0-0x12ff */ }; static unsigned short const keysym_to_unicode_13bc_13be[] = { - 0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */ + 0x0152, 0x0153, 0x0178 /* 0x13b8-0x13bf */ }; -static unsigned short const keysym_to_unicode_14a1_14ff[] = { - 0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */ - 0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */ - 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */ - 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */ - 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */ - 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */ - 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */ - 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */ - 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */ - 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */ - 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */ - 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */ +static unsigned short keysym_to_unicode_14a1_14ff[] = { + 0x2741, 0x00a7, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, /* 0x14a0-0x14a7 */ + 0x2014, 0x002e, 0x055d, 0x002c, 0x2013, 0x058a, 0x2026, 0x055c, /* 0x14a8-0x14af */ + 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, /* 0x14b0-0x14b7 */ + 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, /* 0x14b8-0x14bf */ + 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, /* 0x14c0-0x14c7 */ + 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, /* 0x14c8-0x14cf */ + 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, /* 0x14d0-0x14d7 */ + 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, /* 0x14d8-0x14df */ + 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, /* 0x14e0-0x14e7 */ + 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, /* 0x14e8-0x14ef */ + 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, /* 0x14f0-0x14f7 */ + 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x2019, 0x0027, /* 0x14f8-0x14ff */ }; -static unsigned short const keysym_to_unicode_15d0_15f6[] = { - 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */ - 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */ - 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */ - 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */ - 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */ +static unsigned short keysym_to_unicode_15d0_15f6[] = { + 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, /* 0x15d0-0x15d7 */ + 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, /* 0x15d8-0x15df */ + 0x10e0, 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, /* 0x15e0-0x15e7 */ + 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, /* 0x15e8-0x15ef */ + 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6 /* 0x15f0-0x15f7 */ }; -static unsigned short const keysym_to_unicode_16a0_16f6[] = { - 0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */ - 0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */ - 0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */ - 0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */ - 0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */ - 0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */ +static unsigned short keysym_to_unicode_16a0_16f6[] = { + 0x0000, 0x0000, 0xf0a2, 0x1e8a, 0x0000, 0xf0a5, 0x012c, 0xf0a7, /* 0x16a0-0x16a7 */ + 0xf0a8, 0x01b5, 0x01e6, 0x0000, 0x0000, 0x0000, 0x0000, 0x019f, /* 0x16a8-0x16af */ + 0x0000, 0x0000, 0xf0b2, 0x1e8b, 0x01d1, 0xf0b5, 0x012d, 0xf0b7, /* 0x16b0-0x16b7 */ + 0xf0b8, 0x01b6, 0x01e7, 0x0000, 0x0000, 0x01d2, 0x0000, 0x0275, /* 0x16b8-0x16bf */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x018f, 0x0000, /* 0x16c0-0x16c7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16c8-0x16cf */ + 0x0000, 0x1e36, 0xf0d2, 0xf0d3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d0-0x16d7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16d8-0x16df */ + 0x0000, 0x1e37, 0xf0e2, 0xf0e3, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e0-0x16e7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 0x16e8-0x16ef */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0259 /* 0x16f0-0x16f6 */ }; static unsigned short const keysym_to_unicode_1e9f_1eff[] = { - 0x0303, - 0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */ - 0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */ - 0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */ - 0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */ - 0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */ - 0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */ - 0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */ - 0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */ - 0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */ - 0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */ - 0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */ - 0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */ + 0x0303, + 0x1ea0, 0x1ea1, 0x1ea2, 0x1ea3, 0x1ea4, 0x1ea5, 0x1ea6, 0x1ea7, /* 0x1ea0-0x1ea7 */ + 0x1ea8, 0x1ea9, 0x1eaa, 0x1eab, 0x1eac, 0x1ead, 0x1eae, 0x1eaf, /* 0x1ea8-0x1eaf */ + 0x1eb0, 0x1eb1, 0x1eb2, 0x1eb3, 0x1eb4, 0x1eb5, 0x1eb6, 0x1eb7, /* 0x1eb0-0x1eb7 */ + 0x1eb8, 0x1eb9, 0x1eba, 0x1ebb, 0x1ebc, 0x1ebd, 0x1ebe, 0x1ebf, /* 0x1eb8-0x1ebf */ + 0x1ec0, 0x1ec1, 0x1ec2, 0x1ec3, 0x1ec4, 0x1ec5, 0x1ec6, 0x1ec7, /* 0x1ec0-0x1ec7 */ + 0x1ec8, 0x1ec9, 0x1eca, 0x1ecb, 0x1ecc, 0x1ecd, 0x1ece, 0x1ecf, /* 0x1ec8-0x1ecf */ + 0x1ed0, 0x1ed1, 0x1ed2, 0x1ed3, 0x1ed4, 0x1ed5, 0x1ed6, 0x1ed7, /* 0x1ed0-0x1ed7 */ + 0x1ed8, 0x1ed9, 0x1eda, 0x1edb, 0x1edc, 0x1edd, 0x1ede, 0x1edf, /* 0x1ed8-0x1edf */ + 0x1ee0, 0x1ee1, 0x1ee2, 0x1ee3, 0x1ee4, 0x1ee5, 0x1ee6, 0x1ee7, /* 0x1ee0-0x1ee7 */ + 0x1ee8, 0x1ee9, 0x1eea, 0x1eeb, 0x1eec, 0x1eed, 0x1eee, 0x1eef, /* 0x1ee8-0x1eef */ + 0x1ef0, 0x1ef1, 0x0300, 0x0301, 0x1ef4, 0x1ef5, 0x1ef6, 0x1ef7, /* 0x1ef0-0x1ef7 */ + 0x1ef8, 0x1ef9, 0x01a0, 0x01a1, 0x01af, 0x01b0, 0x0309, 0x0323 /* 0x1ef8-0x1eff */ }; static unsigned short const keysym_to_unicode_20a0_20ac[] = { - 0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */ - 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ + 0x20a0, 0x20a1, 0x20a2, 0x20a3, 0x20a4, 0x20a5, 0x20a6, 0x20a7, /* 0x20a0-0x20a7 */ + 0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */ }; unsigned int @@ -302,49 +301,50 @@ X11_KeySymToUcs4(KeySym keysym) return (keysym & 0x00ffffff); if (keysym > 0 && keysym < 0x100) - return keysym; + return keysym; else if (keysym > 0x1a0 && keysym < 0x200) - return keysym_to_unicode_1a1_1ff[keysym - 0x1a1]; + return keysym_to_unicode_1a1_1ff[keysym - 0x1a1]; else if (keysym > 0x2a0 && keysym < 0x2ff) - return keysym_to_unicode_2a1_2fe[keysym - 0x2a1]; + return keysym_to_unicode_2a1_2fe[keysym - 0x2a1]; else if (keysym > 0x3a1 && keysym < 0x3ff) - return keysym_to_unicode_3a2_3fe[keysym - 0x3a2]; + return keysym_to_unicode_3a2_3fe[keysym - 0x3a2]; else if (keysym > 0x4a0 && keysym < 0x4e0) - return keysym_to_unicode_4a1_4df[keysym - 0x4a1]; + return keysym_to_unicode_4a1_4df[keysym - 0x4a1]; else if (keysym > 0x589 && keysym < 0x5ff) - return keysym_to_unicode_590_5fe[keysym - 0x590]; + return keysym_to_unicode_590_5fe[keysym - 0x590]; else if (keysym > 0x67f && keysym < 0x700) - return keysym_to_unicode_680_6ff[keysym - 0x680]; + return keysym_to_unicode_680_6ff[keysym - 0x680]; else if (keysym > 0x7a0 && keysym < 0x7fa) - return keysym_to_unicode_7a1_7f9[keysym - 0x7a1]; + return keysym_to_unicode_7a1_7f9[keysym - 0x7a1]; else if (keysym > 0x8a3 && keysym < 0x8ff) - return keysym_to_unicode_8a4_8fe[keysym - 0x8a4]; + return keysym_to_unicode_8a4_8fe[keysym - 0x8a4]; else if (keysym > 0x9de && keysym < 0x9f9) - return keysym_to_unicode_9df_9f8[keysym - 0x9df]; + return keysym_to_unicode_9df_9f8[keysym - 0x9df]; else if (keysym > 0xaa0 && keysym < 0xaff) - return keysym_to_unicode_aa1_afe[keysym - 0xaa1]; + return keysym_to_unicode_aa1_afe[keysym - 0xaa1]; else if (keysym > 0xcde && keysym < 0xcfb) - return keysym_to_unicode_cdf_cfa[keysym - 0xcdf]; + return keysym_to_unicode_cdf_cfa[keysym - 0xcdf]; else if (keysym > 0xda0 && keysym < 0xdfa) - return keysym_to_unicode_da1_df9[keysym - 0xda1]; + return keysym_to_unicode_da1_df9[keysym - 0xda1]; else if (keysym > 0xe9f && keysym < 0xf00) - return keysym_to_unicode_ea0_eff[keysym - 0xea0]; + return keysym_to_unicode_ea0_eff[keysym - 0xea0]; else if (keysym > 0x12a0 && keysym < 0x12ff) - return keysym_to_unicode_12a1_12fe[keysym - 0x12a1]; + return keysym_to_unicode_12a1_12fe[keysym - 0x12a1]; else if (keysym > 0x13bb && keysym < 0x13bf) - return keysym_to_unicode_13bc_13be[keysym - 0x13bc]; + return keysym_to_unicode_13bc_13be[keysym - 0x13bc]; else if (keysym > 0x14a0 && keysym < 0x1500) return keysym_to_unicode_14a1_14ff[keysym - 0x14a1]; else if (keysym > 0x15cf && keysym < 0x15f7) - return keysym_to_unicode_15d0_15f6[keysym - 0x15d0]; + return keysym_to_unicode_15d0_15f6[keysym - 0x15d0]; else if (keysym > 0x169f && keysym < 0x16f7) - return keysym_to_unicode_16a0_16f6[keysym - 0x16a0]; + return keysym_to_unicode_16a0_16f6[keysym - 0x16a0]; else if (keysym > 0x1e9e && keysym < 0x1f00) - return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f]; + return keysym_to_unicode_1e9f_1eff[keysym - 0x1e9f]; else if (keysym > 0x209f && keysym < 0x20ad) - return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; + return keysym_to_unicode_20a0_20ac[keysym - 0x20a0]; else - return 0; + return 0; } #endif /* SDL_VIDEO_DRIVER_X11 */ + diff --git a/Engine/lib/sdl/src/video/x11/imKStoUCS.h b/Engine/lib/sdl/src/video/x11/imKStoUCS.h index cc684c2e3..fe4381d98 100644 --- a/Engine/lib/sdl/src/video/x11/imKStoUCS.h +++ b/Engine/lib/sdl/src/video/x11/imKStoUCS.h @@ -1,29 +1,30 @@ #ifndef _imKStoUCS_h #define _imKStoUCS_h -/* Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved. +/* +Copyright (C) 2003-2006,2008 Jamey Sharp, Josh Triplett +Copyright © 2009 Red Hat, Inc. +Copyright 1990-1992,1999,2000,2004,2009,2010 Oracle and/or its affiliates. +All rights reserved. -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 fur- -nished to do so, subject to the following conditions: +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 above copyright notice and this permission notice (including the next +paragraph) 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, FIT- -NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON- -NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the XFree86 Project shall not -be used in advertising or otherwise to promote the sale, use or other deal- -ings in this Software without prior written authorization from the XFree86 -Project. +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. */ extern unsigned int X11_KeySymToUcs4(KeySym keysym); From 170cdadf6000a55f2f3f4fab6bb0fcd659aaa599 Mon Sep 17 00:00:00 2001 From: Areloch Date: Thu, 22 Dec 2016 00:52:34 -0600 Subject: [PATCH 05/50] Fixes window icons with SDL, hooking it through the var $Core::windowIcon as the path. Also adjusted the splash window icon to use the var $Core::splashWindowImage for it's path. --- Engine/source/console/consoleFunctions.cpp | 7 ++- .../source/windowManager/sdl/sdlWindowMgr.cpp | 46 +++++++++++++++++++ Templates/Empty/game/main.cs | 2 + Templates/Full/game/main.cs | 2 + 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index 7f8fbf1c0..76b3f3d9f 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -2141,13 +2141,18 @@ DefineEngineFunction( gotoWebPage, void, ( const char* address ),, //----------------------------------------------------------------------------- -DefineEngineFunction( displaySplashWindow, bool, (const char* path), ("art/gui/splash.bmp"), +DefineEngineFunction( displaySplashWindow, bool, (const char* path), (""), "Display a startup splash window suitable for showing while the engine still starts up.\n\n" "@note This is currently only implemented on Windows.\n\n" "@param path relative path to splash screen image to display.\n" "@return True if the splash window could be successfully initialized.\n\n" "@ingroup Platform" ) { + if (path == "") + { + path = Con::getVariable("$Core::splashWindowImage"); + } + return Platform::displaySplashWindow(path); } diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp index 9dbe1708d..6157374dd 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp @@ -24,6 +24,7 @@ #include "gfx/gfxDevice.h" #include "core/util/journal/process.h" #include "core/strings/unicode.h" +#include "gfx/bitmap/gBitmap.h" #include "SDL.h" @@ -165,6 +166,51 @@ PlatformWindow *PlatformWindowManagerSDL::createWindow(GFXDevice *device, const window->mOwningManager = this; mWindowMap[ window->mWindowId ] = window; + //Now, fetch our window icon, if any + Torque::Path iconPath = Torque::Path(Con::getVariable( "$Core::windowIcon" )); + Resource bmp = GBitmap::load(iconPath); + if (bmp != NULL) + { + U32 pitch; + U32 width = bmp->getWidth(); + bool hasAlpha = bmp->getHasTransparency(); + U32 depth; + + if (hasAlpha) + { + pitch = 4 * width; + depth = 32; + } + else + { + pitch = 3 * width; + depth = 24; + } + + Uint32 rmask, gmask, bmask, amask; + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) + { + S32 shift = hasAlpha ? 8 : 0; + rmask = 0xff000000 >> shift; + gmask = 0x00ff0000 >> shift; + bmask = 0x0000ff00 >> shift; + amask = 0x000000ff >> shift; + } + else + { + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = hasAlpha ? 0xff000000 : 0; + } + + SDL_Surface* iconSurface = SDL_CreateRGBSurfaceFrom(bmp->getAddress(0, 0), bmp->getWidth(), bmp->getHeight(), depth, pitch, rmask, gmask, bmask, amask); + + SDL_SetWindowIcon(window->mWindowHandle, iconSurface); + + SDL_FreeSurface(iconSurface); + } + if(device) { window->mDevice = device; diff --git a/Templates/Empty/game/main.cs b/Templates/Empty/game/main.cs index 22a3ab2ff..87daf9770 100644 --- a/Templates/Empty/game/main.cs +++ b/Templates/Empty/game/main.cs @@ -28,6 +28,8 @@ $defaultGame = "scripts"; // Set profile directory $Pref::Video::ProfilePath = "core/profile"; +$Core::windowIcon = "core/torque.png"; +$Core::splashWindowImage = "art/gui/splash.bmp"; function createCanvas(%windowTitle) { diff --git a/Templates/Full/game/main.cs b/Templates/Full/game/main.cs index 2a261201d..d4a6656e0 100644 --- a/Templates/Full/game/main.cs +++ b/Templates/Full/game/main.cs @@ -28,6 +28,8 @@ $defaultGame = "scripts"; // Set profile directory $Pref::Video::ProfilePath = "core/profile"; +$Core::windowIcon = "core/torque.png"; +$Core::splashWindowImage = "art/gui/splash.bmp"; function createCanvas(%windowTitle) { From 5e47c018b2f8ea5dacb42a0bc3fdbabca361e5d2 Mon Sep 17 00:00:00 2001 From: Johxz Date: Sun, 1 Jan 2017 21:40:41 -0600 Subject: [PATCH 06/50] enable video recording --- .../game/core/scripts/client/screenshot.cs | 15 +++++++ .../Empty/game/scripts/client/default.bind.cs | 43 +++++++++++++++++++ .../game/core/scripts/client/screenshot.cs | 15 +++++++ .../Full/game/scripts/client/default.bind.cs | 43 +++++++++++++++++++ 4 files changed, 116 insertions(+) diff --git a/Templates/Empty/game/core/scripts/client/screenshot.cs b/Templates/Empty/game/core/scripts/client/screenshot.cs index 897325a1a..3c78aa2cd 100644 --- a/Templates/Empty/game/core/scripts/client/screenshot.cs +++ b/Templates/Empty/game/core/scripts/client/screenshot.cs @@ -55,6 +55,9 @@ function formatSessionNumber(%number) // Records a movie file from the Canvas content using the specified fps. // Possible encoder values are "PNG" and "THEORA" (default). //--------------------------------------------------------------------------------------------- + +$RecordingMovie = false; + function recordMovie(%movieName, %fps, %encoder) { // If the canvas doesn't exist yet, setup a flag so it'll @@ -65,12 +68,24 @@ function recordMovie(%movieName, %fps, %encoder) if (%encoder $= "") %encoder = "THEORA"; %resolution = Canvas.getVideoMode(); + + // Start the movie recording + ChatHud.AddLine( "\c4Recording movie file to [\c2" @ %movieName @ "\cr].ogv."); + echo("Recording movie to: " @ %movieName); startVideoCapture(Canvas, %movieName, %encoder, %fps); + + $RecordingMovie = true; } function stopMovie() { + // Stop the current recording + ChatHud.AddLine( "\c4Recording movie file finished."); + echo("Stopped movie recording"); + stopVideoCapture(); + + $RecordingMovie = false; } /// This is bound in initializeCommon() to take diff --git a/Templates/Empty/game/scripts/client/default.bind.cs b/Templates/Empty/game/scripts/client/default.bind.cs index 51dc53d4b..b4216a33d 100644 --- a/Templates/Empty/game/scripts/client/default.bind.cs +++ b/Templates/Empty/game/scripts/client/default.bind.cs @@ -409,6 +409,49 @@ function stopRecordingDemo( %val ) moveMap.bind( keyboard, F3, startRecordingDemo ); moveMap.bind( keyboard, F4, stopRecordingDemo ); +//------------------------------------------------------------------------------ +// Theora Video Capture (Records a movie file) +//------------------------------------------------------------------------------ + +function toggleMovieRecording(%val) +{ + if (!%val) + return; + + %movieEncodingType = "THEORA"; // Valid encoder values are "PNG" and "THEORA" (default). + %movieFPS = 30; // video capture frame rate. + + if (!$RecordingMovie) + { + // locate a non-existent filename to use + for(%i = 0; %i < 1000; %i++) + { + %num = %i; + if(%num < 10) + %num = "0" @ %num; + if(%num < 100) + %num = "0" @ %num; + + %filePath = "movies/movie" @ %num; + if(!isfile(%filePath)) + break; + } + if(%i == 1000) + return; + + // Start the movie recording + recordMovie(%filePath, %movieFPS, %movieEncodingType); + + } + else + { + // Stop the current recording + stopMovie(); + } +} + +// Key binding works at any time and not just while in a game. +GlobalActionMap.bind(keyboard, "alt m", toggleMovieRecording); //------------------------------------------------------------------------------ // Helper Functions diff --git a/Templates/Full/game/core/scripts/client/screenshot.cs b/Templates/Full/game/core/scripts/client/screenshot.cs index 897325a1a..3c78aa2cd 100644 --- a/Templates/Full/game/core/scripts/client/screenshot.cs +++ b/Templates/Full/game/core/scripts/client/screenshot.cs @@ -55,6 +55,9 @@ function formatSessionNumber(%number) // Records a movie file from the Canvas content using the specified fps. // Possible encoder values are "PNG" and "THEORA" (default). //--------------------------------------------------------------------------------------------- + +$RecordingMovie = false; + function recordMovie(%movieName, %fps, %encoder) { // If the canvas doesn't exist yet, setup a flag so it'll @@ -65,12 +68,24 @@ function recordMovie(%movieName, %fps, %encoder) if (%encoder $= "") %encoder = "THEORA"; %resolution = Canvas.getVideoMode(); + + // Start the movie recording + ChatHud.AddLine( "\c4Recording movie file to [\c2" @ %movieName @ "\cr].ogv."); + echo("Recording movie to: " @ %movieName); startVideoCapture(Canvas, %movieName, %encoder, %fps); + + $RecordingMovie = true; } function stopMovie() { + // Stop the current recording + ChatHud.AddLine( "\c4Recording movie file finished."); + echo("Stopped movie recording"); + stopVideoCapture(); + + $RecordingMovie = false; } /// This is bound in initializeCommon() to take diff --git a/Templates/Full/game/scripts/client/default.bind.cs b/Templates/Full/game/scripts/client/default.bind.cs index 1af881a81..ed804bbb2 100644 --- a/Templates/Full/game/scripts/client/default.bind.cs +++ b/Templates/Full/game/scripts/client/default.bind.cs @@ -583,6 +583,49 @@ function stopRecordingDemo( %val ) moveMap.bind( keyboard, F3, startRecordingDemo ); moveMap.bind( keyboard, F4, stopRecordingDemo ); +//------------------------------------------------------------------------------ +// Theora Video Capture (Records a movie file) +//------------------------------------------------------------------------------ + +function toggleMovieRecording(%val) +{ + if (!%val) + return; + + %movieEncodingType = "THEORA"; // Valid encoder values are "PNG" and "THEORA" (default). + %movieFPS = 30; // video capture frame rate. + + if (!$RecordingMovie) + { + // locate a non-existent filename to use + for(%i = 0; %i < 1000; %i++) + { + %num = %i; + if(%num < 10) + %num = "0" @ %num; + if(%num < 100) + %num = "0" @ %num; + + %filePath = "movies/movie" @ %num; + if(!isfile(%filePath)) + break; + } + if(%i == 1000) + return; + + // Start the movie recording + recordMovie(%filePath, %movieFPS, %movieEncodingType); + + } + else + { + // Stop the current recording + stopMovie(); + } +} + +// Key binding works at any time and not just while in a game. +GlobalActionMap.bind(keyboard, "alt m", toggleMovieRecording); //------------------------------------------------------------------------------ // Helper Functions From b23b8d118eab67845e8f932d32901f16dee3a3e1 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Wed, 4 Jan 2017 01:47:01 +1000 Subject: [PATCH 07/50] Physx 3.3 cmake support --- Tools/CMake/basics.cmake | 41 ++++++ Tools/CMake/modules/module_physx3.cmake | 161 ++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 Tools/CMake/modules/module_physx3.cmake diff --git a/Tools/CMake/basics.cmake b/Tools/CMake/basics.cmake index 56954541e..970518f0f 100644 --- a/Tools/CMake/basics.cmake +++ b/Tools/CMake/basics.cmake @@ -165,11 +165,52 @@ macro(addLib libs) endforeach() endmacro() +#addLibRelease will add to only release builds +macro(addLibRelease libs) + foreach(lib ${libs}) + # check if we can build it ourselfs + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/${lib}.cmake") + addLibSrc("${CMAKE_CURRENT_SOURCE_DIR}/libraries/${lib}.cmake") + endif() + # then link against it + # two possibilities: a) target already known, so add it directly, or b) target not yet known, so add it to its cache + if(TARGET ${PROJECT_NAME}) + target_link_libraries(${PROJECT_NAME} optimized "${lib}") + else() + list(APPEND ${PROJECT_NAME}_libsRelease ${lib}) + endif() + endforeach() +endmacro() + +#addLibDebug will add to only debug builds +macro(addLibDebug libs) + foreach(lib ${libs}) + # check if we can build it ourselfs + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/${lib}.cmake") + addLibSrc("${CMAKE_CURRENT_SOURCE_DIR}/libraries/${lib}.cmake") + endif() + # then link against it + # two possibilities: a) target already known, so add it directly, or b) target not yet known, so add it to its cache + if(TARGET ${PROJECT_NAME}) + target_link_libraries(${PROJECT_NAME} debug "${lib}") + else() + list(APPEND ${PROJECT_NAME}_libsDebug ${lib}) + endif() + endforeach() +endmacro() + # this applies cached definitions onto the target macro(_process_libs) if(DEFINED ${PROJECT_NAME}_libs) target_link_libraries(${PROJECT_NAME} "${${PROJECT_NAME}_libs}") endif() + if(DEFINED ${PROJECT_NAME}_libsRelease) + target_link_libraries(${PROJECT_NAME} optimized "${${PROJECT_NAME}_libsRelease}") + endif() + if(DEFINED ${PROJECT_NAME}_libsDebug) + target_link_libraries(${PROJECT_NAME} debug "${${PROJECT_NAME}_libsDebug}") + endif() + endmacro() # apple frameworks diff --git a/Tools/CMake/modules/module_physx3.cmake b/Tools/CMake/modules/module_physx3.cmake new file mode 100644 index 000000000..f58ce1970 --- /dev/null +++ b/Tools/CMake/modules/module_physx3.cmake @@ -0,0 +1,161 @@ +# ----------------------------------------------------------------------------- +# Copyright (c) 2015 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. +# ----------------------------------------------------------------------------- + +# module Physx 3.3 + +option(TORQUE_PHYSICS_PHYSX3 "Use PhysX 3.3 physics" OFF) + +if( NOT TORQUE_PHYSICS_PHYSX3 ) + return() +endif() + +if("${PHYSX3_BASE_PATH}" STREQUAL "") + set(PHYSX3_BASE_PATH "" CACHE PATH "PhysX 3.3 path" FORCE) +endif() + +#still no path we can't go any further +if("${PHYSX3_BASE_PATH}" STREQUAL "") + message(FATAL_ERROR "No PhysX path selected") + return() +endif() + +#set physx path +set(PHYSX3_PATH "${PHYSX3_BASE_PATH}/PhysXSDK") + +# TODO linux support +if(MSVC) +if(TORQUE_CPU_X32) + if(MSVC11) + set(PHYSX3_LIBPATH_PREFIX vc11win32) + elseif(MSVC12) + set(PHYSX3_LIBPATH_PREFIX vc12win32) + elseif(MSVC14) + set(PHYSX3_LIBPATH_PREFIX vc14win32) + else() + return() + endif() +set(PHYSX3_LIBNAME_POSTFIX _x86) + +elseif(TORQUE_CPU_X64) + if(MSVC11) + set(PHYSX3_LIBPATH_PREFIX vc11win64) + elseif(MSVC12) + set(PHYSX3_LIBPATH_PREFIX vc12win64) + elseif(MSVC14) + set(PHYSX3_LIBPATH_PREFIX vc14win64) + else() + return() + endif() +set(PHYSX3_LIBNAME_POSTFIX _x64) + +endif() + +endif(MSVC) + +MACRO(FIND_PHYSX3_LIBRARY VARNAME LIBNAME WITHPOSTFIX) + + set(LIBPOSTFIX "") + if(${WITHPOSTFIX}) + set(LIBPOSTFIX ${PHYSX3_LIBNAME_POSTFIX}) + endif(${WITHPOSTFIX}) + find_library(PHYSX3_${VARNAME}_LIBRARY NAMES ${LIBNAME}${LIBPOSTFIX} + PATHS ${PHYSX3_PATH}/Lib/${PHYSX3_LIBPATH_PREFIX}) + find_library(PHYSX3_${VARNAME}_LIBRARY_DEBUG NAMES ${LIBNAME}DEBUG${LIBPOSTFIX} + PATHS ${PHYSX3_PATH}/Lib/${PHYSX3_LIBPATH_PREFIX}) + +ENDMACRO(FIND_PHYSX3_LIBRARY VARNAME LIBNAME) + +# Find the Libs, we just use the full path to save playing around with link_directories +FIND_PHYSX3_LIBRARY(CORE PhysX3 1) +FIND_PHYSX3_LIBRARY(COMMON PhysX3Common 1) +FIND_PHYSX3_LIBRARY(COOKING PhysX3Cooking 1) +FIND_PHYSX3_LIBRARY(CHARACTER PhysX3CharacterKinematic 1) +FIND_PHYSX3_LIBRARY(EXTENSIONS PhysX3Extensions 0) +FIND_PHYSX3_LIBRARY(TASK PxTask 0) +FIND_PHYSX3_LIBRARY(DEBUGGER PhysXVisualDebuggerSDK 0) +FIND_PHYSX3_LIBRARY(PROFILE PhysXProfileSDK 0) + +if(NOT PHYSX3_CORE_LIBRARY) + return() +endif() + +# Defines +addDef( "TORQUE_PHYSICS_PHYSX3" ) +addDef( "TORQUE_PHYSICS_ENABLED" ) + +# Source +addPath( "${srcDir}/T3D/physics/physx3" ) + +# Includes +addInclude( "${PHYSX3_PATH}/Include" ) +addInclude( "${PHYSX3_PATH}/Include/extensions" ) +addInclude( "${PHYSX3_PATH}/Include/foundation" ) +addInclude( "${PHYSX3_PATH}/Include/characterkinematic" ) +addInclude( "${PHYSX3_PATH}/Include/common" ) + +#Add the libs +set(PHYSX_LIBRARIES_DEBUG + ${PHYSX3_CORE_LIBRARY_DEBUG} + ${PHYSX3_COMMON_LIBRARY_DEBUG} + ${PHYSX3_COOKING_LIBRARY_DEBUG} + ${PHYSX3_CHARACTER_LIBRARY_DEBUG} + ${PHYSX3_EXTENSIONS_LIBRARY_DEBUG} + ${PHYSX3_TASK_LIBRARY_DEBUG} + ${PHYSX3_DEBUGGER_LIBRARY_DEBUG} + ${PHYSX3_PROFILE_LIBRARY_DEBUG} +) + +set(PHYSX_LIBRARIES + ${PHYSX3_CORE_LIBRARY} + ${PHYSX3_COMMON_LIBRARY} + ${PHYSX3_COOKING_LIBRARY} + ${PHYSX3_CHARACTER_LIBRARY} + ${PHYSX3_EXTENSIONS_LIBRARY} + ${PHYSX3_TASK_LIBRARY} + ${PHYSX3_DEBUGGER_LIBRARY} + ${PHYSX3_PROFILE_LIBRARY} +) + +addLibRelease("${PHYSX_LIBRARIES}") +addLibDebug("${PHYSX_LIBRARIES_DEBUG}") + +#Install dll files +if( WIN32 ) + # File Copy for Release + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3CharacterKinematic${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3Common${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3Cooking${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") + + # File Copy for Debug + if(TORQUE_CPU_X32) + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/nvToolsExt32_1.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Debug") + elseif(TORQUE_CPU_X64) + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/nvToolsExt64_1.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Debug") + endif() + + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3DEBUG${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Debug") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3CharacterKinematicDEBUG${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Debug") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3CommonDEBUG${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Debug") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3CookingDEBUG${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Debug") + +endif(WIN32) From e896ce0e4ef3c44e695c74e2e60c209d5eb72f41 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Wed, 4 Jan 2017 01:47:43 +1000 Subject: [PATCH 08/50] Cache PxRenderBuffer --- Engine/source/T3D/physics/physx3/px3World.cpp | 27 +++++++++---------- Engine/source/T3D/physics/physx3/px3World.h | 1 + 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Engine/source/T3D/physics/physx3/px3World.cpp b/Engine/source/T3D/physics/physx3/px3World.cpp index ca5be2302..888417afa 100644 --- a/Engine/source/T3D/physics/physx3/px3World.cpp +++ b/Engine/source/T3D/physics/physx3/px3World.cpp @@ -63,7 +63,8 @@ Px3World::Px3World(): mScene( NULL ), mEditorTimeScale( 1.0f ), mAccumulator( 0 ), mControllerManager(NULL), - mIsSceneLocked(false) + mIsSceneLocked(false), + mRenderBuffer(NULL) { } @@ -177,6 +178,8 @@ void Px3World::destroyWorld() { getPhysicsResults(); + mRenderBuffer = NULL; + // Release the tick processing signals. if ( mProcessList ) { @@ -223,13 +226,14 @@ bool Px3World::initWorld( bool isServer, ProcessList *processList ) sceneDesc.cpuDispatcher = smCpuDispatcher; Con::printf("PhysX3 using Cpu: %d workers", smCpuDispatcher->getWorkerCount()); } - sceneDesc.flags |= physx::PxSceneFlag::eENABLE_CCD; sceneDesc.flags |= physx::PxSceneFlag::eENABLE_ACTIVETRANSFORMS; sceneDesc.filterShader = physx::PxDefaultSimulationFilterShader; mScene = gPhysics3SDK->createScene(sceneDesc); + //cache renderbuffer for use with debug drawing + mRenderBuffer = const_cast(&mScene->getRenderBuffer()); physx::PxDominanceGroupPair debrisDominance( 0.0f, 1.0f ); mScene->setDominanceGroupPair(0,31,debrisDominance); @@ -548,22 +552,17 @@ static ColorI getDebugColor( physx::PxU32 packed ) void Px3World::onDebugDraw( const SceneRenderState *state ) { - if ( !mScene ) + if ( !mScene || !mRenderBuffer ) return; mScene->setVisualizationParameter(physx::PxVisualizationParameter::eSCALE,1.0f); mScene->setVisualizationParameter(physx::PxVisualizationParameter::eBODY_AXES,1.0f); mScene->setVisualizationParameter(physx::PxVisualizationParameter::eCOLLISION_SHAPES,1.0f); - const physx::PxRenderBuffer *renderBuffer = &mScene->getRenderBuffer(); - - if(!renderBuffer) - return; - // Render points { - physx::PxU32 numPoints = renderBuffer->getNbPoints(); - const physx::PxDebugPoint *points = renderBuffer->getPoints(); + physx::PxU32 numPoints = mRenderBuffer->getNbPoints(); + const physx::PxDebugPoint *points = mRenderBuffer->getPoints(); PrimBuild::begin( GFXPointList, numPoints ); @@ -579,8 +578,8 @@ void Px3World::onDebugDraw( const SceneRenderState *state ) // Render lines { - physx::PxU32 numLines = renderBuffer->getNbLines(); - const physx::PxDebugLine *lines = renderBuffer->getLines(); + physx::PxU32 numLines = mRenderBuffer->getNbLines(); + const physx::PxDebugLine *lines = mRenderBuffer->getLines(); PrimBuild::begin( GFXLineList, numLines * 2 ); @@ -598,8 +597,8 @@ void Px3World::onDebugDraw( const SceneRenderState *state ) // Render triangles { - physx::PxU32 numTris = renderBuffer->getNbTriangles(); - const physx::PxDebugTriangle *triangles = renderBuffer->getTriangles(); + physx::PxU32 numTris = mRenderBuffer->getNbTriangles(); + const physx::PxDebugTriangle *triangles = mRenderBuffer->getTriangles(); PrimBuild::begin( GFXTriangleList, numTris * 3 ); diff --git a/Engine/source/T3D/physics/physx3/px3World.h b/Engine/source/T3D/physics/physx3/px3World.h index 9556aac4b..7a14ef4af 100644 --- a/Engine/source/T3D/physics/physx3/px3World.h +++ b/Engine/source/T3D/physics/physx3/px3World.h @@ -61,6 +61,7 @@ protected: ProcessList *mProcessList; F32 mEditorTimeScale; bool mErrorReport; + physx::PxRenderBuffer *mRenderBuffer; physx::PxControllerManager* mControllerManager; static Px3ConsoleStream *smErrorCallback; static physx::PxDefaultAllocator smMemoryAlloc; From 215ae090b47534a477ea33094f20592a647103d4 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Wed, 4 Jan 2017 13:34:33 +1000 Subject: [PATCH 09/50] Physx 2.8 removal --- Engine/source/T3D/physics/physx/px.h | 80 - Engine/source/T3D/physics/physx/pxBody.cpp | 404 --- Engine/source/T3D/physics/physx/pxBody.h | 114 - Engine/source/T3D/physics/physx/pxCasts.h | 150 - Engine/source/T3D/physics/physx/pxCloth.cpp | 923 ------ Engine/source/T3D/physics/physx/pxCloth.h | 176 -- .../source/T3D/physics/physx/pxCollision.cpp | 291 -- Engine/source/T3D/physics/physx/pxCollision.h | 78 - .../T3D/physics/physx/pxContactReporter.cpp | 108 - .../T3D/physics/physx/pxContactReporter.h | 54 - Engine/source/T3D/physics/physx/pxFluid.cpp | 310 -- Engine/source/T3D/physics/physx/pxFluid.h | 107 - .../source/T3D/physics/physx/pxMaterial.cpp | 150 - Engine/source/T3D/physics/physx/pxMaterial.h | 69 - .../source/T3D/physics/physx/pxMultiActor.cpp | 2651 ----------------- .../source/T3D/physics/physx/pxMultiActor.h | 398 --- Engine/source/T3D/physics/physx/pxPlayer.cpp | 428 --- Engine/source/T3D/physics/physx/pxPlayer.h | 106 - Engine/source/T3D/physics/physx/pxPlugin.cpp | 297 -- Engine/source/T3D/physics/physx/pxPlugin.h | 59 - Engine/source/T3D/physics/physx/pxStream.cpp | 174 -- Engine/source/T3D/physics/physx/pxStream.h | 78 - Engine/source/T3D/physics/physx/pxUtils.cpp | 109 - Engine/source/T3D/physics/physx/pxUtils.h | 38 - Engine/source/T3D/physics/physx/pxWorld.cpp | 876 ------ Engine/source/T3D/physics/physx/pxWorld.h | 193 -- 26 files changed, 8421 deletions(-) delete mode 100644 Engine/source/T3D/physics/physx/px.h delete mode 100644 Engine/source/T3D/physics/physx/pxBody.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxBody.h delete mode 100644 Engine/source/T3D/physics/physx/pxCasts.h delete mode 100644 Engine/source/T3D/physics/physx/pxCloth.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxCloth.h delete mode 100644 Engine/source/T3D/physics/physx/pxCollision.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxCollision.h delete mode 100644 Engine/source/T3D/physics/physx/pxContactReporter.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxContactReporter.h delete mode 100644 Engine/source/T3D/physics/physx/pxFluid.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxFluid.h delete mode 100644 Engine/source/T3D/physics/physx/pxMaterial.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxMaterial.h delete mode 100644 Engine/source/T3D/physics/physx/pxMultiActor.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxMultiActor.h delete mode 100644 Engine/source/T3D/physics/physx/pxPlayer.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxPlayer.h delete mode 100644 Engine/source/T3D/physics/physx/pxPlugin.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxPlugin.h delete mode 100644 Engine/source/T3D/physics/physx/pxStream.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxStream.h delete mode 100644 Engine/source/T3D/physics/physx/pxUtils.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxUtils.h delete mode 100644 Engine/source/T3D/physics/physx/pxWorld.cpp delete mode 100644 Engine/source/T3D/physics/physx/pxWorld.h diff --git a/Engine/source/T3D/physics/physx/px.h b/Engine/source/T3D/physics/physx/px.h deleted file mode 100644 index 856035cf7..000000000 --- a/Engine/source/T3D/physics/physx/px.h +++ /dev/null @@ -1,80 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -// -// This PhysX implementation for Torque was originally based on -// the "PhysX in TGEA" resource written by Shannon Scarvaci. -// -// http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=12711 -// - -#ifndef _PHYSX_H_ -#define _PHYSX_H_ - -/* -#ifndef _TORQUE_TYPES_H_ -# include "platform/types.h" -#endif -*/ - -#include "platform/tmm_off.h" - -#ifdef TORQUE_DEBUG -#include -#endif - -#if defined(TORQUE_OS_MAC) && !defined(__APPLE__) - #define __APPLE__ -#elif defined(TORQUE_OS_LINUX) && !defined(LINUX) - #define LINUX -#elif defined(TORQUE_OS_WIN) && !defined(WIN32) - #define WIN32 -#endif - -#ifndef NX_PHYSICS_NXPHYSICS -#include -#endif -#ifndef NX_FOUNDATION_NXSTREAM -#include -#endif -#ifndef NX_COOKING_H -#include -#endif -#ifndef NX_FOUNDATION_NXUSEROUTPUTSTREAM -#include -#endif -#ifndef NX_PHYSICS_NXBIG -#include "NxExtended.h" -#endif -#include -#include -#include -#include -#include -#include - -/// The single global physx sdk object for this process. -extern NxPhysicsSDK *gPhysicsSDK; - -#include "platform/tmm_on.h" - -#endif // _PHYSX_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxBody.cpp b/Engine/source/T3D/physics/physx/pxBody.cpp deleted file mode 100644 index de889139c..000000000 --- a/Engine/source/T3D/physics/physx/pxBody.cpp +++ /dev/null @@ -1,404 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxBody.h" - -#include "T3D/physics/physX/px.h" -#include "T3D/physics/physX/pxCasts.h" -#include "T3D/physics/physX/pxWorld.h" -#include "T3D/physics/physX/pxCollision.h" - - -PxBody::PxBody() : - mActor( NULL ), - mMaterial( NULL ), - mWorld( NULL ), - mBodyFlags( 0 ), - mIsEnabled( true ) -{ -} - -PxBody::~PxBody() -{ - _releaseActor(); -} - -void PxBody::_releaseActor() -{ - if ( !mActor ) - return; - - // This sucks, but it has to happen if we want - // to avoid write lock errors from PhysX right now. - mWorld->releaseWriteLock(); - - mActor->userData = NULL; - - mWorld->releaseActor( *mActor ); - mActor = NULL; - mBodyFlags = 0; - - if ( mMaterial ) - { - mWorld->releaseMaterial( *mMaterial ); - mMaterial = NULL; - } - - mColShape = NULL; -} - -bool PxBody::init( PhysicsCollision *shape, - F32 mass, - U32 bodyFlags, - SceneObject *obj, - PhysicsWorld *world ) -{ - AssertFatal( obj, "PxBody::init - Got a null scene object!" ); - AssertFatal( world, "PxBody::init - Got a null world!" ); - AssertFatal( dynamic_cast( world ), "PxBody::init - The world is the wrong type!" ); - AssertFatal( shape, "PxBody::init - Got a null collision shape!" ); - AssertFatal( dynamic_cast( shape ), "PxBody::init - The collision shape is the wrong type!" ); - AssertFatal( !((PxCollision*)shape)->getShapes().empty(), "PxBody::init - Got empty collision shape!" ); - - // Cleanup any previous actor. - _releaseActor(); - - mWorld = (PxWorld*)world; - mColShape = (PxCollision*)shape; - mBodyFlags = bodyFlags; - - NxActorDesc actorDesc; - NxBodyDesc bodyDesc; - - const bool isKinematic = mBodyFlags & BF_KINEMATIC; - const bool isTrigger = mBodyFlags & BF_TRIGGER; - const bool isDebris = mBodyFlags & BF_DEBRIS; - - if ( isKinematic ) - { - // Kinematics are dynamics... so they need - // a body description. - actorDesc.body = &bodyDesc; - bodyDesc.mass = getMax( mass, 1.0f ); - bodyDesc.flags |= NX_BF_KINEMATIC; - } - else if ( mass > 0.0f ) - { - // We have mass so its a dynamic. - actorDesc.body = &bodyDesc; - bodyDesc.mass = mass; - } - - if ( isTrigger ) - actorDesc.flags |= NX_AF_DISABLE_RESPONSE; - - // Add all the shapes. - const Vector &shapes = mColShape->getShapes(); - for ( U32 i=0; i < shapes.size(); i++ ) - { - NxShapeDesc *desc = shapes[i]; - - // If this hits then something is broken with - // this descrption... check all the fields to be - // sure their values are correctly filled out. - AssertFatal( desc->isValid(), "PxBody::init - Got invalid shape description!" ); - - if ( isTrigger ) - desc->group = 31; - - if ( isDebris ) - desc->group = 30; - - actorDesc.shapes.push_back( desc ); - } - - // This sucks, but it has to happen if we want - // to avoid write lock errors from PhysX right now. - mWorld->releaseWriteLock(); - - mActor = mWorld->getScene()->createActor( actorDesc ); - mIsEnabled = true; - - if ( isDebris ) - mActor->setDominanceGroup( 31 ); - - mUserData.setObject( obj ); - mUserData.setBody( this ); - mActor->userData = &mUserData; - - return true; -} - -void PxBody::setMaterial( F32 restitution, - F32 friction, - F32 staticFriction ) -{ - AssertFatal( mActor, "PxBody::setMaterial - The actor is null!" ); - - // If the body is dynamic then wake it up as - // it may need to change behavior. - if ( isDynamic() ) - mActor->wakeUp(); - - NxMaterialDesc desc; - desc.restitution = restitution; - desc.dynamicFriction = friction; - desc.staticFriction = staticFriction; - - // If we have a material then just update it as the shapes - // should already have them mapped. - if ( mMaterial ) - { - mMaterial->loadFromDesc( desc ); - return; - } - - // If we got here then create a new material and - // assign it to all our shapes. - mMaterial = mWorld->createMaterial( desc ); - U32 matIndex = mMaterial->getMaterialIndex(); - U32 count = mActor->getNbShapes(); - NxShape*const* shapes = mActor->getShapes(); - for ( U32 i=0; i < count; i++ ) - shapes[i]->setMaterial( matIndex ); -} - -void PxBody::setSleepThreshold( F32 linear, F32 angular ) -{ - AssertFatal( mActor, "PxBody::setSleepThreshold - The actor is null!" ); - - mActor->setSleepLinearVelocity( linear ); - mActor->setSleepAngularVelocity( angular ); -} - -void PxBody::setDamping( F32 linear, F32 angular ) -{ - AssertFatal( mActor, "PxBody::setDamping - The actor is null!" ); - mActor->setLinearDamping( linear ); - mActor->setAngularDamping( angular ); -} - -void PxBody::getState( PhysicsState *outState ) -{ - AssertFatal( mActor, "PxBody::getState - The actor is null!" ); - AssertFatal( isDynamic(), "PxBody::getState - This call is only for dynamics!" ); - - // TODO: Fix this to do what we intended... to return - // false so that the caller can early out of the state - // hasn't changed since the last tick. - - outState->position = pxCast( mActor->getGlobalPosition() ); - outState->orientation = pxCast( mActor->getGlobalOrientationQuat() ); - outState->linVelocity = pxCast( mActor->getLinearVelocity() ); - outState->angVelocity = pxCast( mActor->getAngularVelocity() ); - outState->sleeping = mActor->isSleeping(); - outState->momentum = pxCast( mActor->getLinearMomentum() ); -} - -F32 PxBody::getMass() const -{ - AssertFatal( mActor, "PxBody::getCMassPosition - The actor is null!" ); - return mActor->getMass(); -} - -Point3F PxBody::getCMassPosition() const -{ - AssertFatal( mActor, "PxBody::getCMassPosition - The actor is null!" ); - return pxCast( mActor->getCMassGlobalPosition() ); -} - -void PxBody::setLinVelocity( const Point3F &vel ) -{ - AssertFatal( mActor, "PxBody::setLinVelocity - The actor is null!" ); - AssertFatal( isDynamic(), "PxBody::setLinVelocity - This call is only for dynamics!" ); - - mActor->setLinearVelocity( pxCast( vel ) ); -} - -void PxBody::setAngVelocity( const Point3F &vel ) -{ - AssertFatal( mActor, "PxBody::setAngVelocity - The actor is null!" ); - AssertFatal( isDynamic(), "PxBody::setAngVelocity - This call is only for dynamics!" ); - - mActor->setAngularVelocity( pxCast( vel ) ); -} - -Point3F PxBody::getLinVelocity() const -{ - AssertFatal( mActor, "PxBody::getLinVelocity - The actor is null!" ); - AssertFatal( isDynamic(), "PxBody::getLinVelocity - This call is only for dynamics!" ); - - return pxCast( mActor->getLinearVelocity() ); -} - -Point3F PxBody::getAngVelocity() const -{ - AssertFatal( mActor, "PxBody::getAngVelocity - The actor is null!" ); - AssertFatal( isDynamic(), "PxBody::getAngVelocity - This call is only for dynamics!" ); - - return pxCast( mActor->getAngularVelocity() ); -} - -void PxBody::setSleeping( bool sleeping ) -{ - AssertFatal( mActor, "PxBody::setSleeping - The actor is null!" ); - AssertFatal( isDynamic(), "PxBody::setSleeping - This call is only for dynamics!" ); - - if ( sleeping ) - mActor->putToSleep(); - else - mActor->wakeUp(); -} - -bool PxBody::isDynamic() const -{ - AssertFatal( mActor, "PxBody::isDynamic - The actor is null!" ); - return mActor->isDynamic() && ( mBodyFlags & BF_KINEMATIC ) == 0; -} - -PhysicsWorld* PxBody::getWorld() -{ - return mWorld; -} - -PhysicsCollision* PxBody::getColShape() -{ - return mColShape; -} - -MatrixF& PxBody::getTransform( MatrixF *outMatrix ) -{ - AssertFatal( mActor, "PxBody::getTransform - The actor is null!" ); - - mActor->getGlobalPose().getRowMajor44( *outMatrix ); - - return *outMatrix; -} - -Box3F PxBody::getWorldBounds() -{ - AssertFatal( mActor, "PxBody::getTransform - The actor is null!" ); - - NxBounds3 bounds; - bounds.setEmpty(); - NxBounds3 shapeBounds; - - NxShape *const* pShapeArray = mActor->getShapes(); - U32 shapeCount = mActor->getNbShapes(); - - for ( U32 i = 0; i < shapeCount; i++ ) - { - // Get the shape's bounds. - pShapeArray[i]->getWorldBounds( shapeBounds ); - - // Combine them into the total bounds. - bounds.combine( shapeBounds ); - } - - return pxCast( bounds ); -} - -void PxBody::setSimulationEnabled( bool enabled ) -{ - if ( mIsEnabled == enabled ) - return; - - // This sucks, but it has to happen if we want - // to avoid write lock errors from PhysX right now. - mWorld->releaseWriteLock(); - - if ( enabled ) - { - mIsEnabled = true; - mActor->clearActorFlag( NX_AF_DISABLE_RESPONSE ); - mActor->clearActorFlag( NX_AF_DISABLE_COLLISION ); - - // Don't clear the flag if its supposed to be kinematic. - if ( !(mBodyFlags & BF_KINEMATIC) ) - mActor->clearBodyFlag( NX_BF_KINEMATIC ); - - if ( isDynamic() ) - mActor->wakeUp(); - } - else - { - mIsEnabled = false; - mActor->raiseActorFlag( NX_AF_DISABLE_RESPONSE ); - mActor->raiseActorFlag( NX_AF_DISABLE_COLLISION ); - mActor->raiseBodyFlag( NX_BF_KINEMATIC ); - } - - NxShape *const* shapes = mActor->getShapes(); - for ( S32 i = 0; i < mActor->getNbShapes(); i++ ) - shapes[i]->setFlag( NX_SF_DISABLE_RAYCASTING, !mIsEnabled ); -} - -void PxBody::setTransform( const MatrixF &transform ) -{ - AssertFatal( mActor, "PxBody::setTransform - The actor is null!" ); - - // This sucks, but it has to happen if we want - // to avoid write lock errors from PhysX right now. - mWorld->releaseWriteLock(); - - NxMat34 xfm; - xfm.setRowMajor44( transform ); - mActor->setGlobalPose( xfm ); - - // If its dynamic we have more to do. - if ( mActor->isDynamic() && !mActor->readBodyFlag( NX_BF_KINEMATIC ) ) - { - mActor->setLinearVelocity( NxVec3( 0, 0, 0 ) ); - mActor->setAngularVelocity( NxVec3( 0, 0, 0 ) ); - mActor->wakeUp(); - } -} - -void PxBody::applyCorrection( const MatrixF &transform ) -{ - AssertFatal( mActor, "PxBody::applyCorrection - The actor is null!" ); - AssertFatal( isDynamic(), "PxBody::applyCorrection - This call is only for dynamics!" ); - - // This sucks, but it has to happen if we want - // to avoid write lock errors from PhysX right now. - mWorld->releaseWriteLock(); - - NxMat34 xfm; - xfm.setRowMajor44( transform ); - mActor->setGlobalPose( xfm ); -} - -void PxBody::applyImpulse( const Point3F &origin, const Point3F &force ) -{ - AssertFatal( mActor, "PxBody::applyImpulse - The actor is null!" ); - - // This sucks, but it has to happen if we want - // to avoid write lock errors from PhysX right now. - mWorld->releaseWriteLock(); - - if ( mIsEnabled && isDynamic() ) - mActor->addForceAtPos( pxCast( force ), - pxCast( origin ), - NX_IMPULSE ); -} - diff --git a/Engine/source/T3D/physics/physx/pxBody.h b/Engine/source/T3D/physics/physx/pxBody.h deleted file mode 100644 index 2aeec6e0f..000000000 --- a/Engine/source/T3D/physics/physx/pxBody.h +++ /dev/null @@ -1,114 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _T3D_PHYSICS_PXBODY_H_ -#define _T3D_PHYSICS_PXBODY_H_ - -#ifndef _T3D_PHYSICS_PHYSICSBODY_H_ -#include "T3D/physics/physicsBody.h" -#endif -#ifndef _PHYSICS_PHYSICSUSERDATA_H_ -#include "T3D/physics/physicsUserData.h" -#endif -#ifndef _REFBASE_H_ -#include "core/util/refBase.h" -#endif -#ifndef _MMATRIX_H_ -#include "math/mMatrix.h" -#endif - -class PxWorld; -class NxActor; -class PxCollision; -class NxMaterial; - - -class PxBody : public PhysicsBody -{ -protected: - - /// The physics world we are in. - PxWorld *mWorld; - - /// The physics actor. - NxActor *mActor; - - /// The unshared local material used on all the - /// shapes on this actor. - NxMaterial *mMaterial; - - /// We hold the collision reference as it contains - /// allocated objects that we own and must free. - StrongRefPtr mColShape; - - /// - MatrixF mInternalTransform; - - /// The body flags set at creation time. - U32 mBodyFlags; - - /// Is true if this body is enabled and active - /// in the simulation of the scene. - bool mIsEnabled; - - /// - void _releaseActor(); - -public: - - PxBody(); - virtual ~PxBody(); - - // PhysicsObject - virtual PhysicsWorld* getWorld(); - virtual void setTransform( const MatrixF &xfm ); - virtual MatrixF& getTransform( MatrixF *outMatrix ); - virtual Box3F getWorldBounds(); - virtual void setSimulationEnabled( bool enabled ); - virtual bool isSimulationEnabled() { return mIsEnabled; } - - // PhysicsBody - virtual bool init( PhysicsCollision *shape, - F32 mass, - U32 bodyFlags, - SceneObject *obj, - PhysicsWorld *world ); - virtual bool isDynamic() const; - virtual PhysicsCollision* getColShape(); - virtual void setSleepThreshold( F32 linear, F32 angular ); - virtual void setDamping( F32 linear, F32 angular ); - virtual void getState( PhysicsState *outState ); - virtual F32 getMass() const; - virtual Point3F getCMassPosition() const; - virtual void setLinVelocity( const Point3F &vel ); - virtual void setAngVelocity( const Point3F &vel ); - virtual Point3F getLinVelocity() const; - virtual Point3F getAngVelocity() const; - virtual void setSleeping( bool sleeping ); - virtual void setMaterial( F32 restitution, - F32 friction, - F32 staticFriction ); - virtual void applyCorrection( const MatrixF &xfm ); - virtual void applyImpulse( const Point3F &origin, const Point3F &force ); -}; - -#endif // _T3D_PHYSICS_PXBODY_H_ diff --git a/Engine/source/T3D/physics/physx/pxCasts.h b/Engine/source/T3D/physics/physx/pxCasts.h deleted file mode 100644 index ee9555702..000000000 --- a/Engine/source/T3D/physics/physx/pxCasts.h +++ /dev/null @@ -1,150 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PHYSX_CASTS_H_ -#define _PHYSX_CASTS_H_ - -#ifndef _MPOINT3_H_ -#include "math/mPoint3.h" -#endif -#ifndef _MBOX_H_ -#include "math/mBox.h" -#endif -#ifndef _MQUAT_H_ -#include "math/mQuat.h" -#endif - - -template inline T pxCast( const F &from ); - -//------------------------------------------------------------------------- - -template<> -inline Point3F pxCast( const NxVec3 &vec ) -{ - return Point3F( vec.x, vec.y, vec.z ); -} - -template<> -inline NxVec3 pxCast( const Point3F &point ) -{ - return NxVec3( point.x, point.y, point.z ); -} - -//------------------------------------------------------------------------- - -template<> -inline QuatF pxCast( const NxQuat &quat ) -{ - /// The Torque quat has the opposite winding order. - return QuatF( -quat.x, -quat.y, -quat.z, quat.w ); -} - -template<> -inline NxQuat pxCast( const QuatF &quat ) -{ - /// The Torque quat has the opposite winding order. - NxQuat result; - result.setWXYZ( quat.w, -quat.x, -quat.y, -quat.z ); - return result; -} - -//------------------------------------------------------------------------- - -template<> -inline NxBounds3 pxCast( const Box3F &box ) -{ - NxBounds3 bounds; - bounds.set( box.minExtents.x, - box.minExtents.y, - box.minExtents.z, - box.maxExtents.x, - box.maxExtents.y, - box.maxExtents.z ); - return bounds; -} - -template<> -inline Box3F pxCast( const NxBounds3 &bounds ) -{ - return Box3F( bounds.min.x, - bounds.min.y, - bounds.min.z, - bounds.max.x, - bounds.max.y, - bounds.max.z ); -} - -//------------------------------------------------------------------------- - -template<> -inline NxVec3 pxCast( const NxExtendedVec3 &xvec ) -{ - return NxVec3( xvec.x, xvec.y, xvec.z ); -} - -template<> -inline NxExtendedVec3 pxCast( const NxVec3 &vec ) -{ - return NxExtendedVec3( vec.x, vec.y, vec.z ); -} - -//------------------------------------------------------------------------- - -template<> -inline NxExtendedVec3 pxCast( const Point3F &point ) -{ - return NxExtendedVec3( point.x, point.y, point.z ); -} - -template<> -inline Point3F pxCast( const NxExtendedVec3 &xvec ) -{ - return Point3F( xvec.x, xvec.y, xvec.z ); -} - -//------------------------------------------------------------------------- - -template<> -inline NxBox pxCast( const NxExtendedBounds3 &exBounds ) -{ - NxExtendedVec3 center; - exBounds.getCenter( center ); - NxVec3 extents; - exBounds.getExtents( extents ); - - NxBox box; - box.center.set( center.x, center.y, center.z ); - box.extents = extents; - box.rot.id(); - - return box; -} - -template<> -inline NxExtendedBounds3 pxCast( const NxBox &box ) -{ - AssertFatal( false, "Casting a NxBox to NxExtendedBounds3 is impossible without losing rotation data!" ); - return NxExtendedBounds3(); -} - -#endif // _PHYSX_CASTS_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxCloth.cpp b/Engine/source/T3D/physics/physx/pxCloth.cpp deleted file mode 100644 index 723e71b67..000000000 --- a/Engine/source/T3D/physics/physx/pxCloth.cpp +++ /dev/null @@ -1,923 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxCloth.h" - -#include "console/consoleTypes.h" -#include "scene/sceneManager.h" -#include "scene/sceneRenderState.h" -#include "renderInstance/renderPassManager.h" -#include "lighting/lightQuery.h" -#include "T3D/physics/physicsPlugin.h" -#include "T3D/physics/physx/pxWorld.h" -#include "T3D/physics/physx/pxStream.h" -#include "T3D/physics/physx/pxCasts.h" -#include "gfx/gfxDrawUtil.h" -#include "math/mathIO.h" -#include "core/stream/bitStream.h" -#include "materials/materialManager.h" -#include "materials/baseMatInstance.h" - - -IMPLEMENT_CO_NETOBJECT_V1( PxCloth ); - -ConsoleDocClass( PxCloth, - - "@brief Rectangular patch of cloth simulated by PhysX.\n\n" - - "PxCloth is affected by other objects in the simulation but does not itself " - "affect others, it is essentially a visual effect. Eg, shooting at cloth will " - "disturb it but will not explode the projectile.\n\n" - - "Be careful with the cloth size and resolution because it can easily become " - "performance intensive to simulate. A single piece of cloth that is very " - "large or high resolution is also much more expensive than multiple pieces " - "that add up to the same number of verts.\n\n" - - "Note that most field docs have been copied from their PhysX counterpart.\n\n" - - "@ingroup Physics" -); - -enum PxClothAttachment {}; -DefineBitfieldType( PxClothAttachment ); - -ImplementBitfieldType( PxClothAttachment, - "Soon to be deprecated\n" - "@internal" ) - { 0, "Bottom Right" }, - { 1, "Bottom Left" }, - { 2, "Top Right" }, - { 3, "Top Left" }, - { 4, "Top Center" }, - { 5, "Bottom Center" }, - { 6, "Right Center" }, - { 7, "Left Center" }, - { 8, "Top Edge" }, - { 9, "Bottom Edge" }, - { 10, "Right Edge" }, - { 11, "Left Edge" } -EndImplementBitfieldType; - - -PxCloth::PxCloth() - : mWorld( NULL ), - mScene( NULL ), - mMatInst( NULL ) -{ - mVertexRenderBuffer = NULL; - mIndexRenderBuffer = NULL; - - mMaxVertices = 0; - mMaxIndices = 0; - - mClothMesh = NULL; - mCloth = NULL; - - mPatchVerts.set( 8, 8 ); - mPatchSize.set( 8.0f, 8.0f ); - - mNetFlags.set( Ghostable | ScopeAlways ); - mTypeMask |= StaticObjectType | StaticShapeObjectType; - - mReceiveBuffers.setToDefault(); - - mBendingEnabled = false; - mDampingEnabled = false; - mTriangleCollisionEnabled = false; - mSelfCollisionEnabled = false; - - mDensity = 1.0f; - mThickness = 0.1f; - mFriction = 0.25f; - mBendingStiffness = 0.5f; - mDampingCoefficient = 0.25f; - - mAttachmentMask = 0; -} - -PxCloth::~PxCloth() -{ -} - -bool PxCloth::onAdd() -{ - if ( !Parent::onAdd() ) - return false; - - // Cloth is only created on the client. - if ( isClientObject() ) - { - mWorld = dynamic_cast( PHYSICSMGR->getWorld( "client" ) ); - - if ( !mWorld || !mWorld->getScene() ) - { - Con::errorf( "PxCloth::onAdd() - PhysXWorld not initialized... cloth disabled!" ); - return true; - } - - mScene = mWorld->getScene(); - - mResetXfm = getTransform(); - - _createClothPatch(); - - PhysicsPlugin::getPhysicsResetSignal().notify( this, &PxCloth::onPhysicsReset, 1053.0f ); - } - - // On the server we use the static update - // to setup the bounds of the cloth. - if ( isServerObject() ) - _updateStaticCloth(); - - addToScene(); - - // Also the server object never ticks. - if ( isServerObject() ) - setProcessTick( false ); - - return true; -} - -void PxCloth::onRemove() -{ - SAFE_DELETE( mMatInst ); - - if ( isClientObject() ) - { - _releaseCloth(); - _releaseMesh(); - - PhysicsPlugin::getPhysicsResetSignal().remove( this, &PxCloth::onPhysicsReset ); - } - - removeFromScene(); - - Parent::onRemove(); -} - -void PxCloth::onPhysicsReset( PhysicsResetEvent reset ) -{ - // Store the reset transform for later use. - if ( reset == PhysicsResetEvent_Store ) - mResetXfm = getTransform(); - - // Recreate the cloth at the last reset position. - _recreateCloth( mResetXfm ); -} - -void PxCloth::initPersistFields() -{ - Parent::initPersistFields(); - - addField( "material", TypeMaterialName, Offset( mMaterialName, PxCloth ), - "@brief Name of the material to render.\n\n" ); - - addField( "samples", TypePoint2I, Offset( mPatchVerts, PxCloth ), - "@brief The number of cloth vertices in width and length.\n\n" - "At least two verts should be defined.\n\n"); - - addField( "size", TypePoint2F, Offset( mPatchSize, PxCloth ), - "@brief The width and height of the cloth.\n\n" ); - - addField( "bending", TypeBool, Offset( mBendingEnabled, PxCloth ), - "@brief Enables or disables bending resistance.\n\n" - "Set the bending resistance through PxCloth::bendingStiffness." ); - - addField( "damping", TypeBool, Offset( mDampingEnabled, PxCloth ), - "@brief Enable/disable damping of internal velocities.\n\n" ); - - addField( "triangleCollision", TypeBool, Offset( mTriangleCollisionEnabled, PxCloth ), - "@brief Not supported in current release (according to PhysX docs).\n\n" - "Enables or disables collision detection of cloth triangles against the scene. " - "If not set, only collisions of cloth particles are detected. If set, " - "collisions of cloth triangles are detected as well." ); - - addField( "selfCollision", TypeBool, Offset( mSelfCollisionEnabled, PxCloth ), - "@brief Enables or disables self-collision handling within a single piece of cloth.\n\n" ); - - addField( "density", TypeF32, Offset( mDensity, PxCloth ), - "@brief Density of the cloth (Mass per Area).\n\n" ); - - addField( "thickness", TypeF32, Offset( mThickness, PxCloth ), - "@brief Value representing how thick the cloth is.\n\n" - "The thickness is usually a fraction of the overall extent of the cloth and " - "should not be set to a value greater than that. A good value is the maximal " - "distance between two adjacent cloth particles in their rest pose. Visual " - "artifacts or collision problems may appear if the thickness is too small.\n\n" ); - - addField( "friction", TypeF32, Offset( mFriction, PxCloth ), - "@brief Friction coefficient in the range 0 to 1.\n\n" - "Defines the damping of the velocities of cloth particles that are in contact." ); - - addField( "bendingStiffness", TypeF32, Offset( mBendingStiffness, PxCloth ), - "@brief Bending stiffness of the cloth in the range 0 to 1.\n\n" ); - - addField( "dampingCoefficient", TypeF32, Offset( mDampingCoefficient, PxCloth ), - "@brief Spring damping of the cloth in the range 0 to 1.\n\n" ); - - addField( "attachments", TYPEID< PxClothAttachment >(), Offset( mAttachmentMask, PxCloth ), - "@brief Optional way to specify cloth verts that will be attached to the world position " - "it is created at.\n\n" ); - - // Cloth doesn't support scale. - removeField( "scale" ); -} - -void PxCloth::inspectPostApply() -{ - Parent::inspectPostApply(); - - // Must have at least 2 verts. - mPatchVerts.x = getMax( 2, mPatchVerts.x ); - mPatchVerts.y = getMax( 2, mPatchVerts.y ); - if ( isServerObject() ) - _updateStaticCloth(); - - setMaskBits( TransformMask | MaterialMask | ClothMask ); -} - -U32 PxCloth::packUpdate( NetConnection *conn, U32 mask, BitStream *stream ) -{ - U32 retMask = Parent::packUpdate( conn, mask, stream ); - - if ( stream->writeFlag( mask & TransformMask ) ) - mathWrite( *stream, getTransform() ); - - if ( stream->writeFlag( mask & MaterialMask ) ) - stream->write( mMaterialName ); - - if ( stream->writeFlag( mask & ClothMask ) ) - { - mathWrite( *stream, mPatchVerts ); - mathWrite( *stream, mPatchSize ); - - stream->write( mAttachmentMask ); - - stream->writeFlag( mBendingEnabled ); - stream->writeFlag( mDampingEnabled ); - stream->writeFlag( mTriangleCollisionEnabled ); - stream->writeFlag( mSelfCollisionEnabled ); - stream->write( mThickness ); - stream->write( mFriction ); - stream->write( mBendingStiffness ); - stream->write( mDampingCoefficient ); - - stream->write( mDensity ); - } - - return retMask; -} - -void PxCloth::unpackUpdate( NetConnection *conn, BitStream *stream ) -{ - Parent::unpackUpdate( conn, stream ); - - // TransformMask - if ( stream->readFlag() ) - { - MatrixF mat; - mathRead( *stream, &mat ); - setTransform( mat ); - } - - // MaterialMask - if ( stream->readFlag() ) - { - stream->read( &mMaterialName ); - SAFE_DELETE( mMatInst ); - } - - // ClothMask - if ( stream->readFlag() ) - { - Point2I patchVerts; - Point2F patchSize; - mathRead( *stream, &patchVerts ); - mathRead( *stream, &patchSize ); - - if ( patchVerts != mPatchVerts || - !patchSize.equal( mPatchSize ) ) - { - mPatchVerts = patchVerts; - mPatchSize = patchSize; - _releaseMesh(); - } - - U32 attachMask; - stream->read( &attachMask ); - if ( attachMask != mAttachmentMask ) - { - mAttachmentMask = attachMask; - _releaseCloth(); - } - - mBendingEnabled = stream->readFlag(); - mDampingEnabled = stream->readFlag(); - mTriangleCollisionEnabled = stream->readFlag(); - mSelfCollisionEnabled = stream->readFlag(); - stream->read( &mThickness ); - stream->read( &mFriction ); - stream->read( &mBendingStiffness ); - stream->read( &mDampingCoefficient ); - - F32 density; - stream->read( &density ); - if ( density != mDensity ) - { - mDensity = density; - _releaseCloth(); - } - - if ( isClientObject() && - isProperlyAdded() && - mWorld && - !mCloth ) - { - _createClothPatch(); - } - - _updateClothProperties(); - } -} - -void PxCloth::_recreateCloth( const MatrixF &transform ) -{ - if ( !mWorld ) - return; - - mWorld->getPhysicsResults(); - - Parent::setTransform( transform ); - - _createClothPatch(); -} - -void PxCloth::setTransform( const MatrixF &mat ) -{ - Parent::setTransform( mat ); - setMaskBits( TransformMask ); - - // Only need to do this if we're on the server - // or if we're not currently ticking physics. - if ( !mWorld || !mWorld->isEnabled() ) - _updateStaticCloth(); -} - -void PxCloth::setScale( const VectorF &scale ) -{ - // Cloth doesn't support scale as it has plenty - // of complications... sharing meshes, thickness, - // transform origin, etc. - return; -} - -void PxCloth::prepRenderImage( SceneRenderState *state ) -{ - if ( mIsVBDirty ) - _updateVBIB(); - - // Recreate the material if we need to. - if ( !mMatInst ) - _initMaterial(); - - // If we don't have a material instance after the override then - // we can skip rendering all together. - BaseMatInstance *matInst = state->getOverrideMaterial( mMatInst ); - if ( !matInst ) - return; - - MeshRenderInst *ri = state->getRenderPass()->allocInst(); - - // If we need lights then set them up. - if ( matInst->isForwardLit() ) - { - LightQuery query; - query.init( getWorldSphere() ); - query.getLights( ri->lights, 8 ); - } - - ri->projection = state->getRenderPass()->allocSharedXform(RenderPassManager::Projection); - ri->objectToWorld = &MatrixF::Identity; - - ri->worldToCamera = state->getRenderPass()->allocSharedXform(RenderPassManager::View); - ri->type = RenderPassManager::RIT_Mesh; - - ri->primBuff = &mPrimBuffer; - ri->vertBuff = &mVB; - - ri->matInst = matInst; - ri->prim = state->getRenderPass()->allocPrim(); - ri->prim->type = GFXTriangleList; - ri->prim->minIndex = 0; - ri->prim->startIndex = 0; - ri->prim->numPrimitives = mNumIndices / 3; - - ri->prim->startVertex = 0; - ri->prim->numVertices = mNumVertices; - - ri->defaultKey = matInst->getStateHint(); - ri->defaultKey2 = (U32)ri->vertBuff; - - state->getRenderPass()->addInst( ri ); -} - -void PxCloth::_releaseMesh() -{ - if ( !mClothMesh ) - return; - - _releaseCloth(); - - mWorld->releaseClothMesh( *mClothMesh ); - mClothMesh = NULL; - - delete [] mVertexRenderBuffer; - mVertexRenderBuffer = NULL; - delete [] mIndexRenderBuffer; - mIndexRenderBuffer = NULL; -} - -void PxCloth::_releaseCloth() -{ - if ( !mCloth ) - return; - - mWorld->releaseCloth( *mCloth ); - mCloth = NULL; -} - -void PxCloth::_initClothMesh() -{ - // Make sure we can change the world. - mWorld->releaseWriteLock(); - - _releaseMesh(); - - // Must have at least 2 verts. - mPatchVerts.x = getMax( 2, mPatchVerts.x ); - mPatchVerts.y = getMax( 2, mPatchVerts.y ); - - // Generate a uniform cloth patch, - // w and h are the width and height, - // d is the distance between vertices. - mNumVertices = mPatchVerts.x * mPatchVerts.y; - mNumIndices = (mPatchVerts.x-1) * (mPatchVerts.y-1) * 2; - - NxClothMeshDesc desc; - desc.numVertices = mNumVertices; - desc.numTriangles = mNumIndices; - desc.pointStrideBytes = sizeof(NxVec3); - desc.triangleStrideBytes = 3*sizeof(NxU32); - desc.points = (NxVec3*)dMalloc(sizeof(NxVec3)*desc.numVertices); - desc.triangles = (NxU32*)dMalloc(sizeof(NxU32)*desc.numTriangles*3); - desc.flags = 0; - - U32 i,j; - NxVec3 *p = (NxVec3*)desc.points; - - F32 patchWidth = mPatchSize.x / (F32)( mPatchVerts.x - 1 ); - F32 patchHeight = mPatchSize.y / (F32)( mPatchVerts.y - 1 ); - - for (i = 0; i < mPatchVerts.y; i++) - { - for (j = 0; j < mPatchVerts.x; j++) - { - p->set( patchWidth * j, 0.0f, patchHeight * i ); - p++; - } - } - - NxU32 *id = (NxU32*)desc.triangles; - - for (i = 0; i < mPatchVerts.y-1; i++) - { - for (j = 0; j < mPatchVerts.x-1; j++) - { - NxU32 i0 = i * mPatchVerts.x + j; - NxU32 i1 = i0 + 1; - NxU32 i2 = i0 + mPatchVerts.x; - NxU32 i3 = i2 + 1; - if ( (j+i) % 2 ) - { - *id++ = i0; - *id++ = i2; - *id++ = i1; - *id++ = i1; - *id++ = i2; - *id++ = i3; - } - else - { - *id++ = i0; - *id++ = i2; - *id++ = i3; - *id++ = i0; - *id++ = i3; - *id++ = i1; - } - } - } - - NxCookingInterface *cooker = PxWorld::getCooking(); - cooker->NxInitCooking(); - - // Ok... cook the mesh! - NxCookingParams params; - params.targetPlatform = PLATFORM_PC; - params.skinWidth = 0.01f; - params.hintCollisionSpeed = false; - - cooker->NxSetCookingParams( params ); - - PxMemStream cooked; - - if ( cooker->NxCookClothMesh( desc, cooked ) ) - { - cooked.resetPosition(); - mClothMesh = gPhysicsSDK->createClothMesh( cooked ); - } - - cooker->NxCloseCooking(); - - NxVec3 *ppoints = (NxVec3*)desc.points; - NxU32 *triangs = (NxU32*)desc.triangles; - - dFree( ppoints ); - dFree( triangs ); - - if ( mClothMesh ) - _initReceiveBuffers(); -} - -void PxCloth::_initReceiveBuffers() -{ - // here we setup the buffers through which the SDK returns the dynamic cloth data - // we reserve more memory for vertices than the initial mesh takes - // because tearing creates new vertices - // the SDK only tears cloth as long as there is room in these buffers - - mMaxVertices = 3 * mNumVertices; - mMaxIndices = 3 * mNumIndices; - - // Allocate Render Buffer for Vertices if it hasn't been done before - mVertexRenderBuffer = new GFXVertexPNTT[mMaxVertices]; - mIndexRenderBuffer = new U16[mMaxIndices]; - - mReceiveBuffers.verticesPosBegin = &(mVertexRenderBuffer[0].point); - mReceiveBuffers.verticesNormalBegin = &(mVertexRenderBuffer[0].normal); - mReceiveBuffers.verticesPosByteStride = sizeof(GFXVertexPNTT); - mReceiveBuffers.verticesNormalByteStride = sizeof(GFXVertexPNTT); - mReceiveBuffers.maxVertices = mMaxVertices; - mReceiveBuffers.numVerticesPtr = &mNumVertices; - - // the number of triangles is constant, even if the cloth is torn - mReceiveBuffers.indicesBegin = &mIndexRenderBuffer[0]; - mReceiveBuffers.indicesByteStride = sizeof(NxU16); - mReceiveBuffers.maxIndices = mMaxIndices; - mReceiveBuffers.numIndicesPtr = &mNumIndices; - - // Set up texture coords. - - F32 dx = 1.0f / (F32)(mPatchVerts.x-1); - F32 dy = 1.0f / (F32)(mPatchVerts.y-1); - - F32 *coord = (F32*)&mVertexRenderBuffer[0].texCoord; - for ( U32 i = 0; i < mPatchVerts.y; i++) - { - for ( U32 j = 0; j < mPatchVerts.x; j++) - { - coord[0] = j*dx; - coord[1] = i*-dy; - coord += sizeof( GFXVertexPNTT ) / sizeof( F32 ); - } - } - - // the parent index information would be needed if we used textured cloth - //mReceiveBuffers.parentIndicesBegin = (U32*)malloc(sizeof(U32)*mMaxVertices); - //mReceiveBuffers.parentIndicesByteStride = sizeof(U32); - //mReceiveBuffers.maxParentIndices = mMaxVertices; - //mReceiveBuffers.numParentIndicesPtr = &mNumParentIndices; - - mMeshDirtyFlags = 0; - mReceiveBuffers.dirtyBufferFlagsPtr = &mMeshDirtyFlags; - - // init the buffers in case we want to draw the mesh - // before the SDK as filled in the correct values - - mReceiveBuffers.flags |= NX_MDF_16_BIT_INDICES; -} - -bool PxCloth::_createClothPatch() -{ - // Make sure we have a mesh. - if ( !mClothMesh ) - { - _initClothMesh(); - if ( !mClothMesh ) - return false; - } - - // Make sure we can change the world. - mWorld->releaseWriteLock(); - - _releaseCloth(); - - NxClothDesc desc; - desc.globalPose.setRowMajor44( getTransform() ); - desc.thickness = mThickness; - desc.density = mDensity; - desc.bendingStiffness = mBendingStiffness; - desc.dampingCoefficient = mDampingCoefficient; - desc.friction = mFriction; - - if ( mBendingEnabled ) - desc.flags |= NX_CLF_BENDING; - if ( mDampingEnabled ) - desc.flags |= NX_CLF_DAMPING; - if ( mTriangleCollisionEnabled ) - desc.flags |= NX_CLF_TRIANGLE_COLLISION; - if ( mSelfCollisionEnabled ) - desc.flags |= NX_CLF_SELFCOLLISION; - - desc.clothMesh = mClothMesh; - desc.meshData = mReceiveBuffers; - - if ( !desc.isValid() ) - return false; - - mCloth = mScene->createCloth( desc ); - mIsVBDirty = true; - - _updateStaticCloth(); - _setupAttachments(); - - return true; -} - -void PxCloth::_updateClothProperties() -{ - if ( !mCloth ) - return; - - mCloth->setThickness( mThickness ); - mCloth->setBendingStiffness( mBendingStiffness ); - mCloth->setDampingCoefficient( mDampingCoefficient ); - mCloth->setFriction( mFriction ); - - NxU32 flags = NX_CLF_GRAVITY; // TODO: Expose this? - if ( mBendingEnabled ) - flags |= NX_CLF_BENDING; - if ( mDampingEnabled ) - flags |= NX_CLF_DAMPING; - if ( mTriangleCollisionEnabled ) - flags |= NX_CLF_TRIANGLE_COLLISION; - if ( mSelfCollisionEnabled ) - flags |= NX_CLF_SELFCOLLISION; - mCloth->setFlags( flags ); -} - -void PxCloth::_initMaterial() -{ - SAFE_DELETE( mMatInst ); - - Material *material = NULL; - if (mMaterialName.isNotEmpty() ) - Sim::findObject( mMaterialName, material ); - - if ( material ) - mMatInst = material->createMatInstance(); - else - mMatInst = MATMGR->createMatInstance( "WarningMaterial" ); - - GFXStateBlockDesc desc; - desc.setCullMode( GFXCullNone ); - mMatInst->addStateBlockDesc( desc ); - - mMatInst->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat() ); -} - -void PxCloth::_updateVBIB() -{ - PROFILE_SCOPE( PxCloth_UpdateVBIB ); - - mIsVBDirty = false; - - // Don't set the VB if the vertex count is the same! - if ( mVB.isNull() || mVB->mNumVerts < mNumVertices ) - mVB.set( GFX, mNumVertices, GFXBufferTypeDynamic ); - - GFXVertexPNTT *vert = mVertexRenderBuffer; - GFXVertexPNTT *secondVert = NULL; - - for ( U32 i = 0; i < mNumVertices; i++ ) - { - if ( i % (U32)mPatchSize.x == 0 && i != 0 ) - { - secondVert = vert; - secondVert--; - vert->tangent = -(vert->point - secondVert->point); - } - else - { - secondVert = vert; - secondVert++; - vert->tangent = vert->point - secondVert->point; - } - - vert->tangent.normalize(); - vert++; - } - - GFXVertexPNTT *vpPtr = mVB.lock(); - dMemcpy( vpPtr, mVertexRenderBuffer, sizeof( GFXVertexPNTT ) * mNumVertices ); - mVB.unlock(); - - if ( mPrimBuffer.isNull() || mPrimBuffer->mIndexCount < mNumIndices ) - mPrimBuffer.set( GFX, mNumIndices, 0, GFXBufferTypeDynamic ); - - U16 *pbPtr; - mPrimBuffer.lock( &pbPtr ); - dMemcpy( pbPtr, mIndexRenderBuffer, sizeof( U16 ) * mNumIndices ); - mPrimBuffer.unlock(); -} - -void PxCloth::_updateStaticCloth() -{ - // Setup the unsimulated world bounds. - mObjBox.set( 0, mThickness * -0.5f, 0, - mPatchSize.x, mThickness * 0.5f, mPatchSize.y ); - resetWorldBox(); - - // If we don't have render buffers then we're done. - if ( !mVertexRenderBuffer || !mIndexRenderBuffer ) - return; - - // Make sure the VBs are updated. - mIsVBDirty = true; - - F32 patchWidth = mPatchSize.x / (F32)(mPatchVerts.x-1); - F32 patchHeight = mPatchSize.y / (F32)(mPatchVerts.y-1); - - Point3F normal( 0, 1, 0 ); - getTransform().mulV( normal ); - - GFXVertexPNTT *vert = mVertexRenderBuffer; - - for (U32 y = 0; y < mPatchVerts.y; y++) - { - for (U32 x = 0; x < mPatchVerts.x; x++) - { - vert->point.set( patchWidth * x, 0.0f, patchHeight * y ); - getTransform().mulP( vert->point ); - vert->normal = normal; - vert++; - } - } - - U16 *index = mIndexRenderBuffer; - mNumIndices = (mPatchVerts.x-1) * (mPatchVerts.y-1) * 6; - U16 yOffset = mPatchVerts.x; - - for (U32 y = 0; y < mPatchVerts.y-1; y++) - { - for (U32 x = 0; x < mPatchVerts.x-1; x++) - { - U16 base = x + ( yOffset * y ); - - index[0] = base; - index[1] = base + 1; - index[2] = base + 1 + yOffset; - - index[3] = base + 1 + yOffset; - index[4] = base + yOffset; - index[5] = base; - - index += 6; - } - } -} - -void PxCloth::processTick( const Move *move ) -{ - // Make sure the cloth is created. - if ( !mCloth ) - return; - - // TODO: Remove this hack! - const bool enableWind = Con::getBoolVariable( "$PxCloth::enableWind", false ); - - if ( enableWind ) - { - NxVec3 windVec( 25.0f + NxMath::rand(-5.0f, 5.0f), - NxMath::rand(-5.0f, 5.0f), - NxMath::rand(-5.0f, 5.0f) ); - - mCloth->setWindAcceleration( windVec ); - - // Wake the cloth! - mCloth->wakeUp(); - } - else - mCloth->setWindAcceleration( NxVec3( 0, 0, 0 ) ); - - // Update bounds. - if ( mWorld->getEnabled() ) - { - NxBounds3 box; - mCloth->getWorldBounds( box ); - - Point3F min = pxCast( box.min ); - Point3F max = pxCast( box.max ); - - mWorldBox.set( min, max ); - mObjBox = mWorldBox; - - getWorldTransform().mul( mObjBox ); - } - else - { - mObjBox.set( 0, mThickness * -0.5f, 0, - mPatchSize.x, mThickness * 0.5f, mPatchSize.y ); - } - - resetWorldBox(); - - // Update the VB on the next render. - mIsVBDirty = true; -} - -void PxCloth::interpolateTick( F32 delta ) -{ - // Nothing to do for now! -} - -bool PxCloth::onNewDataBlock( GameBaseData *dptr, bool reload ) -{ - return false; -} - -void PxCloth::_setupAttachments() -{ - if ( !mCloth || !mWorld ) - return; - - // Set up attachments - // Bottom right = bit 0 - // Bottom left = bit 1 - // Top right = bit 2 - // Top left = bit 3 - - if ( mAttachmentMask & BIT( 0 ) ) - mCloth->attachVertexToGlobalPosition( 0, mCloth->getPosition( 0 ) ); - if ( mAttachmentMask & BIT( 1 ) ) - mCloth->attachVertexToGlobalPosition( mPatchVerts.x-1, mCloth->getPosition( mPatchVerts.x-1 ) ); - if ( mAttachmentMask & BIT( 2 ) ) - mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x, mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - mPatchVerts.x ) ); - if ( mAttachmentMask & BIT( 3 ) ) - mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - 1, mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - 1 ) ); - if ( mAttachmentMask & BIT( 4 ) ) - mCloth->attachVertexToGlobalPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2), mCloth->getPosition( mPatchVerts.x * mPatchVerts.y - (mPatchVerts.x/2) ) ); - if ( mAttachmentMask & BIT( 5 ) ) - mCloth->attachVertexToGlobalPosition( (mPatchVerts.x/2), mCloth->getPosition( (mPatchVerts.x/2) ) ); - if ( mAttachmentMask & BIT( 6 ) ) - mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2), mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) ) ); - if ( mAttachmentMask & BIT( 7 ) ) - mCloth->attachVertexToGlobalPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1), mCloth->getPosition( mPatchVerts.x * (mPatchVerts.y/2) + (mPatchVerts.x-1) ) ); - - if ( mAttachmentMask & BIT( 8 ) ) - for ( U32 i = mPatchVerts.x * mPatchVerts.y - mPatchVerts.x; i < mPatchVerts.x * mPatchVerts.y; i++ ) - mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) ); - - if ( mAttachmentMask & BIT( 9 ) ) - for ( U32 i = 0; i < mPatchVerts.x; i++ ) - mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) ); - - if ( mAttachmentMask & BIT( 10 ) ) - for ( U32 i = 0; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x ) - mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) ); - - if ( mAttachmentMask & BIT( 11 ) ) - for ( U32 i = mPatchVerts.x-1; i < mPatchVerts.x * mPatchVerts.y; i+=mPatchVerts.x ) - mCloth->attachVertexToGlobalPosition( i, mCloth->getPosition( i ) ); -} \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxCloth.h b/Engine/source/T3D/physics/physx/pxCloth.h deleted file mode 100644 index 5df158861..000000000 --- a/Engine/source/T3D/physics/physx/pxCloth.h +++ /dev/null @@ -1,176 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PXCLOTH_H_ -#define _PXCLOTH_H_ - -#ifndef _GAMEBASE_H_ -#include "T3D/gameBase/gameBase.h" -#endif -#ifndef _GFXPRIMITIVEBUFFER_H_ -#include "gfx/gfxPrimitiveBuffer.h" -#endif -#ifndef _GFXVERTEXBUFFER_H_ -#include "gfx/gfxVertexBuffer.h" -#endif -#ifndef _PHYSX_H_ -#include "T3D/physics/physx/px.h" -#endif -#ifndef _T3D_PHYSICS_PHYSICSPLUGIN_H_ -#include "T3D/physics/physicsPlugin.h" -#endif - -class Material; -class BaseMatInstance; -class PxWorld; -class NxScene; -class NxClothMesh; -class NxCloth; - - -class PxCloth : public GameBase -{ - typedef GameBase Parent; - - enum MaskBits - { - TransformMask = Parent::NextFreeMask << 0, - ClothMask = Parent::NextFreeMask << 1, - MaterialMask = Parent::NextFreeMask << 3, - NextFreeMask = Parent::NextFreeMask << 4 - }; - -public: - - PxCloth(); - virtual ~PxCloth(); - - DECLARE_CONOBJECT( PxCloth ); - - // SimObject - virtual bool onAdd(); - virtual void onRemove(); - static void initPersistFields(); - virtual void inspectPostApply(); - void onPhysicsReset( PhysicsResetEvent reset ); - - // NetObject - virtual U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream ); - virtual void unpackUpdate( NetConnection *conn, BitStream *stream ); - - // SceneObject - virtual void setTransform( const MatrixF &mat ); - virtual void setScale( const VectorF &scale ); - virtual void prepRenderImage( SceneRenderState *state ); - - // GameBase - virtual bool onNewDataBlock( GameBaseData *dptr, bool reload ); - virtual void processTick( const Move *move ); - virtual void interpolateTick( F32 delta ); - -protected: - - PxWorld *mWorld; - - NxScene *mScene; - - /// Cooked cloth collision mesh. - NxClothMesh *mClothMesh; - - /// The cloth actor used - NxCloth *mCloth; - - NxMeshData mReceiveBuffers; - - bool mBendingEnabled; - bool mDampingEnabled; - bool mTriangleCollisionEnabled; - bool mSelfCollisionEnabled; - - F32 mDensity; - F32 mThickness; - F32 mFriction; - F32 mBendingStiffness; - F32 mStretchingStiffness; - F32 mDampingCoefficient; - F32 mCollisionResponseCoefficient; - F32 mAttachmentResponseCoefficient; - - U32 mAttachmentMask; - - static EnumTable mAttachmentFlagTable; - - String mMaterialName; - SimObjectPtr mMaterial; - BaseMatInstance *mMatInst; - - String lookupName; - - /// The output verts from the PhysX simulation. - GFXVertexPNTT *mVertexRenderBuffer; - - /// The output indices from the PhysX simulation. - U16 *mIndexRenderBuffer; - - U32 mMaxVertices; - U32 mMaxIndices; - - /// The number of indices in the cloth which - /// is updated by the PhysX simulation. - U32 mNumIndices; - - /// The number of verts in the cloth which - /// is updated by the PhysX simulation. - U32 mNumVertices; - - U32 mMeshDirtyFlags; - bool mIsVBDirty; - - GFXPrimitiveBufferHandle mPrimBuffer; - GFXVertexBufferHandle mVB; - - Point2I mPatchVerts; - Point2F mPatchSize; - - MatrixF mResetXfm; - - void _initMaterial(); - - void _releaseMesh(); - void _releaseCloth(); - - bool _createClothPatch(); - - void _recreateCloth( const MatrixF &transform ); - - void _updateClothProperties(); - - void _initClothMesh(); - void _initReceiveBuffers(); - void _setupAttachments(); - - void _updateStaticCloth(); - - void _updateVBIB(); -}; - -#endif // _PXCLOTH_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxCollision.cpp b/Engine/source/T3D/physics/physx/pxCollision.cpp deleted file mode 100644 index b08636d64..000000000 --- a/Engine/source/T3D/physics/physx/pxCollision.cpp +++ /dev/null @@ -1,291 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxCollision.h" - -#include "math/mPoint3.h" -#include "math/mMatrix.h" -#include "T3D/physics/physX/px.h" -#include "T3D/physics/physX/pxCasts.h" -#include "T3D/physics/physX/pxWorld.h" -#include "T3D/physics/physX/pxStream.h" - - -PxCollision::PxCollision() -{ -} - -PxCollision::~PxCollision() -{ - // We may be deleteting SDK data... so make - // sure we have the the scene write lock. - PxWorld::releaseWriteLocks(); - - for ( U32 i=0; i < mColShapes.size(); i++ ) - { - // Check for special types which need cleanup. - NxShapeDesc *desc = mColShapes[i]; - - if ( desc->getType() == NX_SHAPE_CONVEX ) - gPhysicsSDK->releaseConvexMesh( *((NxConvexShapeDesc*)desc)->meshData ); - else if ( desc->getType() == NX_SHAPE_MESH ) - gPhysicsSDK->releaseTriangleMesh( *((NxTriangleMeshShapeDesc*)desc)->meshData ); - else if ( desc->getType() == NX_SHAPE_HEIGHTFIELD ) - gPhysicsSDK->releaseHeightField( *((NxHeightFieldShapeDesc*)desc)->heightField ); - - // Delete the descriptor. - delete desc; - } - - mColShapes.clear(); -} - -void PxCollision::addPlane( const PlaneF &plane ) -{ - NxBoxShapeDesc *desc = new NxBoxShapeDesc; - desc->skinWidth = 0.01f; - desc->dimensions.set( 10000.0f, 10000.0f, 100.0f ); - desc->localPose.t.z = -100.0f; - - // TODO: Fix rotation to match plane normal! - //boxDesc->localPose.M.setColumn( 0, NxVec3( plane.x, plane.y, plane.z ) ); - //boxDesc->localPose.M.setColumn( 1, NxVec3( plane.x, plane.y, plane.z ) ); - //boxDesc->localPose.M.setColumn( 2, NxVec3( plane.x, plane.y, plane.z ) ); - - mColShapes.push_back( desc ); -} - -void PxCollision::addBox( const Point3F &halfWidth, - const MatrixF &localXfm ) -{ - NxBoxShapeDesc *desc = new NxBoxShapeDesc; - desc->skinWidth = 0.01f; - desc->dimensions.set( halfWidth.x, halfWidth.y, halfWidth.z ); - desc->localPose.setRowMajor44( localXfm ); - mColShapes.push_back( desc ); -} - -void PxCollision::addSphere( F32 radius, - const MatrixF &localXfm ) -{ - NxSphereShapeDesc *desc = new NxSphereShapeDesc; - desc->skinWidth = 0.01f; - desc->radius = radius; - desc->localPose.setRowMajor44( localXfm ); - mColShapes.push_back( desc ); -} - -void PxCollision::addCapsule( F32 radius, - F32 height, - const MatrixF &localXfm ) -{ - NxCapsuleShapeDesc *desc = new NxCapsuleShapeDesc; - desc->skinWidth = 0.01f; - desc->radius = radius; - desc->height = height; - desc->localPose.setRowMajor44( localXfm ); - mColShapes.push_back( desc ); -} - -bool PxCollision::addConvex( const Point3F *points, - U32 count, - const MatrixF &localXfm ) -{ - // Mesh cooking requires that both - // scenes not be write locked! - PxWorld::releaseWriteLocks(); - - NxCookingInterface *cooker = PxWorld::getCooking(); - cooker->NxInitCooking(); - - NxConvexMeshDesc meshDesc; - meshDesc.numVertices = count; - meshDesc.pointStrideBytes = sizeof(Point3F); - meshDesc.points = points; - meshDesc.flags = NX_CF_COMPUTE_CONVEX | NX_CF_INFLATE_CONVEX; - - // Cook it! - NxCookingParams params; - #ifdef TORQUE_OS_XENON - params.targetPlatform = PLATFORM_XENON; - #else - params.targetPlatform = PLATFORM_PC; - #endif - params.skinWidth = 0.01f; - params.hintCollisionSpeed = true; - cooker->NxSetCookingParams( params ); - - PxMemStream stream; - bool cooked = cooker->NxCookConvexMesh( meshDesc, stream ); - cooker->NxCloseCooking(); - - if ( !cooked ) - return false; - - stream.resetPosition(); - NxConvexMesh *meshData = gPhysicsSDK->createConvexMesh( stream ); - if ( !meshData ) - return false; - - NxConvexShapeDesc *desc = new NxConvexShapeDesc; - desc->skinWidth = 0.01f; - desc->meshData = meshData; - desc->localPose.setRowMajor44( localXfm ); - mColShapes.push_back( desc ); - - return true; -} - -bool PxCollision::addTriangleMesh( const Point3F *vert, - U32 vertCount, - const U32 *index, - U32 triCount, - const MatrixF &localXfm ) -{ - // Mesh cooking requires that both - // scenes not be write locked! - PxWorld::releaseWriteLocks(); - - NxCookingInterface *cooker = PxWorld::getCooking(); - cooker->NxInitCooking(); - - NxTriangleMeshDesc meshDesc; - meshDesc.numVertices = vertCount; - meshDesc.numTriangles = triCount; - meshDesc.pointStrideBytes = sizeof(Point3F); - meshDesc.triangleStrideBytes = 3*sizeof(U32); - meshDesc.points = vert; - meshDesc.triangles = index; - meshDesc.flags = NX_MF_FLIPNORMALS; - - // Cook it! - NxCookingParams params; - #ifdef TORQUE_OS_XENON - params.targetPlatform = PLATFORM_XENON; - #else - params.targetPlatform = PLATFORM_PC; - #endif - params.skinWidth = 0.01f; - params.hintCollisionSpeed = true; - cooker->NxSetCookingParams( params ); - - PxMemStream stream; - bool cooked = cooker->NxCookTriangleMesh( meshDesc, stream ); - cooker->NxCloseCooking(); - if ( !cooked ) - return false; - - stream.resetPosition(); - NxTriangleMesh *meshData = gPhysicsSDK->createTriangleMesh( stream ); - if ( !meshData ) - return false; - - NxTriangleMeshShapeDesc *desc = new NxTriangleMeshShapeDesc; - desc->skinWidth = 0.01f; - desc->meshData = meshData; - desc->localPose.setRowMajor44( localXfm ); - mColShapes.push_back( desc ); - - return true; -} - -bool PxCollision::addHeightfield( const U16 *heights, - const bool *holes, - U32 blockSize, - F32 metersPerSample, - const MatrixF &localXfm ) -{ - // Since we're creating SDK level data we - // have to have access to all active worlds. - PxWorld::releaseWriteLocks(); - - // Init the heightfield description. - NxHeightFieldDesc heightFieldDesc; - heightFieldDesc.nbColumns = blockSize; - heightFieldDesc.nbRows = blockSize; - heightFieldDesc.thickness = -10.0f; - heightFieldDesc.convexEdgeThreshold = 0; - - // Allocate the samples. - heightFieldDesc.samples = new NxU32[ blockSize * blockSize ]; - heightFieldDesc.sampleStride = sizeof(NxU32); - NxU8 *currentByte = (NxU8*)heightFieldDesc.samples; - - for ( U32 row = 0; row < blockSize; row++ ) - { - const U32 tess = ( row + 1 ) % 2; - - for ( U32 column = 0; column < blockSize; column++ ) - { - NxHeightFieldSample *currentSample = (NxHeightFieldSample*)currentByte; - - U32 index = ( blockSize - row - 1 ) + ( column * blockSize ); - currentSample->height = heights[ index ]; - - if ( holes && holes[ getMax( (S32)index - 1, 0 ) ] ) // row index for holes adjusted so PhysX collision shape better matches rendered terrain - { - currentSample->materialIndex0 = 0; - currentSample->materialIndex1 = 0; - } - else - { - currentSample->materialIndex0 = 1; //materialIds[0]; - currentSample->materialIndex1 = 1; //materialIds[0]; - } - - currentSample->tessFlag = ( column + tess ) % 2; - - currentByte += heightFieldDesc.sampleStride; - } - } - - // Build it. - NxHeightFieldShapeDesc *desc = new NxHeightFieldShapeDesc; - desc->heightField = gPhysicsSDK->createHeightField( heightFieldDesc ); - - // Destroy the temp sample array. - delete [] heightFieldDesc.samples; - - // TerrainBlock uses a 11.5 fixed point height format - // giving it a maximum height range of 0 to 2048. - desc->heightScale = 0.03125f; - - desc->rowScale = metersPerSample; - desc->columnScale = metersPerSample; - desc->materialIndexHighBits = 0; - desc->skinWidth = 0.01f; - - // Use the local pose to align the heightfield - // to what Torque will expect. - NxMat33 rotX; - rotX.rotX( Float_HalfPi ); - NxMat33 rotZ; - rotZ.rotZ( Float_Pi ); - NxMat34 rot; - rot.M.multiply( rotZ, rotX ); - rot.t.set( ( blockSize - 1 ) * metersPerSample, 0, 0 ); - desc->localPose = rot; - - mColShapes.push_back( desc ); - return true; -} diff --git a/Engine/source/T3D/physics/physx/pxCollision.h b/Engine/source/T3D/physics/physx/pxCollision.h deleted file mode 100644 index 54263b792..000000000 --- a/Engine/source/T3D/physics/physx/pxCollision.h +++ /dev/null @@ -1,78 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _T3D_PHYSICS_PXCOLLISION_H_ -#define _T3D_PHYSICS_PXCOLLISION_H_ - -#ifndef _T3D_PHYSICS_PHYSICSCOLLISION_H_ -#include "T3D/physics/physicsCollision.h" -#endif -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif - -class NxShapeDesc; - - -class PxCollision : public PhysicsCollision -{ -protected: - - /// The collision representation. - Vector mColShapes; - - /// Helper for adding shapes. - //void _addShape( btCollisionShape *shape, const MatrixF &localXfm ); - -public: - - PxCollision(); - virtual ~PxCollision(); - - /// Return the PhysX shape descriptions. - const Vector& getShapes() const { return mColShapes; } - - // PhysicsCollision - virtual void addPlane( const PlaneF &plane ); - virtual void addBox( const Point3F &halfWidth, - const MatrixF &localXfm ); - virtual void addSphere( F32 radius, - const MatrixF &localXfm ); - virtual void addCapsule( F32 radius, - F32 height, - const MatrixF &localXfm ); - virtual bool addConvex( const Point3F *points, - U32 count, - const MatrixF &localXfm ); - virtual bool addTriangleMesh( const Point3F *vert, - U32 vertCount, - const U32 *index, - U32 triCount, - const MatrixF &localXfm ); - virtual bool addHeightfield( const U16 *heights, - const bool *holes, - U32 blockSize, - F32 metersPerSample, - const MatrixF &localXfm ); -}; - -#endif // _T3D_PHYSICS_PXCOLLISION_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxContactReporter.cpp b/Engine/source/T3D/physics/physx/pxContactReporter.cpp deleted file mode 100644 index 33b1c3dab..000000000 --- a/Engine/source/T3D/physics/physx/pxContactReporter.cpp +++ /dev/null @@ -1,108 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxContactReporter.h" - -#include "T3D/physics/physX/pxCasts.h" -#include "T3D/physics/physicsUserData.h" -#include "T3D/physics/physX/pxMultiActor.h" -#include "platform/profiler.h" - - -PxContactReporter::PxContactReporter() -{ -} - -PxContactReporter::~PxContactReporter() -{ -} - -void PxContactReporter::onContactNotify( NxContactPair &pair, NxU32 events ) -{ - PROFILE_SCOPE( PxContactReporter_OnContactNotify ); - - // For now we only care about start touch events. - if ( !( events & NX_NOTIFY_ON_START_TOUCH ) ) - return; - - // Skip if either actor is deleted. - if ( pair.isDeletedActor[0] || pair.isDeletedActor[1] ) - return; - - NxActor *actor0 = pair.actors[0]; - NxActor *actor1 = pair.actors[1]; - - PhysicsUserData *userData0 = PhysicsUserData::cast( actor0->userData ); - PhysicsUserData *userData1 = PhysicsUserData::cast( actor1->userData ); - - // Early out if we don't have user data or signals to notify. - if ( ( !userData0 || userData0->getContactSignal().isEmpty() ) && - ( !userData1 || userData1->getContactSignal().isEmpty() ) ) - return; - - // Get an average contact point. - U32 points = 0; - NxVec3 hitPoint( 0.0f ); - NxContactStreamIterator iter( pair.stream ); - while( iter.goNextPair() ) - { - while( iter.goNextPatch() ) - { - while( iter.goNextPoint() ) - { - hitPoint += iter.getPoint(); - ++points; - } - } - } - hitPoint /= (F32)points; - - if ( userData0 ) - userData0->getContactSignal().trigger( userData0, - userData1, - pxCast( hitPoint ), - pxCast( pair.sumNormalForce ) ); - - if ( userData1 ) - userData1->getContactSignal().trigger( userData1, - userData0, - pxCast( hitPoint ), - pxCast( -pair.sumNormalForce ) ); -} - -bool PxUserNotify::onJointBreak( NxReal breakingForce, NxJoint &brokenJoint ) -{ - PROFILE_SCOPE( PxUserNotify_OnJointBreak ); - - PxUserData *userData = PxUserData::getData( brokenJoint ); - - if ( userData ) - userData->getOnJointBreakSignal().trigger( breakingForce, brokenJoint ); - - // NOTE: Returning true here will tell the - // PhysX SDK to delete the joint, which will - // cause MANY problems if any of the user app's - // objects still hold references to it. - - return false; -} \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxContactReporter.h b/Engine/source/T3D/physics/physx/pxContactReporter.h deleted file mode 100644 index 883d61b9c..000000000 --- a/Engine/source/T3D/physics/physx/pxContactReporter.h +++ /dev/null @@ -1,54 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PXCONTACTREPORTER_H_ -#define _PXCONTACTREPORTER_H_ - -#ifndef _PHYSX_H_ -#include "T3D/physics/physX/px.h" -#endif - - -class PxContactReporter : public NxUserContactReport -{ -protected: - - virtual void onContactNotify( NxContactPair& pair, NxU32 events ); - -public: - - PxContactReporter(); - virtual ~PxContactReporter(); -}; - - - -class PxUserNotify : public NxUserNotify -{ -public: - virtual bool onJointBreak( NxReal breakingForce, NxJoint &brokenJoint ); - virtual void onWake( NxActor **actors, NxU32 count ) {} - virtual void onSleep ( NxActor **actors, NxU32 count ) {} -}; - - -#endif // _PXCONTACTREPORTER_H_ diff --git a/Engine/source/T3D/physics/physx/pxFluid.cpp b/Engine/source/T3D/physics/physx/pxFluid.cpp deleted file mode 100644 index efe5d453b..000000000 --- a/Engine/source/T3D/physics/physx/pxFluid.cpp +++ /dev/null @@ -1,310 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physx/pxFluid.h" - -#include "console/consoleTypes.h" -#include "scene/sceneRenderState.h" -#include "renderInstance/renderPassManager.h" -#include "T3D/physics/physicsPlugin.h" -#include "T3D/physics/physx/pxWorld.h" -#include "T3D/physics/physx/pxCasts.h" -#include "gfx/gfxDrawUtil.h" -#include "math/mathIO.h" -#include "core/stream/bitStream.h" - - -IMPLEMENT_CO_NETOBJECT_V1( PxFluid ); - -ConsoleDocClass( PxFluid, - "@brief Experimental and unfinished Torque wrapper class for NxFluid.\n\n" - "@internal\n" -); - -PxFluid::PxFluid() - : mWorld( NULL ), - mScene( NULL ), - mParticles( NULL ), - mFluid( NULL ), - mEmitter( NULL ), - mParticleCount( 0 ) -{ - mNetFlags.set( Ghostable | ScopeAlways ); - mTypeMask |= StaticObjectType | StaticShapeObjectType; -} - -PxFluid::~PxFluid() -{ - -} - -bool PxFluid::onAdd() -{ - if ( !Parent::onAdd() ) - return false; - - mWorld = dynamic_cast( PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ) ); - - if ( !mWorld || !mWorld->getScene() ) - { - Con::errorf( "PxMultiActor::onAdd() - PhysXWorld not initialized!" ); - return false; - } - - mScene = mWorld->getScene(); - - if ( isClientObject() ) - _createFluid(); - - Point3F halfScale = Point3F::One * 0.5f; - mObjBox.minExtents = -halfScale; - mObjBox.maxExtents = halfScale; - resetWorldBox(); - - addToScene(); - - return true; -} - -void PxFluid::onRemove() -{ - if ( isClientObject() ) - _destroyFluid(); - - removeFromScene(); - - Parent::onRemove(); -} - -void PxFluid::initPersistFields() -{ - Parent::initPersistFields(); -} - -void PxFluid::inspectPostApply() -{ - Parent::inspectPostApply(); - - setMaskBits( UpdateMask ); -} - -U32 PxFluid::packUpdate( NetConnection *conn, U32 mask, BitStream *stream ) -{ - U32 retMask = Parent::packUpdate( conn, mask, stream ); - - if ( stream->writeFlag( mask & UpdateMask ) ) - { - mathWrite( *stream, getTransform() ); - mathWrite( *stream, getScale() ); - - stream->write( mEmitter ? mEmitter->getRate() : 0 ); - } - - stream->writeFlag( isProperlyAdded() && mask & ResetMask ); - - return retMask; -} - -void PxFluid::unpackUpdate( NetConnection *conn, BitStream *stream ) -{ - Parent::unpackUpdate( conn, stream ); - - // UpdateMask - if ( stream->readFlag() ) - { - MatrixF mat; - mathRead( *stream, &mat ); - Point3F scale; - mathRead( *stream, &scale ); - - setScale( scale ); - setTransform( mat ); - - F32 rate; - stream->read( &rate ); - setRate( rate ); - } - - // ResetMask - if ( stream->readFlag() ) - resetParticles(); -} - -void PxFluid::setTransform( const MatrixF &mat ) -{ - Parent::setTransform( mat ); - - if ( mEmitter ) - { - NxMat34 nxMat; - nxMat.setRowMajor44( mat ); - mEmitter->setGlobalPose( nxMat ); - } -} - -void PxFluid::setScale( const VectorF &scale ) -{ - Point3F lastScale = getScale(); - - Point3F halfScale = Point3F::One * 0.5f; - mObjBox.minExtents = -halfScale; - mObjBox.maxExtents = halfScale; - resetWorldBox(); - - Parent::setScale( scale ); - - if ( lastScale != getScale() && - mEmitter ) - { - _destroyFluid(); - _createFluid(); - } -} - -void PxFluid::prepRenderImage( SceneRenderState *state ) -{ - if ( !state->isDiffusePass() ) - return; - - ObjectRenderInst *ri = state->getRenderPass()->allocInst(); - ri->renderDelegate.bind( this, &PxFluid::renderObject ); - ri->type = RenderPassManager::RIT_Object; - state->getRenderPass()->addInst( ri ); -} - -void PxFluid::resetParticles() -{ - if ( mEmitter ) - mEmitter->resetEmission( MAX_PARTICLES ); - setMaskBits( ResetMask ); -} - -void PxFluid::setRate( F32 rate ) -{ - if ( mEmitter ) - mEmitter->setRate( rate ); - setMaskBits( UpdateMask ); -} - -void PxFluid::renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) -{ - GFXStateBlockDesc desc; - desc.setBlend( true ); - desc.setZReadWrite( true, false ); - - for ( U32 i = 0; i < mParticleCount; i++ ) - { - FluidParticle &particle = mParticles[i]; - Point3F pnt = pxCast( particle.position ); - - Box3F box( 0.2f ); - box.minExtents += pnt; - box.maxExtents += pnt; - - GFX->getDrawUtil()->drawCube( desc, box, ColorI::BLUE ); - } -} - -void PxFluid::_createFluid() -{ - /* - // Set structure to pass particles, and receive them after every simulation step - NxParticleData particleData; - particleData.numParticlesPtr = &mParticleCount; - particleData.bufferPos = &mParticles[0].position.x; - particleData.bufferPosByteStride = sizeof(FluidParticle); - particleData.bufferVel = &mParticles[0].velocity.x; - particleData.bufferVelByteStride = sizeof(FluidParticle); - particleData.bufferLife = &mParticles[0].lifetime; - particleData.bufferLifeByteStride = sizeof(FluidParticle); - - // Create a fluid descriptor - NxFluidDesc fluidDesc; - fluidDesc.kernelRadiusMultiplier = 2.3f; - fluidDesc.restParticlesPerMeter = 10.0f; - fluidDesc.stiffness = 200.0f; - fluidDesc.viscosity = 22.0f; - fluidDesc.restDensity = 1000.0f; - fluidDesc.damping = 0.0f; - fluidDesc.simulationMethod = NX_F_SPH; - fluidDesc.initialParticleData = particleData; - fluidDesc.particlesWriteData = particleData; - */ - - NxFluidDesc fluidDesc; - fluidDesc.setToDefault(); - fluidDesc.simulationMethod = NX_F_SPH; - fluidDesc.maxParticles = MAX_PARTICLES; - fluidDesc.restParticlesPerMeter = 50; - fluidDesc.stiffness = 1; - fluidDesc.viscosity = 6; - fluidDesc.flags = NX_FF_VISUALIZATION|NX_FF_ENABLED; - - mParticles = new FluidParticle[MAX_PARTICLES]; - dMemset( mParticles, 0, sizeof(FluidParticle) * MAX_PARTICLES ); - - NxParticleData &particleData = fluidDesc.particlesWriteData; - - particleData.numParticlesPtr = &mParticleCount; - particleData.bufferPos = &mParticles[0].position.x; - particleData.bufferPosByteStride = sizeof(FluidParticle); - particleData.bufferVel = &mParticles[0].velocity.x; - particleData.bufferVelByteStride = sizeof(FluidParticle); - particleData.bufferLife = &mParticles[0].lifetime; - particleData.bufferLifeByteStride = sizeof(FluidParticle); - - mFluid = mScene->createFluid( fluidDesc ); - - - //Create Emitter. - NxFluidEmitterDesc emitterDesc; - emitterDesc.setToDefault(); - emitterDesc.dimensionX = getScale().x; - emitterDesc.dimensionY = getScale().y; - emitterDesc.relPose.setColumnMajor44( getTransform() ); - emitterDesc.rate = 5.0f; - emitterDesc.randomAngle = 0.1f; - emitterDesc.fluidVelocityMagnitude = 6.5f; - emitterDesc.maxParticles = 0; - emitterDesc.particleLifetime = 4.0f; - emitterDesc.type = NX_FE_CONSTANT_FLOW_RATE; - emitterDesc.shape = NX_FE_ELLIPSE; - mEmitter = mFluid->createEmitter(emitterDesc); -} - -void PxFluid::_destroyFluid() -{ - delete[] mParticles; - mScene->releaseFluid( *mFluid ); - mEmitter = NULL; -} - -ConsoleMethod( PxFluid, resetParticles, void, 2, 2, "" ) -{ - object->resetParticles(); -} - -ConsoleMethod( PxFluid, setRate, void, 2, 2, "" ) -{ - object->setRate( dAtof(argv[2]) ); -} \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxFluid.h b/Engine/source/T3D/physics/physx/pxFluid.h deleted file mode 100644 index ae7fe4f3c..000000000 --- a/Engine/source/T3D/physics/physx/pxFluid.h +++ /dev/null @@ -1,107 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PXFLUID_H_ -#define _PXFLUID_H_ - -#ifndef _SCENEOBJECT_H_ -#include "scene/sceneObject.h" -#endif -#ifndef _PHYSX_H_ -#include "T3D/physics/physx/px.h" -#endif - -class BaseMatInstance; -class PxWorld; -class NxScene; - - -class PxFluid : public SceneObject -{ - typedef SceneObject Parent; - -protected: - - enum NetMasks - { - UpdateMask = Parent::NextFreeMask, - ResetMask = Parent::NextFreeMask << 1, - NextFreeMask = Parent::NextFreeMask << 2 - }; - - struct FluidParticle - { - NxVec3 position; - NxVec3 velocity; - NxReal density; - NxReal lifetime; - NxU32 id; - NxVec3 collisionNormal; - }; - - #define MAX_PARTICLES 100 - -public: - - PxFluid(); - virtual ~PxFluid(); - - DECLARE_CONOBJECT( PxFluid ); - - // SimObject - virtual bool onAdd(); - virtual void onRemove(); - static void initPersistFields(); - virtual void inspectPostApply(); - - // NetObject - virtual U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream ); - virtual void unpackUpdate( NetConnection *conn, BitStream *stream ); - - // SceneObject - virtual void setTransform( const MatrixF &mat ); - virtual void setScale( const VectorF &scale ); - virtual void prepRenderImage( SceneRenderState *state ); - - void resetParticles(); - void setRate( F32 rate ); - -protected: - - void renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ); - - void _createFluid(); - void _destroyFluid(); - -protected: - - PxWorld *mWorld; - NxScene *mScene; - - FluidParticle *mParticles; - //NxParticleData *mParticleData; - NxFluid *mFluid; - U32 mParticleCount; - NxFluidEmitter *mEmitter; -}; - -#endif // _PXFLUID_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxMaterial.cpp b/Engine/source/T3D/physics/physx/pxMaterial.cpp deleted file mode 100644 index 9a5656394..000000000 --- a/Engine/source/T3D/physics/physx/pxMaterial.cpp +++ /dev/null @@ -1,150 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/px.h" - -#include "T3D/physics/physX/pxMaterial.h" - -#include "T3D/physics/physX/pxWorld.h" -#include "T3D/physics/physicsPlugin.h" -#include "console/consoleTypes.h" -#include "core/stream/bitStream.h" - - -IMPLEMENT_CO_DATABLOCK_V1( PxMaterial ); - -ConsoleDocClass( PxMaterial, - - "@brief Defines a PhysX material assignable to a PxMaterial.\n\n" - - "When two actors collide, the collision behavior that results depends on the material properties " - "of the actors' surfaces. For example, the surface properties determine if the actors will or will " - "not bounce, or if they will slide or stick. Currently, the only special feature supported by materials " - "is anisotropic friction, but according to Nvidia, other effects such as moving surfaces and more types " - "of friction are slotted for future release.\n\n" - - "For more information, refer to Nvidia's PhysX docs.\n\n" - - "@ingroup Physics" -); - -PxMaterial::PxMaterial() -: mNxMat( NULL ), - mNxMatId( -1 ), - restitution( 0.0f ), - staticFriction( 0.1f ), - dynamicFriction( 0.95f ), - mServer( false ) -{ -} - -PxMaterial::~PxMaterial() -{ -} - -void PxMaterial::consoleInit() -{ - Parent::consoleInit(); -} - -void PxMaterial::initPersistFields() -{ - Parent::initPersistFields(); - - addGroup("PxMaterial"); - - addField( "restitution", TypeF32, Offset( restitution, PxMaterial ), - "@brief Coeffecient of a bounce applied to the shape in response to a collision.\n\n" - "A value of 0 makes the object bounce as little as possible, while higher values up to 1.0 result in more bounce.\n\n" - "@note Values close to or above 1.0 may cause stability problems and/or increasing energy."); - addField( "staticFriction", TypeF32, Offset( staticFriction, PxMaterial ), - "@brief Coefficient of static %friction to be applied.\n\n" - "Static %friction determines the force needed to start moving an at-rest object in contact with a surface. " - "If the force applied onto shape cannot overcome the force of static %friction, the shape will remain at rest. " - "A higher coefficient will require a larger force to start motion. " - "@note This value should be larger than 0.\n\n"); - addField( "dynamicFriction", TypeF32, Offset( dynamicFriction, PxMaterial ), - "@brief Coefficient of dynamic %friction to be applied.\n\n" - "Dynamic %friction reduces the velocity of a moving object while it is in contact with a surface. " - "A higher coefficient will result in a larger reduction in velocity. " - "A shape's dynamicFriction should be equal to or larger than 0.\n\n"); - - endGroup("PxMaterial"); -} - -void PxMaterial::onStaticModified( const char *slotName, const char *newValue ) -{ - if ( isProperlyAdded() && mNxMat != NULL ) - { - mNxMat->setRestitution( restitution ); - mNxMat->setStaticFriction( staticFriction ); - mNxMat->setDynamicFriction( dynamicFriction ); - } -} - -bool PxMaterial::preload( bool server, String &errorBuffer ) -{ - mServer = server; - - PxWorld *world = dynamic_cast( PHYSICSMGR->getWorld( server ? "server" : "client" ) ); - - if ( !world ) - { - // TODO: Error... in error buffer? - return false; - } - - NxMaterialDesc material; - material.restitution = restitution; - material.staticFriction = staticFriction; - material.dynamicFriction = dynamicFriction; - - mNxMat = world->createMaterial( material ); - mNxMatId = mNxMat->getMaterialIndex(); - - if ( mNxMatId == -1 ) - { - errorBuffer = "PxMaterial::preload() - unable to create material!"; - return false; - } - - return Parent::preload( server, errorBuffer ); -} - -void PxMaterial::packData( BitStream* stream ) -{ - Parent::packData( stream ); - - stream->write( restitution ); - stream->write( staticFriction ); - stream->write( dynamicFriction ); -} - -void PxMaterial::unpackData( BitStream* stream ) -{ - Parent::unpackData( stream ); - - stream->read( &restitution ); - stream->read( &staticFriction ); - stream->read( &dynamicFriction ); -} diff --git a/Engine/source/T3D/physics/physx/pxMaterial.h b/Engine/source/T3D/physics/physx/pxMaterial.h deleted file mode 100644 index b1e0dd7f0..000000000 --- a/Engine/source/T3D/physics/physx/pxMaterial.h +++ /dev/null @@ -1,69 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PHYSX_MATERIAL_H -#define _PHYSX_MATERIAL_H - -#ifndef _SIMBASE_H_ -#include "console/simBase.h" -#endif -#ifndef _DYNAMIC_CONSOLETYPES_H_ -#include "console/dynamicTypes.h" -#endif - -class NxMaterial; - -class PxMaterial : public SimDataBlock -{ - typedef SimDataBlock Parent; - -protected: - - F32 restitution; - F32 staticFriction; - F32 dynamicFriction; - - NxMaterial *mNxMat; - S32 mNxMatId; - - bool mServer; - -public: - - DECLARE_CONOBJECT( PxMaterial ); - - PxMaterial(); - ~PxMaterial(); - - static void consoleInit(); - static void initPersistFields(); - virtual void onStaticModified( const char *slotName, const char *newValue ); - - bool preload( bool server, String &errorBuffer ); - virtual void packData( BitStream* stream ); - virtual void unpackData( BitStream* stream ); - - S32 getMaterialId() const { return mNxMatId; } - -}; - -#endif // _PHYSX_MATERIAL_H \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxMultiActor.cpp b/Engine/source/T3D/physics/physx/pxMultiActor.cpp deleted file mode 100644 index 6abdcdaad..000000000 --- a/Engine/source/T3D/physics/physx/pxMultiActor.cpp +++ /dev/null @@ -1,2651 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxMultiActor.h" - -#include "console/consoleTypes.h" -#include "core/stream/fileStream.h" -#include "core/stream/bitStream.h" -#include "core/resourceManager.h" -#include "core/strings/stringUnit.h" -#include "sim/netConnection.h" -#include "math/mathIO.h" -#include "math/mathUtils.h" -#include "gfx/gfxTransformSaver.h" -#include "gfx/gfxDrawUtil.h" -#include "gfx/primBuilder.h" -#include "collision/collision.h" -#include "collision/abstractPolyList.h" -#include "ts/tsShapeInstance.h" -#include "ts/tsPartInstance.h" -#include "lighting/lightManager.h" -#include "scene/sceneManager.h" -#include "scene/sceneRenderState.h" -#include "scene/sceneObjectLightingPlugin.h" -#include "T3D/objectTypes.h" -#include "T3D/containerQuery.h" -#include "T3D/fx/particleEmitter.h" -#include "T3D/debris.h" -#include "renderInstance/renderPassManager.h" -#include "gui/worldEditor/editor.h" // For gEditingMission -#include "T3D/physics/physX/px.h" -#include "T3D/physics/physX/pxWorld.h" -#include "T3D/physics/physX/pxMaterial.h" -#include "T3D/physics/physX/pxCasts.h" -#include "T3D/physics/physx/pxUtils.h" -#include "sfx/sfxSystem.h" - -#include -#include -#include - - -class PxMultiActor_Notify : public NXU_userNotify -{ -protected: - - Vector mActors; - - Vector mShapes; - - Vector mJoints; - - const NxMat34 mTransform; - - const Point3F mScale; - - F32 mMassScale; - - NxCompartment *mCompartment; - - PxMaterial *mMaterial; - - Vector *mActorUserProperties; - - Vector *mJointUserProperties; - -public: - - void NXU_notifyJoint( NxJoint *joint, const char *userProperties ) - { - if ( mJointUserProperties ) - mJointUserProperties->push_back( userProperties ); - mJoints.push_back( joint ); - } - - bool NXU_preNotifyJoint( NxJointDesc &joint, const char *userProperties ) - { - joint.localAnchor[0].x *= mScale.x; - joint.localAnchor[0].y *= mScale.y; - joint.localAnchor[0].z *= mScale.z; - - joint.localAnchor[1].x *= mScale.x; - joint.localAnchor[1].y *= mScale.y; - joint.localAnchor[1].z *= mScale.z; - - // The PhysX exporter from 3dsMax doesn't allow creation - // of fixed joints. It also doesn't seem to export the - // joint names! So look for joints which all all the - // motion axes are locked... make those fixed joints. - if ( joint.getType() == NX_JOINT_D6 ) - { - NxD6JointDesc *d6Joint = static_cast( &joint ); - - if ( d6Joint->xMotion == NX_D6JOINT_MOTION_LOCKED && - d6Joint->yMotion == NX_D6JOINT_MOTION_LOCKED && - d6Joint->zMotion == NX_D6JOINT_MOTION_LOCKED && - d6Joint->swing1Motion == NX_D6JOINT_MOTION_LOCKED && - d6Joint->swing2Motion == NX_D6JOINT_MOTION_LOCKED && - d6Joint->twistMotion == NX_D6JOINT_MOTION_LOCKED ) - { - // Ok... build a new fixed joint. - NxFixedJointDesc fixed; - fixed.actor[0] = joint.actor[0]; - fixed.actor[1] = joint.actor[1]; - fixed.localNormal[0] = joint.localNormal[0]; - fixed.localNormal[1] = joint.localNormal[1]; - fixed.localAxis[0] = joint.localAxis[0]; - fixed.localAxis[1] = joint.localAxis[1]; - fixed.localAnchor[0] = joint.localAnchor[0]; - fixed.localAnchor[1] = joint.localAnchor[1]; - fixed.maxForce = joint.maxForce; - fixed.maxTorque = joint.maxTorque; - fixed.name = joint.name; - fixed.userData = joint.userData; - fixed.jointFlags = joint.jointFlags; - - // What scene are we adding this to? - NxActor *actor = fixed.actor[0] ? fixed.actor[0] : fixed.actor[1]; - NxScene &scene = actor->getScene(); - - NxJoint* theJoint = scene.createJoint( fixed ); - mJoints.push_back( theJoint ); - if ( mJointUserProperties ) - mJointUserProperties->push_back( userProperties ); - - // Don't generate this joint. - return false; - } - } - - return true; - } - - void NXU_notifyActor( NxActor *actor, const char *userProperties ) - { - mActors.push_back( actor ); - - // Save the shapes. - for ( U32 i=0; i < actor->getNbShapes(); i++ ) - mShapes.push_back( actor->getShapes()[i] ); - - mActorUserProperties->push_back( userProperties ); - }; - - bool NXU_preNotifyMaterial( NxMaterialDesc &t, const char *userProperties ) - { - // Don't generate materials if we have one defined! - return !mMaterial; - } - - bool NXU_preNotifyActor( NxActorDesc &actor, const char *userProperties ) - { - // Set the right compartment. - actor.compartment = mCompartment; - - if ( actor.shapes.size() == 0 ) - Con::warnf( "PxMultiActor_Notify::NXU_preNotifyActor, got an actor (%s) with no shapes, was this intentional?", actor.name ); - - // For every shape, cast to its particular type - // and apply the scale to size, mass and localPosition. - for( S32 i = 0; i < actor.shapes.size(); i++ ) - { - // If we have material then set it. - if ( mMaterial ) - actor.shapes[i]->materialIndex = mMaterial->getMaterialId(); - - switch( actor.shapes[i]->getType() ) - { - case NX_SHAPE_BOX: - { - NxBoxShapeDesc *boxDesc = (NxBoxShapeDesc*)actor.shapes[i]; - - boxDesc->mass *= mMassScale; - - boxDesc->dimensions.x *= mScale.x; - boxDesc->dimensions.y *= mScale.y; - boxDesc->dimensions.z *= mScale.z; - - boxDesc->localPose.t.x *= mScale.x; - boxDesc->localPose.t.y *= mScale.y; - boxDesc->localPose.t.z *= mScale.z; - break; - } - - case NX_SHAPE_SPHERE: - { - NxSphereShapeDesc *sphereDesc = (NxSphereShapeDesc*)actor.shapes[i]; - - sphereDesc->mass *= mMassScale; - - // TODO: Spheres do not work with non-uniform - // scales very well... how do we fix this? - sphereDesc->radius *= mScale.x; - - sphereDesc->localPose.t.x *= mScale.x; - sphereDesc->localPose.t.y *= mScale.y; - sphereDesc->localPose.t.z *= mScale.z; - break; - } - - case NX_SHAPE_CAPSULE: - { - NxCapsuleShapeDesc *capsuleDesc = (NxCapsuleShapeDesc*)actor.shapes[i]; - - capsuleDesc->mass *= mMassScale; - - // TODO: Capsules do not work with non-uniform - // scales very well... how do we fix this? - capsuleDesc->radius *= mScale.x; - capsuleDesc->height *= mScale.y; - - capsuleDesc->localPose.t.x *= mScale.x; - capsuleDesc->localPose.t.y *= mScale.y; - capsuleDesc->localPose.t.z *= mScale.z; - break; - } - - default: - { - static String lookup[] = - { - "PLANE", - "SPHERE", - "BOX", - "CAPSULE", - "WHEEL", - "CONVEX", - "MESH", - "HEIGHTFIELD" - }; - - Con::warnf( "PxMultiActor_Notify::NXU_preNotifyActor, unsupported shape type (%s), on Actor (%s)", lookup[actor.shapes[i]->getType()].c_str(), actor.name ); - - delete actor.shapes[i]; - actor.shapes.erase( actor.shapes.begin() + i ); - --i; - break; - } - } - } - - NxBodyDesc *body = const_cast( actor.body ); - if ( body ) - { - // Must scale all of these parameters, else there will be odd results! - body->mass *= mMassScale; - body->massLocalPose.t.multiply( mMassScale, body->massLocalPose.t ); - body->massSpaceInertia.multiply( mMassScale, body->massSpaceInertia ); - - // Ragdoll damping! - //body->sleepDamping = 1.7f; - //body->linearDamping = 0.4f; - //body->angularDamping = 0.08f; - //body->wakeUpCounter = 0.3f; - } - - return true; - }; - -public: - - PxMultiActor_Notify( NxCompartment *compartment, - PxMaterial *material, - const NxMat34& mat, - const Point3F& scale, - Vector *actorProps = NULL, - Vector *jointProps = NULL ) - : mCompartment( compartment ), - mMaterial( material ), - mScale( scale ), - mTransform( mat ), - mActorUserProperties( actorProps ), - mJointUserProperties( jointProps ) - { - const F32 unit = VectorF( 1.0f, 1.0f, 1.0f ).len(); - mMassScale = mScale.len() / unit; - } - - virtual ~PxMultiActor_Notify() - { - } - - const Vector& getActors() { return mActors; } - const Vector& getShapes() { return mShapes; } - const Vector& getJoints() { return mJoints; } -}; - -ConsoleDocClass( PxMultiActorData, - - "@brief Defines the properties of a type of PxMultiActor.\n\n" - - "Usually it is prefered to use PhysicsShape rather than PxMultiActor because " - "a PhysicsShape is not PhysX specific and can be much easier to setup.\n\n" - - "For more information, refer to Nvidia's PhysX docs.\n\n" - - "@ingroup Physics" -); - -IMPLEMENT_CO_DATABLOCK_V1(PxMultiActorData); - -PxMultiActorData::PxMultiActorData() - : material( NULL ), - collection( NULL ), - waterDragScale( 1.0f ), - buoyancyDensity( 1.0f ), - angularDrag( 0.0f ), - linearDrag( 0.0f ), - clientOnly( false ), - singlePlayerOnly( false ), - shapeName( StringTable->insert( "" ) ), - physXStream( StringTable->insert( "" ) ), - breakForce( 0.0f ) -{ - for ( S32 i = 0; i < MaxCorrectionNodes; i++ ) - correctionNodeNames[i] = StringTable->insert( "" ); - - for ( S32 i = 0; i < MaxCorrectionNodes; i++ ) - correctionNodes[i] = -1; - - for ( S32 i = 0; i < NumMountPoints; i++ ) - { - mountNodeNames[i] = StringTable->insert( "" ); - mountPointNode[i] = -1; - } -} - -PxMultiActorData::~PxMultiActorData() -{ - if ( collection ) - NXU::releaseCollection( collection ); -} - -void PxMultiActorData::initPersistFields() -{ - Parent::initPersistFields(); - - addGroup("Media"); - addField( "shapeName", TypeFilename, Offset( shapeName, PxMultiActorData ), - "@brief Path to the .DAE or .DTS file to render.\n\n"); - endGroup("Media"); - - // PhysX collision properties. - addGroup( "Physics" ); - - addField( "physXStream", TypeFilename, Offset( physXStream, PxMultiActorData ), - "@brief .XML file containing data such as actors, shapes, and joints.\n\n" - "These files can be created using a free PhysX plugin for 3DS Max.\n\n"); - addField( "material", TYPEID< PxMaterial >(), Offset( material, PxMultiActorData ), - "@brief An optional PxMaterial to be used for the PxMultiActor.\n\n" - "Defines properties such as friction and restitution. " - "Unrelated to the material used for rendering. The physXStream will contain " - "defined materials that can be customized in 3DS Max. " - "To override the material for all physics shapes in the physXStream, specify a material here.\n\n"); - - addField( "noCorrection", TypeBool, Offset( noCorrection, PxMultiActorData ), - "@hide" ); - - UTF8 buff[256]; - for ( S32 i=0; i < MaxCorrectionNodes; i++ ) - { - //dSprintf( buff, sizeof(buff), "correctionNode%d", i ); - addField( buff, TypeString, Offset( correctionNodeNames[i], PxMultiActorData ), "@hide" ); - } - - for ( S32 i=0; i < NumMountPoints; i++ ) - { - //dSprintf( buff, sizeof(buff), "mountNode%d", i ); - addField( buff, TypeString, Offset( mountNodeNames[i], PxMultiActorData ), "@hide" ); - } - - addField( "angularDrag", TypeF32, Offset( angularDrag, PxMultiActorData ), - "@brief Value used to help calculate rotational drag force while submerged in water.\n\n"); - addField( "linearDrag", TypeF32, Offset( linearDrag, PxMultiActorData ), - "@brief Value used to help calculate linear drag force while submerged in water.\n\n"); - addField( "waterDragScale", TypeF32, Offset( waterDragScale, PxMultiActorData ), - "@brief Scale to apply to linear and angular dampening while submerged in water.\n\n "); - addField( "buoyancyDensity", TypeF32, Offset( buoyancyDensity, PxMultiActorData ), - "@brief The density used to calculate buoyant forces.\n\n" - "The result of the calculated buoyancy is relative to the density of the WaterObject the PxMultiActor is within.\n\n" - "@note This value is necessary because Torque 3D does its own buoyancy simulation. It is not handled by PhysX." - "@see WaterObject::density"); - - endGroup( "Physics" ); - - addField( "clientOnly", TypeBool, Offset( clientOnly, PxMultiActorData ), - "@hide"); - addField( "singlePlayerOnly", TypeBool, Offset( singlePlayerOnly, PxMultiActorData ), - "@hide"); - addField( "breakForce", TypeF32, Offset( breakForce, PxMultiActorData ), - "@brief Force required to break an actor.\n\n" - "This value does not apply to joints. " - "If an actor is associated with a joint it will break whenever the joint does. " - "This allows an actor \"not\" associated with a joint to also be breakable.\n\n"); -} - -void PxMultiActorData::packData(BitStream* stream) -{ - Parent::packData(stream); - - stream->writeString( shapeName ); - stream->writeString( physXStream ); - - if( stream->writeFlag( material ) ) - stream->writeRangedU32( packed ? SimObjectId( material ) : material->getId(), - DataBlockObjectIdFirst, DataBlockObjectIdLast ); - - if ( !stream->writeFlag( noCorrection ) ) - { - // Write the correction node indices for the client. - for ( S32 i = 0; i < MaxCorrectionNodes; i++ ) - stream->write( correctionNodes[i] ); - } - - for ( S32 i = 0; i < NumMountPoints; i++ ) - stream->write( mountPointNode[i] ); - - stream->write( waterDragScale ); - stream->write( buoyancyDensity ); - stream->write( angularDrag ); - stream->write( linearDrag ); - - stream->writeFlag( clientOnly ); - stream->writeFlag( singlePlayerOnly ); - stream->write( breakForce ); -} - -void PxMultiActorData::unpackData(BitStream* stream) -{ - Parent::unpackData(stream); - - shapeName = stream->readSTString(); - physXStream = stream->readSTString(); - - if( stream->readFlag() ) - material = (PxMaterial*)stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast ); - - noCorrection = stream->readFlag(); - if ( !noCorrection ) - { - for ( S32 i = 0; i < MaxCorrectionNodes; i++ ) - stream->read( &correctionNodes[i] ); - } - - for ( S32 i = 0; i < NumMountPoints; i++ ) - stream->read( &mountPointNode[i] ); - - stream->read( &waterDragScale ); - stream->read( &buoyancyDensity ); - stream->read( &angularDrag ); - stream->read( &linearDrag ); - - clientOnly = stream->readFlag(); - singlePlayerOnly = stream->readFlag(); - stream->read( &breakForce ); -} - -bool PxMultiActorData::preload( bool server, String &errorBuffer ) -{ - if ( !Parent::preload( server, errorBuffer ) ) - return false; - - // If the stream is null, exit. - if ( !physXStream || !physXStream[0] ) - { - errorBuffer = "PxMultiActorData::preload: physXStream is unset!"; - return false; - } - - // Set up our buffer for the binary stream filename path. - UTF8 binPhysXStream[260] = { 0 }; - const UTF8* ext = dStrrchr( physXStream, '.' ); - - // Copy the xml stream path except for the extension. - if ( ext ) - dStrncpy( binPhysXStream, physXStream, getMin( 260, ext - physXStream ) ); - else - dStrncpy( binPhysXStream, physXStream, 260 ); - - // Concatenate the binary extension. - dStrcat( binPhysXStream, ".nxb" ); - - // Get the modified times of the two files. - FileTime xmlTime = {0}, binTime = {0}; - Platform::getFileTimes( physXStream, NULL, &xmlTime ); - Platform::getFileTimes( binPhysXStream, NULL, &binTime ); - - // If the binary is newer... load that. - if ( Platform::compareFileTimes( binTime, xmlTime ) >= 0 ) - _loadCollection( binPhysXStream, true ); - - // If the binary failed... then load the xml. - if ( !collection ) - { - _loadCollection( physXStream, false ); - - // If loaded... resave the xml in binary format - // for quicker subsequent loads. - if ( collection ) - NXU::saveCollection( collection, binPhysXStream, NXU::FT_BINARY ); - } - - // If it still isn't loaded then we've failed! - if ( !collection ) - { - errorBuffer = String::ToString( "PxMultiActorDatas::preload: could not load '%s'!", physXStream ); - return false; - } - - if (!shapeName || shapeName[0] == '\0') - { - errorBuffer = "PxMultiActorDatas::preload: no shape name!"; - return false; - } - - shape = ResourceManager::get().load( shapeName ); - - if (bool(shape) == false) - { - errorBuffer = String::ToString( "PxMultiActorData::preload: unable to load shape: %s", shapeName ); - return false; - } - - // Find the client side material. - if ( !server && material ) - Sim::findObject( SimObjectId(material), material ); - - // Get the ignore node indexes from the names. - for ( S32 i = 0; i < MaxCorrectionNodes; i++ ) - { - if( !correctionNodeNames[i] || !correctionNodeNames[i][0] ) - continue; - - correctionNodes[i] = shape->findNode( correctionNodeNames[i] ); - } - - // Resolve mount point node indexes - for ( S32 i = 0; i < NumMountPoints; i++) - { - char fullName[256]; - - if ( !mountNodeNames[i] || !mountNodeNames[i][0] ) - { - dSprintf(fullName,sizeof(fullName),"mount%d",i); - mountPointNode[i] = shape->findNode(fullName); - } - else - mountPointNode[i] = shape->findNode(mountNodeNames[i]); - } - - // Register for file change notification to reload the collection - if ( server ) - Torque::FS::AddChangeNotification( physXStream, this, &PxMultiActorData::_onFileChanged ); - - return true; -} - -void PxMultiActorData::_onFileChanged( const Torque::Path &path ) -{ - reload(); -} - -void PxMultiActorData::reload() -{ - bool result = _loadCollection( physXStream, false ); - - if ( !result ) - Con::errorf( "PxMultiActorData::reload(), _loadCollection failed..." ); - - // Inform MultiActors who use this datablock to reload. - mReloadSignal.trigger(); -} - -bool PxMultiActorData::_loadCollection( const UTF8 *path, bool isBinary ) -{ - if ( collection ) - { - NXU::releaseCollection( collection ); - collection = NULL; - } - - FileStream fs; - if ( !fs.open( path, Torque::FS::File::Read ) ) - return false; - - // Load the data into memory. - U32 size = fs.getStreamSize(); - FrameTemp buff( size ); - fs.read( size, buff ); - - // If the stream didn't read anything, there's a problem. - if ( size <= 0 ) - return false; - - // Ok... try to load it. - collection = NXU::loadCollection( path, - isBinary ? NXU::FT_BINARY : NXU::FT_XML, - buff, - size ); - - return collection != NULL; -} - - -bool PxMultiActorData::createActors( NxScene *scene, - NxCompartment *compartment, - const NxMat34 *nxMat, - const Point3F& scale, - Vector *outActors, - Vector *outShapes, - Vector *outJoints, - Vector *outActorUserProperties, - Vector *outJointUserProperties ) -{ - if ( !scene ) - { - Con::errorf( "PxMultiActorData::createActor() - returned null NxScene" ); - return NULL; - } - - PxMultiActor_Notify pxNotify( compartment, material, *nxMat, scale, outActorUserProperties, outJointUserProperties ); - - NXU::instantiateCollection( collection, *gPhysicsSDK, scene, nxMat, &pxNotify ); - - *outActors = pxNotify.getActors(); - *outJoints = pxNotify.getJoints(); - if ( outShapes ) - *outShapes = pxNotify.getShapes(); - - if ( outActors->empty() ) - { - Con::errorf( "PxMultiActorData::createActors() - NXUStream notifier returned empty actors or joints!" ); - return false; - } - - return true; -} - -ConsoleDocClass( PxMultiActor, - - "@brief Represents a destructible physical object simulated using PhysX.\n\n" - - "Usually it is prefered to use PhysicsShape and not PxMultiActor because " - "it is not PhysX specific and much easier to setup.\n" - - "@see PxMultiActorData.\n" - "@ingroup Physics" -); - -IMPLEMENT_CO_NETOBJECT_V1(PxMultiActor); - -PxMultiActor::PxMultiActor() - : mShapeInstance( NULL ), - mRootActor( NULL ), - mWorld( NULL ), - mStartImpulse( 0, 0, 0 ), - mResetXfm( true ), - mActorScale( 0, 0, 0 ), - mDebugRender( false ), - mIsDummy( false ), - mBroken( false ), - mDataBlock( NULL ) -{ - mNetFlags.set( Ghostable | ScopeAlways ); - - mTypeMask |= StaticObjectType | StaticShapeObjectType; - - //mUserData.setObject( this ); -} - -void PxMultiActor::initPersistFields() -{ - Parent::initPersistFields(); - - /* - // We're overloading these fields from SceneObject - // in order to force it to go thru setTransform! - removeField( "position" ); - removeField( "rotation" ); - removeField( "scale" ); - - addGroup( "Transform" ); - - addProtectedField( "position", TypeMatrixPosition, 0, - &PxMultiActor::_setPositionField, - &PxMultiActor::_getPositionField, - "" ); - - addProtectedField( "rotation", TypeMatrixRotation, 0, - &PxMultiActor::_setRotationField, - &PxMultiActor::_getRotationField, - "" ); - - addField( "scale", TypePoint3F, Offset( mObjScale, PxMultiActor ) ); - - endGroup( "Transform" ); - */ - - //addGroup("Physics"); - // addField( "AngularDrag", TypeF32, ) - //endGroup("Physics"); - - addGroup( "Debug" ); - addField( "debugRender", TypeBool, Offset( mDebugRender, PxMultiActor ), "@hide"); - addField( "broken", TypeBool, Offset( mBroken, PxMultiActor ), "@hide"); - endGroup( "Debug" ); - - //addGroup("Collision"); - //endGroup("Collision"); -} - -bool PxMultiActor::onAdd() -{ - PROFILE_SCOPE( PxMultiActor_OnAdd ); - - if (!Parent::onAdd() || !mDataBlock ) - return false; - - mIsDummy = isClientObject() && PHYSICSMGR->isSinglePlayer(); //&& mDataBlock->singlePlayerOnly; - - mShapeInstance = new TSShapeInstance( mDataBlock->shape, isClientObject() ); - - mObjBox = mDataBlock->shape->bounds; - resetWorldBox(); - - addToScene(); - - String worldName = isServerObject() ? "server" : "client"; - - // SinglePlayer objects only have server-side physics representations. - if ( mIsDummy ) - worldName = "server"; - - mWorld = dynamic_cast( PHYSICSMGR->getWorld( worldName ) ); - if ( !mWorld || !mWorld->getScene() ) - { - Con::errorf( "PxMultiActor::onAdd() - PhysXWorld not initialized!" ); - return false; - } - - applyWarp( getTransform(), true, false ); - mResetXfm = getTransform(); - - if ( !_createActors( getTransform() ) ) - { - Con::errorf( "PxMultiActor::onAdd(), _createActors failed" ); - return false; - } - - if ( !mIsDummy ) - mDataBlock->mReloadSignal.notify( this, &PxMultiActor::onFileNotify ); - - // If the editor is on... let it know! - //if ( gEditingMission ) - //onEditorEnable(); // TODO: Fix this up. - - PhysicsPlugin::getPhysicsResetSignal().notify( this, &PxMultiActor::onPhysicsReset, 1050.0f ); - - setAllBroken( false ); - - if ( isServerObject() ) - scriptOnAdd(); - - return true; -} - - -void PxMultiActor::onRemove() -{ - removeFromScene(); - - _destroyActors(); - mWorld = NULL; - - SAFE_DELETE( mShapeInstance ); - - PhysicsPlugin::getPhysicsResetSignal().remove( this, &PxMultiActor::onPhysicsReset ); - - if ( !mIsDummy && mDataBlock ) - mDataBlock->mReloadSignal.remove( this, &PxMultiActor::onFileNotify ); - - Parent::onRemove(); -} - -void PxMultiActor::_destroyActors() -{ - // Dummies don't have physics objects. - if ( mIsDummy || !mWorld ) - return; - - mWorld->releaseWriteLock(); - - // Clear the root actor. - mRootActor = NULL; - - // Clear the relative transforms. - //mRelXfms.clear(); - - // The shapes are owned by the actors, so - // we just need to clear them. - mShapes.clear(); - - // Release the joints first. - for( S32 i = 0; i < mJoints.size(); i++ ) - { - NxJoint *joint = mJoints[i]; - - if ( !joint ) - continue; - - // We allocate per joint userData and we must free it. - PxUserData *jointData = PxUserData::getData( *joint ); - if ( jointData ) - delete jointData; - - mWorld->releaseJoint( *joint ); - } - mJoints.clear(); - - // Now release the actors. - for( S32 i = 0; i < mActors.size(); i++ ) - { - NxActor *actor = mActors[i]; - - PxUserData *actorData = PxUserData::getData( *actor ); - if ( actorData ) - delete actorData; - - if ( actor ) - mWorld->releaseActor( *actor ); - } - mActors.clear(); -} - -bool PxMultiActor::_createActors( const MatrixF &xfm ) -{ - if ( mIsDummy ) - { - // Dummies don't have physics objects, but - // they do handle actor deltas. - - PxMultiActor *serverObj = static_cast( mServerObject.getObject() ); - mActorDeltas.setSize( serverObj->mActors.size() ); - dMemset( mActorDeltas.address(), 0, mActorDeltas.memSize() ); - - return true; - } - - NxMat34 nxMat; - nxMat.setRowMajor44( xfm ); - - // Store the scale for comparison in setScale(). - mActorScale = getScale(); - - // Release the write lock so we can create actors. - mWorld->releaseWriteLock(); - - Vector actorUserProperties; - Vector jointUserProperties; - bool created = mDataBlock->createActors( mWorld->getScene(), - NULL, - &nxMat, - mActorScale, - &mActors, - &mShapes, - &mJoints, - &actorUserProperties, - &jointUserProperties ); - - // Debug output... - //for ( U32 i = 0; i < mJoints.size(); i++ ) - // Con::printf( "Joint0 name: '%s'", mJoints[i]->getName() ); - //for ( U32 i = 0; i < actorUserProperties.size(); i++ ) - //Con::printf( "actor%i UserProperties: '%s'", i, actorUserProperties[i].c_str() ); - //for ( U32 i = 0; i < jointUserProperties.size(); i++ ) - // Con::printf( "joint%i UserProperties: '%s'", i, jointUserProperties[i].c_str() ); - - if ( !created ) - { - Con::errorf( "PxMultiActor::_createActors() - failed!" ); - return false; - } - - // Make the first actor the root actor by default, but - // if we have a kinematic actor then use that. - mRootActor = mActors[0]; - for ( S32 i = 0; i < mActors.size(); i++ ) - { - if ( mActors[i]->readBodyFlag( NX_BF_KINEMATIC ) ) - { - mRootActor = mActors[i]; - break; - } - } - - mDelta.pos = mDelta.lastPos = getPosition(); - mDelta.rot = mDelta.lastRot = getTransform(); - - bool *usedActors = new bool[mActors.size()]; - dMemset( usedActors, 0, sizeof(bool) * mActors.size() ); - - TSShape *shape = mShapeInstance->getShape(); - - // Should already be done when actors are destroyed. - mMappedActors.clear(); - Vector mappedActorProperties; - - // Remap the actors to the shape instance's bone indices. - for( S32 i = 0; i < mShapeInstance->mNodeTransforms.size(); i++ ) - { - if ( !shape ) - break; - - UTF8 comparisonName[260] = { 0 }; - NxActor *actor = NULL; - NxActor *pushActor = NULL; - String actorProperties; - - S32 nodeNameIdx = shape->nodes[i].nameIndex; - const UTF8 *nodeName = shape->getName( nodeNameIdx ); - - S32 dl = -1; - dStrcpy( comparisonName, String::GetTrailingNumber( nodeName, dl ) ); //, ext - nodeName ); - dSprintf( comparisonName, sizeof( comparisonName ), "%s_pxactor", comparisonName ); - - //String test( nodeName ); - //AssertFatal( test.find("gableone",0,String::NoCase) == String::NPos, "found it" ); - - // If we find an actor that corresponds to this node we will - // push it back into the remappedActors vector, otherwise - // we will push back NULL. - for ( S32 j = 0; j < mActors.size(); j++ ) - { - actor = mActors[j]; - const UTF8 *actorName = actor->getName(); - - if ( dStricmp( comparisonName, actorName ) == 0 ) - { - pushActor = actor; - actorProperties = actorUserProperties[j]; - usedActors[j] = true; - break; - } - } - - mMappedActors.push_back( pushActor ); - mappedActorProperties.push_back( actorProperties ); - if ( !pushActor ) - dl = -1; - mMappedActorDL.push_back( dl ); - - // Increase the sleep tolerance. - if ( pushActor ) - { - //pushActor->raiseBodyFlag( NX_BF_ENERGY_SLEEP_TEST ); - //pushActor->setSleepEnergyThreshold( 2 ); - //pushActor->userData = NULL; - } - } - - // Delete any unused/orphaned actors. - for ( S32 i = 0; i < mActors.size(); i++ ) - { - if ( usedActors[i] ) - continue; - - NxActor *actor = mActors[i]; - - Con::errorf( "PxMultiActor::_createActors() - Orphan NxActor - '%s'!", actor->getName() ); - - if ( actor == mRootActor ) - { - Con::errorf( "PxMultiActor::_createActors() - root actor (%s) was orphan, cannot continue.", actor->getName() ); - return false; - } - - // Remove references to shapes of the deleted actor. - for ( S32 i = 0; i < mShapes.size(); i++ ) - { - if ( &(mShapes[i]->getActor()) == actor ) - { - mShapes.erase_fast(i); - i--; - } - } - - mWorld->releaseActor( *actor ); - } - - // Done with this helper. - delete [] usedActors; - - // Repopulate mActors with one entry per real actor we own. - mActors.clear(); - mMappedToActorIndex.clear(); - actorUserProperties.clear(); - for ( S32 i = 0; i < mMappedActors.size(); i++ ) - { - S32 index = -1; - if ( mMappedActors[i] ) - { - index = mActors.push_back_unique( mMappedActors[i] ); - while ( index >= actorUserProperties.size() ) - actorUserProperties.push_back( String::EmptyString ); - actorUserProperties[index] = mappedActorProperties[i]; - } - mMappedToActorIndex.push_back( index ); - } - - if ( mActors.size() == 0 ) - { - Con::errorf( "PxMultiActor::_createActors, got zero actors! Were all actors orphans?" ); - return false; - } - - // Initialize the actor deltas. - mActorDeltas.setSize( mActors.size() ); - dMemset( mActorDeltas.address(), 0, mActorDeltas.memSize() ); - - // Assign user data for actors. - for ( U32 i = 0; i < mActors.size(); i++ ) - { - NxActor *actor = mActors[i]; - if ( !actor ) - continue; - - actor->userData = _createActorUserData( actor, actorUserProperties[i] ); - } - - //NxActor *actor1; - //NxActor *actor2; - //PxUserData *pUserData; - - // Allocate user data for joints. - for ( U32 i = 0; i < mJoints.size(); i++ ) - { - NxJoint *joint = mJoints[i]; - if ( !joint ) - continue; - - joint->userData = _createJointUserData( joint, jointUserProperties[i] ); - - /* - // Set actors attached to joints as not-pushable (by the player). - joint->getActors( &actor1, &actor2 ); - if ( actor1 ) - { - pUserData = PxUserData::getData( *actor1 ); - if ( pUserData ) - pUserData->mCanPush = false; - } - if ( actor2 ) - { - pUserData = PxUserData::getData( *actor2 ); - if ( pUserData ) - pUserData->mCanPush = false; - } - */ - } - - // Set actors and meshes to the unbroken state. - setAllBroken( false ); - - return true; -} - -PxUserData* PxMultiActor::_createActorUserData( NxActor *actor, String &userProperties ) -{ - PxUserData *actorData = new PxUserData(); - actorData->setObject( this ); - - // We use this for saving relative xfms for 'broken' actors. - NxMat34 actorPose = actor->getGlobalPose(); - NxMat34 actorSpaceXfm; - actorPose.getInverse( actorSpaceXfm ); - - const String actorName( actor->getName() ); - - static const String showStr( "PxBrokenShow" ); - static const String hideStr( "PxBrokenHide" ); - - // 3DSMax saves out double newlines, replace them with one. - userProperties.replace( "\r\n", "\n" ); - - U32 propertyCount = StringUnit::getUnitCount( userProperties, "\n" ); - for ( U32 i = 0; i < propertyCount; i++ ) - { - String propertyStr = StringUnit::getUnit( userProperties, i, "\n" ); - U32 wordCount = StringUnit::getUnitCount( propertyStr, "=" ); - - if ( wordCount == 0 ) - { - // We sometimes get empty lines between properties, - // which doesn't break anything. - continue; - } - - if ( wordCount != 2 ) - { - Con::warnf( "PxMultiActor::_createActorUserData, malformed UserProperty string (%s) for actor (%s)", propertyStr.c_str(), actorName.c_str() ); - continue; - } - - String propertyName = StringUnit::getUnit( propertyStr, 0, "=" ); - String propertyValue = StringUnit::getUnit( propertyStr, 1, "=" ); - - Vector *dstVector = NULL; - if ( propertyName.equal( showStr, String::NoCase ) ) - dstVector = &actorData->mBrokenActors; - else if ( propertyName.equal( hideStr, String::NoCase ) ) - dstVector = &actorData->mUnbrokenActors; - - if ( !dstVector ) - continue; - - U32 valueCount = StringUnit::getUnitCount( propertyValue, "," ); - for ( U32 j = 0; j < valueCount; j++ ) - { - String val = StringUnit::getUnit( propertyValue, j, "," ); - - NxActor *pActor = _findActor( val ); - if ( !pActor ) - Con::warnf( "PxMultiActor::_createActorUserData, actor (%s) was not found when parsing UserProperties for actor (%s)", val.c_str(), actorName.c_str() ); - else - { - dstVector->push_back( pActor ); - - if ( dstVector == &actorData->mBrokenActors ) - { - NxMat34 relXfm = pActor->getGlobalPose(); - relXfm.multiply( relXfm, actorSpaceXfm ); - actorData->mRelXfm.push_back( relXfm ); - } - } - } - } - - // Only add a contact signal to this actor if - // we have objects we can break. - if ( actorData->mBrokenActors.size() > 0 && - mDataBlock->breakForce > 0.0f ) - { - actor->setContactReportFlags( NX_NOTIFY_ON_START_TOUCH_FORCE_THRESHOLD | NX_NOTIFY_FORCES ); - actor->setContactReportThreshold( mDataBlock->breakForce ); - actorData->getContactSignal().notify( this, &PxMultiActor::_onContact ); - } - - return actorData; -} - -PxUserData* PxMultiActor::_createJointUserData( NxJoint *joint, String &userProperties ) -{ - PxUserData *jointData = new PxUserData(); - jointData->setObject( this ); - - // We use this for saving relative xfms for 'broken' actors. - NxActor *actor0; - NxActor *actor1; - joint->getActors( &actor0, &actor1 ); - NxMat34 actorPose = actor0->getGlobalPose(); - NxMat34 actorSpaceXfm; - actorPose.getInverse( actorSpaceXfm ); - - // The PxMultiActor will live longer than the joint - // so this notify shouldn't ever need to be removed. Although if someone - // other than this multiactor were to register for this notify and their - // lifetime could be shorter, then 'they' might have to. - jointData->getOnJointBreakSignal().notify( this, &PxMultiActor::_onJointBreak ); - - // JCFHACK: put this in userProperties too. - Sim::findObject( "JointBreakEmitter", jointData->mParticleEmitterData ); - - String showStr( "PxBrokenShow" ); - String hideStr( "PxBrokenHide" ); - - // Max saves out double newlines, replace them with one. - userProperties.replace( "\r\n", "\n" ); - - U32 propertyCount = StringUnit::getUnitCount( userProperties, "\n" ); - for ( U32 i = 0; i < propertyCount; i++ ) - { - String propertyStr = StringUnit::getUnit( userProperties, i, "\n" ); - U32 wordCount = StringUnit::getUnitCount( propertyStr, "=" ); - - if ( wordCount == 0 ) - { - // We sometimes get empty lines between properties, - // which doesn't break anything. - continue; - } - - if ( wordCount != 2 ) - { - Con::warnf( "PxMultiActor::_createJointUserData, malformed UserProperty string (%s) for joint (%s)", propertyStr.c_str(), joint->getName() ); - continue; - } - - String propertyName = StringUnit::getUnit( propertyStr, 0, "=" ); - String propertyValue = StringUnit::getUnit( propertyStr, 1, "=" ); - - Vector *dstVector = NULL; - if ( propertyName.equal( showStr, String::NoCase ) ) - dstVector = &jointData->mBrokenActors; - else if ( propertyName.equal( hideStr, String::NoCase ) ) - dstVector = &jointData->mUnbrokenActors; - - if ( !dstVector ) - continue; - - U32 valueCount = StringUnit::getUnitCount( propertyValue, "," ); - for ( U32 j = 0; j < valueCount; j++ ) - { - String val = StringUnit::getUnit( propertyValue, j, "," ); - - NxActor *pActor = _findActor( val ); - if ( !pActor ) - Con::warnf( "PxMultiActor::_createJointUserData, actor (%s) was not found when parsing UserProperties for joint (%s)", val.c_str(), joint->getName() ); - else - { - dstVector->push_back( pActor ); - - if ( dstVector == &jointData->mBrokenActors ) - { - NxMat34 relXfm = pActor->getGlobalPose(); - relXfm.multiply( relXfm, actorSpaceXfm ); - jointData->mRelXfm.push_back( relXfm ); - } - } - } - } - - return jointData; -} - -NxActor* PxMultiActor::_findActor( const String &actorName ) const -{ - for ( U32 i = 0; i < mActors.size(); i++ ) - { - NxActor *actor = mActors[i]; - if ( !actor ) - continue; - - if ( dStricmp( actor->getName(), actorName ) == 0 ) - return actor; - } - - return NULL; -} - -String PxMultiActor::_getMeshName( const NxActor *actor ) const -{ - String meshName = actor->getName(); - meshName.replace( "_pxactor", "" ); - //meshName = StringUnit::getUnit( meshName, 0, "_" ); - return meshName; -} - -bool PxMultiActor::onNewDataBlock( GameBaseData *dptr, bool reload ) -{ - mDataBlock = dynamic_cast(dptr); - - if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) ) - return false; - - // JCF: if we supported it, we would recalculate the value of mIsDummy now, - // but that would really hose everything since an object that was a dummy - // wouldn't have any actors and would need to create them, etc... - - scriptOnNewDataBlock(); - - return true; -} - -void PxMultiActor::inspectPostApply() -{ - // Make sure we call the parent... else - // we won't get transform and scale updates! - Parent::inspectPostApply(); - - //setMaskBits( LightMask ); - setMaskBits( UpdateMask ); -} - -void PxMultiActor::onStaticModified( const char *slotName, const char *newValue ) -{ - if ( isProperlyAdded() && dStricmp( slotName, "broken" ) == 0 ) - setAllBroken( dAtob(newValue) ); -} - -void PxMultiActor::onDeleteNotify( SimObject *obj ) -{ - Parent::onDeleteNotify(obj); - if ( obj == mMount.object ) - unmount(); -} - -void PxMultiActor::onFileNotify() -{ - // Destroy the existing actors and recreate them... - - mWorld->getPhysicsResults(); - _destroyActors(); - _createActors( mResetXfm ); -} - -void PxMultiActor::onPhysicsReset( PhysicsResetEvent reset ) -{ - // Dummies don't create or destroy actors, they just reuse the - // server object's ones. - if ( mIsDummy ) - return; - - // Store the reset transform for later use. - if ( reset == PhysicsResetEvent_Store ) - { - mRootActor->getGlobalPose().getRowMajor44( mResetXfm ); - } - else if ( reset == PhysicsResetEvent_Restore ) - { - // Destroy the existing actors and recreate them to - // ensure they are in the proper mission startup state. - mWorld->getPhysicsResults(); - - _destroyActors(); - _createActors( mResetXfm ); - } - - for ( U32 i = 0; i < mActors.size(); i++ ) - { - if ( !mActors[i] ) - continue; - - mActors[i]->wakeUp(); - } -} - -void PxMultiActor::prepRenderImage( SceneRenderState *state ) -{ - PROFILE_SCOPE( PxMultiActor_PrepRenderImage ); - - if ( !mShapeInstance ) - return; - - Point3F cameraOffset; - getTransform().getColumn(3,&cameraOffset); - cameraOffset -= state->getDiffuseCameraPosition(); - F32 dist = cameraOffset.len(); - if ( dist < 0.01f ) - dist = 0.01f; - - F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z)); - - S32 dl = mShapeInstance->setDetailFromDistance( state, dist * invScale ); - if ( dl < 0 ) - return; - - GFXTransformSaver saver; - - // Set up our TS render state here. - TSRenderState rdata; - rdata.setSceneState( state ); - - // We might have some forward lit materials - // so pass down a query to gather lights. - LightQuery query; - query.init( getWorldSphere() ); - rdata.setLightQuery( &query ); - - MatrixF mat = getRenderTransform(); - mat.scale( getScale() ); - GFX->setWorldMatrix( mat ); - - if ( mDebugRender || Con::getBoolVariable( "$PxDebug::render", false ) ) - { - ObjectRenderInst *ri = state->getRenderPass()->allocInst(); - ri->renderDelegate.bind( this, &PxMultiActor::_debugRender ); - ri->type = RenderPassManager::RIT_Object; - state->getRenderPass()->addInst( ri ); - } - else - mShapeInstance->render( rdata ); -} - -void PxMultiActor::_debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ) -{ - if ( mShapeInstance ) - { - GFXTransformSaver saver; - - MatrixF mat = getRenderTransform(); - mat.scale( mObjScale ); - GFX->multWorld( mat ); - - //mShapeInstance->renderDebugNodes(); - } - - Vector *actors = &mActors; - if ( mIsDummy ) - { - PxMultiActor *serverObj = static_cast( mServerObject.getObject() ); - if ( serverObj ) - actors = &serverObj->mActors; - } - - if ( !actors ) - return; - - for ( U32 i = 0; i < actors->size(); i++ ) - { - NxActor *pActor = (*actors)[i]; - if ( !pActor ) - continue; - - PxUtils::drawActor( pActor ); - } -} - -void PxMultiActor::_onJointBreak( NxReal breakForce, NxJoint &brokenJoint ) -{ - // Dummies do not have physics objects - // and shouldn't receive this callback. - if ( mIsDummy ) - return; - - NxActor *actor0 = NULL; - NxActor *actor1 = NULL; - brokenJoint.getActors( &actor0, &actor1 ); - NxMat34 parentPose = actor0->getGlobalPose(); - - Point3F jointPos = pxCast( brokenJoint.getGlobalAnchor() ); - - PxUserData *jointData = PxUserData::getData( brokenJoint ); - setBroken( parentPose, NxVec3( 0.0f ), jointData, true ); - - // NOTE: We do not NULL the joint in the list, - // or release it here, as we allow it to be released - // by the _destroyActors function on a reset or destruction - // of the PxMultiActor. -} - -void PxMultiActor::_onContact( PhysicsUserData *us, - PhysicsUserData *them, - const Point3F &hitPoint, - const Point3F &hitForce ) -{ - PxUserData *data = (PxUserData*)us; - if ( data && - !data->mIsBroken && - hitForce.len() > mDataBlock->breakForce ) - setAllBroken( true ); -} - -U32 PxMultiActor::packUpdate(NetConnection *con, U32 mask, BitStream *stream) -{ - U32 retMask = Parent::packUpdate(con, mask, stream); - - stream->writeFlag( mDebugRender ); - - stream->writeFlag( mask & SleepMask ); - - if ( stream->writeFlag( mask & WarpMask ) ) - { - stream->writeAffineTransform( getTransform() ); - } - else if ( stream->writeFlag( mask & MoveMask ) ) - { - /* - stream->writeAffineTransform( getTransform() ); - - NxActor *actor = mActors[ mDataBlock->correctionNodes[0] ]; - - const NxVec3& linVel = actor->getLinearVelocity(); - stream->write( linVel.x ); - stream->write( linVel.y ); - stream->write( linVel.z ); - */ - } - - // This internally uses the mask passed to it. - if ( mLightPlugin ) - retMask |= mLightPlugin->packUpdate( this, LightMask, con, mask, stream ); - - return retMask; -} - - -void PxMultiActor::unpackUpdate(NetConnection *con, BitStream *stream) -{ - Parent::unpackUpdate(con, stream); - - mDebugRender = stream->readFlag(); - - if ( stream->readFlag() ) // SleepMask - { - for ( S32 i = 0; i < mActors.size(); i++ ) - { - NxActor *actor = mActors[i]; - - if ( !actor ) - continue; - - if ( actor ) - actor->putToSleep(); - } - } - - if ( stream->readFlag() ) // WarpMask - { - // If we set a warp mask, - // we need to instantly move - // the actor to the new position - // without applying any corrections. - MatrixF mat; - stream->readAffineTransform( &mat ); - - applyWarp( mat, true, false ); - } - else if ( stream->readFlag() ) // MoveMask - { - /* - MatrixF mat; - stream->readAffineTransform( &mat ); - - NxVec3 linVel, angVel; - stream->read( &linVel.x ); - stream->read( &linVel.y ); - stream->read( &linVel.z ); - - applyCorrection( mat, linVel, angVel ); - */ - } -/* - if ( stream->readFlag() ) // ImpulseMask - { - // TODO : Set up correction nodes. - - NxVec3 linVel; - stream->read( &linVel.x ); - stream->read( &linVel.y ); - stream->read( &linVel.z ); - - NxActor *actor = mActors[ mDataBlock->correctionNodes[0] ]; - - if ( actor ) - { - mWorld->releaseWriteLock(); - actor->setLinearVelocity( linVel ); - mStartImpulse.zero(); - } - else - mStartImpulse.set( linVel.x, linVel.y, linVel.z ); - } -*/ - if ( mLightPlugin ) - mLightPlugin->unpackUpdate( this, con, stream ); -} - -void PxMultiActor::setScale( const VectorF& scale ) -{ - if ( scale == getScale() ) - return; - - // This is so that the level - // designer can change the scale - // of a PhysXSingleActor in the editor - // and have the PhysX representation updated properly. - - // First we call the parent's setScale - // so that the ScaleMask can be set. - Parent::setScale( scale ); - - // Check to see if the scale has really changed. - if ( !isProperlyAdded() || mActorScale.equal( scale ) ) - return; - - // Recreate the physics actors. - _destroyActors(); - _createActors( getTransform() ); -} - -void PxMultiActor::applyWarp( const MatrixF& newMat, bool interpRender, bool sweep ) -{ - // Do we have actors to move? - if ( mRootActor ) - { - // Get ready to change the physics state. - mWorld->releaseWriteLock(); - - /// Convert the new transform to nx. - NxMat34 destXfm; - destXfm.setRowMajor44( newMat ); - - // Get the inverse of the root actor transform - // so we can move all the actors relative to it. - NxMat34 rootInverseXfm; - mRootActor->getGlobalPose().getInverse( rootInverseXfm ); - - // Offset all the actors. - MatrixF tMat; - NxMat34 newXfm, relXfm; - for ( S32 i = 0; i < mActors.size(); i++ ) - { - NxActor *actor = mActors[i]; - if ( !actor ) - continue; - - const bool isKinematic = actor->readBodyFlag( NX_BF_KINEMATIC ); - - // Stop any velocity on it. - if ( !isKinematic ) - { - actor->setAngularVelocity( NxVec3( 0.0f ) ); - actor->setLinearVelocity( NxVec3( 0.0f ) ); - } - - // Get the transform relative to the current root. - relXfm.multiply( actor->getGlobalPose(), rootInverseXfm ); - - /* - if ( sweep ) - { - actor->getGl obalPose().getRowMajor44( mResetPos[i] ); - sweepTest( &newMat ); - } - */ - - // - newXfm.multiply( relXfm, destXfm ); - //if ( isKinematic ) - //actor->moveGlobalPose( newXfm ); - //else - actor->setGlobalPose( newXfm ); - - // Reset the delta. - Delta &delta = mActorDeltas[i]; - delta.pos = pxCast( newXfm.t ); - newXfm.getRowMajor44( tMat ); - delta.rot.set( tMat ); - - if ( !interpRender ) - { - mActorDeltas[i].lastPos = mActorDeltas[i].pos; - mActorDeltas[i].lastRot = mActorDeltas[i].rot; - } - } - } - - Parent::setTransform( newMat ); - - mDelta.pos = newMat.getPosition(); - mDelta.rot = newMat; - - if ( !interpRender ) - { - mDelta.lastPos = mDelta.pos; - mDelta.lastRot = mDelta.rot; - } -} - -/* -bool PxMultiActor::_setPositionField( void *obj, const char *data ) -{ - PxMultiActor *object = reinterpret_cast( obj ); - - MatrixF transform( object->getTransform() ); - Con::setData( TypeMatrixPosition, &transform, 0, 1, &data ); - - object->setTransform( transform ); - - return false; -} - -const char* PxMultiActor::_getPositionField( void *obj, const char *data ) -{ - PxMultiActor *object = reinterpret_cast( obj ); - return Con::getData( TypeMatrixPosition, - &object->mObjToWorld, - 0 ); -} - -bool PxMultiActor::_setRotationField( void *obj, const char *data ) -{ - PxMultiActor *object = reinterpret_cast( obj ); - - MatrixF transform( object->getTransform() ); - Con::setData( TypeMatrixRotation, &transform, 0, 1, &data ); - - object->setTransform( transform ); - - return false; -} - -const char* PxMultiActor::_getRotationField( void *obj, const char *data ) -{ - PxMultiActor *object = reinterpret_cast( obj ); - return Con::getData( TypeMatrixRotation, - &object->mObjToWorld, - 0 ); -} -*/ - -void PxMultiActor::setTransform( const MatrixF& mat ) -{ - applyWarp( mat, false, true ); - setMaskBits( WarpMask ); -} - -void PxMultiActor::mountObject( SceneObject *obj, U32 node ) -{ - if (obj->getObjectMount()) - obj->unmount(); - - obj->mountObject( this, (node >= 0 && node < PxMultiActorData::NumMountPoints) ? node: 0 ); -} - - -void PxMultiActor::unmountObject( SceneObject *obj ) -{ - obj->unmountObject( this ); -} - -bool PxMultiActor::_getNodeTransform( U32 nodeIdx, MatrixF *outXfm ) -{ - if ( !mShapeInstance ) - return false; - - PxMultiActor *actorOwner = this; - if ( mIsDummy ) - { - actorOwner = static_cast( mServerObject.getObject() ); - if ( !actorOwner ) - return false; - } - - TSShape *shape = mShapeInstance->getShape(); - String nodeName = shape->getNodeName( nodeIdx ); - - NxActor *pActor = NULL; - UTF8 comparisonName[260] = { 0 }; - S32 dummy = -1; - - // Convert the passed node name to a valid actor name. - dStrcpy( comparisonName, String::GetTrailingNumber( nodeName, dummy ) ); - dSprintf( comparisonName, sizeof( comparisonName ), "%s_pxactor", comparisonName ); - - // If we have an actor with that name, we are done. - pActor = actorOwner->_findActor( comparisonName ); - if ( pActor ) - { - pActor->getGlobalPose().getRowMajor44( *outXfm ); - return true; - } - - // Check if the parent node has an actor... - - S32 parentIdx = shape->nodes[nodeIdx].parentIndex; - if ( parentIdx == -1 ) - return false; - - const String &parentName = shape->getNodeName( parentIdx ); - dStrcpy( comparisonName, String::GetTrailingNumber( parentName, dummy ) ); - dSprintf( comparisonName, sizeof( comparisonName ), "%s_pxactor", comparisonName ); - - pActor = actorOwner->_findActor( comparisonName ); - if ( !pActor ) - return false; - - MatrixF actorMat; - pActor->getGlobalPose().getRowMajor44( actorMat ); - - MatrixF nmat; - QuatF q; - TSTransform::setMatrix( shape->defaultRotations[nodeIdx].getQuatF(&q),shape->defaultTranslations[nodeIdx],&nmat); - *outXfm->mul( actorMat, nmat ); - - return true; -} - -void PxMultiActor::getMountTransform(U32 mountPoint,MatrixF* mat) -{ - // Returns mount point to world space transform - if (mountPoint < PxMultiActorData::NumMountPoints) { - S32 ni = mDataBlock->mountPointNode[mountPoint]; - if (ni != -1) { - if ( _getNodeTransform( ni, mat ) ) - return; - } - } - *mat = mObjToWorld; -} - -void PxMultiActor::getRenderMountTransform(U32 mountPoint,MatrixF* mat) -{ - // Returns mount point to world space transform - if (mountPoint < PxMultiActorData::NumMountPoints) { - S32 ni = mDataBlock->mountPointNode[mountPoint]; - if (ni != -1) { - if ( _getNodeTransform( ni, mat ) ) - return; - } - } - *mat = getRenderTransform(); -} - -void PxMultiActor::processTick( const Move *move ) -{ - PROFILE_SCOPE( PxMultiActor_ProcessTick ); - - // Set the last pos/rot to the - // values of the previous tick for interpolateTick. - mDelta.lastPos = mDelta.pos; - mDelta.lastRot = mDelta.rot; - - /* - NxActor *corrActor = mActors[ mDataBlock->correctionNodes[0] ]; - - if ( corrActor->isSleeping() || corrActor->readBodyFlag( NX_BF_FROZEN ) ) - { - if ( !mSleepingLastTick ) - setMaskBits( WarpMask | SleepMask ); - - mSleepingLastTick = true; - - // HACK! Refactor sleeping so that we don't - // sleep when only one correction actor does. - _updateBounds(); - - return; - } - - mSleepingLastTick = false; - */ - - MatrixF mat; - Vector *actors; - - if ( mIsDummy ) - { - PxMultiActor *serverObj = static_cast( mServerObject.getObject() ); - if ( !serverObj ) - return; - - mat = serverObj->getTransform(); - actors = &serverObj->mActors; - } - else - { - // Container buoyancy & drag - _updateContainerForces(); - - // Save the transform from the root actor. - mRootActor->getGlobalPose().getRowMajor44( mat ); - actors = &mActors; - } - - // Update the transform and the root delta. - Parent::setTransform( mat ); - mDelta.pos = mat.getPosition(); - mDelta.rot.set( mat ); - - // On the client we update the individual - // actor deltas as well for interpolation. - if ( isClientObject() ) - { - PROFILE_SCOPE( PxMultiActor_ProcessTick_UpdateDeltas ); - - for ( U32 i = 0; i < mActorDeltas.size(); i++ ) - { - if ( !(*actors)[i] ) - continue; - - Delta &delta = mActorDeltas[i]; - - // Store the last position. - delta.lastPos = delta.pos; - delta.lastRot = delta.rot; - - // Get the new position. - (*actors)[i]->getGlobalPose().getRowMajor44( (NxF32*)mat ); - - // Calculate the delta between the current - // global pose and the last global pose. - delta.pos = mat.getPosition(); - delta.rot.set( mat ); - } - } - - // Update the bounding box to match the physics. - _updateBounds(); - - // Set the MoveMask so this will be updated to the client. - //setMaskBits( MoveMask ); -} - -void PxMultiActor::interpolateTick( F32 delta ) -{ - PROFILE_SCOPE( PxMultiActor_InterpolateTick ); - - Point3F interpPos; - QuatF interpRot; - { - // Interpolate the position based on the delta. - interpPos.interpolate( mDelta.pos, mDelta.lastPos, delta ); - - // Interpolate the rotation based on the delta. - interpRot.interpolate( mDelta.rot, mDelta.lastRot, delta ); - - // Set up the interpolated transform. - MatrixF interpMat; - interpRot.setMatrix( &interpMat ); - interpMat.setPosition( interpPos ); - - Parent::setRenderTransform( interpMat ); - } - - PxMultiActor *srcObj = NULL; - if ( mIsDummy ) - srcObj = static_cast( mServerObject.getObject() ); - else - srcObj = this; - - // JCF: to disable applying NxActor positions to the renderable mesh - // you can uncomment this line. - //srcObj = NULL; - if ( mShapeInstance && srcObj != NULL ) - { - mShapeInstance->animate(); - getDynamicXfms( srcObj, delta ); - } -} - -/* -void PxMultiActor::sweepTest( MatrixF *mat ) -{ - NxVec3 nxCurrPos = getPosition(); - - // If the position is zero, - // the parent hasn't been updated yet - // and we don't even need to do the sweep test. - // This is a fix for a problem that was happening - // where on the add of the PhysXSingleActor, it would - // set the position to a very small value because it would be getting a hit - // even though the current position was 0. - if ( nxCurrPos.isZero() ) - return; - - // Set up the flags and the query structure. - NxU32 flags = NX_SF_STATICS | NX_SF_DYNAMICS; - - NxSweepQueryHit sweepResult; - dMemset( &sweepResult, 0, sizeof( sweepResult ) ); - - NxVec3 nxNewPos = mat->getPosition(); - - // Get the velocity which will be our sweep direction and distance. - NxVec3 nxDir = nxNewPos - nxCurrPos; - if ( nxDir.isZero() ) - return; - - NxActor *corrActor = mActors[ mDataBlock->correctionNodes[0] ]; - - // Get the scene and do the sweep. - corrActor->wakeUp(); - corrActor->linearSweep( nxDir, flags, NULL, 1, &sweepResult, NULL ); - - if ( sweepResult.hitShape && sweepResult.t < nxDir.magnitude() ) - { - nxDir.normalize(); - nxDir *= sweepResult.t; - nxCurrPos += nxDir; - - mat->setPosition( Point3F( nxCurrPos.x, nxCurrPos.y, nxCurrPos.z ) ); - } -} -*/ - -/* -void PxMultiActor::applyCorrection( const MatrixF& mat, const NxVec3& linVel, const NxVec3& angVel ) -{ - // Sometimes the actor hasn't been - // created yet during the call from unpackUpdate. - NxActor *corrActor = mActors[ mDataBlock->correctionNodes[0] ]; - - if ( !corrActor || mForceSleep ) - return; - - NxVec3 newPos = mat.getPosition(); - NxVec3 currPos = getPosition(); - - NxVec3 offset = newPos - currPos; - - // If the difference isn't large enough, - // just set the new transform, no correction. - if ( offset.magnitude() > 0.3f ) - { - // If we're going to set the linear or angular velocity, - // we do it before we add a corrective force, since it would be overwritten otherwise. - NxVec3 currLinVel, currAngVel; - currLinVel = corrActor->getLinearVelocity(); - currAngVel = corrActor->getAngularVelocity(); - - // Scale the corrective force by half, - // otherwise it will over correct and oscillate. - NxVec3 massCent = corrActor->getCMassGlobalPosition(); - corrActor->addForceAtPos( offset, massCent, NX_SMOOTH_VELOCITY_CHANGE ); - - // If the linear velocity is divergent enough, change to server linear velocity. - if ( (linVel - currLinVel).magnitude() > 0.3f ) - corrActor->setLinearVelocity( linVel ); - // Same for angular. - if ( (angVel - currAngVel).magnitude() > 0.3f ) - corrActor->setAngularVelocity( angVel ); - } - - Parent::setTransform( mat ); -} -*/ - -void PxMultiActor::_updateBounds() -{ - PROFILE_SCOPE( PxMultiActor_UpdateBounds ); - - if ( mIsDummy ) - { - PxMultiActor *serverObj = static_cast( mServerObject.getObject() ); - if ( !serverObj ) - return; - - mWorldBox = serverObj->getWorldBox(); - mWorldSphere = serverObj->getWorldSphere(); - mObjBox = serverObj->getObjBox(); - mRenderWorldBox = serverObj->getRenderWorldBox(); - mRenderWorldSphere = mWorldSphere; - - return; - } - - NxBounds3 bounds; - bounds.setEmpty(); - - NxBounds3 shapeBounds; - - for ( U32 i = 0; i < mActors.size(); i++ ) - { - NxActor *pActor = mActors[i]; - - if ( !pActor || pActor->readActorFlag( NX_AF_DISABLE_COLLISION ) ) - continue; - - NxShape *const* pShapeArray = pActor->getShapes(); - U32 shapeCount = pActor->getNbShapes(); - for ( U32 i = 0; i < shapeCount; i++ ) - { - // Get the shape's bounds. - pShapeArray[i]->getWorldBounds( shapeBounds ); - - // Combine them into the total bounds. - bounds.combine( shapeBounds ); - } - } - - mWorldBox = pxCast( bounds ); - - mWorldBox.getCenter(&mWorldSphere.center); - mWorldSphere.radius = (mWorldBox.maxExtents - mWorldSphere.center).len(); - - mObjBox = mWorldBox; - mWorldToObj.mul(mObjBox); - - mRenderWorldBox = mWorldBox; - mRenderWorldSphere = mWorldSphere; -} - -void PxMultiActor::getDynamicXfms( PxMultiActor *srcObj, F32 dt ) -{ - PROFILE_SCOPE( PxMultiActor_getDynamicXfms ); - - Vector *torqueXfms = &mShapeInstance->mNodeTransforms; - const MatrixF &objectXfm = getRenderWorldTransform(); - - AssertFatal( torqueXfms->size() == srcObj->mMappedActors.size(), "The two skeletons are different!" ); - - TSShape *shape = mShapeInstance->getShape(); - - // TODO: We're currently preparing deltas and getting - // dynamic xforms even if the object isn't visible. - // we should probably try to delay all this until - // we're about to render. - // - /* - // TODO: Set up deltas! - if ( mCurrPos.empty() || mCurrRot.empty() ) - _prepareDeltas(); - */ - - MatrixF globalXfm; - MatrixF mat, tmp; - QuatF newRot; - Point3F newPos; - - S32 dl = mShapeInstance->getCurrentDetail(); - if ( dl < 0 ) - return; - - const String &detailName = shape->getName( shape->details[dl].nameIndex ); - S32 detailSize = -1; - String::GetTrailingNumber( detailName, detailSize ); - - for( S32 i = 0; i < srcObj->mMappedActors.size(); i++ ) - { - NxActor *actor = srcObj->mMappedActors[i]; - - if ( !actor || actor->readBodyFlag( NX_BF_KINEMATIC ) ) - continue; - - // see if the node at this index is part of the - // currently visible detail level. - if ( srcObj->mMappedActorDL[i] != detailSize ) - continue; - - // Get the right actor delta structure. - U32 index = srcObj->mMappedToActorIndex[i]; - const Delta &delta = mActorDeltas[index]; - - // Do the interpolation. - newRot.interpolate( delta.rot, delta.lastRot, dt ); - newRot.setMatrix( &globalXfm ); - newPos.interpolate( delta.pos, delta.lastPos, dt ); - globalXfm.setPosition( newPos ); - - (*torqueXfms)[i].mul( objectXfm, globalXfm ); - } -} - -void PxMultiActor::applyImpulse( const Point3F &pos, const VectorF &vec ) -{ - // TODO : Implement this based on correction nodes. - /* - if ( !mWorld || !mActor ) - return; - - mWorld->releaseWriteLock(); - - NxVec3 linVel = mActor->getLinearVelocity(); - NxVec3 nxVel( vel.x, vel.y, vel.z ); - - mActor->setLinearVelocity(linVel + nxVel); - */ - - // JCF: something more complex is required to apply forces / breakage - // on only individual actors, and we don't have enough data to do that - // within this method. - - if ( vec.len() > mDataBlock->breakForce ) - setAllBroken( true ); - - NxVec3 nxvec = pxCast( vec ); - NxVec3 nxpos = pxCast( pos ); - - for ( U32 i = 0; i < mActors.size(); i++ ) - { - NxActor *actor = mActors[i]; - if ( actor->isDynamic() && - !actor->readBodyFlag( NX_BF_KINEMATIC ) && - !actor->readActorFlag( NX_AF_DISABLE_COLLISION ) ) - { - actor->addForceAtPos( nxvec, nxpos, NX_IMPULSE ); - } - } - - //setMaskBits( ImpulseMask ); -} - -void PxMultiActor::applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ) -{ - mWorld->releaseWriteLock(); - - // Find all currently enabled actors hit by the impulse radius... - Vector hitActors; - NxVec3 nxorigin = pxCast(origin); - NxSphere impulseSphere( nxorigin, radius ); - - for ( U32 i = 0; i < mActors.size(); i++ ) - { - NxActor *pActor = mActors[i]; - - if ( pActor->readActorFlag( NX_AF_DISABLE_COLLISION ) || - !pActor->isDynamic() || - pActor->readBodyFlag( NX_BF_KINEMATIC ) ) - continue; - - U32 numShapes = pActor->getNbShapes(); - NxShape *const* pShapeArray = pActor->getShapes(); - - for ( U32 j = 0; j < numShapes; j++ ) - { - const NxShape *pShape = pShapeArray[j]; - - if ( pShape->checkOverlapSphere( impulseSphere ) ) - { - hitActors.push_back( pActor ); - break; - } - } - } - - // Apply forces to hit actors, but swap out for broken - // actors first if appropriate... - for ( U32 i = 0; i < hitActors.size(); i++ ) - { - NxActor *pActor = hitActors[i]; - - PxUserData *pUserData = PxUserData::getData( *pActor ); - - // TODO: We should calculate the real force accounting - // for falloff before we break things with it. - - // If we have enough force, and this is an actor that - // can be 'broken' by impacts, break it now. - if ( pUserData && - //pUserData->mCanPush && - pUserData->mBrokenActors.size() > 0 && - magnitude > mDataBlock->breakForce ) - { - setBroken( pActor->getGlobalPose(), - pActor->getLinearVelocity(), - pUserData, - true ); - - // apply force that would have been applied to this actor - // to the broken actors we just enabled. - - for ( U32 j = 0; j < pUserData->mBrokenActors.size(); j++ ) - { - NxActor *pBrokenActor = pUserData->mBrokenActors[j]; - _applyActorRadialForce( pBrokenActor, nxorigin, radius, magnitude ); - } - } - else - { - // Apply force to the actor. - _applyActorRadialForce( pActor, nxorigin, radius, magnitude ); - } - } -} - -void PxMultiActor::_applyActorRadialForce( NxActor *inActor, const NxVec3 &origin, F32 radius, F32 magnitude ) -{ - // TODO: We're not getting a good torque force - // out of explosions because we're not picking - // the nearest point on the actor to the origin - // of the radial force. - - NxVec3 force = inActor->getCMassGlobalPosition() - origin; - NxF32 dist = force.magnitude(); - force.normalize(); - - if ( dist == 0.0f ) - force *= magnitude; - else - force *= mClampF( radius / dist, 0.0f, 1.0f ) * magnitude; - - // HACK: Make the position we push the force thru between the - // actor pos and its center of mass. This gives us some - // rotational force as well as make the covered structure - // explode better. - NxVec3 forcePos = ( inActor->getGlobalPosition() + inActor->getCMassGlobalPosition() ) / 2.0f; - inActor->addForceAtPos( force, forcePos, NX_VELOCITY_CHANGE ); -} - -void PxMultiActor::_updateContainerForces() -{ - if ( !mWorld->getEnabled() ) - return; - - PROFILE_SCOPE( PxMultiActor_updateContainerForces ); - - // Update container drag and buoyancy properties ( for each Actor ) - - for ( U32 i = 0; i < mActors.size(); i++ ) - { - NxActor *pActor = mActors[i]; - - if ( !pActor || - pActor->readBodyFlag(NX_BF_KINEMATIC) || - pActor->readActorFlag(NX_AF_DISABLE_COLLISION) ) - continue; - - // Get world bounds of this actor ( the combination of all shape bounds ) - NxShape *const* shapes = pActor->getShapes(); - NxBounds3 bounds; - bounds.setEmpty(); - NxBounds3 shapeBounds; - - for ( U32 i = 0; i < pActor->getNbShapes(); i++ ) - { - NxShape *pShape = shapes[i]; - pShape->getWorldBounds(shapeBounds); - - bounds.combine( shapeBounds ); - } - - Box3F boundsBox = pxCast(bounds); - - ContainerQueryInfo info; - info.box = boundsBox; - info.mass = pActor->getMass(); - - // Find and retreive physics info from intersecting WaterObject(s) - mContainer->findObjects( boundsBox, WaterObjectType|PhysicalZoneObjectType, findRouter, &info ); - - // Calculate buoyancy and drag - F32 angDrag = mDataBlock->angularDrag; - F32 linDrag = mDataBlock->linearDrag; - F32 buoyancy = 0.0f; - - if ( true ) //info.waterCoverage >= 0.1f) - { - F32 waterDragScale = info.waterViscosity * mDataBlock->waterDragScale; - F32 powCoverage = mPow( info.waterCoverage, 0.25f ); - - if ( info.waterCoverage > 0.0f ) - { - //angDrag = mBuildAngDrag * waterDragScale; - //linDrag = mBuildLinDrag * waterDragScale; - angDrag = mLerp( angDrag, angDrag * waterDragScale, powCoverage ); - linDrag = mLerp( linDrag, linDrag * waterDragScale, powCoverage ); - } - - buoyancy = ( info.waterDensity / mDataBlock->buoyancyDensity ) * mPow( info.waterCoverage, 2.0f ); - } - - // Apply drag (dampening) - pActor->setLinearDamping( linDrag ); - pActor->setAngularDamping( angDrag ); - - // Apply buoyancy force - if ( buoyancy != 0 ) - { - // A little hackery to prevent oscillation - // Based on this blog post: - // (http://reinot.blogspot.com/2005/11/oh-yes-they-float-georgie-they-all.html) - // JCF: disabled! - NxVec3 gravity; - mWorld->getScene()->getGravity(gravity); - //NxVec3 velocity = pActor->getLinearVelocity(); - - NxVec3 buoyancyForce = buoyancy * -gravity * TickSec * pActor->getMass(); - //F32 currHeight = getPosition().z; - //const F32 C = 2.0f; - //const F32 M = 0.1f; - - //if ( currHeight + velocity.z * TickSec * C > info.waterHeight ) - // buoyancyForce *= M; - - pActor->addForceAtPos( buoyancyForce, pActor->getCMassGlobalPosition(), NX_IMPULSE ); - } - - // Apply physical zone forces - if ( info.appliedForce.len() > 0.001f ) - pActor->addForceAtPos( pxCast(info.appliedForce), pActor->getCMassGlobalPosition(), NX_IMPULSE ); - } -} - -/* -ConsoleMethod( PxMultiActor, applyImpulse, void, 3, 3, "applyImpulse - takes a velocity vector to apply") -{ - VectorF vec; - dSscanf( argv[2],"%g %g %g", - &vec.x,&vec.y,&vec.z ); - - object->applyImpulse( vec ); -} -*/ - -void PxMultiActor::setAllBroken( bool isBroken ) -{ - PROFILE_SCOPE( PxMultiActor_SetAllBroken ); - - if ( mIsDummy ) - { - PxMultiActor *serverObj = static_cast( mServerObject.getObject() ); - serverObj->setAllBroken( isBroken ); - return; - } - - mWorld->releaseWriteLock(); - - NxActor *actor0 = NULL; - NxActor *actor1 = NULL; - NxMat34 parentPose; - - for ( U32 i = 0; i < mJoints.size(); i++ ) - { - NxJoint *joint = mJoints[i]; - if ( !joint ) - continue; - - PxUserData *jointData = PxUserData::getData( *joint ); - if ( !jointData ) - continue; - - joint->getActors( &actor0, &actor1 ); - parentPose = actor0->getGlobalPose(); - - setBroken( parentPose, NxVec3(0.0f), jointData, isBroken ); - } - - for ( U32 i = 0; i < mActors.size(); i++ ) - { - NxActor *actor = mActors[i]; - if ( !actor ) - continue; - - PxUserData *actorData = PxUserData::getData( *actor ); - if ( !actorData ) - continue; - - setBroken( actor->getGlobalPose(), - actor->getLinearVelocity(), - actorData, - isBroken ); - } -} - -void PxMultiActor::setBroken( const NxMat34 &parentPose, - const NxVec3 &parentVel, - PxUserData *userData, - bool isBroken ) -{ - PROFILE_SCOPE( PxMultiActor_SetBroken ); - - // TODO: This function is highly inefficent and - // way too complex to follow... the hacked single - // player mode doesn't help. - - // Be careful not to set something broken twice. - if ( isBroken && - userData->mIsBroken == isBroken ) - return; - - userData->mIsBroken = isBroken; - - Vector *hideActors = NULL; - Vector *showActors = NULL; - - if ( isBroken ) - { - hideActors = &userData->mUnbrokenActors; - showActors = &userData->mBrokenActors; - } - else - { - hideActors = &userData->mBrokenActors; - showActors = &userData->mUnbrokenActors; - } - - NxActor *pActor = NULL; - MatrixF tMat; - for ( U32 i = 0; i < hideActors->size(); i++ ) - { - pActor = (*hideActors)[i]; - - pActor->raiseActorFlag( NX_AF_DISABLE_COLLISION ); - pActor->raiseBodyFlag( NX_BF_KINEMATIC ); - pActor->putToSleep(); - - NxShape *const* pShapeArray = pActor->getShapes(); - U32 shapeCount = pActor->getNbShapes(); - for ( U32 i = 0; i < shapeCount; i++ ) - pShapeArray[i]->setFlag( NX_SF_DISABLE_RAYCASTING, true ); - - setMeshHidden( _getMeshName( pActor ), true ); - } - - // Get the client side delta array. - Vector *actorDeltas = NULL; - if ( isClientObject() ) - actorDeltas = &mActorDeltas; - else if ( isServerObject() && PHYSICSMGR->isSinglePlayer() ) - { - PxMultiActor *clientObj = static_cast( getClientObject() ); - if ( clientObj ) - actorDeltas = &clientObj->mActorDeltas; - } - U32 index; - - for ( U32 i = 0; i < showActors->size(); i++ ) - { - pActor = (*showActors)[i]; - - if ( showActors == &userData->mBrokenActors ) - { - NxMat34 pose; - pose.multiply( parentPose, userData->mRelXfm[i] ); - pActor->setGlobalPose( pose ); - - if ( actorDeltas ) - { - for ( U32 j=0; j < mMappedActors.size(); j++ ) - { - if ( mMappedActors[j] == pActor ) - { - index = mMappedToActorIndex[j]; - - // Reset the delta. - Delta &delta = (*actorDeltas)[index]; - delta.pos = pxCast( pose.t ); - pose.getRowMajor44( tMat ); - delta.rot.set( tMat ); - delta.lastPos = delta.pos; - delta.lastRot = delta.rot; - - break; - } - } - } - } - - pActor->clearActorFlag( NX_AF_DISABLE_COLLISION ); - pActor->clearBodyFlag( NX_BF_KINEMATIC ); - pActor->setLinearVelocity( parentVel ); - pActor->wakeUp(); - - NxShape *const* pShapeArray = pActor->getShapes(); - U32 shapeCount = pActor->getNbShapes(); - for ( U32 i = 0; i < shapeCount; i++ ) - pShapeArray[i]->setFlag( NX_SF_DISABLE_RAYCASTING, false ); - - setMeshHidden( _getMeshName(pActor), false ); - } -} - -void PxMultiActor::setAllHidden( bool hide ) -{ - for ( U32 i = 0; i < mShapeInstance->mMeshObjects.size(); i++ ) - mShapeInstance->setMeshForceHidden( i, hide ); -} - -ConsoleMethod( PxMultiActor, setAllHidden, void, 3, 3, "( bool )" - "@brief Hides or unhides all meshes contained in the PxMultiActor.\n\n" - "Hidden meshes will not be rendered.") -{ - object->setAllHidden( dAtob(argv[2]) ); -} - -void PxMultiActor::setMeshHidden( String namePrefix, bool hidden ) -{ - if ( isServerObject() && PHYSICSMGR->isSinglePlayer() ) - { - PxMultiActor *clientObj = static_cast( getClientObject() ); - if ( clientObj ) - clientObj->setMeshHidden( namePrefix, hidden ); - } - - for ( U32 i = 0; i < mShapeInstance->mMeshObjects.size(); i++ ) - { - String meshName = mShapeInstance->getShape()->getMeshName( i ); - - if ( meshName.find( namePrefix ) != String::NPos ) - { - mShapeInstance->setMeshForceHidden( i, hidden ); - return; - } - } - - Con::warnf( "PxMultiActor::setMeshHidden - could not find mesh containing substring (%s)", namePrefix.c_str() ); -} - -ConsoleMethod( PxMultiActor, setBroken, void, 3, 3, "( bool )" - "@brief Sets the PxMultiActor to a broken or unbroken state.\n\n") -{ - object->setAllBroken( dAtob( argv[2] ) ); -} - -void PxMultiActorData::dumpModel() -{ - TSShapeInstance *inst = new TSShapeInstance( shape, true ); - - String path = Platform::getMainDotCsDir(); - path += "/model.dump"; - - FileStream *st; - if((st = FileStream::createAndOpen( path, Torque::FS::File::Write )) != NULL) - { - if ( inst ) - inst->dump( *st ); - else - Con::errorf( "PxMultiActor::dumpModel, no ShapeInstance." ); - - delete st; - } - else - Con::errorf( "PxMultiActor::dumpModel, error opening dump file." ); -} - -ConsoleMethod( PxMultiActorData, dumpModel, void, 2, 2, - "@brief Dumps model hierarchy and details to a file.\n\n" - "The file will be created as \'model.dump\' in the game folder. " - "If model.dump already exists, it will be overwritten.\n\n") -{ - object->dumpModel(); -} - -ConsoleMethod( PxMultiActor, setMeshHidden, void, 4, 4, "(string meshName, bool isHidden)" - "@brief Prevents the provided mesh from being rendered.\n\n") -{ - object->setMeshHidden( argv[2], dAtob( argv[3] ) ); -} - -void PxMultiActor::listMeshes( const String &state ) const -{ - if ( mShapeInstance ) - mShapeInstance->listMeshes( state ); -} - -ConsoleMethod( PxMultiActor, listMeshes, void, 3, 3, "(enum Hidden/Shown/All)" - "@brief Lists all meshes of the provided type in the console window.\n\n" - "@param All Lists all of the %PxMultiActor's meshes.\n" - "@param Hidden Lists all of the %PxMultiActor's hidden meshes.\n" - "@param Shown Lists all of the %PxMultiActor's visible meshes.\n") -{ - object->listMeshes( argv[2] ); -}; - -ConsoleMethod( PxMultiActorData, reload, void, 2, 2, "" - "@brief Reloads all data used for the PxMultiActorData.\n\n" - "If the reload sucessfully completes, all PxMultiActor's will be notified.\n\n") -{ - object->reload(); -} diff --git a/Engine/source/T3D/physics/physx/pxMultiActor.h b/Engine/source/T3D/physics/physx/pxMultiActor.h deleted file mode 100644 index 891ca4ac8..000000000 --- a/Engine/source/T3D/physics/physx/pxMultiActor.h +++ /dev/null @@ -1,398 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PXMULTIACTOR_H -#define _PXMULTIACTOR_H - -#ifndef _GAMEBASE_H_ -#include "T3D/gameBase/gameBase.h" -#endif -#ifndef __RESOURCE_H__ -#include "core/resource.h" -#endif -#ifndef _T3D_PHYSICS_PHYSICSPLUGIN_H_ -#include "T3D/physics/physicsPlugin.h" -#endif -#ifndef _PHYSX_H_ -#include "T3D/physics/physx/px.h" -#endif -#ifndef _STRINGUNIT_H_ -#include "core/strings/stringUnit.h" -#endif -#ifndef _PHYSICS_PHYSICSUSERDATA_H_ -#include "T3D/physics/physicsUserData.h" -#endif -#ifndef _TSSHAPE_H_ -#include "ts/tsShape.h" -#endif - - -class TSShapeInstance; -class BaseMatInstance; -class PxMultiActor; -class PxWorld; -class PxMaterial; -class NxScene; -class NxActor; -class NxShape; -class NxCompartment; -class NxJoint; -class NxMat34; -class NxVec3; -class ParticleEmitterData; - - -namespace NXU -{ - class NxuPhysicsCollection; -} - - -class PxUserData : public PhysicsUserData -{ -public: - - /// The constructor. - PxUserData() - : PhysicsUserData(), - mIsBroken( false ), - mParticleEmitterData( NULL ) - { - } - - static PxUserData* getData( const NxActor &actor ) - { - PxUserData *result = (PxUserData*)actor.userData; - - AssertFatal( !result || typeid( *result ) == typeid( PxUserData ), - "PxUserData::getData - The pointer is the wrong type!" ); - - return result; - } - - static PxUserData* getData( const NxJoint &joint ) - { - PxUserData *result = (PxUserData*)joint.userData; - - AssertFatal( !result || typeid( *result ) == typeid( PxUserData ), - "PxUserData::getData - The pointer is the wrong type!" ); - - return result; - } - - typedef Signal JointBreakSignal; - - JointBreakSignal& getOnJointBreakSignal() { return mOnJointBreakSignal; } - - // Breakable stuff... - Vector mUnbrokenActors; - Vector mBrokenActors; - Vector mRelXfm; - ParticleEmitterData *mParticleEmitterData; - bool mIsBroken; - JointBreakSignal mOnJointBreakSignal; -}; - - -class ParticleEmitterData; - -class PxMultiActorData : public GameBaseData -{ - typedef GameBaseData Parent; - -public: - - PxMultiActorData(); - virtual ~PxMultiActorData(); - - DECLARE_CONOBJECT(PxMultiActorData); - - static void initPersistFields(); - - void packData(BitStream* stream); - void unpackData(BitStream* stream); - - bool preload( bool server, String &errorBuffer ); - //bool onAdd(); - - void allocPrimBuffer( S32 overrideSize = -1 ); - - bool _loadCollection( const UTF8 *path, bool isBinary ); - - void _onFileChanged( const Torque::Path &path ); - - void reload(); - - void dumpModel(); - - Signal mReloadSignal; - -public: - - // Rendering - StringTableEntry shapeName; - Resource shape; - - PxMaterial *material; - - /// Filename to load the physics actor from. - StringTableEntry physXStream; - - enum - { - NumMountPoints = 32, - MaxCorrectionNodes = 2 - }; - - StringTableEntry correctionNodeNames[MaxCorrectionNodes]; - StringTableEntry mountNodeNames[NumMountPoints]; - S32 correctionNodes[MaxCorrectionNodes]; - S32 mountPointNode[NumMountPoints]; ///< Node index of mountPoint - - /// If true no network corrections will - /// be done during gameplay. - bool noCorrection; - - /// Physics collection that holds the actor - /// and all associated shapes and data. - NXU::NxuPhysicsCollection *collection; - - bool createActors( NxScene *scene, - NxCompartment *compartment, - const NxMat34 *nxMat, - const Point3F& scale, - Vector *outActors, - Vector *outShapes, - Vector *outJoints, - Vector *outActorUserProperties, - Vector *outJointUserProperties ); - - /// Angular and Linear Drag (dampening) is scaled by this when in water. - F32 waterDragScale; - - /// The density of this object (for purposes of buoyancy calculation only). - F32 buoyancyDensity; - - F32 angularDrag; - F32 linearDrag; - - /// If this flag is set to true, - /// the physics actors will only be - /// created on the client, and the server - /// object is only responsible for ghosting. - /// Objects with this flag set will never stop - /// the physics player from moving through them. - bool clientOnly; - - bool singlePlayerOnly; - - /// When applyImpulse is passed a force of this magnitude or greater - /// any actors hit by the force vector that have broken versions - /// will become 'broken'. - F32 breakForce; -}; - - -class PxMultiActor : public GameBase -{ - typedef GameBase Parent; - - enum MaskBits - { - MoveMask = Parent::NextFreeMask << 0, - WarpMask = Parent::NextFreeMask << 1, - LightMask = Parent::NextFreeMask << 2, - SleepMask = Parent::NextFreeMask << 3, - ForceSleepMask = Parent::NextFreeMask << 4, - ImpulseMask = Parent::NextFreeMask << 5, - UpdateMask = Parent::NextFreeMask << 6, - MountedMask = Parent::NextFreeMask << 7, - NextFreeMask = Parent::NextFreeMask << 8 - }; - -public: - - PxMultiActor(); - - DECLARE_CONOBJECT( PxMultiActor ); - static void initPersistFields(); - - // SimObject - bool onAdd(); - void onRemove(); - void inspectPostApply(); - void onPhysicsReset( PhysicsResetEvent reset ); - void onStaticModified( const char *slotName, const char *newValue ); - void onDeleteNotify( SimObject *obj ); - - // NetObject - U32 packUpdate( NetConnection *conn, U32 mask, BitStream *stream ); - void unpackUpdate( NetConnection *conn, BitStream *stream ); - - // SceneObject - void prepRenderImage( SceneRenderState *state ); - void setScale( const VectorF &scale ); - void setTransform( const MatrixF &mat ); - virtual void mountObject( SceneObject *obj, U32 node ); - virtual void unmountObject( SceneObject *obj ); - virtual void getMountTransform( U32 mountPoint, MatrixF *mat ); - virtual void getRenderMountTransform( U32 index, MatrixF *mat ); - - // GameBase - virtual bool onNewDataBlock( GameBaseData *dptr, bool reload ); - virtual void processTick( const Move *move ); - virtual void interpolateTick( F32 delta ); - virtual void applyImpulse( const Point3F &pos, const VectorF &vec ); - virtual void applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ); - - /// PxMultiActor - /// @{ - - /// Set visibility of all broken/unbroken meshes to match this state. - void setAllBroken( bool isBroken ); - - /// Sets up actors and meshes associated with the passed joint to reflect - /// the desired state. - void setBroken( const NxMat34 &parentPose, - const NxVec3 &parentVel, - PxUserData *userData, - bool isBroken ); - - /// - void setMeshHidden( String namePrefix, bool hidden ); - - void setAllHidden( bool hide ); - - void listMeshes( const String &state ) const; - - void _onJointBreak( NxReal breakForce, NxJoint &brokenJoint ); - - void _onContact( PhysicsUserData *us, - PhysicsUserData *them, - const Point3F &hitPoint, - const Point3F &hitForce ); - - void applyWarp( const MatrixF& mat, bool interpRender, bool sweep ); - - void getDynamicXfms( PxMultiActor *srcObj, F32 dt ); - - /// @} - -protected: - - /// This creates the physics objects. - bool _createActors( const MatrixF &xfm ); - - /// Creates a PxUserData for a joint and parses userProperties into it. - PxUserData* _createJointUserData( NxJoint *joint, String &userProperties ); - - /// Creates a PxUserData and parses userProperties into it. - PxUserData* _createActorUserData( NxActor *actor, String &userProperties ); - - /// Called to cleanup the physics objects. - void _destroyActors(); - - NxActor* _findActor( const String &actorName ) const; - - /// Get the corresponding meshName for a given actor. - String _getMeshName( const NxActor *actor ) const; - - /// - void _updateBounds(); - - void _updateContainerForces(); - - void _debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat ); - - void onFileNotify(); - - void _applyActorRadialForce( NxActor *inActor, const NxVec3 &origin, F32 radius, F32 magnitude ); - - void _updateDeltas( bool clearDelta ); - - bool _getNodeTransform( U32 nodeIdx, MatrixF *outXfm ); - -protected: - - PxMultiActorData *mDataBlock; - - PxWorld *mWorld; - - Vector mActors; - Vector mMappedActors; - Vector mMappedToActorIndex; - Vector mMappedActorDL; - Vector mJoints; - Vector mShapes; - - /// This is the root actor whose transform is the - /// transform of this SceneObject. - NxActor *mRootActor; - - TSShapeInstance *mShapeInstance; - Resource mDebrisShape; - - struct Delta - { - Point3F pos; - Point3F lastPos; - QuatF rot; - QuatF lastRot; - }; - - Delta mDelta; - - Vector mActorDeltas; - - /// The transform of this actor when it was first - /// created. It is used to reset the physics state - /// when the editor is enabled. - MatrixF mResetXfm; - - - /// The userdata object assigned to all actors - /// and joints of this multi-actor. - //PxUserData mUserData; - - /// - //Vector mRelXfms; - - /// This is the scale the actors were built at and - /// is used to decide if we need to recreate them. - VectorF mActorScale; - //F32 mBuildAngDrag; - //F32 mBuildLinDrag; - - VectorF mStartImpulse; - - bool mDebugRender; - - /// A helper set to true if is a client object and - /// is a singlePlayerOnly object. - bool mIsDummy; - - /// Helper for - bool mBroken; -}; - -#endif // _PXMULTIACTOR_H - diff --git a/Engine/source/T3D/physics/physx/pxPlayer.cpp b/Engine/source/T3D/physics/physx/pxPlayer.cpp deleted file mode 100644 index cf4ca9038..000000000 --- a/Engine/source/T3D/physics/physx/pxPlayer.cpp +++ /dev/null @@ -1,428 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxPlayer.h" - -#include "T3D/physics/physicsPlugin.h" -#include "T3D/physics/physX/pxWorld.h" -#include "T3D/physics/physX/pxCasts.h" -#include "collision/collision.h" -//#include "gfx/gfxDrawUtil.h" -//#include "sim/netConnection.h" - - -PxPlayer::PxPlayer() - : PhysicsPlayer(), - mController( NULL ), - mWorld( NULL ), - mObject( NULL ), - mSkinWidth( 0.1f ), - mOriginOffset( 0.0f ) -{ - PHYSICSMGR->getPhysicsResetSignal().notify( this, &PxPlayer::_onPhysicsReset ); -} - -PxPlayer::~PxPlayer() -{ - _releaseController(); - PHYSICSMGR->getPhysicsResetSignal().remove( this, &PxPlayer::_onPhysicsReset ); -} - -void PxPlayer::_releaseController() -{ - if ( mController ) - { - mController->getActor()->userData = NULL; - mWorld->getStaticChangedSignal().remove( this, &PxPlayer::_onStaticChanged ); - mWorld->releaseController( *mController ); - mController = NULL; - } -} - -void PxPlayer::init( const char *type, - const Point3F &size, - F32 runSurfaceCos, - F32 stepHeight, - SceneObject *obj, - PhysicsWorld *world ) -{ - AssertFatal( obj, "PxPlayer::init - Got a null scene object!" ); - AssertFatal( world, "PxPlayer::init - Got a null world!" ); - AssertFatal( dynamic_cast( world ), "PxPlayer::init - The world is the wrong type!" ); - - // Cleanup any previous controller. - _releaseController(); - - mObject = obj; - mWorld = (PxWorld*)world; - mOriginOffset = size.z * 0.5f; - - //if ( dStricmp( type, "Capsule" ) == 0 ) - { - NxCapsuleControllerDesc desc; - desc.skinWidth = 0.05f; // Expose? - desc.radius = getMax( size.x, size.y ) * 0.5f; - desc.radius -= desc.skinWidth; - desc.height = size.z - ( desc.radius * 2.0f ); - desc.height -= desc.skinWidth * 2.0f; - - desc.climbingMode = CLIMB_CONSTRAINED; - desc.position.set( 0, 0, 0 ); - desc.upDirection = NX_Z; - desc.callback = this; // TODO: Fix this as well! - desc.slopeLimit = runSurfaceCos; - desc.stepOffset = stepHeight; - mController = mWorld->createController( desc ); - } - //else - { - //mColShape = new btBoxShape( btVector3( 0.5f, 0.5f, 1.0f ) ); - //mOriginOffset = 1.0f; - } - - mWorld->getStaticChangedSignal().notify( this, &PxPlayer::_onStaticChanged ); - - // Put the kinematic actor on group 29. - NxActor *kineActor = mController->getActor(); - kineActor->setGroup( 29 ); - NxShape *const *shapes = kineActor->getShapes(); - for ( U32 i=0; i < kineActor->getNbShapes(); i++ ) - shapes[i]->setGroup( 29 ); - - mUserData.setObject( obj ); - kineActor->userData = &mUserData; -} - -void PxPlayer::_onStaticChanged() -{ - mController->reportSceneChanged(); -} - -void PxPlayer::_onPhysicsReset( PhysicsResetEvent reset ) -{ - // The PhysX controller will crash out if it doesn't clear its - // list of static elements when they are deleted. By calling this - // on physics events we clear the cache and we don't get crashes. - // - // This all depends on not doing moves and sweeps when the - // simulation is paused... we need to stop operating. - - if ( mController ) - mController->reportSceneChanged(); -} - -Point3F PxPlayer::move( const VectorF &disp, CollisionList &outCol ) -{ - AssertFatal( mController, "PxPlayer::move - The controller is null!" ); - - // Return the last position if the simulation is stopped. - // - // See PxPlayer::_onPhysicsReset - if ( !mWorld->isEnabled() ) - { - Point3F newPos = pxCast( mController->getDebugPosition() ); - newPos.z -= mOriginOffset; - //outCol->point = newPos; - //outCol->normal.set( 0, 0, 1 ); - return newPos; - } - - mWorld->releaseWriteLock(); - - mCollisionList = &outCol; - - // PhysX 2.8.4 checks up an up displacement and if found will assume - // the player is flying and remove the step offset. If we have a small - // z displacement here, zero it out. - NxVec3 dispNx( disp.x, disp.y, disp.z ); - if (mIsZero(disp.z)) - dispNx.z = 0.0f; - - NxU32 activeGroups = 0xFFFFFFFF; - activeGroups &= ~( 1<<31 ); // Skip activeGroup for triggers ( 31 ) - activeGroups &= ~( 1<<30 ); // Skip activeGroup for debris / non interactive dynamics ( 30 ) - - NxU32 collisionFlags = NXCC_COLLISION_SIDES | NXCC_COLLISION_DOWN | NXCC_COLLISION_UP; - - mController->move( dispNx, activeGroups, 0.0001f, collisionFlags ); - - Point3F newPos = pxCast( mController->getDebugPosition() ); - newPos.z -= mOriginOffset; - - mCollisionList = NULL; - - return newPos; -} - -NxControllerAction PxPlayer::onShapeHit( const NxControllerShapeHit& hit ) -{ - if (!mCollisionList || mCollisionList->getCount() >= CollisionList::MaxCollisions) - return NX_ACTION_NONE; - - NxActor *actor = &hit.shape->getActor(); - PhysicsUserData *userData = PhysicsUserData::cast( actor->userData ); - - if ( actor->readActorFlag( NX_AF_DISABLE_RESPONSE ) ) - return NX_ACTION_NONE; - - // Fill out the Collision - // structure for use later. - Collision &col = mCollisionList->increment(); - dMemset( &col, 0, sizeof( col ) ); - - col.normal = pxCast( hit.worldNormal ); - col.point.set( hit.worldPos.x, hit.worldPos.y, hit.worldPos.z ); - col.distance = hit.length; - if ( userData ) - col.object = userData->getObject(); - - // If the collision direction is sideways then modify the collision normal - // to remove any z component. This takes care of any sideways collisions - // with the round bottom of the capsule when it comes to the Player class - // velocity calculations. We want all sideways collisions to be treated - // as if they hit the side of a cylinder. - if (mIsZero(hit.dir.z)) - { - if (col.normal.z > 0.0f) - { - // This will only remove the z component of the collision normal - // for the bottom of the character controller, which would hit during - // a step. We'll leave the top hemisphere of the character's capsule - // alone as bumping one's head is an entirely different story. This - // helps with low doorways. - col.normal.z = 0.0f; - col.normal.normalizeSafe(); - } - } - else - { - // PhysX doesn't perform callbacks in its upwards collision check so if - // this isn't a sideways collision then it must be a downwards one. In this - // case we want to have the collision normal only point in the opposite direction. - // i.e. up If we include the sideways part of the normal then the Player class - // velocity calculations using this normal will affect the player's forwards - // momentum. This is especially noticable on stairs as the rounded bottom of - // the capsule slides up the corner of a stair. - col.normal.set(0.0f, 0.0f, 1.0f); - } - - /* - if ( userData && - userData->mCanPush && - actor->isDynamic() && - !actor->readBodyFlag( NX_BF_KINEMATIC ) && - !mDummyMove ) - { - NxActor *ctrlActor = mController->getActor(); - - // So the object is neither - // a static or a kinematic, - // meaning we need to figure out - // if we have enough force to push it. - - // Get the hit object's force - // and scale it by the amount - // that it's acceleration is going - // against our acceleration. - const Point3F &hitObjLinVel = pxCast( actor->getLinearVelocity() ); - - F32 hitObjMass = actor->getMass(); - - VectorF hitObjDeltaVel = hitObjLinVel * TickSec; - VectorF hitObjAccel = hitObjDeltaVel / TickSec; - - VectorF controllerLinVel = pxCast( controllerActor->getLinearVelocity() ); - VectorF controllerDeltaVel = controllerLinVel * TickSec; - VectorF controllerAccel = controllerDeltaVel / TickSec; - - Point3F hitObjForce = (hitObjMass * hitObjAccel); - Point3F playerForce = (controllerActor->getMass() * controllerAccel); - - VectorF normalizedObjVel( hitObjLinVel ); - normalizedObjVel.normalizeSafe(); - - VectorF normalizedPlayerVel( pxCast( controllerActor->getLinearVelocity() ) ); - normalizedPlayerVel.normalizeSafe(); - - F32 forceDot = mDot( normalizedObjVel, normalizedPlayerVel ); - - hitObjForce *= forceDot; - - playerForce = playerForce - hitObjForce; - - if ( playerForce.x > 0.0f || playerForce.y > 0.0f || playerForce.z > 0.0f ) - actor->addForceAtPos( NxVec3( playerForce.x, playerForce.y, playerForce.z ), actor->getCMassGlobalPosition() ); - - //Con::printf( "onShapeHit: %f %f %f", playerForce.x, playerForce.y, playerForce.z ); - } - */ - - return NX_ACTION_PUSH; -} - -NxControllerAction PxPlayer::onControllerHit( const NxControllersHit& hit ) -{ - if (!mCollisionList || mCollisionList->getCount() >= CollisionList::MaxCollisions) - return NX_ACTION_NONE; - - NxActor *actor = hit.other->getActor(); - PhysicsUserData *userData = PhysicsUserData::cast( actor->userData ); - - if ( actor->readActorFlag( NX_AF_DISABLE_RESPONSE ) ) - return NX_ACTION_NONE; - - // For controller-to-controller hit we don't have an actual hit point, so all - // we can do is set the hit object. - Collision &col = mCollisionList->increment(); - dMemset( &col, 0, sizeof( col ) ); - if ( userData ) - col.object = userData->getObject(); - - return NX_ACTION_NONE; -} - -void PxPlayer::findContact( SceneObject **contactObject, - VectorF *contactNormal, - Vector *outOverlapObjects ) const -{ - AssertFatal( mController, "PxPlayer::findContact - The controller is null!" ); - - // See PxPlayer::_onPhysicsReset - if ( !mWorld->isEnabled() ) - return; - - // Calculate the sweep motion... - F32 halfCapSize = mOriginOffset; - F32 halfSmallCapSize = halfCapSize * 0.8f; - F32 diff = halfCapSize - halfSmallCapSize; - - const F32 mSkinWidth = 0.1f; - - F32 offsetDist = diff + mSkinWidth + 0.01f; - NxVec3 motion(0,0,-offsetDist); - - /* - // Construct the capsule... - F32 radius = mCapsuleController->getRadius(); - F32 halfHeight = mCapsuleController->getHeight() * 0.5f; - - NxCapsule capsule; - capsule.p0 = capsule.p1 = pxCast( mCapsuleController->getDebugPosition() ); - capsule.p0.z -= halfHeight; - capsule.p1.z += halfHeight; - capsule.radius = radius; - */ - - NxSweepQueryHit sweepHit; - NxU32 hitCount = mController->getActor()->linearSweep( motion, NX_SF_STATICS | NX_SF_DYNAMICS, NULL, 1, &sweepHit, NULL ); - - if ( hitCount > 0 ) - { - PhysicsUserData *data = PhysicsUserData::cast( sweepHit.hitShape->getActor().userData ); - if ( data ) - { - *contactObject = data->getObject(); - *contactNormal = pxCast( sweepHit.normal ); - } - } - - // Check for overlapped objects ( triggers ) - - if ( !outOverlapObjects ) - return; - - NxCapsuleShape *shape = reinterpret_cast( mController->getActor()->getShapes()[0] ); - NxCapsule worldCapsule; - shape->getWorldCapsule( worldCapsule ); - - // Test only against activeGroup with triggers ( 31 ). - NxU32 activeGroups = 1 << 31; - - NxShape *shapes[10]; - - hitCount = mWorld->getScene()->overlapCapsuleShapes( worldCapsule, NX_ALL_SHAPES, 10, shapes, NULL, activeGroups ); - - for ( S32 i = 0; i < hitCount; i++ ) - { - PhysicsUserData *data = PhysicsUserData::cast( shapes[i]->getActor().userData ); - if ( data ) - outOverlapObjects->push_back( data->getObject() ); - } -} - -void PxPlayer::enableCollision() -{ - AssertFatal( mController, "PxPlayer::enableCollision - The controller is null!" ); - - mWorld->releaseWriteLock(); - mController->setCollision( true ); -} - -void PxPlayer::disableCollision() -{ - AssertFatal( mController, "PxPlayer::disableCollision - The controller is null!" ); - - mWorld->releaseWriteLock(); - mController->setCollision( false ); -} - -PhysicsWorld* PxPlayer::getWorld() -{ - return mWorld; -} - -void PxPlayer::setTransform( const MatrixF &transform ) -{ - AssertFatal( mController, "PxPlayer::setTransform - The controller is null!" ); - - mWorld->releaseWriteLock(); - - Point3F newPos = transform.getPosition(); - newPos.z += mOriginOffset; - - const Point3F &curPos = pxCast(mController->getDebugPosition()); - - if ( !(newPos - curPos ).isZero() ) - mController->setPosition( pxCast(newPos) ); -} - -MatrixF& PxPlayer::getTransform( MatrixF *outMatrix ) -{ - AssertFatal( mController, "PxPlayer::getTransform - The controller is null!" ); - - Point3F newPos = pxCast( mController->getDebugPosition() ); - newPos.z -= mOriginOffset; - outMatrix->setPosition( newPos ); - - return *outMatrix; -} - -void PxPlayer::setScale( const Point3F &scale ) -{ -} - -Box3F PxPlayer::getWorldBounds() -{ - Con::warnf( "PxPlayer::getWorldBounds - not implemented" ); - return Box3F::Invalid; -} \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxPlayer.h b/Engine/source/T3D/physics/physx/pxPlayer.h deleted file mode 100644 index 419ddcc2b..000000000 --- a/Engine/source/T3D/physics/physx/pxPlayer.h +++ /dev/null @@ -1,106 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PXPLAYER_H -#define _PXPLAYER_H - -#ifndef _PHYSX_H_ -#include "T3D/physics/physX/px.h" -#endif -#ifndef _T3D_PHYSICS_PHYSICSPLAYER_H_ -#include "T3D/physics/physicsPlayer.h" -#endif -#ifndef _T3D_PHYSICSCOMMON_H_ -#include "T3D/physics/physicsCommon.h" -#endif - - -class PxWorld; -class NxController; - - -class PxPlayer : public PhysicsPlayer, public NxUserControllerHitReport -{ -protected: - - NxController *mController; - - F32 mSkinWidth; - - PxWorld *mWorld; - - SceneObject *mObject; - - /// Used to get collision info out of the - /// NxUserControllerHitReport callbacks. - CollisionList *mCollisionList; - - /// - F32 mOriginOffset; - - /// - F32 mStepHeight; - - /// - void _releaseController(); - - // NxUserControllerHitReport - virtual NxControllerAction onShapeHit( const NxControllerShapeHit& hit ); - virtual NxControllerAction onControllerHit( const NxControllersHit& hit ); - - void _findContact( SceneObject **contactObject, VectorF *contactNormal ) const; - - void _onPhysicsReset( PhysicsResetEvent reset ); - - void _onStaticChanged(); - -public: - - PxPlayer(); - virtual ~PxPlayer(); - - // PhysicsObject - virtual PhysicsWorld* getWorld(); - virtual void setTransform( const MatrixF &transform ); - virtual MatrixF& getTransform( MatrixF *outMatrix ); - virtual void setScale( const Point3F &scale ); - virtual Box3F getWorldBounds(); - virtual void setSimulationEnabled( bool enabled ) {} - virtual bool isSimulationEnabled() { return true; } - - // PhysicsPlayer - virtual void init( const char *type, - const Point3F &size, - F32 runSurfaceCos, - F32 stepHeight, - SceneObject *obj, - PhysicsWorld *world ); - virtual Point3F move( const VectorF &displacement, CollisionList &outCol ); - virtual void findContact( SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects ) const; - virtual bool testSpacials( const Point3F &nPos, const Point3F &nSize ) const { return true; } - virtual void setSpacials( const Point3F &nPos, const Point3F &nSize ) {} - virtual void enableCollision(); - virtual void disableCollision(); -}; - - -#endif // _PXPLAYER_H \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxPlugin.cpp b/Engine/source/T3D/physics/physx/pxPlugin.cpp deleted file mode 100644 index bb3352983..000000000 --- a/Engine/source/T3D/physics/physx/pxPlugin.cpp +++ /dev/null @@ -1,297 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "console/consoleTypes.h" -#include "T3D/physics/physX/pxPlugin.h" - -#include "T3D/physics/physicsShape.h" -#include "T3D/physics/physX/pxWorld.h" -#include "T3D/physics/physX/pxBody.h" -#include "T3D/physics/physX/pxPlayer.h" -#include "T3D/physics/physX/pxCollision.h" -#include "T3D/gameBase/gameProcess.h" -#include "core/util/tNamedFactory.h" - - -extern bool gPhysXLogWarnings; - -AFTER_MODULE_INIT( Sim ) -{ - NamedFactory::add( "PhysX", &PxPlugin::create ); - - #if defined(TORQUE_OS_WIN) || defined(TORQUE_OS_XBOX) || defined(TORQUE_OS_XENON) - NamedFactory::add( "default", &PxPlugin::create ); - #endif - - Con::addVariable( "$PhysXLogWarnings", TypeBool, &gPhysXLogWarnings, - "@brief Output PhysX warnings to the console.\n\n" - "@ingroup Physics\n"); -} - - -PhysicsPlugin* PxPlugin::create() -{ - // Only create the plugin if it hasn't been set up AND - // the PhysX world is successfully initialized. - bool success = PxWorld::restartSDK( false ); - if ( success ) - return new PxPlugin(); - - return NULL; -} - -PxPlugin::PxPlugin() -{ -} - -PxPlugin::~PxPlugin() -{ -} - -void PxPlugin::destroyPlugin() -{ - // Cleanup any worlds that are still kicking. - Map::Iterator iter = mPhysicsWorldLookup.begin(); - for ( ; iter != mPhysicsWorldLookup.end(); iter++ ) - { - iter->value->destroyWorld(); - delete iter->value; - } - mPhysicsWorldLookup.clear(); - - PxWorld::restartSDK( true ); - - delete this; -} - -void PxPlugin::reset() -{ - // First delete all the cleanup objects. - if ( getPhysicsCleanup() ) - getPhysicsCleanup()->deleteAllObjects(); - - getPhysicsResetSignal().trigger( PhysicsResetEvent_Restore ); - - // Now let each world reset itself. - Map::Iterator iter = mPhysicsWorldLookup.begin(); - for ( ; iter != mPhysicsWorldLookup.end(); iter++ ) - iter->value->reset(); -} - -PhysicsCollision* PxPlugin::createCollision() -{ - return new PxCollision(); -} - -PhysicsBody* PxPlugin::createBody() -{ - return new PxBody(); -} - -PhysicsPlayer* PxPlugin::createPlayer() -{ - return new PxPlayer(); -} - -bool PxPlugin::isSimulationEnabled() const -{ - bool ret = false; - PxWorld *world = static_cast( getWorld( smClientWorldName ) ); - if ( world ) - { - ret = world->getEnabled(); - return ret; - } - - world = static_cast( getWorld( smServerWorldName ) ); - if ( world ) - { - ret = world->getEnabled(); - return ret; - } - - return ret; -} - -void PxPlugin::enableSimulation( const String &worldName, bool enable ) -{ - PxWorld *world = static_cast( getWorld( worldName ) ); - if ( world ) - world->setEnabled( enable ); -} - -void PxPlugin::setTimeScale( const F32 timeScale ) -{ - // Grab both the client and - // server worlds and set their time - // scales to the passed value. - PxWorld *world = static_cast( getWorld( smClientWorldName ) ); - if ( world ) - world->setEditorTimeScale( timeScale ); - - world = static_cast( getWorld( smServerWorldName ) ); - if ( world ) - world->setEditorTimeScale( timeScale ); -} - -const F32 PxPlugin::getTimeScale() const -{ - // Grab both the client and - // server worlds and call - // setEnabled( true ) on them. - PxWorld *world = static_cast( getWorld( smClientWorldName ) ); - if ( !world ) - { - world = static_cast( getWorld( smServerWorldName ) ); - if ( !world ) - return 0.0f; - } - - return world->getEditorTimeScale(); -} - -bool PxPlugin::createWorld( const String &worldName ) -{ - Map::Iterator iter = mPhysicsWorldLookup.find( worldName ); - PhysicsWorld *world = NULL; - - iter != mPhysicsWorldLookup.end() ? world = (*iter).value : world = NULL; - - if ( world ) - { - Con::errorf( "PxPlugin::createWorld - %s world already exists!", worldName.c_str() ); - return false; - } - - world = new PxWorld(); - - if ( worldName.equal( smClientWorldName, String::NoCase ) ) - world->initWorld( false, ClientProcessList::get() ); - else - world->initWorld( true, ServerProcessList::get() ); - - mPhysicsWorldLookup.insert( worldName, world ); - - return world != NULL; -} - -void PxPlugin::destroyWorld( const String &worldName ) -{ - Map::Iterator iter = mPhysicsWorldLookup.find( worldName ); - if ( iter == mPhysicsWorldLookup.end() ) - return; - - PhysicsWorld *world = (*iter).value; - world->destroyWorld(); - delete world; - - mPhysicsWorldLookup.erase( iter ); -} - -PhysicsWorld* PxPlugin::getWorld( const String &worldName ) const -{ - if ( mPhysicsWorldLookup.isEmpty() ) - return NULL; - - Map::ConstIterator iter = mPhysicsWorldLookup.find( worldName ); - - return iter != mPhysicsWorldLookup.end() ? (*iter).value : NULL; -} - -PhysicsWorld* PxPlugin::getWorld() const -{ - if ( mPhysicsWorldLookup.size() == 0 ) - return NULL; - - Map::ConstIterator iter = mPhysicsWorldLookup.begin(); - return iter->value; -} - -U32 PxPlugin::getWorldCount() const -{ - return mPhysicsWorldLookup.size(); -} - -void PxPlugin::_onDebugDrawEnabled( bool enabled ) -{ - if ( !enabled ) - gPhysicsSDK->setParameter( NX_VISUALIZATION_SCALE, 0.0f ); -} - -ConsoleFunction( physXRemoteDebuggerConnect, bool, 1, 3, "" ) -{ - if ( !gPhysicsSDK ) - { - Con::errorf( "PhysX SDK not initialized!" ); - return false; - } - - NxRemoteDebugger *debugger = gPhysicsSDK->getFoundationSDK().getRemoteDebugger(); - - if ( debugger->isConnected() ) - { - Con::errorf( "RemoteDebugger already connected... call disconnect first!" ); - return false; - } - - const UTF8 *host = "localhost"; - U32 port = 5425; - - if ( argc >= 2 ) - host = argv[1]; - if ( argc >= 3 ) - port = dAtoi( argv[2] ); - - // Before we connect we need to have write access - // to both the client and server worlds. - PxWorld::releaseWriteLocks(); - - // Connect! - debugger->connect( host, port ); - if ( !debugger->isConnected() ) - { - Con::errorf( "RemoteDebugger failed to connect!" ); - return false; - } - - Con::printf( "RemoteDebugger connected to %s at port %u!", host, port ); - return true; -} - -ConsoleFunction( physXRemoteDebuggerDisconnect, void, 1, 1, "" ) -{ - if ( !gPhysicsSDK ) - { - Con::errorf( "PhysX SDK not initialized!" ); - return; - } - - NxRemoteDebugger *debugger = gPhysicsSDK->getFoundationSDK().getRemoteDebugger(); - - if ( debugger->isConnected() ) - { - debugger->flush(); - debugger->disconnect(); - Con::printf( "RemoteDebugger disconnected!" ); - } -} diff --git a/Engine/source/T3D/physics/physx/pxPlugin.h b/Engine/source/T3D/physics/physx/pxPlugin.h deleted file mode 100644 index c32c1162c..000000000 --- a/Engine/source/T3D/physics/physx/pxPlugin.h +++ /dev/null @@ -1,59 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _T3D_PHYSICS_PXPLUGIN_H_ -#define _T3D_PHYSICS_PXPLUGIN_H_ - -#ifndef _T3D_PHYSICS_PHYSICSPLUGIN_H_ -#include "T3D/physics/physicsPlugin.h" -#endif - - -class PxPlugin : public PhysicsPlugin -{ -public: - - PxPlugin(); - ~PxPlugin(); - - /// Create function for factory. - static PhysicsPlugin* create(); - - // PhysicsPlugin - virtual void destroyPlugin(); - virtual void reset(); - virtual PhysicsCollision* createCollision(); - virtual PhysicsBody* createBody(); - virtual PhysicsPlayer* createPlayer(); - virtual bool isSimulationEnabled() const; - virtual void enableSimulation( const String &worldName, bool enable ); - virtual void setTimeScale( const F32 timeScale ); - virtual const F32 getTimeScale() const; - virtual bool createWorld( const String &worldName ); - virtual void destroyWorld( const String &worldName ); - virtual PhysicsWorld* getWorld( const String &worldName ) const; - virtual PhysicsWorld* getWorld() const; - virtual U32 getWorldCount() const; - virtual void _onDebugDrawEnabled( bool enabled ); -}; - -#endif // _T3D_PHYSICS_PXPLUGIN_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxStream.cpp b/Engine/source/T3D/physics/physx/pxStream.cpp deleted file mode 100644 index 6c7565ee6..000000000 --- a/Engine/source/T3D/physics/physx/pxStream.cpp +++ /dev/null @@ -1,174 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxStream.h" - -#include "console/console.h" -#include "console/consoleTypes.h" -#include "core/strings/stringFunctions.h" - - -PxMemStream::PxMemStream() - : mMemStream( 1024 ) -{ -} - -PxMemStream::~PxMemStream() -{ -} - -void PxMemStream::resetPosition() -{ - mMemStream.setPosition( 0 ); -} - -NxU8 PxMemStream::readByte() const -{ - NxU8 out; - mMemStream.read( &out ); - return out; -} - -NxU16 PxMemStream::readWord() const -{ - NxU16 out; - mMemStream.read( &out ); - return out; -} - -NxU32 PxMemStream::readDword() const -{ - NxU32 out; - mMemStream.read( &out ); - return out; -} - -float PxMemStream::readFloat() const -{ - float out; - mMemStream.read( &out ); - return out; -} - -double PxMemStream::readDouble() const -{ - double out; - mMemStream.read( &out ); - return out; -} - -void PxMemStream::readBuffer( void *buffer, NxU32 size ) const -{ - mMemStream.read( size, buffer ); -} - -NxStream& PxMemStream::storeByte( NxU8 b ) -{ - mMemStream.write( b ); - return *this; -} - -NxStream& PxMemStream::storeWord( NxU16 w ) -{ - mMemStream.write( w ); - return *this; -} - -NxStream& PxMemStream::storeDword( NxU32 d ) -{ - mMemStream.write( d ); - return *this; -} - -NxStream& PxMemStream::storeFloat( NxReal f ) -{ - mMemStream.write( f ); - return *this; -} - -NxStream& PxMemStream::storeDouble( NxF64 f ) -{ - mMemStream.write( f ); - return *this; -} - -NxStream& PxMemStream::storeBuffer( const void *buffer, NxU32 size ) -{ - mMemStream.write( size, buffer ); - return *this; -} - - -bool gPhysXLogWarnings = false; - -PxConsoleStream::PxConsoleStream() -{ -} - -PxConsoleStream::~PxConsoleStream() -{ -} - -void PxConsoleStream::reportError( NxErrorCode code, const char *message, const char* file, int line ) -{ - #ifdef TORQUE_DEBUG - - // If we're in debug mode and the error code is serious then - // pop up a message box to make sure we see it. - if ( code < NXE_DB_INFO ) - { - UTF8 info[1024]; - dSprintf( info, 1024, "File: %s\nLine: %d\n%s", file, line, message ); - Platform::AlertOK( "PhysX Error", info ); - } - - #endif - - // In all other cases we just dump the message to the console. - if ( code == NXE_DB_WARNING ) - { - if ( gPhysXLogWarnings ) - Con::printf( "PhysX Warning:\n %s(%d) : %s\n", file, line, message ); - } - else - Con::printf( "PhysX Error:\n %s(%d) : %s\n", file, line, message ); -} - -NxAssertResponse PxConsoleStream::reportAssertViolation (const char *message, const char *file,int line) -{ - // Assert if we're in debug mode... - bool triggerBreak = false; - #ifdef TORQUE_DEBUG - triggerBreak = PlatformAssert::processAssert( PlatformAssert::Fatal, file, line, message ); - #endif - - // In all other cases we just dump the message to the console. - Con::errorf( "PhysX Assert:\n %s(%d) : %s\n", file, line, message ); - - return triggerBreak ? NX_AR_BREAKPOINT : NX_AR_CONTINUE; -} - -void PxConsoleStream::print( const char *message ) -{ - Con::printf( "PhysX Says: %s\n", message ); -} diff --git a/Engine/source/T3D/physics/physx/pxStream.h b/Engine/source/T3D/physics/physx/pxStream.h deleted file mode 100644 index 8dc875fa3..000000000 --- a/Engine/source/T3D/physics/physx/pxStream.h +++ /dev/null @@ -1,78 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _T3D_PHYSICS_PXSTREAM_H_ -#define _T3D_PHYSICS_PXSTREAM_H_ - -#ifndef _PHYSX_H_ -#include "T3D/physics/physX/px.h" -#endif -#ifndef _MEMSTREAM_H_ -#include "core/stream/memStream.h" -#endif - - -class PxMemStream : public NxStream -{ -public: - - PxMemStream(); - virtual ~PxMemStream(); - - void resetPosition(); - - // NxStream - NxU8 readByte() const; - NxU16 readWord() const; - NxU32 readDword() const; - float readFloat() const; - double readDouble() const; - void readBuffer( void *buffer, NxU32 size ) const; - NxStream& storeByte( NxU8 b ); - NxStream& storeWord( NxU16 w ); - NxStream& storeDword( NxU32 d ); - NxStream& storeFloat( NxReal f ); - NxStream& storeDouble( NxF64 f ); - NxStream& storeBuffer( const void* buffer, NxU32 size ); - -protected: - - mutable MemStream mMemStream; -}; - - -class PxConsoleStream : public NxUserOutputStream -{ -protected: - - // NxUserOutputStream - void reportError( NxErrorCode code, const char *message, const char* file, int line ); - NxAssertResponse reportAssertViolation( const char *message, const char *file, int line ); - void print( const char *message ); - -public: - - PxConsoleStream(); - ~PxConsoleStream(); -}; - -#endif // _T3D_PHYSICS_PXSTREAM_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxUtils.cpp b/Engine/source/T3D/physics/physx/pxUtils.cpp deleted file mode 100644 index 05671806f..000000000 --- a/Engine/source/T3D/physics/physx/pxUtils.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physx/pxUtils.h" - -#include "gfx/gfxTransformSaver.h" -#include "gfx/gfxDrawUtil.h" -#include "math/mMatrix.h" -#include "math/mPoint3.h" -#include "T3D/physics/physX/px.h" -#include "T3D/physics/physX/pxCasts.h" - -namespace PxUtils { - -void drawActor( NxActor *inActor ) -{ - GFXDrawUtil *drawer = GFX->getDrawUtil(); - //drawer->setZRead( false ); - - // Determine alpha we render shapes with. - const U8 enabledAlpha = 255; - const U8 disabledAlpha = 100; - U8 renderAlpha = inActor->readActorFlag( NX_AF_DISABLE_COLLISION ) ? disabledAlpha : enabledAlpha; - - // Determine color we render actors and shapes with. - ColorI actorColor( 0, 0, 255, 200 ); - ColorI shapeColor = ( inActor->isSleeping() ? ColorI( 0, 0, 255, renderAlpha ) : ColorI( 255, 0, 255, renderAlpha ) ); - - MatrixF actorMat(true); - inActor->getGlobalPose().getRowMajor44( actorMat ); - - GFXStateBlockDesc desc; - desc.setBlend( true ); - desc.setZReadWrite( true, false ); - desc.setCullMode( GFXCullNone ); - - // Draw an xfm gizmo for the actor's globalPose... - //drawer->drawTransform( desc, actorMat, Point3F::One, actorColor ); - - // Loop through and render all the actor's shapes.... - - NxShape *const*pShapeArray = inActor->getShapes(); - U32 numShapes = inActor->getNbShapes(); - - for ( U32 i = 0; i < numShapes; i++ ) - { - const NxShape *shape = pShapeArray[i]; - - Point3F shapePos = pxCast( shape->getGlobalPosition() ); - MatrixF shapeMat(true); - shape->getGlobalPose().getRowMajor44(shapeMat); - shapeMat.setPosition( Point3F::Zero ); - - switch ( shape->getType() ) - { - case NX_SHAPE_SPHERE: - { - NxSphereShape *sphere = (NxSphereShape*)shape; - drawer->drawSphere( desc, sphere->getRadius(), shapePos, shapeColor ); - - break; - } - case NX_SHAPE_BOX: - { - NxBoxShape *box = (NxBoxShape*)shape; - Point3F size = pxCast( box->getDimensions() ); - drawer->drawCube( desc, size*2, shapePos, shapeColor, &shapeMat ); - break; - } - case NX_SHAPE_CAPSULE: - { - shapeMat.mul( MatrixF( EulerF( mDegToRad(90.0f), mDegToRad(90.0f), 0 ) ) ); - - NxCapsuleShape *capsule = (NxCapsuleShape*)shape; - drawer->drawCapsule( desc, shapePos, capsule->getRadius(), capsule->getHeight(), shapeColor, &shapeMat ); - - break; - } - default: - { - break; - } - } - } - - //drawer->clearZDefined(); -} - -} // namespace PxUtils \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxUtils.h b/Engine/source/T3D/physics/physx/pxUtils.h deleted file mode 100644 index 1c1d9873b..000000000 --- a/Engine/source/T3D/physics/physx/pxUtils.h +++ /dev/null @@ -1,38 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PXUTILS_H_ -#define _PXUTILS_H_ - - -class NxActor; - - -namespace PxUtils { - - /// Debug render an actor, loops through all shapes - /// and translates primitive types into drawUtil calls. - void drawActor( NxActor *inActor ); - -} // namespace PxUtils - -#endif // _PXUTILS_H_ \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx/pxWorld.cpp b/Engine/source/T3D/physics/physx/pxWorld.cpp deleted file mode 100644 index 0ec3d7fea..000000000 --- a/Engine/source/T3D/physics/physx/pxWorld.cpp +++ /dev/null @@ -1,876 +0,0 @@ -//----------------------------------------------------------------------------- -// 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. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "T3D/physics/physX/pxWorld.h" - -#include "T3D/physics/physX/px.h" -#include "T3D/physics/physX/pxPlugin.h" -#include "T3D/physics/physX/pxMaterial.h" -#include "T3D/physics/physX/pxContactReporter.h" -#include "T3D/physics/physX/pxStream.h" -#include "T3D/physics/physX/pxCasts.h" -#include "T3D/physics/physicsUserData.h" - -#include "core/stream/bitStream.h" -#include "platform/profiler.h" -#include "sim/netConnection.h" -#include "console/console.h" -#include "console/consoleTypes.h" -#include "core/util/safeDelete.h" -#include "T3D/tsstatic.h" -#include "T3D/gameBase/gameProcess.h" -#include "gfx/sim/debugDraw.h" -#include "gfx/primBuilder.h" - -#include - - -static const F32 PhysicsStepTime = (F32)TickMs / 1000.0f; -static const U32 PhysicsMaxIterations = 8; -static const F32 PhysicsMaxTimeStep = PhysicsStepTime / 2.0f; - -NxPhysicsSDK *gPhysicsSDK = NULL; -NxCookingInterface *PxWorld::smCooking = NULL; -PxConsoleStream *PxWorld::smConsoleStream = NULL; - - -PxWorld::PxWorld() : - mScene( NULL ), - mConactReporter( NULL ), - mProcessList( NULL ), - mIsSimulating( false ), - mErrorReport( false ), - mTickCount( 0 ), - mIsEnabled( false ), - mEditorTimeScale( 1.0f ) -{ - if ( !CCTAllocator::mAllocator ) - CCTAllocator::mAllocator = new NxUserAllocatorDefault(); - mControllerManager = new CharacterControllerManager( CCTAllocator::mAllocator ); -} - -PxWorld::~PxWorld() -{ - delete mControllerManager; -} - -NxCookingInterface* PxWorld::getCooking() -{ - if ( !smCooking ) - smCooking = NxGetCookingLib( NX_PHYSICS_SDK_VERSION ); - - return smCooking; -} - -bool PxWorld::_init( bool isServer, ProcessList *processList ) -{ - if ( !gPhysicsSDK ) - { - Con::errorf( "PhysXWorld::init - PhysXSDK not initialized!" ); - return false; - } - - // Create the scene description. - NxSceneDesc sceneDesc; - sceneDesc.userData = this; - - // Set up default gravity. - sceneDesc.gravity.set( mGravity.x, mGravity.y, mGravity.z ); - - // The master scene is always on the CPU and is used - // mostly for static shapes. - sceneDesc.simType = NX_SIMULATION_SW; // [9/28/2009 Pat] Why is this software? Should be software server, hardware client? - - // Threading... seems to improve performance. - // - // TODO: I was getting random crashes in debug when doing - // edit and continue... lets see if i still get them with - // the threading disabled. - // - sceneDesc.flags |= NX_SF_ENABLE_MULTITHREAD | NX_SF_DISABLE_SCENE_MUTEX; - sceneDesc.threadMask = 0xfffffffe; - sceneDesc.internalThreadCount = PHYSICSMGR->getThreadCount(); - - // Create the scene. - mScene = gPhysicsSDK->createScene(sceneDesc); - if ( !mScene ) - { - Con::errorf( "PhysXWorld - %s world createScene returned a null scene!", isServer ? "Server" : "Client" ); - return false; - } - - /* - // Make note of what we've created. - String simType = sceneDesc.simType == NX_SIMULATION_SW ? "software" : "hardware"; - String clientOrServer = this == isServer ? "server" : "client"; - Con::printf( "PhysXWorld::init() - Created %s %s simulation!", - clientOrServer.c_str(), - simType.c_str() ); - */ - - mScene->setTiming( PhysicsMaxTimeStep, PhysicsMaxIterations, NX_TIMESTEP_FIXED ); - - // TODO: Add dummy actor with scene name! - - // Set the global contact reporter. - - mConactReporter = new PxContactReporter(); - mScene->setUserContactReport( mConactReporter ); - - // Set the global PxUserNotify - - mUserNotify = new PxUserNotify(); - mScene->setUserNotify( mUserNotify ); - - // Now create the dynamic rigid body compartment which - // can reside on the hardware when hardware is present. - /* - NxCompartmentDesc compartmentDesc; - compartmentDesc.type = NX_SCT_RIGIDBODY; - compartmentDesc.deviceCode = NX_DC_PPU_AUTO_ASSIGN; - mRigidCompartment = mScene->createCompartment( compartmentDesc ); - if ( !mRigidCompartment ) - { - Con::errorf( "PhysXWorld - Creation of rigid body compartment failed!" ); - return false; - } - */ - - // Hook up the tick processing signals for advancing physics. - // - // First an overview of how physics and the game ticks - // interact with each other. - // - // In Torque you normally tick the server and then the client - // approximately every 32ms. So before the game tick we call - // getPhysicsResults() to get the new physics state and call - // tickPhysics() when the game tick is done to start processing - // the next physics state. This means PhysX is happily doing - // physics in a separate thread while we're doing rendering, - // sound, input, networking, etc. - // - // Because your frame rate is rarely perfectly even you can - // get cases where you may tick the server or the client - // several times in a row. This happens most often in debug - // mode, but can also happen in release. - // - // The simple implementation is to do a getPhysicsResults() and - // tickPhysics() for each tick. But this very bad! It forces - // immediate results from PhysX which blocks the primary thread - // and further slows down processing. It leads to slower and - // slower frame rates as the simulation is never able to catch - // up to the current tick. - // - // The trick is processing physics once for backlogged ticks - // with the total of the elapsed tick time. This is a huge - // performance gain and keeps you from blocking on PhysX. - // - // This does have a side effect that when it occurs you'll get - // ticks where the physics state hasn't advanced, but this beats - // single digit frame rates. - // - AssertFatal( processList, "PxWorld::init() - We need a process list to create the world!" ); - mProcessList = processList; - mProcessList->preTickSignal().notify( this, &PxWorld::getPhysicsResults ); - mProcessList->postTickSignal().notify( this, &PxWorld::tickPhysics, 1000.0f ); - - // Setup the default material. - NxMaterial *dmat = mScene->getMaterialFromIndex( 0 ); - dmat->setRestitution( 0.2f ); - dmat->setStaticFriction( 0.6f ); - dmat->setDynamicFriction( 0.4f ); - - // Setup dominance groups. - - // Group 31 is for debris and other objects which can be pushed but cannot push back. - // Group 0 is for everything else. - - NxConstraintDominance debrisDominance( 0.0f, 1.0f ); - mScene->setDominanceGroupPair( 0, 31, debrisDominance ); - - return true; -} - -void PxWorld::_destroy() -{ - // Make sure the simulation is stopped! - getPhysicsResults(); - _releaseQueues(); - - #ifdef TORQUE_DEBUG - - U32 actorCount = mScene->getNbActors(); - U32 jointCount = mScene->getNbJoints(); - - if ( actorCount != 0 || jointCount != 0 ) - { - // Dump the names of any actors or joints that - // were not released before the destruction of - // this scene. - - for ( U32 i=0; i < actorCount; i++ ) - { - const NxActor *actor = mScene->getActors()[i]; - Con::errorf( "Orphan NxActor - '%s'!", actor->getName() ); - } - - mScene->resetJointIterator(); - for ( ;; ) - { - const NxJoint *joint = mScene->getNextJoint(); - if ( !joint ) - break; - - Con::errorf( "Orphan NxJoint - '%s'!", joint->getName() ); - } - - AssertFatal( false, "PhysXWorld::_destroy() - Some actors and/or joints were not released!" ); - } - - #endif // TORQUE_DEBUG - - //NxCloseCooking(); - - // Release the tick processing signals. - if ( mProcessList ) - { - mProcessList->preTickSignal().remove( this, &PxWorld::getPhysicsResults ); - mProcessList->postTickSignal().remove( this, &PxWorld::tickPhysics ); - mProcessList = NULL; - } - - // Destroy the scene. - if ( mScene ) - { - // Delete the contact reporter. - mScene->setUserContactReport( NULL ); - SAFE_DELETE( mConactReporter ); - - // First shut down threads... this makes it - // safe to release the scene. - mScene->shutdownWorkerThreads(); - - // Release the scene. - gPhysicsSDK->releaseScene( *mScene ); - mScene = NULL; - } - - // Try to restart the sdk if we can. - //restartSDK(); -} - -bool PxWorld::restartSDK( bool destroyOnly, PxWorld *clientWorld, PxWorld *serverWorld ) -{ - // If either the client or the server still exist - // then we cannot reset the SDK. - if ( clientWorld || serverWorld ) - return false; - - // Destroy the existing SDK. - if ( gPhysicsSDK ) - { - NXU::releasePersistentMemory(); - gPhysicsSDK->release(); - gPhysicsSDK = NULL; - smCooking = NULL; - SAFE_DELETE( smConsoleStream ); - } - - // If we're not supposed to restart... return. - if ( destroyOnly ) - return true; - - smConsoleStream = new PxConsoleStream(); - - NxPhysicsSDKDesc sdkDesc; - sdkDesc.flags |= NX_SDKF_NO_HARDWARE; // [9/28/2009 Pat] Why is this disabled? - - NxSDKCreateError error; - gPhysicsSDK = NxCreatePhysicsSDK( NX_PHYSICS_SDK_VERSION, - NULL, - smConsoleStream, - sdkDesc, - &error ); - if ( !gPhysicsSDK ) - { - Con::errorf( "PhysX failed to initialize! Error code: %d", error ); - Platform::messageBox( Con::getVariable( "$appName" ), - avar("PhysX could not be started!\r\n" - "Please be sure you have the latest version of PhysX installed.\r\n" - "Error Code: %d", error), - MBOk, MIStop ); - Platform::forceShutdown( -1 ); - - // We shouldn't get here, but this shuts up - // source diagnostic tools. - return false; - } - - // Set the default skin width for all actors. - gPhysicsSDK->setParameter( NX_SKIN_WIDTH, 0.01f ); - - return true; -} - -void PxWorld::tickPhysics( U32 elapsedMs ) -{ - if ( !mScene || !mIsEnabled ) - return; - - // Did we forget to call getPhysicsResults somewhere? - AssertFatal( !mIsSimulating, "PhysXWorld::tickPhysics() - Already simulating!" ); - - // The elapsed time should be non-zero and - // a multiple of TickMs! - AssertFatal( elapsedMs != 0 && - ( elapsedMs % TickMs ) == 0 , "PhysXWorld::tickPhysics() - Got bad elapsed time!" ); - - PROFILE_SCOPE(PxWorld_TickPhysics); - - // Convert it to seconds. - const F32 elapsedSec = (F32)elapsedMs * 0.001f; - - // For some reason this gets reset all the time - // and it must be called before the simulate. - mScene->setFilterOps( NX_FILTEROP_OR, - NX_FILTEROP_OR, - NX_FILTEROP_AND ); - mScene->setFilterBool( false ); - NxGroupsMask zeroMask; - zeroMask.bits0=zeroMask.bits1=zeroMask.bits2=zeroMask.bits3=0; - mScene->setFilterConstant0( zeroMask ); - mScene->setFilterConstant1( zeroMask ); - - mScene->simulate( elapsedSec * mEditorTimeScale ); - mScene->flushStream(); - mIsSimulating = true; - - //Con::printf( "%s PhysXWorld::tickPhysics!", this == smClientWorld ? "Client" : "Server" ); -} - -void PxWorld::releaseWriteLocks() -{ - PxWorld *world = dynamic_cast( PHYSICSMGR->getWorld( "server" ) ); - - if ( world ) - world->releaseWriteLock(); - - world = dynamic_cast( PHYSICSMGR->getWorld( "client" ) ); - - if ( world ) - world->releaseWriteLock(); -} - -void PxWorld::releaseWriteLock() -{ - if ( !mScene || !mIsSimulating ) - return; - - PROFILE_SCOPE(PxWorld_ReleaseWriteLock); - - // We use checkResults here to release the write lock - // but we do not change the simulation flag or increment - // the tick count... we may have gotten results, but the - // simulation hasn't really ticked! - mScene->checkResults( NX_RIGID_BODY_FINISHED, true ); - AssertFatal( mScene->isWritable(), "PhysXWorld::releaseWriteLock() - We should have been writable now!" ); -} - -void PxWorld::getPhysicsResults() -{ - if ( !mScene || !mIsSimulating ) - return; - - PROFILE_SCOPE(PxWorld_GetPhysicsResults); - - // Get results from scene. - mScene->fetchResults( NX_RIGID_BODY_FINISHED, true ); - mIsSimulating = false; - mTickCount++; - - // Release any joints/actors that were waiting - // for the scene to become writable. - _releaseQueues(); - - //Con::printf( "%s PhysXWorld::getPhysicsResults!", this == smClientWorld ? "Client" : "Server" ); -} - -NxMaterial* PxWorld::createMaterial( NxMaterialDesc &material ) -{ - if ( !mScene ) - return NULL; - - // We need the writelock to create a material! - releaseWriteLock(); - - NxMaterial *mat = mScene->createMaterial( material ); - if ( !mat ) - return NULL; - - return mat; -} - -NxController* PxWorld::createController( NxControllerDesc &desc ) -{ - if ( !mScene ) - return NULL; - - // We need the writelock! - releaseWriteLock(); - - return mControllerManager->createController( mScene, desc ); -} - -void PxWorld::releaseActor( NxActor &actor ) -{ - AssertFatal( &actor.getScene() == mScene, "PhysXWorld::releaseActor() - Bad scene!" ); - - // Clear the userdata. - actor.userData = NULL; - - // actors are one of the few objects that are stable removing this way in physx 2.8 - if (mScene->isWritable() ) - { - mScene->releaseActor( actor ); - } - else - { - mReleaseActorQueue.push_back( &actor ); - } -} - -void PxWorld::releaseMaterial( NxMaterial &mat ) -{ - AssertFatal( &mat.getScene() == mScene, "PhysXWorld::releaseMaterial() - Bad scene!" ); - - // If the scene is not simulating then we have the - // write lock and can safely delete it now. - if ( !mIsSimulating ) - mScene->releaseMaterial( mat ); - else - mReleaseMaterialQueue.push_back( &mat ); -} - -void PxWorld::releaseHeightField( NxHeightField &heightfield ) -{ - // Always delay releasing a heightfield, for whatever reason, - // it causes lots of deadlock asserts if we do it here, even if - // the scene "says" its writable. - // - // Actually this is probably because a heightfield is owned by the "sdk" and - // not an individual scene so if either the client "or" server scene are - // simulating it asserts, thats just my theory. - - mReleaseHeightFieldQueue.push_back( &heightfield ); -} - -void PxWorld::releaseJoint( NxJoint &joint ) -{ - AssertFatal( &joint.getScene() == mScene, "PhysXWorld::releaseJoint() - Bad scene!" ); - - AssertFatal( !mReleaseJointQueue.contains( &joint ), - "PhysXWorld::releaseJoint() - Joint already exists in the release queue!" ); - - // Clear the userdata. - joint.userData = NULL; - - // If the scene is not simulating then we have the - // write lock and can safely delete it now. - if ( !mIsSimulating ) - mScene->releaseJoint( joint ); - else - mReleaseJointQueue.push_back( &joint ); -} - -void PxWorld::releaseCloth( NxCloth &cloth ) -{ - AssertFatal( &cloth.getScene() == mScene, "PhysXWorld::releaseCloth() - Bad scene!" ); - - // Clear the userdata. - cloth.userData = NULL; - - // If the scene is not simulating then we have the - // write lock and can safely delete it now. - if ( !mIsSimulating ) - mScene->releaseCloth( cloth ); - else - mReleaseClothQueue.push_back( &cloth ); -} - -void PxWorld::releaseFluid( NxFluid &fluid ) -{ - AssertFatal( &fluid.getScene() == mScene, "PhysXWorld::releaseFluid() - Bad scene!" ); - - // Clear the userdata. - fluid.userData = NULL; - - // If the scene is not simulating then we have the - // write lock and can safely delete it now. - if ( !mIsSimulating ) - mScene->releaseFluid( fluid ); - else - mReleaseFluidQueue.push_back( &fluid ); -} - -void PxWorld::releaseClothMesh( NxClothMesh &clothMesh ) -{ - // We need the writelock to release. - releaseWriteLock(); - - gPhysicsSDK->releaseClothMesh( clothMesh ); -} - -void PxWorld::releaseController( NxController &controller ) -{ - // TODO: This isn't safe to do with actors and - // joints, so we probably need a queue like we - // do for them. - - // We need the writelock to release. - releaseWriteLock(); - - mControllerManager->releaseController( controller ); -} - -void PxWorld::_releaseQueues() -{ - AssertFatal( mScene, "PhysXWorld::_releaseQueues() - The scene is null!" ); - - // We release joints still pending in the queue - // first as they depend on the actors. - for ( S32 i = 0; i < mReleaseJointQueue.size(); i++ ) - { - NxJoint *currJoint = mReleaseJointQueue[i]; - mScene->releaseJoint( *currJoint ); - } - - // All the joints should be released, clear the queue. - mReleaseJointQueue.clear(); - - // Now release any actors still pending in the queue. - bool staticChanged = false; - for ( S32 i = 0; i < mReleaseActorQueue.size(); i++ ) - { - NxActor *currActor = mReleaseActorQueue[i]; - staticChanged |= !currActor->isDynamic(); - mScene->releaseActor( *currActor ); - } - - // All the actors should be released, clear the queue. - mReleaseActorQueue.clear(); - - // Now release any materials still pending in the queue. - for ( S32 i = 0; i < mReleaseMaterialQueue.size(); i++ ) - { - NxMaterial *currMat = mReleaseMaterialQueue[i]; - mScene->releaseMaterial( *currMat ); - } - - // All the materials should be released, clear the queue. - mReleaseMaterialQueue.clear(); - - // Now release any cloth still pending in the queue. - for ( S32 i = 0; i < mReleaseClothQueue.size(); i++ ) - { - NxCloth *currCloth = mReleaseClothQueue[i]; - mScene->releaseCloth( *currCloth ); - } - - // All the actors should be released, clear the queue. - mReleaseClothQueue.clear(); - - // Release heightfields that don't still have references. - for ( S32 i = 0; i < mReleaseHeightFieldQueue.size(); i++ ) - { - NxHeightField *currHeightfield = mReleaseHeightFieldQueue[i]; - - if ( currHeightfield->getReferenceCount() == 0 ) - { - gPhysicsSDK->releaseHeightField( *currHeightfield ); - mReleaseHeightFieldQueue.erase_fast( i ); - i--; - } - } - - // Clear fluid queue - for ( S32 i = 0; i < mReleaseFluidQueue.size(); i++ ) - { - NxFluid *currFluid = mReleaseFluidQueue[i]; - mScene->releaseFluid( *currFluid ); - } - mReleaseFluidQueue.clear(); - - if ( staticChanged ) - mStaticChangedSignal.trigger(); -} - -void PxWorld::setEnabled( bool enabled ) -{ - mIsEnabled = enabled; - - if ( !mIsEnabled ) - getPhysicsResults(); -} - -bool PxWorld::initWorld( bool isServer, ProcessList *processList ) -{ - /* This stuff is handled outside. - PxWorld* world = PxWorld::getWorld( isServer ); - if ( world ) - { - Con::errorf( "PhysXWorld::initWorld - %s world already exists!", isServer ? "Server" : "Client" ); - return false; - } - */ - - if ( !_init( isServer, processList ) ) - return false; - - return true; -} - -void PxWorld::destroyWorld() -{ - //PxWorld* world = PxWorld::getWorld( serverWorld ); - /* - if ( !world ) - { - Con::errorf( "PhysXWorld::destroyWorld - %s world already destroyed!", serverWorld ? "Server" : "Client" ); - return; - } - */ - //world->_destroy(); - //delete world; - - _destroy(); -} - -bool PxWorld::castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo *ri, const Point3F &impulse ) -{ - NxRay worldRay; - worldRay.orig = pxCast( startPnt ); - worldRay.dir = pxCast( endPnt - startPnt ); - NxF32 maxDist = worldRay.dir.magnitude(); - worldRay.dir.normalize(); - - U32 groups = 0xffffffff; - groups &= ~( 1<<31 ); // No trigger shapes! - - NxRaycastHit hitInfo; - NxShape *hitShape = mScene->raycastClosestShape( worldRay, NX_ALL_SHAPES, hitInfo, groups, maxDist ); - - if ( !hitShape ) - return false; - - //if ( hitShape->userData != NULL ) - // return false; - - NxActor &actor = hitShape->getActor(); - PhysicsUserData *userData = PhysicsUserData::cast( actor.userData ); - - if ( ri ) - { - ri->object = ( userData != NULL ) ? userData->getObject() : NULL; - - // If we were passed a RayInfo, we can only return true signifying a collision - // if we hit an object that actually has a torque object associated with it. - // - // In some ways this could be considered an error, either a physx object - // has raycast-collision enabled that shouldn't or someone did not set - // an object in this actor's userData. - // - if ( ri->object == NULL ) - return false; - - ri->distance = hitInfo.distance; - ri->normal = pxCast( hitInfo.worldNormal ); - ri->point = pxCast( hitInfo.worldImpact ); - ri->t = maxDist / hitInfo.distance; - } - - if ( impulse.isZero() || - !actor.isDynamic() || - actor.readBodyFlag( NX_BF_KINEMATIC ) ) - return true; - - NxVec3 force = pxCast( impulse );//worldRay.dir * forceAmt; - actor.addForceAtPos( force, hitInfo.worldImpact, NX_IMPULSE ); - - return true; -} - -PhysicsBody* PxWorld::castRay( const Point3F &start, const Point3F &end, U32 bodyTypes ) -{ - NxRay worldRay; - worldRay.orig = pxCast( start ); - worldRay.dir = pxCast( end - start ); - F32 maxDist = worldRay.dir.normalize(); - - U32 groups = 0xFFFFFFFF; - if ( !( bodyTypes & BT_Player ) ) - groups &= ~( 1<<29 ); - - // TODO: For now always skip triggers and debris, - // but we should consider how game specifc this API - // should be in the future. - groups &= ~( 1<<31 ); // triggers - groups &= ~( 1<<30 ); // debris - - U32 shapesType = 0; - if ( bodyTypes & BT_Static ) - shapesType |= NX_STATIC_SHAPES; - if ( bodyTypes & BT_Dynamic ) - shapesType |= NX_DYNAMIC_SHAPES; - - NxRaycastHit hitInfo; - NxShape *hitShape = mScene->raycastClosestShape( worldRay, (NxShapesType)shapesType, hitInfo, groups, maxDist ); - if ( !hitShape ) - return NULL; - - NxActor &actor = hitShape->getActor(); - PhysicsUserData *userData = PhysicsUserData::cast( actor.userData ); - if ( !userData ) - return NULL; - - return userData->getBody(); -} - -void PxWorld::explosion( const Point3F &pos, F32 radius, F32 forceMagnitude ) -{ - // Find Actors at the position within the radius - // and apply force to them. - - NxVec3 nxPos = pxCast( pos ); - NxShape **shapes = (NxShape**)NxAlloca(10*sizeof(NxShape*)); - NxSphere worldSphere( nxPos, radius ); - - NxU32 numHits = mScene->overlapSphereShapes( worldSphere, NX_ALL_SHAPES, 10, shapes, NULL ); - - for ( NxU32 i = 0; i < numHits; i++ ) - { - NxActor &actor = shapes[i]->getActor(); - - bool dynamic = actor.isDynamic(); - - if ( !dynamic ) - continue; - - bool kinematic = actor.readBodyFlag( NX_BF_KINEMATIC ); - - if ( kinematic ) - continue; - - NxVec3 force = actor.getGlobalPosition() - nxPos; - force.normalize(); - force *= forceMagnitude; - - actor.addForceAtPos( force, nxPos, NX_IMPULSE, true ); - } -} - -static ColorI getDebugColor( NxU32 packed ) -{ - ColorI col; - col.blue = (packed)&0xff; - col.green = (packed>>8)&0xff; - col.red = (packed>>16)&0xff; - col.alpha = 255; - - return col; -} - -void PxWorld::onDebugDraw( const SceneRenderState *state ) -{ - if ( !mScene ) - return; - - // We need the write lock to be able to request - // the NxDebugRenderable object. - releaseWriteLock(); - - // TODO: We need to expose the different types of visualization - // options to script and add a GUI for toggling them! - - gPhysicsSDK->setParameter( NX_VISUALIZATION_SCALE, 1.0f ); - //gPhysicsSDK->setParameter( NX_VISUALIZE_BODY_MASS_AXES, 0.0f ); - gPhysicsSDK->setParameter( NX_VISUALIZE_BODY_AXES, 1.0f ); - gPhysicsSDK->setParameter( NX_VISUALIZE_COLLISION_SHAPES, 1.0f ); - - const NxDebugRenderable *data = mScene->getDebugRenderable(); - if ( !data ) - return; - - // Render points - { - NxU32 numPoints = data->getNbPoints(); - const NxDebugPoint *points = data->getPoints(); - - PrimBuild::begin( GFXPointList, numPoints ); - - while ( numPoints-- ) - { - PrimBuild::color( getDebugColor(points->color) ); - PrimBuild::vertex3fv( &points->p.x ); - points++; - } - - PrimBuild::end(); - } - - // Render lines - { - NxU32 numLines = data->getNbLines(); - const NxDebugLine *lines = data->getLines(); - - PrimBuild::begin( GFXLineList, numLines * 2 ); - - while ( numLines-- ) - { - PrimBuild::color( getDebugColor( lines->color ) ); - PrimBuild::vertex3fv( &lines->p0.x ); - PrimBuild::vertex3fv( &lines->p1.x ); - lines++; - } - - PrimBuild::end(); - } - - // Render triangles - { - NxU32 numTris = data->getNbTriangles(); - const NxDebugTriangle *triangles = data->getTriangles(); - - PrimBuild::begin( GFXTriangleList, numTris * 3 ); - - while ( numTris-- ) - { - PrimBuild::color( getDebugColor( triangles->color ) ); - PrimBuild::vertex3fv( &triangles->p0.x ); - PrimBuild::vertex3fv( &triangles->p1.x ); - PrimBuild::vertex3fv( &triangles->p2.x ); - triangles++; - } - - PrimBuild::end(); - } -} diff --git a/Engine/source/T3D/physics/physx/pxWorld.h b/Engine/source/T3D/physics/physx/pxWorld.h deleted file mode 100644 index d9d570336..000000000 --- a/Engine/source/T3D/physics/physx/pxWorld.h +++ /dev/null @@ -1,193 +0,0 @@ -//----------------------------------------------------------------------------- -// 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 _PHYSX_WORLD_H_ -#define _PHYSX_WORLD_H_ - -#ifndef _T3D_PHYSICS_PHYSICSWORLD_H_ -#include "T3D/physics/physicsWorld.h" -#endif -#ifndef _MMATH_H_ -#include "math/mMath.h" -#endif -#ifndef _PHYSX_H_ -#include "T3D/physics/physX/px.h" -#endif -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif - -class PxContactReporter; -class PxUserNotify; -class NxController; -class NxControllerDesc; -class ShapeBase; -class TSStatic; -class SceneObject; -class ProcessList; -class GameBase; -class CharacterControllerManager; -class PxConsoleStream; - - -class PxWorld : public PhysicsWorld -{ -protected: - - F32 mEditorTimeScale; - - Vector mReleaseClothQueue; - Vector mReleaseJointQueue; - Vector mReleaseActorQueue; - Vector mReleaseMaterialQueue; - Vector mReleaseHeightFieldQueue; - Vector mReleaseFluidQueue; - //Vector> mReleaseColQueue; - - Vector mCatchupQueue; - - PxContactReporter *mConactReporter; - - PxUserNotify *mUserNotify; - - NxScene *mScene; - - CharacterControllerManager *mControllerManager; - - bool mErrorReport; - - bool mIsEnabled; - - bool mIsSimulating; - - U32 mTickCount; - - ProcessList *mProcessList; - - bool _init( bool isServer, ProcessList *processList ); - - void _destroy(); - - void _releaseQueues(); - - void _updateScheduledStatics(); - - /// The mesh cooking interface which is loaded on first use. - /// @see getCooking - static NxCookingInterface *smCooking; - - /// The console stream for PhysX error reporting. - static PxConsoleStream *smConsoleStream; - -public: - - // PhysicWorld - virtual bool initWorld( bool isServer, ProcessList *processList ); - virtual void destroyWorld(); - virtual bool castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo *ri, const Point3F &impulse ); - virtual PhysicsBody* castRay( const Point3F &start, const Point3F &end, U32 bodyTypes = BT_All ); - virtual void explosion( const Point3F &pos, F32 radius, F32 forceMagnitude ); - virtual void onDebugDraw( const SceneRenderState *state ); - virtual void reset() {} - virtual bool isEnabled() const { return mIsEnabled; } - - /// @name Static Methods - /// @{ - - static bool restartSDK( bool destroyOnly = false, PxWorld *clientWorld = NULL, PxWorld *serverWorld = NULL ); - - static void releaseWriteLocks(); - - /// @} - - PxWorld(); - virtual ~PxWorld(); - -public: - - NxScene* getScene() { return mScene; } - - /// Returns the cooking interface. Will only return NULL - /// in the case of a missing or bad PhysX install. - static NxCookingInterface* getCooking(); - - U32 getTick() { return mTickCount; } - - void tickPhysics( U32 elapsedMs ); - - void getPhysicsResults(); - - //void enableCatchupMode( GameBase *obj ); - - bool isWritable() const { return !mIsSimulating; /* mScene->isWritable(); */ } - - void releaseWriteLock(); - - void setEnabled( bool enabled ); - bool getEnabled() const { return mIsEnabled; } - - NxMaterial* createMaterial( NxMaterialDesc &material ); - - /// - /// @see releaseController - NxController* createController( NxControllerDesc &desc ); - - //U16 setMaterial(NxMaterialDesc &material, U16 id); - - // NOTE: This is all a mess, but its a side effect of how - // PhysX works. Many objects cannot be deleted without write - // access to the scene. Worse some objects cannot be deleted - // until their owner objects are deleted first. - // - // For these reasons we have these methods to register objects to be - // released after the Scene has been ticked. - // - // Since there is no common base to PhysX objects we're stuck with - // this list of release methods. - // - - void releaseActor( NxActor &actor ); - - void releaseMaterial( NxMaterial &mat ); - - void releaseJoint( NxJoint &joint ); - - void releaseCloth( NxCloth &cloth ); - - void releaseClothMesh( NxClothMesh &clothMesh ); - - void releaseController( NxController &controller ); - - void releaseHeightField( NxHeightField &heightfield ); - - void releaseFluid( NxFluid &fluid ); - - //void releaseCol( PxCollision *col ); - - /// Returns the contact reporter for this scene. - PxContactReporter* getContactReporter() { return mConactReporter; } - - void setEditorTimeScale( F32 timeScale ) { mEditorTimeScale = timeScale; } - const F32 getEditorTimeScale() const { return mEditorTimeScale; } -}; - -#endif // _PHYSX_WORLD_H_ From 18c906ca0924e51783f4e5c13505c7a62550053c Mon Sep 17 00:00:00 2001 From: rextimmy Date: Wed, 4 Jan 2017 17:20:43 +1000 Subject: [PATCH 10/50] Physx cmake module correction --- Tools/CMake/modules/module_physx3.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tools/CMake/modules/module_physx3.cmake b/Tools/CMake/modules/module_physx3.cmake index f58ce1970..5545120ee 100644 --- a/Tools/CMake/modules/module_physx3.cmake +++ b/Tools/CMake/modules/module_physx3.cmake @@ -141,10 +141,10 @@ addLibDebug("${PHYSX_LIBRARIES_DEBUG}") #Install dll files if( WIN32 ) # File Copy for Release - INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") - INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3CharacterKinematic${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") - INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3Common${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") - INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3Cooking${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Optimized") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Release") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3CharacterKinematic${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Release") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3Common${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Release") + INSTALL(FILES "${PHYSX3_PATH}/Bin/${PHYSX3_LIBPATH_PREFIX}/PhysX3Cooking${PHYSX3_LIBNAME_POSTFIX}.dll" DESTINATION "${projectOutDir}" CONFIGURATIONS "Release") # File Copy for Debug if(TORQUE_CPU_X32) From 714362fc607c403fca8c8b020cf59e6f472e8d1a Mon Sep 17 00:00:00 2001 From: rextimmy Date: Wed, 4 Jan 2017 19:40:22 +1000 Subject: [PATCH 11/50] Physics timing --- Engine/source/T3D/physics/bullet/btWorld.cpp | 4 ++-- Engine/source/T3D/physics/physicsWorld.cpp | 3 +++ Engine/source/T3D/physics/physicsWorld.h | 4 ++++ Engine/source/T3D/physics/physx3/px3World.cpp | 22 ++++--------------- Engine/source/T3D/physics/physx3/px3World.h | 3 --- 5 files changed, 13 insertions(+), 23 deletions(-) diff --git a/Engine/source/T3D/physics/bullet/btWorld.cpp b/Engine/source/T3D/physics/bullet/btWorld.cpp index 3b2a5777c..0ad7418b8 100644 --- a/Engine/source/T3D/physics/bullet/btWorld.cpp +++ b/Engine/source/T3D/physics/bullet/btWorld.cpp @@ -123,8 +123,8 @@ void BtWorld::tickPhysics( U32 elapsedMs ) // Convert it to seconds. const F32 elapsedSec = (F32)elapsedMs * 0.001f; - // Simulate... it is recommended to always use Bullet's default fixed timestep/ - mDynamicsWorld->stepSimulation( elapsedSec * mEditorTimeScale ); + // Simulate + mDynamicsWorld->stepSimulation( elapsedSec * mEditorTimeScale, smPhysicsMaxSubSteps, smPhysicsStepTime); mIsSimulating = true; diff --git a/Engine/source/T3D/physics/physicsWorld.cpp b/Engine/source/T3D/physics/physicsWorld.cpp index 7b1f49b3a..65b254885 100644 --- a/Engine/source/T3D/physics/physicsWorld.cpp +++ b/Engine/source/T3D/physics/physicsWorld.cpp @@ -23,6 +23,9 @@ #include "platform/platform.h" #include "T3D/physics/physicsWorld.h" +//Physics timing +F32 PhysicsWorld::smPhysicsStepTime = 1.0f / 60.f; //default 60fps +U32 PhysicsWorld::smPhysicsMaxSubSteps = 4; PhysicsWorld::PhysicsWorld() : mGravity( 0, 0, -20.0f ) // NOTE: This matches the gravity used for player objects. diff --git a/Engine/source/T3D/physics/physicsWorld.h b/Engine/source/T3D/physics/physicsWorld.h index 115c32324..a18cffb98 100644 --- a/Engine/source/T3D/physics/physicsWorld.h +++ b/Engine/source/T3D/physics/physicsWorld.h @@ -111,6 +111,10 @@ public: virtual PhysicsBody* castRay( const Point3F &start, const Point3F &end, U32 bodyTypes = BT_All ) = 0; virtual void explosion( const Point3F &pos, F32 radius, F32 forceMagnitude ) = 0; + + /// Physics timing + static F32 smPhysicsStepTime; + static U32 smPhysicsMaxSubSteps; }; diff --git a/Engine/source/T3D/physics/physx3/px3World.cpp b/Engine/source/T3D/physics/physx3/px3World.cpp index ca5be2302..0c871d0ba 100644 --- a/Engine/source/T3D/physics/physx3/px3World.cpp +++ b/Engine/source/T3D/physics/physx3/px3World.cpp @@ -50,9 +50,6 @@ physx::PxDefaultCpuDispatcher* Px3World::smCpuDispatcher=NULL; Px3ConsoleStream* Px3World::smErrorCallback = NULL; physx::PxVisualDebuggerConnection* Px3World::smPvdConnection=NULL; physx::PxDefaultAllocator Px3World::smMemoryAlloc; -//Physics timing -F32 Px3World::smPhysicsStepTime = 1.0f/(F32)TickMs; -U32 Px3World::smPhysicsMaxIterations = 4; Px3World::Px3World(): mScene( NULL ), mProcessList( NULL ), @@ -76,12 +73,6 @@ physx::PxCooking *Px3World::getCooking() return smCooking; } -void Px3World::setTiming(F32 stepTime,U32 maxIterations) -{ - smPhysicsStepTime = stepTime; - smPhysicsMaxIterations = maxIterations; -} - bool Px3World::restartSDK( bool destroyOnly, Px3World *clientWorld, Px3World *serverWorld) { // If either the client or the server still exist @@ -246,20 +237,20 @@ bool Px3World::initWorld( bool isServer, ProcessList *processList ) // Most of this borrowed from bullet physics library, see btDiscreteDynamicsWorld.cpp bool Px3World::_simulate(const F32 dt) { - int numSimulationSubSteps = 0; + S32 numSimulationSubSteps = 0; //fixed timestep with interpolation mAccumulator += dt; if (mAccumulator >= smPhysicsStepTime) { - numSimulationSubSteps = int(mAccumulator / smPhysicsStepTime); + numSimulationSubSteps = S32(mAccumulator / smPhysicsStepTime); mAccumulator -= numSimulationSubSteps * smPhysicsStepTime; } if (numSimulationSubSteps) { //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt - int clampedSimulationSteps = (numSimulationSubSteps > smPhysicsMaxIterations)? smPhysicsMaxIterations : numSimulationSubSteps; + S32 clampedSimulationSteps = (numSimulationSubSteps > smPhysicsMaxSubSteps)? smPhysicsMaxSubSteps : numSimulationSubSteps; - for (int i=0;ifetchResults(true); mScene->simulate(smPhysicsStepTime); @@ -618,8 +609,3 @@ void Px3World::onDebugDraw( const SceneRenderState *state ) } } -//set simulation timing via script -DefineEngineFunction( physx3SetSimulationTiming, void, ( F32 stepTime, U32 maxSteps ),, "Set simulation timing of the PhysX 3 plugin" ) -{ - Px3World::setTiming(stepTime,maxSteps); -} diff --git a/Engine/source/T3D/physics/physx3/px3World.h b/Engine/source/T3D/physics/physx3/px3World.h index 9556aac4b..fdec5e5a4 100644 --- a/Engine/source/T3D/physics/physx3/px3World.h +++ b/Engine/source/T3D/physics/physx3/px3World.h @@ -69,8 +69,6 @@ protected: static physx::PxProfileZoneManager* smProfileZoneManager; static physx::PxDefaultCpuDispatcher* smCpuDispatcher; static physx::PxVisualDebuggerConnection* smPvdConnection; - static F32 smPhysicsStepTime; - static U32 smPhysicsMaxIterations; F32 mAccumulator; bool _simulate(const F32 dt); @@ -103,7 +101,6 @@ public: static bool restartSDK( bool destroyOnly = false, Px3World *clientWorld = NULL, Px3World *serverWorld = NULL ); static void releaseWriteLocks(); static physx::PxCooking *getCooking(); - static void setTiming(F32 stepTime,U32 maxIterations); static void lockScenes(); static void unlockScenes(); }; From 1559e7a3d38523dccc0f724a8af1684b10bc1d43 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Thu, 5 Jan 2017 10:38:05 +1000 Subject: [PATCH 12/50] PhysicsShape applyForce function --- Engine/source/T3D/physics/bullet/btBody.cpp | 20 +++++++++++++++++++- Engine/source/T3D/physics/bullet/btBody.h | 3 ++- Engine/source/T3D/physics/physicsBody.h | 5 ++++- Engine/source/T3D/physics/physicsShape.cpp | 14 ++++++++++++++ Engine/source/T3D/physics/physicsShape.h | 1 + Engine/source/T3D/physics/physx3/px3Body.cpp | 10 ++++++++++ Engine/source/T3D/physics/physx3/px3Body.h | 1 + 7 files changed, 51 insertions(+), 3 deletions(-) diff --git a/Engine/source/T3D/physics/bullet/btBody.cpp b/Engine/source/T3D/physics/bullet/btBody.cpp index e1a84cf9f..33d0240a4 100644 --- a/Engine/source/T3D/physics/bullet/btBody.cpp +++ b/Engine/source/T3D/physics/bullet/btBody.cpp @@ -356,7 +356,7 @@ void BtBody::applyImpulse( const Point3F &origin, const Point3F &force ) mActor->activate(); } -void BtBody::applyTorque(const Point3F &torque) +void BtBody::applyTorque( const Point3F &torque ) { AssertFatal(mActor, "BtBody::applyTorque - The actor is null!"); AssertFatal(isDynamic(), "BtBody::applyTorque - This call is only for dynamics!"); @@ -367,6 +367,24 @@ void BtBody::applyTorque(const Point3F &torque) mActor->activate(); } +void BtBody::applyForce( const Point3F &force ) +{ + AssertFatal(mActor, "BtBody::applyForce - The actor is null!"); + AssertFatal(isDynamic(), "BtBody::applyForce - This call is only for dynamics!"); + + if (mCenterOfMass) + { + Point3F relForce(force); + mCenterOfMass->mulV(relForce); + mActor->applyCentralForce(btCast(relForce)); + } + else + mActor->applyCentralForce(btCast(force)); + + if (!mActor->isActive()) + mActor->activate(); +} + Box3F BtBody::getWorldBounds() { btVector3 min, max; diff --git a/Engine/source/T3D/physics/bullet/btBody.h b/Engine/source/T3D/physics/bullet/btBody.h index c93ac5393..84b7dddc0 100644 --- a/Engine/source/T3D/physics/bullet/btBody.h +++ b/Engine/source/T3D/physics/bullet/btBody.h @@ -111,7 +111,8 @@ public: F32 staticFriction ); virtual void applyCorrection( const MatrixF &xfm ); virtual void applyImpulse( const Point3F &origin, const Point3F &force ); - virtual void applyTorque(const Point3F &torque); + virtual void applyTorque( const Point3F &torque ); + virtual void applyForce( const Point3F &force ); virtual void findContact(SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects) const; virtual void moveKinematicTo(const MatrixF &xfm); diff --git a/Engine/source/T3D/physics/physicsBody.h b/Engine/source/T3D/physics/physicsBody.h index dd609cee7..28cf95d45 100644 --- a/Engine/source/T3D/physics/physicsBody.h +++ b/Engine/source/T3D/physics/physicsBody.h @@ -115,7 +115,10 @@ public: virtual void applyImpulse( const Point3F &origin, const Point3F &force ) = 0; /// - virtual void applyTorque(const Point3F &torque) = 0; + virtual void applyTorque( const Point3F &torque ) = 0; + + /// + virtual void applyForce( const Point3F &force ) = 0; virtual void findContact(SceneObject **contactObject, diff --git a/Engine/source/T3D/physics/physicsShape.cpp b/Engine/source/T3D/physics/physicsShape.cpp index c69d9458e..627b38a35 100644 --- a/Engine/source/T3D/physics/physicsShape.cpp +++ b/Engine/source/T3D/physics/physicsShape.cpp @@ -863,6 +863,12 @@ void PhysicsShape::applyTorque( const Point3F &torque ) mPhysicsRep->applyTorque( torque ); } +void PhysicsShape::applyForce( const Point3F &force ) +{ + if (mPhysicsRep && mPhysicsRep->isDynamic()) + mPhysicsRep->applyForce( force ); +} + void PhysicsShape::applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ) { if ( !mPhysicsRep || !mPhysicsRep->isDynamic() ) @@ -1193,4 +1199,12 @@ DefineEngineMethod( PhysicsShape, applyTorque, void, (Point3F torque), , "@note This value is ignored on physics shapes that are not dynamic. Wakes up the dynamic physics shape if it is sleeping.\n") { object->applyTorque( torque ); +} + +DefineEngineMethod(PhysicsShape, applyForce, void, (Point3F force), , + "@brief Add a force to a dynamic physics shape.\n\n" + "@param force to apply to the dynamic physics shape\n" + "@note This value is ignored on physics shapes that are not dynamic. Wakes up the dynamic physics shape if it is sleeping.\n") +{ + object->applyForce( force ); } \ No newline at end of file diff --git a/Engine/source/T3D/physics/physicsShape.h b/Engine/source/T3D/physics/physicsShape.h index 162a0368d..92092df64 100644 --- a/Engine/source/T3D/physics/physicsShape.h +++ b/Engine/source/T3D/physics/physicsShape.h @@ -247,6 +247,7 @@ public: void applyImpulse( const Point3F &pos, const VectorF &vec ); void applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ); void applyTorque( const Point3F &torque ); + void applyForce( const Point3F &force ); void setScale(const VectorF & scale); // GameBase diff --git a/Engine/source/T3D/physics/physx3/px3Body.cpp b/Engine/source/T3D/physics/physx3/px3Body.cpp index 708a01d0a..2d5fb46f7 100644 --- a/Engine/source/T3D/physics/physx3/px3Body.cpp +++ b/Engine/source/T3D/physics/physx3/px3Body.cpp @@ -427,6 +427,16 @@ void Px3Body::applyTorque( const Point3F &torque ) actor->addTorque( px3Cast(torque), physx::PxForceMode::eFORCE, true); } +void Px3Body::applyForce( const Point3F &force ) +{ + AssertFatal(mActor, "Px3Body::applyTorque - The actor is null!"); + + mWorld->releaseWriteLock(); + physx::PxRigidDynamic *actor = mActor->is(); + if (mIsEnabled && isDynamic()) + actor->addForce( px3Cast(force), physx::PxForceMode::eFORCE, true); +} + void Px3Body::findContact(SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects) const diff --git a/Engine/source/T3D/physics/physx3/px3Body.h b/Engine/source/T3D/physics/physx3/px3Body.h index 56713e3fb..7873293bc 100644 --- a/Engine/source/T3D/physics/physx3/px3Body.h +++ b/Engine/source/T3D/physics/physx3/px3Body.h @@ -118,6 +118,7 @@ public: virtual void applyCorrection( const MatrixF &xfm ); virtual void applyImpulse( const Point3F &origin, const Point3F &force ); virtual void applyTorque( const Point3F &torque ); + virtual void applyForce( const Point3F &force ); virtual void findContact(SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects) const; virtual void moveKinematicTo(const MatrixF &xfm); From 233771dcdc449ea6d33886cc61d368ab91c95a63 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Thu, 5 Jan 2017 17:39:10 -0500 Subject: [PATCH 13/50] Don't use the register keyword with modern compilers, they know better than you (and complain that it's deprecated to boot --- Engine/source/console/CMDscan.cpp | 42 +++++++++++++++---------------- Engine/source/console/CMDscan.l | 2 +- Engine/source/console/cmdgram.cpp | 20 +++++++-------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Engine/source/console/CMDscan.cpp b/Engine/source/console/CMDscan.cpp index 98f31fa3c..6aedd587f 100644 --- a/Engine/source/console/CMDscan.cpp +++ b/Engine/source/console/CMDscan.cpp @@ -774,9 +774,9 @@ YY_MALLOC_DECL YY_DECL { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; #line 105 "CMDscan.l" @@ -823,7 +823,7 @@ YY_DECL yy_match: do { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { yy_last_accepting_state = yy_current_state; @@ -1048,7 +1048,7 @@ case 37: YY_RULE_SETUP #line 143 "CMDscan.l" { /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */ - register int c = 0, l; + int c = 0, l; for ( ; ; ) { l = c; @@ -1430,9 +1430,9 @@ case YY_STATE_EOF(INITIAL): static int yy_get_next_buffer() { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; + char *dest = yy_current_buffer->yy_ch_buf; + char *source = yytext_ptr; + int number_to_move, i; int ret_val; if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) @@ -1560,14 +1560,14 @@ static int yy_get_next_buffer() static yy_state_type yy_get_previous_state() { - register yy_state_type yy_current_state; - register char *yy_cp; + yy_state_type yy_current_state; + char *yy_cp; yy_current_state = yy_start; for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yy_last_accepting_state = yy_current_state; @@ -1599,10 +1599,10 @@ static yy_state_type yy_try_NUL_trans( yy_current_state ) yy_state_type yy_current_state; #endif { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; + int yy_is_jam; + char *yy_cp = yy_c_buf_p; - register YY_CHAR yy_c = 1; + YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yy_last_accepting_state = yy_current_state; @@ -1623,14 +1623,14 @@ yy_state_type yy_current_state; #ifndef YY_NO_UNPUT #ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) +static void yyunput( int c, char *yy_bp ) #else static void yyunput( c, yy_bp ) int c; -register char *yy_bp; +char *yy_bp; #endif { - register char *yy_cp = yy_c_buf_p; + char *yy_cp = yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yy_hold_char; @@ -1638,10 +1638,10 @@ register char *yy_bp; if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ + int number_to_move = yy_n_chars + 2; + char *dest = &yy_current_buffer->yy_ch_buf[ yy_current_buffer->yy_buf_size + 2]; - register char *source = + char *source = &yy_current_buffer->yy_ch_buf[number_to_move]; while ( source > yy_current_buffer->yy_ch_buf ) @@ -2095,7 +2095,7 @@ yyconst char *s2; int n; #endif { - register int i; + int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } diff --git a/Engine/source/console/CMDscan.l b/Engine/source/console/CMDscan.l index 4464fb5f4..d9b92b6d2 100644 --- a/Engine/source/console/CMDscan.l +++ b/Engine/source/console/CMDscan.l @@ -141,7 +141,7 @@ HEXDIGIT [a-fA-F0-9] "SPC" { CMDlval.i = MakeToken< int >( ' ', lineIndex ); return '@'; } "@" { CMDlval.i = MakeToken< int >( 0, lineIndex ); return '@'; } "/*" { /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */ - register int c = 0, l; + int c = 0, l; for ( ; ; ) { l = c; diff --git a/Engine/source/console/cmdgram.cpp b/Engine/source/console/cmdgram.cpp index c7aeaa095..064394aaa 100644 --- a/Engine/source/console/cmdgram.cpp +++ b/Engine/source/console/cmdgram.cpp @@ -1288,9 +1288,9 @@ __yy_memcpy (from, to, count) char *to; int count; { - register char *f = from; - register char *t = to; - register int i = count; + char *f = from; + char *t = to; + int i = count; while (i-- > 0) *t++ = *f++; @@ -1303,9 +1303,9 @@ __yy_memcpy (from, to, count) static void __yy_memcpy (char *from, char *to, int count) { - register char *f = from; - register char *t = to; - register int i = count; + char *f = from; + char *t = to; + int i = count; while (i-- > 0) *t++ = *f++; @@ -1333,10 +1333,10 @@ int yyparse(YYPARSE_PARAM) YYPARSE_PARAM_DECL { - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; + int yystate; + int yyn; + short *yyssp; + YYSTYPE *yyvsp; int yyerrstatus; /* number of tokens to shift before error messages enabled */ int yychar1 = 0; /* lookahead token as an internal (translated) token number */ From cd98ee730ffd2e0471e746ae22e6f1927cb2e5e7 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Thu, 5 Jan 2017 20:00:33 -0500 Subject: [PATCH 14/50] Matched up platform semaphore declarations --- Engine/source/platformSDL/threads/semaphore.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Engine/source/platformSDL/threads/semaphore.cpp b/Engine/source/platformSDL/threads/semaphore.cpp index b31cb3688..af9141e87 100644 --- a/Engine/source/platformSDL/threads/semaphore.cpp +++ b/Engine/source/platformSDL/threads/semaphore.cpp @@ -25,8 +25,9 @@ #include #include -struct PlatformSemaphore +class PlatformSemaphore { +public: SDL_sem *semaphore; PlatformSemaphore(S32 initialCount) From 609b3783695e1f0486297a34348ca7e052767be0 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Thu, 5 Jan 2017 20:01:52 -0500 Subject: [PATCH 15/50] The wrong array was being indexed, and the type checker didn't catch it because it was a variadic function --- Engine/source/sfx/sfxController.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/source/sfx/sfxController.cpp b/Engine/source/sfx/sfxController.cpp index 76a5c1d45..f5f17dfb6 100644 --- a/Engine/source/sfx/sfxController.cpp +++ b/Engine/source/sfx/sfxController.cpp @@ -324,8 +324,8 @@ void SFXController::_printInsn( Insn& insn) Con::printf( "[SFXController] ip=%d: slot=%d: state=%s: Delay %f:%f:%f", mIp, insn.mSlotIndex, insn.mState ? insn.mState->getName() : "", insn.mArg.mDelayTime.mValue[ 0 ], - insn.mArg.mDelayTime.mVariance[ 0 ], - insn.mArg.mDelayTime.mVariance[ 1 ] + insn.mArg.mDelayTime.mVariance[ 0 ][ 0 ], + insn.mArg.mDelayTime.mVariance[ 0 ][ 1 ] ); break; From 5a53fe731169790892340d6fa10c763924066557 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Thu, 5 Jan 2017 22:48:23 -0500 Subject: [PATCH 16/50] Started variadic templates in engine API --- Engine/source/console/engineAPI.h | 1345 ++--------------------------- 1 file changed, 59 insertions(+), 1286 deletions(-) diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index c2b940f01..a0b9d8900 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -23,6 +23,9 @@ #ifndef _ENGINEAPI_H_ #define _ENGINEAPI_H_ +#include +#include + #ifndef _CONSOLETYPES_H_ #include "console/consoleTypes.h" #endif @@ -333,953 +336,19 @@ struct EngineUnmarshallData< ConsoleValueRef > /// @{ // Helper type to factor out commonalities between function and method trampolines. -template< typename T > -struct _EngineTrampoline -{ - struct Args {}; + + +template struct _EngineTrampoline { + struct Args {}; }; -template< typename R, typename A > -struct _EngineTrampoline< R( A ) > +template< typename R, typename ...ArgTs > +struct _EngineTrampoline< R( ArgTs ... ) > { - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - }; + typedef std::tuple Args; + std::tuple argT; }; -template< typename R, typename A, typename B > -struct _EngineTrampoline< R( A, B ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C > -struct _EngineTrampoline< R( A, B, C ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D > -struct _EngineTrampoline< R( A, B, C, D ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineTrampoline< R( A, B, C, D, E ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineTrampoline< R( A, B, C, D, E, F ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< F >::ValueType f() const - { - return EngineTypeTraits< F >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineTrampoline< R( A, B, C, D, E, F, G ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< F >::ValueType f() const - { - return EngineTypeTraits< F >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< G >::ValueType g() const - { - return EngineTypeTraits< G >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineTrampoline< R( A, B, C, D, E, F, G, H ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< F >::ValueType f() const - { - return EngineTypeTraits< F >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< G >::ValueType g() const - { - return EngineTypeTraits< G >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< H >::ValueType h() const - { - return EngineTypeTraits< H >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< F >::ValueType f() const - { - return EngineTypeTraits< F >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< G >::ValueType g() const - { - return EngineTypeTraits< G >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< H >::ValueType h() const - { - return EngineTypeTraits< H >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< I >::ValueType i() const - { - return EngineTypeTraits< I >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I, J ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< F >::ValueType f() const - { - return EngineTypeTraits< F >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< G >::ValueType g() const - { - return EngineTypeTraits< G >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< H >::ValueType h() const - { - return EngineTypeTraits< H >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< I >::ValueType i() const - { - return EngineTypeTraits< I >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< J >::ValueType j() const - { - return EngineTypeTraits< J >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< J >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I, J, K ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< K >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< F >::ValueType f() const - { - return EngineTypeTraits< F >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< G >::ValueType g() const - { - return EngineTypeTraits< G >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< H >::ValueType h() const - { - return EngineTypeTraits< H >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< I >::ValueType i() const - { - return EngineTypeTraits< I >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< J >::ValueType j() const - { - return EngineTypeTraits< J >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< J >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< K >::ValueType k() const - { - return EngineTypeTraits< K >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< K >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) ] ) ) ); - } - }; -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineTrampoline< R( A, B, C, D, E, F, G, H, I, J, K, L ) > -{ - struct Args - { - char data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< K >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< L >::ArgumentValueType ) ]; - - typename EngineTypeTraits< A >::ValueType a() const - { - return EngineTypeTraits< A >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< A >::ArgumentValueType* > - ( &data[ 0 ] ) ) ); - } - - typename EngineTypeTraits< B >::ValueType b() const - { - return EngineTypeTraits< B >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< B >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< C >::ValueType c() const - { - return EngineTypeTraits< C >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< C >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< D >::ValueType d() const - { - return EngineTypeTraits< D >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< D >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< E >::ValueType e() const - { - return EngineTypeTraits< E >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< E >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< F >::ValueType f() const - { - return EngineTypeTraits< F >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< F >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< G >::ValueType g() const - { - return EngineTypeTraits< G >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< G >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< H >::ValueType h() const - { - return EngineTypeTraits< H >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< H >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< I >::ValueType i() const - { - return EngineTypeTraits< I >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< I >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< J >::ValueType j() const - { - return EngineTypeTraits< J >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< J >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< K >::ValueType k() const - { - return EngineTypeTraits< K >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< K >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) ] ) ) ); - } - - typename EngineTypeTraits< L >::ValueType l() const - { - return EngineTypeTraits< L >::ArgumentToValue( - *( reinterpret_cast< const typename EngineTypeTraits< L >::ArgumentValueType* > - ( &data[ sizeof( typename EngineTypeTraits< A >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< B >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< C >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< D >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< E >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< F >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< G >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< H >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< I >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< J >::ArgumentValueType ) + - sizeof( typename EngineTypeTraits< K >::ArgumentValueType ) ] ) ) ); - } - }; -}; - - template< typename T > struct _EngineFunctionTrampolineBase : public _EngineTrampoline< T > { @@ -1290,125 +359,30 @@ struct _EngineFunctionTrampolineBase : public _EngineTrampoline< T > template< typename T > struct _EngineFunctionTrampoline {}; -template< typename R > -struct _EngineFunctionTrampoline< R() > : public _EngineFunctionTrampolineBase< R() > +template< typename R, typename ...ArgTs > +struct _EngineFunctionTrampoline< R(ArgTs...) > : public _EngineFunctionTrampolineBase< R(ArgTs...) > { - static R jmp( R ( *fn )(), const typename _EngineFunctionTrampolineBase< R() >::Args& args ) +private: + using Super = _EngineFunctionTrampolineBase< R(ArgTs...) >; + using ArgsType = typename Super::Args; + + template struct Seq {}; + template struct Gens : Gens {}; + template struct Gens<0, I...>{ typedef Seq type; }; + + template + static R dispatchHelper(typename Super::FunctionType fn, const ArgsType& args, Seq) { + return R( fn(std::get(args) ...) ); + } + + using SeqType = typename Gens::type; +public: + static R jmp(typename Super::FunctionType fn, const ArgsType& args ) { - return R( fn() ); + return dispatchHelper(fn, args, SeqType()); } }; - -template< typename R, typename A > -struct _EngineFunctionTrampoline< R( A ) > : public _EngineFunctionTrampolineBase< R( A ) > -{ - static R jmp( R ( *fn )( A ), const typename _EngineFunctionTrampolineBase< R( A ) >::Args& args ) - { - return R( fn( args.a() ) ); - } -}; - -template< typename R, typename A, typename B > -struct _EngineFunctionTrampoline< R( A, B ) > : public _EngineFunctionTrampolineBase< R( A, B ) > -{ - static R jmp( R ( *fn )( A, B ), const typename _EngineFunctionTrampolineBase< R( A, B ) >::Args& args ) - { - return R( fn( args.a(), args.b() ) ); - } -}; - -template< typename R, typename A, typename B, typename C > -struct _EngineFunctionTrampoline< R( A, B, C ) > : public _EngineFunctionTrampolineBase< R( A, B, C ) > -{ - static R jmp( R ( *fn )( A, B, C ), const typename _EngineFunctionTrampolineBase< R( A, B, C ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D > -struct _EngineFunctionTrampoline< R( A, B, C, D ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D ) > -{ - static R jmp( R ( *fn )( A, B, C, D ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineFunctionTrampoline< R( A, B, C, D, E ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineFunctionTrampoline< R( A, B, C, D, E, F ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E, F ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E, F, G ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E, F, G, H ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I, J ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I, J, K ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k() ) ); - } -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineFunctionTrampoline< R( A, B, C, D, E, F, G, H, I, J, K, L ) > : public _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) > -{ - static R jmp( R ( *fn )( A, B, C, D, E, F, G, H, I, J, K, L ), const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) >::Args& args ) - { - return R( fn( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k(), args.l() ) ); - } -}; - - // Trampolines for engine methods template< typename T > @@ -1417,165 +391,34 @@ struct _EngineMethodTrampolineBase : public _EngineTrampoline< T > {}; template< typename Frame, typename T > struct _EngineMethodTrampoline {}; -template< typename Frame, typename R > -struct _EngineMethodTrampoline< Frame, R() > : public _EngineMethodTrampolineBase< R() > +template< typename Frame, typename R, typename ...ArgTs > +struct _EngineMethodTrampoline< Frame, R(ArgTs ...) > : public _EngineMethodTrampolineBase< R(ArgTs ...) > { - typedef R( FunctionType )( typename Frame::ObjectType* ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R() >::Args& args ) + using FunctionType = R( typename Frame::ObjectType*, ArgTs ...); +private: + using Super = _EngineMethodTrampolineBase< R(ArgTs ...) >; + using ArgsType = typename _EngineFunctionTrampolineBase< R(ArgTs ...) >::Args; + + template struct Seq {}; + template struct Gens : Gens {}; + template struct Gens<0, I...>{ typedef Seq type; }; + + template + static R dispatchHelper(Frame f, const ArgsType& args, Seq) { + return R( f._exec(std::get(args) ...) ); + } + + using SeqType = typename Gens::type; +public: + static R jmp( typename Frame::ObjectType* object, const ArgsType& args ) { + Frame f; f.object = object; - return R( f._exec() ); + return dispatchHelper(f, args, SeqType()); } }; - -template< typename Frame, typename R, typename A > -struct _EngineMethodTrampoline< Frame, R( A ) > : public _EngineMethodTrampolineBase< R( A ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B > -struct _EngineMethodTrampoline< Frame, R( A, B ) > : public _EngineMethodTrampolineBase< R( A, B ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C > -struct _EngineMethodTrampoline< Frame, R( A, B, C ) > : public _EngineMethodTrampolineBase< R( A, B, C ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D ) > : public _EngineMethodTrampolineBase< R( A, B, C, D ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I, J ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I, J, K ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k() ) ); - } -}; - -template< typename Frame, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineMethodTrampoline< Frame, R( A, B, C, D, E, F, G, H, I, J, K, L ) > : public _EngineMethodTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) > -{ - typedef R( FunctionType )( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K, L ); - static R jmp( typename Frame::ObjectType* object, const typename _EngineFunctionTrampolineBase< R( A, B, C, D, E, F, G, H, I, J, K, L ) >::Args& args ) - { - Frame f; - f.object = object; - return R( f._exec( args.a(), args.b(), args.c(), args.d(), args.e(), args.f(), args.g(), args.h(), args.i(), args.j(), args.k(), args.l() ) ); - } -}; - - - /// @} @@ -1671,83 +514,13 @@ struct _EngineConsoleThunkType< void > struct _EngineConsoleThunkCountArgs { - template< typename A > - U32 operator ()( A a ) - { - return 1; - } - - template< typename A, typename B > - U32 operator ()( A a, B b ) - { - return 2; - } - - template< typename A, typename B, typename C > - U32 operator ()( A a, B b, C c ) - { - return 3; - } - - template< typename A, typename B, typename C, typename D > - U32 operator ()( A a, B b, C c, D d ) - { - return 4; - } - - template< typename A, typename B, typename C, typename D, typename E > - U32 operator ()( A a, B b, C c, D d, E e ) - { - return 5; - } - - template< typename A, typename B, typename C, typename D, typename E, typename F > - U32 operator ()( A a, B b, C c, D d, E e, F f ) - { - return 6; - } - - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G > - U32 operator ()( A a, B b, C c, D d, E e, F f, G g ) - { - return 7; - } - - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > - U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h ) - { - return 8; - } - - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > - U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i ) - { - return 9; - } - - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > - U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) - { - return 10; - } - - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > - U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) - { - return 11; - } - - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > - U32 operator ()( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) - { - return 12; - } - - - operator U32() const - { - return 0; - } + template U32 operator()(ArgTs... args){ + return sizeof...(ArgTs); + } + + operator U32() const{ // WHAT IS THIS?? + return 0; + } }; @@ -4651,4 +3424,4 @@ template<> struct _EngineConsoleExecCallbackHelper : public _BaseEn // Re-enable some VC warnings we disabled for this file. #pragma warning( pop ) // 4510 and 4610 -#endif // !_ENGINEAPI_H_ \ No newline at end of file +#endif // !_ENGINEAPI_H_ From 26da831b0170c731ba3a0416a2dfe4a5585f8c09 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 02:14:38 -0500 Subject: [PATCH 17/50] This commit is broken, but has a lot of important stuff in it. Trying to figure out why my constructor thinks it doesn't take any parameters --- Engine/source/console/engineAPI.h | 857 +++--------------------- Engine/source/console/engineFunctions.h | 717 +------------------- 2 files changed, 108 insertions(+), 1466 deletions(-) diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index a0b9d8900..ee1a34c7b 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -437,6 +437,7 @@ inline const char* _EngineConsoleThunkReturnValue( const T& value ) { return EngineMarshallData( value ); } + inline bool _EngineConsoleThunkReturnValue( bool value ) { return value; @@ -518,7 +519,7 @@ struct _EngineConsoleThunkCountArgs return sizeof...(ArgTs); } - operator U32() const{ // WHAT IS THIS?? + operator U32() const{ // FIXME: WHAT IS THIS?? I'm pretty sure it's incorrect, and it's the version that is invoked by all the macros return 0; } }; @@ -527,801 +528,95 @@ struct _EngineConsoleThunkCountArgs // Encapsulation of a legacy console function invocation. +namespace engineAPI{ + namespace detail{ + template + struct ThunkHelpers { + using SelfType = ThunkHelpers; + using FunctionType = R(*)(ArgTs...); + template using MethodType = R(Frame::*)(ArgTs ...) const; + template using IthArgType = typename std::tuple_element >::type; + + template struct Seq {}; + template struct Gens : Gens {}; + template struct Gens<0, I...>{ typedef Seq type; }; + + typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; + static constexpr S32 NUM_ARGS = sizeof...(ArgTs) + startArgc; + + template + static IthArgType getRealArgValue(S32 argc, ConsoleValueRef *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs) + { + return (startArgc + index) < argc + ? EngineUnmarshallData< IthArgType >()( argv[ startArgc + index ] ) + : std::get(defaultArgs.mArgs); + } + + template + static R dispatchHelper(S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs, Seq){ + return fn(SelfType::getRealArgValue(argc, argv, defaultArgs) ...); + } + + template + static R dispatchHelper(S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs, Seq){ + return (frame->*fn)(SelfType::getRealArgValue(argc, argv, defaultArgs) ...); + } + + using SeqType = typename Gens::type; + }; + } +} template< S32 startArgc, typename T > struct _EngineConsoleThunk {}; -template< S32 startArgc, typename R > -struct _EngineConsoleThunk< startArgc, R() > +template< S32 startArgc, typename R, typename ...ArgTs > +struct _EngineConsoleThunk< startArgc, R(ArgTs...) > { - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 0; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )(), const _EngineFunctionDefaultArguments< void() >& ) +private: + using Helper = engineAPI::detail::ThunkHelpers; + using SeqType = typename Helper::SeqType; +public: + typedef typename Helper::FunctionType FunctionType; + typedef typename Helper::ReturnType ReturnType; + template using MethodType = typename Helper::template MethodType; + static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; + + static ReturnType thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) { - return _EngineConsoleThunkReturnValue( fn() ); + return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType())); } template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& ) + static ReturnType thunk( S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) { - return _EngineConsoleThunkReturnValue( ( frame->*fn )() ); + return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType())); } }; -template< S32 startArgc > -struct _EngineConsoleThunk< startArgc, void() > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 0; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )(), const _EngineFunctionDefaultArguments< void() >& ) - { - fn(); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )() const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType* ) >& ) - { - return ( frame->*fn )(); - } +// Have to do a partial specialization for void-returning functions :( +template +struct _EngineConsoleThunk { +private: + using Helper = engineAPI::detail::ThunkHelpers; + using SeqType = typename Helper::SeqType; +public: + typedef typename Helper::FunctionType FunctionType; + typedef typename Helper::ReturnType ReturnType; + template using MethodType = typename Helper::template MethodType; + static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; + + static void thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) + { + Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType()); + } + template< typename Frame > + static void thunk( S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) + { + Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType()); + } }; - -template< S32 startArgc, typename R, typename A > -struct _EngineConsoleThunk< startArgc, R( A ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 1 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - - return _EngineConsoleThunkReturnValue( fn( a ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a ) ); - } -}; - -template< S32 startArgc, typename A > -struct _EngineConsoleThunk< startArgc, void( A ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 1 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A ), const _EngineFunctionDefaultArguments< void( A ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - - fn( a ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - - ( frame->*fn )( a ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B > -struct _EngineConsoleThunk< startArgc, R( A, B ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 2 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b ) ); - } -}; - -template< S32 startArgc, typename A, typename B > -struct _EngineConsoleThunk< startArgc, void( A, B ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 2 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B ), const _EngineFunctionDefaultArguments< void( A, B ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - - fn( a, b ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - - ( frame->*fn )( a, b ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C > -struct _EngineConsoleThunk< startArgc, R( A, B, C ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 3 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C > -struct _EngineConsoleThunk< startArgc, void( A, B, C ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 3 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C ), const _EngineFunctionDefaultArguments< void( A, B, C ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - - fn( a, b, c ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - - ( frame->*fn )( a, b, c ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 4 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 4 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D ), const _EngineFunctionDefaultArguments< void( A, B, C, D ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - - fn( a, b, c, d ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - - ( frame->*fn )( a, b, c, d ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 5 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 5 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - - fn( a, b, c, d, e ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - - ( frame->*fn )( a, b, c, d, e ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 6 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 6 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - - fn( a, b, c, d, e, f ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - - ( frame->*fn )( a, b, c, d, e, f ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 7 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 7 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - - fn( a, b, c, d, e, f, g ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - - ( frame->*fn )( a, b, c, d, e, f, g ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 8 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 8 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - - fn( a, b, c, d, e, f, g, h ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - - ( frame->*fn )( a, b, c, d, e, f, g, h ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 9 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 9 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - - fn( a, b, c, d, e, f, g, h, i ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - - ( frame->*fn )( a, b, c, d, e, f, g, h, i ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 10 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i, j ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 10 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) ); - - fn( a, b, c, d, e, f, g, h, i, j ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) ); - - ( frame->*fn )( a, b, c, d, e, f, g, h, i, j ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 11 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j, k ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 11 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) ); - - fn( a, b, c, d, e, f, g, h, i, j, k ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) ); - - ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k ); - } -}; - - -template< S32 startArgc, typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineConsoleThunk< startArgc, R( A, B, C, D, E, F, G, H, I, J, K, L ) > -{ - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static const S32 NUM_ARGS = 12 + startArgc; - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( *fn )( A, B, C, D, E, F, G, H, I, J, K, L ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) ); - L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L >()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) ); - - return _EngineConsoleThunkReturnValue( fn( a, b, c, d, e, f, g, h, i, j, k, l ) ); - } - template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, R ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K, L ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) ); - L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L >()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) ); - - return _EngineConsoleThunkReturnValue( ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k, l ) ); - } -}; - -template< S32 startArgc, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineConsoleThunk< startArgc, void( A, B, C, D, E, F, G, H, I, J, K, L ) > -{ - typedef void ReturnType; - static const S32 NUM_ARGS = 12 + startArgc; - static void thunk( S32 argc, ConsoleValueRef *argv, void ( *fn )( A, B, C, D, E, F, G, H, I, J, K, L ), const _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.a ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.b ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.c ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.d ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.e ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.f ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.g ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.h ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.i ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.j ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.k ) ); - L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L >()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) ); - - fn( a, b, c, d, e, f, g, h, i, j, k, l ); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, void ( Frame::*fn )( A, B, C, D, E, F, G, H, I, J, K, L ) const, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, A, B, C, D, E, F, G, H, I, J, K, L ) >& defaultArgs ) - { - A a = ( startArgc + 0 < argc ? EngineUnmarshallData< A >()( argv[ startArgc + 0 ] ) : A( defaultArgs.b ) ); - B b = ( startArgc + 1 < argc ? EngineUnmarshallData< B >()( argv[ startArgc + 1 ] ) : B( defaultArgs.c ) ); - C c = ( startArgc + 2 < argc ? EngineUnmarshallData< C >()( argv[ startArgc + 2 ] ) : C( defaultArgs.d ) ); - D d = ( startArgc + 3 < argc ? EngineUnmarshallData< D >()( argv[ startArgc + 3 ] ) : D( defaultArgs.e ) ); - E e = ( startArgc + 4 < argc ? EngineUnmarshallData< E >()( argv[ startArgc + 4 ] ) : E( defaultArgs.f ) ); - F f = ( startArgc + 5 < argc ? EngineUnmarshallData< F >()( argv[ startArgc + 5 ] ) : F( defaultArgs.g ) ); - G g = ( startArgc + 6 < argc ? EngineUnmarshallData< G >()( argv[ startArgc + 6 ] ) : G( defaultArgs.h ) ); - H h = ( startArgc + 7 < argc ? EngineUnmarshallData< H >()( argv[ startArgc + 7 ] ) : H( defaultArgs.i ) ); - I i = ( startArgc + 8 < argc ? EngineUnmarshallData< I >()( argv[ startArgc + 8 ] ) : I( defaultArgs.j ) ); - J j = ( startArgc + 9 < argc ? EngineUnmarshallData< J >()( argv[ startArgc + 9 ] ) : J( defaultArgs.k ) ); - K k = ( startArgc + 10 < argc ? EngineUnmarshallData< K >()( argv[ startArgc + 10 ] ) : K( defaultArgs.l ) ); - L l = ( startArgc + 11 < argc ? EngineUnmarshallData< L >()( argv[ startArgc + 11 ] ) : L( defaultArgs.l ) ); - - ( frame->*fn )( a, b, c, d, e, f, g, h, i, j, k, l ); - } -}; - - - /// @} /// @name API Definition Macros diff --git a/Engine/source/console/engineFunctions.h b/Engine/source/console/engineFunctions.h index dedefcf35..fc97a81d1 100644 --- a/Engine/source/console/engineFunctions.h +++ b/Engine/source/console/engineFunctions.h @@ -87,693 +87,40 @@ struct EngineFunctionDefaultArguments // Structure encapsulating default arguments to an engine API function. template< typename T > struct _EngineFunctionDefaultArguments {}; -template<> -struct _EngineFunctionDefaultArguments< void() > : public EngineFunctionDefaultArguments -{ - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } -}; -template< typename A > -struct _EngineFunctionDefaultArguments< void( A ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( A a ) - : a( a ) - { mNumDefaultArgs = 1; } -}; -template< typename A, typename B > -struct _EngineFunctionDefaultArguments< void( A, B ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( B b ) - : b( b ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( A a, B b ) - : a( a ), - b( b ) - { mNumDefaultArgs = 2; } -}; -template< typename A, typename B, typename C > -struct _EngineFunctionDefaultArguments< void( A, B, C ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( C c ) - : c( c ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( B b, C c ) - : b( b ), - c( c ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( A a, B b, C c ) - : a( a ), - b( b ), - c( c ) - { mNumDefaultArgs = 3; } -}; -template< typename A, typename B, typename C, typename D > -struct _EngineFunctionDefaultArguments< void( A, B, C, D ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( D d ) - : d( d ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( C c, D d ) - : c( c ), - d( d ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( B b, C c, D d ) - : b( b ), - c( c ), - d( d ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d ) - : a( a ), - b( b ), - c( c ), - d( d ) - { mNumDefaultArgs = 4; } -}; -template< typename A, typename B, typename C, typename D, typename E > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( E e ) - : e( e ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( D d, E e ) - : d( d ), - e( e ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( C c, D d, E e ) - : c( c ), - d( d ), - e( e ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e ) - : b( b ), - c( c ), - d( d ), - e( e ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ) - { mNumDefaultArgs = 5; } -}; -template< typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E, F ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - typename EngineTypeTraits< F >::DefaultArgumentValueStoreType f; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( F f ) - : f( f ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( E e, F f ) - : e( e ), - f( f ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( D d, E e, F f ) - : d( d ), - e( e ), - f( f ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( C c, D d, E e, F f ) - : c( c ), - d( d ), - e( e ), - f( f ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e, F f ) - : b( b ), - c( c ), - d( d ), - e( e ), - f( f ) - { mNumDefaultArgs = 5; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e, F f ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ), - f( f ) - { mNumDefaultArgs = 6; } -}; -template< typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - typename EngineTypeTraits< F >::DefaultArgumentValueStoreType f; - typename EngineTypeTraits< G >::DefaultArgumentValueStoreType g; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( G g ) - : g( g ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( F f, G g ) - : f( f ), - g( g ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( E e, F f, G g ) - : e( e ), - f( f ), - g( g ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( D d, E e, F f, G g ) - : d( d ), - e( e ), - f( f ), - g( g ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( C c, D d, E e, F f, G g ) - : c( c ), - d( d ), - e( e ), - f( f ), - g( g ) - { mNumDefaultArgs = 5; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e, F f, G g ) - : b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ) - { mNumDefaultArgs = 6; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e, F f, G g ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ) - { mNumDefaultArgs = 7; } -}; -template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - typename EngineTypeTraits< F >::DefaultArgumentValueStoreType f; - typename EngineTypeTraits< G >::DefaultArgumentValueStoreType g; - typename EngineTypeTraits< H >::DefaultArgumentValueStoreType h; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( H h ) - : h( h ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( G g, H h ) - : g( g ), - h( h ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( F f, G g, H h ) - : f( f ), - g( g ), - h( h ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( E e, F f, G g, H h ) - : e( e ), - f( f ), - g( g ), - h( h ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( D d, E e, F f, G g, H h ) - : d( d ), - e( e ), - f( f ), - g( g ), - h( h ) - { mNumDefaultArgs = 5; } - _EngineFunctionDefaultArguments( C c, D d, E e, F f, G g, H h ) - : c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ) - { mNumDefaultArgs = 6; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e, F f, G g, H h ) - : b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ) - { mNumDefaultArgs = 7; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e, F f, G g, H h ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ) - { mNumDefaultArgs = 8; } -}; -template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - typename EngineTypeTraits< F >::DefaultArgumentValueStoreType f; - typename EngineTypeTraits< G >::DefaultArgumentValueStoreType g; - typename EngineTypeTraits< H >::DefaultArgumentValueStoreType h; - typename EngineTypeTraits< I >::DefaultArgumentValueStoreType i; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( I i ) - : i( i ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( H h, I i ) - : h( h ), - i( i ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( G g, H h, I i ) - : g( g ), - h( h ), - i( i ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( F f, G g, H h, I i ) - : f( f ), - g( g ), - h( h ), - i( i ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( E e, F f, G g, H h, I i ) - : e( e ), - f( f ), - g( g ), - h( h ), - i( i ) - { mNumDefaultArgs = 5; } - _EngineFunctionDefaultArguments( D d, E e, F f, G g, H h, I i ) - : d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ) - { mNumDefaultArgs = 6; } - _EngineFunctionDefaultArguments( C c, D d, E e, F f, G g, H h, I i ) - : c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ) - { mNumDefaultArgs = 7; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e, F f, G g, H h, I i ) - : b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ) - { mNumDefaultArgs = 8; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e, F f, G g, H h, I i ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ) - { mNumDefaultArgs = 9; } -}; -template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - typename EngineTypeTraits< F >::DefaultArgumentValueStoreType f; - typename EngineTypeTraits< G >::DefaultArgumentValueStoreType g; - typename EngineTypeTraits< H >::DefaultArgumentValueStoreType h; - typename EngineTypeTraits< I >::DefaultArgumentValueStoreType i; - typename EngineTypeTraits< J >::DefaultArgumentValueStoreType j; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( J j ) - : j( j ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( I i, J j ) - : i( i ), - j( j ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( H h, I i, J j ) - : h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( G g, H h, I i, J j ) - : g( g ), - h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( F f, G g, H h, I i, J j ) - : f( f ), - g( g ), - h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 5; } - _EngineFunctionDefaultArguments( E e, F f, G g, H h, I i, J j ) - : e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 6; } - _EngineFunctionDefaultArguments( D d, E e, F f, G g, H h, I i, J j ) - : d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 7; } - _EngineFunctionDefaultArguments( C c, D d, E e, F f, G g, H h, I i, J j ) - : c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 8; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e, F f, G g, H h, I i, J j ) - : b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 9; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ) - { mNumDefaultArgs = 10; } -}; -template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K ) > : public EngineFunctionDefaultArguments -{ - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - typename EngineTypeTraits< F >::DefaultArgumentValueStoreType f; - typename EngineTypeTraits< G >::DefaultArgumentValueStoreType g; - typename EngineTypeTraits< H >::DefaultArgumentValueStoreType h; - typename EngineTypeTraits< I >::DefaultArgumentValueStoreType i; - typename EngineTypeTraits< J >::DefaultArgumentValueStoreType j; - typename EngineTypeTraits< K >::DefaultArgumentValueStoreType k; - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( K k ) - : k( k ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( J j, K k ) - : j( j ), - k( k ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( I i, J j, K k ) - : i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( H h, I i, J j, K k ) - : h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( G g, H h, I i, J j, K k ) - : g( g ), - h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 5; } - _EngineFunctionDefaultArguments( F f, G g, H h, I i, J j, K k ) - : f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 6; } - _EngineFunctionDefaultArguments( E e, F f, G g, H h, I i, J j, K k ) - : e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 7; } - _EngineFunctionDefaultArguments( D d, E e, F f, G g, H h, I i, J j, K k ) - : d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 8; } - _EngineFunctionDefaultArguments( C c, D d, E e, F f, G g, H h, I i, J j, K k ) - : c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 9; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) - : b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 10; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ) - { mNumDefaultArgs = 11; } -}; -template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineFunctionDefaultArguments< void( A, B, C, D, E, F, G, H, I, J, K, L ) > : public EngineFunctionDefaultArguments +template +struct _EngineFunctionDefaultArguments< void(ArgTs...) > : public EngineFunctionDefaultArguments { - typename EngineTypeTraits< A >::DefaultArgumentValueStoreType a; - typename EngineTypeTraits< B >::DefaultArgumentValueStoreType b; - typename EngineTypeTraits< C >::DefaultArgumentValueStoreType c; - typename EngineTypeTraits< D >::DefaultArgumentValueStoreType d; - typename EngineTypeTraits< E >::DefaultArgumentValueStoreType e; - typename EngineTypeTraits< F >::DefaultArgumentValueStoreType f; - typename EngineTypeTraits< G >::DefaultArgumentValueStoreType g; - typename EngineTypeTraits< H >::DefaultArgumentValueStoreType h; - typename EngineTypeTraits< I >::DefaultArgumentValueStoreType i; - typename EngineTypeTraits< J >::DefaultArgumentValueStoreType j; - typename EngineTypeTraits< K >::DefaultArgumentValueStoreType k; - typename EngineTypeTraits< L >::DefaultArgumentValueStoreType l; - - _EngineFunctionDefaultArguments() - { mNumDefaultArgs = 0; } - _EngineFunctionDefaultArguments( L l ) - : l( l ) - { mNumDefaultArgs = 1; } - _EngineFunctionDefaultArguments( K k, L l ) - : k( k ), - l( l ) - { mNumDefaultArgs = 2; } - _EngineFunctionDefaultArguments( J j, K k, L l ) - : j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 3; } - _EngineFunctionDefaultArguments( I i, J j, K k, L l ) - : i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 4; } - _EngineFunctionDefaultArguments( H h, I i, J j, K k, L l ) - : h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 5; } - _EngineFunctionDefaultArguments( G g, H h, I i, J j, K k, L l ) - : g( g ), - h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 6; } - _EngineFunctionDefaultArguments( F f, G g, H h, I i, J j, K k, L l ) - : f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 7; } - _EngineFunctionDefaultArguments( E e, F f, G g, H h, I i, J j, K k, L l ) - : e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 8; } - _EngineFunctionDefaultArguments( D d, E e, F f, G g, H h, I i, J j, K k, L l ) - : d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 9; } - _EngineFunctionDefaultArguments( C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) - : c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 10; } - _EngineFunctionDefaultArguments( B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) - : b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 11; } - _EngineFunctionDefaultArguments( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) - : a( a ), - b( b ), - c( c ), - d( d ), - e( e ), - f( f ), - g( g ), - h( h ), - i( i ), - j( j ), - k( k ), - l( l ) - { mNumDefaultArgs = 12; } + + + template using DefVST = typename EngineTypeTraits::DefaultArgumentValueStoreType; + + std::tuple ...> mArgs; +private: + using SelfType = _EngineFunctionDefaultArguments< void(ArgTs...) >; + + template struct Seq {}; + template struct Gens : Gens {}; + + template struct Gens<0, I...>{ typedef Seq type; }; + + template + void copyHelper(std::tuple ...> defaultArgs, Seq) { + constexpr size_t offset = (sizeof...(ArgTs) - sizeof...(TailTs)); + std::tie(std::get(mArgs)...) = defaultArgs; + } + + template using MaybeVoidEnabled = typename std::enable_if::type; + + template MaybeVoidEnabled tailInit(DefVST ...tail) { + mNumDefaultArgs = sizeof...(TailTs); + copyHelper(std::make_tuple(tail...), typename Gens::type()); + }; +public: + template _EngineFunctionDefaultArguments(DefVST ...tail) + { + tailInit(tail...); + } }; #pragma pack( pop ) From 35cc16d22c63d16149b5447307b548654d2cd706 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 03:17:53 -0500 Subject: [PATCH 18/50] slightly better organization, but same compiling problem --- Engine/source/console/engineFunctions.h | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Engine/source/console/engineFunctions.h b/Engine/source/console/engineFunctions.h index fc97a81d1..86f57feb8 100644 --- a/Engine/source/console/engineFunctions.h +++ b/Engine/source/console/engineFunctions.h @@ -91,10 +91,7 @@ struct _EngineFunctionDefaultArguments {}; template struct _EngineFunctionDefaultArguments< void(ArgTs...) > : public EngineFunctionDefaultArguments { - - template using DefVST = typename EngineTypeTraits::DefaultArgumentValueStoreType; - std::tuple ...> mArgs; private: using SelfType = _EngineFunctionDefaultArguments< void(ArgTs...) >; @@ -105,22 +102,24 @@ private: template struct Gens<0, I...>{ typedef Seq type; }; template - void copyHelper(std::tuple ...> defaultArgs, Seq) { + static void copyHelper(std::tuple ...> &args, std::tuple ...> &defaultArgs, Seq) { constexpr size_t offset = (sizeof...(ArgTs) - sizeof...(TailTs)); - std::tie(std::get(mArgs)...) = defaultArgs; + std::tie(std::get(args)...) = defaultArgs; } - template using MaybeVoidEnabled = typename std::enable_if::type; + template using MaybeSelfEnabled = typename std::enable_if::type; - template MaybeVoidEnabled tailInit(DefVST ...tail) { - mNumDefaultArgs = sizeof...(TailTs); - copyHelper(std::make_tuple(tail...), typename Gens::type()); + template static MaybeSelfEnabled tailInit(DefVST ...tail) { + std::tuple argsT; + std::tuple tailT = std::make_tuple(tail...); + SelfType::copyHelper(argsT, tailT, typename Gens::type()); + return argsT; }; + public: - template _EngineFunctionDefaultArguments(DefVST ...tail) - { - tailInit(tail...); - } + template _EngineFunctionDefaultArguments(DefVST ...tail) + : EngineFunctionDefaultArguments({sizeof...(TailTs)}), mArgs(tailInit(tail...)) + {} }; #pragma pack( pop ) From 733fd3ef6d69b541517564f4380c5469718bdf74 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 14:06:04 -0500 Subject: [PATCH 19/50] Fixed up the passing of the tuple types --- Engine/source/console/engineFunctions.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Engine/source/console/engineFunctions.h b/Engine/source/console/engineFunctions.h index 86f57feb8..d0b4fa719 100644 --- a/Engine/source/console/engineFunctions.h +++ b/Engine/source/console/engineFunctions.h @@ -109,16 +109,16 @@ private: template using MaybeSelfEnabled = typename std::enable_if::type; - template static MaybeSelfEnabled tailInit(DefVST ...tail) { - std::tuple argsT; - std::tuple tailT = std::make_tuple(tail...); - SelfType::copyHelper(argsT, tailT, typename Gens::type()); + template static MaybeSelfEnabled tailInit(TailTs ...tail) { + std::tuple...> argsT; + std::tuple...> tailT = std::make_tuple(tail...); + SelfType::copyHelper(argsT, tailT, typename Gens::type()); return argsT; }; public: - template _EngineFunctionDefaultArguments(DefVST ...tail) - : EngineFunctionDefaultArguments({sizeof...(TailTs)}), mArgs(tailInit(tail...)) + template _EngineFunctionDefaultArguments(TailTs ...tail) + : EngineFunctionDefaultArguments({sizeof...(TailTs)}), mArgs(SelfType::tailInit(tail...)) {} }; From 88106f9032399d926afd3e3d3b5286c3fad204a1 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 14:50:41 -0500 Subject: [PATCH 20/50] Fixed type inference for nulls in console functions --- Engine/source/T3D/aiPlayer.cpp | 6 +++--- Engine/source/T3D/fx/particleEmitterNode.cpp | 2 +- Engine/source/T3D/fx/ribbonNode.cpp | 3 +-- Engine/source/T3D/tsStatic.cpp | 4 ++-- Engine/source/app/badWordFilter.cpp | 2 +- Engine/source/console/consoleTypes.h | 1 + Engine/source/console/engineAPI.h | 9 ++++++--- Engine/source/console/engineFunctions.h | 2 ++ Engine/source/console/enginePrimitives.h | 2 ++ Engine/source/gfx/gfxShader.cpp | 2 +- Engine/source/gfx/video/videoCapture.cpp | 4 ++-- Engine/source/gui/core/guiCanvas.cpp | 2 +- Engine/source/gui/editor/guiEditCtrl.cpp | 4 ++-- Engine/source/gui/editor/guiMenuBar.cpp | 2 +- Engine/source/lighting/lightManager.cpp | 2 +- Engine/source/scene/sceneContainer.cpp | 2 +- Engine/source/sim/actionMap.cpp | 2 +- 17 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Engine/source/T3D/aiPlayer.cpp b/Engine/source/T3D/aiPlayer.cpp index 88b500205..7565f7831 100644 --- a/Engine/source/T3D/aiPlayer.cpp +++ b/Engine/source/T3D/aiPlayer.cpp @@ -1317,7 +1317,7 @@ bool AIPlayer::checkInLos(GameBase* target, bool _useMuzzle, bool _checkEnabled) return hit; } -DefineEngineMethod(AIPlayer, checkInLos, bool, (ShapeBase* obj, bool useMuzzle, bool checkEnabled),(NULL, false, false), +DefineEngineMethod(AIPlayer, checkInLos, bool, (ShapeBase* obj, bool useMuzzle, bool checkEnabled),(nullAsType(), false, false), "@brief Check whether an object is in line of sight.\n" "@obj Object to check. (If blank, it will check the current target).\n" "@useMuzzle Use muzzle position. Otherwise use eye position. (defaults to false).\n" @@ -1366,7 +1366,7 @@ bool AIPlayer::checkInFoV(GameBase* target, F32 camFov, bool _checkEnabled) return (dot > mCos(camFov)); } -DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (NULL, 45.0f, false), +DefineEngineMethod(AIPlayer, checkInFoV, bool, (ShapeBase* obj, F32 fov, bool checkEnabled), (nullAsType(), 45.0f, false), "@brief Check whether an object is within a specified veiw cone.\n" "@obj Object to check. (If blank, it will check the current target).\n" "@fov view angle in degrees.(Defaults to 45)\n" @@ -1440,7 +1440,7 @@ F32 AIPlayer::getTargetDistance(GameBase* target, bool _checkEnabled) return (getPosition() - target->getPosition()).len(); } -DefineEngineMethod(AIPlayer, getTargetDistance, F32, (ShapeBase* obj, bool checkEnabled), (NULL, false), +DefineEngineMethod(AIPlayer, getTargetDistance, F32, (ShapeBase* obj, bool checkEnabled), (nullAsType(), false), "@brief The distance to a given object.\n" "@obj Object to check. (If blank, it will check the current target).\n" "@checkEnabled check whether the object can take damage and if so is still alive.(Defaults to false)\n") diff --git a/Engine/source/T3D/fx/particleEmitterNode.cpp b/Engine/source/T3D/fx/particleEmitterNode.cpp index bb362417b..e03e5a1a7 100644 --- a/Engine/source/T3D/fx/particleEmitterNode.cpp +++ b/Engine/source/T3D/fx/particleEmitterNode.cpp @@ -395,7 +395,7 @@ void ParticleEmitterNode::setEmitterDataBlock(ParticleEmitterData* data) } -DefineEngineMethod(ParticleEmitterNode, setEmitterDataBlock, void, (ParticleEmitterData* emitterDatablock), (NULL), +DefineEngineMethod(ParticleEmitterNode, setEmitterDataBlock, void, (ParticleEmitterData* emitterDatablock), (nullAsType()), "Assigns the datablock for this emitter node.\n" "@param emitterDatablock ParticleEmitterData datablock to assign\n" "@tsexample\n" diff --git a/Engine/source/T3D/fx/ribbonNode.cpp b/Engine/source/T3D/fx/ribbonNode.cpp index 2582fbe6f..7e73fbc59 100644 --- a/Engine/source/T3D/fx/ribbonNode.cpp +++ b/Engine/source/T3D/fx/ribbonNode.cpp @@ -39,7 +39,6 @@ ConsoleDocClass( RibbonNodeData, ConsoleDocClass( RibbonNode, "" ); - //----------------------------------------------------------------------------- // RibbonNodeData //----------------------------------------------------------------------------- @@ -299,7 +298,7 @@ void RibbonNode::setRibbonDatablock(RibbonData* data) mRibbonDatablock = data; } -DefineEngineMethod(RibbonNode, setRibbonDatablock, void, (RibbonData* ribbonDatablock), (0), +DefineEngineMethod(RibbonNode, setRibbonDatablock, void, (RibbonData* ribbonDatablock), (nullAsType()), "Assigns the datablock for this ribbon node.\n" "@param ribbonDatablock RibbonData datablock to assign\n" "@tsexample\n" diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 3997d40dd..0f7b69ef3 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -1256,7 +1256,7 @@ DefineEngineMethod( TSStatic, getTargetCount, S32,(),, // This method is able to change materials per map to with others. The material that is being replaced is being mapped to // unmapped_mat as a part of this transition -DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Material* oldMat, Material* newMat ),("",NULL,NULL), +DefineEngineMethod( TSStatic, changeMaterial, void, ( const char* mapTo, Material* oldMat, Material* newMat ),("",nullAsType(),nullAsType()), "@brief Change one of the materials on the shape.\n\n" "This method changes materials per mapTo with others. The material that " @@ -1323,4 +1323,4 @@ DefineEngineMethod( TSStatic, getModelFile, const char *, (),, ) { return object->getShapeFileName(); -} \ No newline at end of file +} diff --git a/Engine/source/app/badWordFilter.cpp b/Engine/source/app/badWordFilter.cpp index 7f1dd51a6..e267f5032 100644 --- a/Engine/source/app/badWordFilter.cpp +++ b/Engine/source/app/badWordFilter.cpp @@ -254,7 +254,7 @@ DefineEngineFunction(addBadWord, bool, (const char* badWord),, return gBadWordFilter->addBadWord(badWord); } -DefineEngineFunction(filterString, const char *, (const char* baseString, const char* replacementChars), (NULL, NULL), +DefineEngineFunction(filterString, const char *, (const char* baseString, const char* replacementChars), (nullAsType(), nullAsType()), "@brief Replaces the characters in a string with designated text\n\n" "Uses the bad word filter to determine which characters within the string will be replaced.\n\n" diff --git a/Engine/source/console/consoleTypes.h b/Engine/source/console/consoleTypes.h index 8080a8830..8b64d4fa1 100644 --- a/Engine/source/console/consoleTypes.h +++ b/Engine/source/console/consoleTypes.h @@ -39,6 +39,7 @@ #include "console/engineStructs.h" #endif +template constexpr T nullAsType(){ return nullptr; } /// @file /// Legacy TS-based console type definitions. diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index ee1a34c7b..c4976ad55 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -547,9 +547,12 @@ namespace engineAPI{ template static IthArgType getRealArgValue(S32 argc, ConsoleValueRef *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs) { - return (startArgc + index) < argc - ? EngineUnmarshallData< IthArgType >()( argv[ startArgc + index ] ) - : std::get(defaultArgs.mArgs); + if((startArgc + index) < argc) + { + return EngineUnmarshallData< IthArgType >()( argv[ startArgc + index ] ); + } else { + return std::get(defaultArgs.mArgs); + } } template diff --git a/Engine/source/console/engineFunctions.h b/Engine/source/console/engineFunctions.h index d0b4fa719..4346b39cf 100644 --- a/Engine/source/console/engineFunctions.h +++ b/Engine/source/console/engineFunctions.h @@ -23,6 +23,8 @@ #ifndef _ENGINEFUNCTIONS_H_ #define _ENGINEFUNCTIONS_H_ +#include + #ifndef _ENGINEEXPORTS_H_ #include "console/engineExports.h" #endif diff --git a/Engine/source/console/enginePrimitives.h b/Engine/source/console/enginePrimitives.h index 72f1899e7..7f0b37670 100644 --- a/Engine/source/console/enginePrimitives.h +++ b/Engine/source/console/enginePrimitives.h @@ -41,6 +41,8 @@ DECLARE_PRIMITIVE_R(S32); DECLARE_PRIMITIVE_R(U32); DECLARE_PRIMITIVE_R(F32); DECLARE_PRIMITIVE_R(F64); +DECLARE_PRIMITIVE_R(U64); +DECLARE_PRIMITIVE_R(S64); DECLARE_PRIMITIVE_R(void*); diff --git a/Engine/source/gfx/gfxShader.cpp b/Engine/source/gfx/gfxShader.cpp index 54f1893e6..1fc35a995 100644 --- a/Engine/source/gfx/gfxShader.cpp +++ b/Engine/source/gfx/gfxShader.cpp @@ -178,7 +178,7 @@ void GFXShader::_unlinkBuffer( GFXShaderConstBuffer *buf ) DefineEngineFunction( addGlobalShaderMacro, void, - ( const char *name, const char *value ), ( NULL ), + ( const char *name, const char *value ), ( nullAsType() ), "Adds a global shader macro which will be merged with the script defined " "macros on every shader. The macro will replace the value of an existing " "macro of the same name. For the new macro to take effect all the shaders " diff --git a/Engine/source/gfx/video/videoCapture.cpp b/Engine/source/gfx/video/videoCapture.cpp index 230baf501..0af46af10 100644 --- a/Engine/source/gfx/video/videoCapture.cpp +++ b/Engine/source/gfx/video/videoCapture.cpp @@ -340,7 +340,7 @@ DefineEngineFunction( stopVideoCapture, void, (),, DefineEngineFunction( playJournalToVideo, void, ( const char *journalFile, const char *videoFile, const char *encoder, F32 framerate, Point2I resolution ), - ( NULL, "THEORA", 30.0f, Point2I::Zero ), + ( nullAsType(), "THEORA", 30.0f, Point2I::Zero ), "Load a journal file and capture it video.\n" "@ingroup Rendering\n" ) { @@ -357,4 +357,4 @@ DefineEngineFunction( playJournalToVideo, void, VIDCAP->waitForCanvas(); Journal::Play( journalFile ); -} \ No newline at end of file +} diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index a3f2344f2..400e50d73 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -2147,7 +2147,7 @@ ConsoleDocFragment _popDialog2( "void popDialog();" ); -DefineConsoleMethod( GuiCanvas, popDialog, void, (GuiControl * gui), (NULL), "(GuiControl ctrl=NULL)" +DefineConsoleMethod( GuiCanvas, popDialog, void, (GuiControl * gui), (nullAsType()), "(GuiControl ctrl=NULL)" "@hide") { if (gui) diff --git a/Engine/source/gui/editor/guiEditCtrl.cpp b/Engine/source/gui/editor/guiEditCtrl.cpp index f972ec8ca..5c4c09fb3 100644 --- a/Engine/source/gui/editor/guiEditCtrl.cpp +++ b/Engine/source/gui/editor/guiEditCtrl.cpp @@ -2582,7 +2582,7 @@ DefineConsoleMethod( GuiEditCtrl, moveSelection, void, (S32 dx, S32 dy), , "Move //----------------------------------------------------------------------------- -DefineConsoleMethod( GuiEditCtrl, saveSelection, void, (const char * filename), (NULL), "( string fileName=null ) - Save selection to file or clipboard.") +DefineConsoleMethod( GuiEditCtrl, saveSelection, void, (const char * filename), (nullAsType()), "( string fileName=null ) - Save selection to file or clipboard.") { object->saveSelection( filename ); @@ -2590,7 +2590,7 @@ DefineConsoleMethod( GuiEditCtrl, saveSelection, void, (const char * filename), //----------------------------------------------------------------------------- -DefineConsoleMethod( GuiEditCtrl, loadSelection, void, (const char * filename), (NULL), "( string fileName=null ) - Load selection from file or clipboard.") +DefineConsoleMethod( GuiEditCtrl, loadSelection, void, (const char * filename), (nullAsType()), "( string fileName=null ) - Load selection from file or clipboard.") { object->loadSelection( filename ); diff --git a/Engine/source/gui/editor/guiMenuBar.cpp b/Engine/source/gui/editor/guiMenuBar.cpp index 4a9a4cefa..ea16d4728 100644 --- a/Engine/source/gui/editor/guiMenuBar.cpp +++ b/Engine/source/gui/editor/guiMenuBar.cpp @@ -216,7 +216,7 @@ DefineEngineMethod(GuiMenuBar, addMenu, void, (const char* menuText, S32 menuId) } DefineEngineMethod(GuiMenuBar, addMenuItem, void, (const char* targetMenu, const char* menuItemText, S32 menuItemId, const char* accelerator, int checkGroup, const char *cmd), - ("","",0,NULL,-1,""), + ("","",0,nullAsType(),-1,""), "@brief Adds a menu item to the specified menu. The menu argument can be either the text of a menu or its id.\n\n" "@param menu Menu name or menu Id to add the new item to.\n" "@param menuItemText Text for the new menu item.\n" diff --git a/Engine/source/lighting/lightManager.cpp b/Engine/source/lighting/lightManager.cpp index f53f5284d..2f8ddd5ee 100644 --- a/Engine/source/lighting/lightManager.cpp +++ b/Engine/source/lighting/lightManager.cpp @@ -442,7 +442,7 @@ DefineEngineFunction( setLightManager, bool, ( const char *name ),, return gClientSceneGraph->setLightManager( name ); } -DefineEngineFunction( lightScene, bool, ( const char *completeCallbackFn, const char *mode ), ( NULL, NULL ), +DefineEngineFunction( lightScene, bool, ( const char *completeCallbackFn, const char *mode ), ( nullAsType(), nullAsType() ), "Will generate static lighting for the scene if supported by the active light manager.\n\n" "If mode is \"forceAlways\", the lightmaps will be regenerated regardless of whether " "lighting cache files can be written to. If mode is \"forceWritable\", then the lightmaps " diff --git a/Engine/source/scene/sceneContainer.cpp b/Engine/source/scene/sceneContainer.cpp index f5a271794..fbcd485aa 100644 --- a/Engine/source/scene/sceneContainer.cpp +++ b/Engine/source/scene/sceneContainer.cpp @@ -1602,7 +1602,7 @@ DefineEngineFunction( containerSearchCurrRadiusDist, F32, ( bool useClientContai //TODO: make RayInfo an API type DefineEngineFunction( containerRayCast, const char*, - ( Point3F start, Point3F end, U32 mask, SceneObject *pExempt, bool useClientContainer ), ( NULL, false ), + ( Point3F start, Point3F end, U32 mask, SceneObject *pExempt, bool useClientContainer ), ( nullAsType(), false ), "@brief Cast a ray from start to end, checking for collision against items matching mask.\n\n" "If pExempt is specified, then it is temporarily excluded from collision checks (For " diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index e4455d458..a1b5c6ac2 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -1991,7 +1991,7 @@ DefineEngineMethod( ActionMap, unbindObj, bool, ( const char* device, const char return object->processUnbind( device, action, simObject ); } -DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ), ( NULL, false ), +DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ), ( nullAsType(), false ), "@brief Saves the ActionMap to a file or dumps it to the console.\n\n" "@param fileName The file path to save the ActionMap to. If a filename is not specified " " the ActionMap will be dumped to the console.\n" From 0dfb15dc57dd20cc1612ef24713b5a9955ceb6e3 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 14:55:21 -0500 Subject: [PATCH 21/50] Another set of templates converted to be variadic --- Engine/source/console/engineAPI.h | 93 ++----------------------------- 1 file changed, 4 insertions(+), 89 deletions(-) diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index c4976ad55..3ed1ad21e 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -1128,98 +1128,13 @@ struct _EngineCallbackHelper : mThis( pThis ), mFn( fn ) {} - template< typename R > - R call() const + template< typename R, typename ...ArgTs > + R call(ArgTs ...args) const { - typedef R( FunctionType )( EngineObject* ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis ) ); + typedef R( FunctionType )( EngineObject*, ArgTs... ); + return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, args... ) ); } - - template< typename R, typename A > - R call( A a ) const - { - typedef R( FunctionType )( EngineObject*, A ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a ) ); - } - - template< typename R, typename A, typename B > - R call( A a, B b ) const - { - typedef R( FunctionType )( EngineObject*, A, B ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b ) ); - } - - template< typename R, typename A, typename B, typename C > - R call( A a, B b, C c ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c ) ); - } - - template< typename R, typename A, typename B, typename C, typename D > - R call( A a, B b, C c, D d ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E > - R call( A a, B b, C c, D d, E e ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > - R call( A a, B b, C c, D d, E e, F f ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e, f ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > - R call( A a, B b, C c, D d, E e, F f, G g ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e, f, g ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > - R call( A a, B b, C c, D d, E e, F f, G g, H h ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e, f, g, h ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e, f, g, h, i ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J, K ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j, k ) ); - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) const - { - typedef R( FunctionType )( EngineObject*, A, B, C, D, E, F, G, H, I, J, K, L ); - return R( reinterpret_cast< FunctionType* >( const_cast(mFn) )( mThis, a, b, c, d, e, f, g, h, i, j, k, l ) ); - } - }; From 62e3fae060a04711c01f5f6ba2fa9d4a933856ca Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 15:45:06 -0500 Subject: [PATCH 22/50] so many variadics. --- Engine/source/console/engineAPI.h | 1424 +---------------------------- 1 file changed, 45 insertions(+), 1379 deletions(-) diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index 3ed1ad21e..896bf336a 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -567,6 +567,14 @@ namespace engineAPI{ using SeqType = typename Gens::type; }; + + struct MarshallHelpers { + template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const ArgTs& ...args){} + template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const H& head, const Tail& ...tail){ + EngineMarshallData(head, argc, argv); + marshallEach(argc, argv, tail...); + } + }; } } @@ -1165,6 +1173,8 @@ public: // Base helper for console callbacks struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper { +private: + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis ) @@ -1173,493 +1183,29 @@ public: mArgc = mInitialArgc = pThis ? 2 : 1 ; mCallbackName = callbackName; } - - template< typename R > - R call() + + template< typename R, typename ...ArgTs > + R call(ArgTs ...args) { if (Con::isMainThread()) { ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc, mArgv); + CSTK.reserveValues(mArgc + sizeof...(ArgTs), mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); + + Helper::marshallEach(mArgc, mArgv, args...); + return R( EngineUnmarshallData< R >()( _exec() ) ); } else { SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb); + SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc + sizeof...(ArgTs), NULL, false, &cb); evt->populateArgs(mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - - - template< typename R, typename A > - R call( A a ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+1, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B > - R call( A a, B b ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+2, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C > - R call( A a, B b, C c ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+3, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D > - R call( A a, B b, C c, D d ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+4, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E > - R call( A a, B b, C c, D d, E e ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+5, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > - R call( A a, B b, C c, D d, E e, F f ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+6, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > - R call( A a, B b, C c, D d, E e, F f, G g ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+7, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > - R call( A a, B b, C c, D d, E e, F f, G g, H h ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+8, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+9, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+10, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+11, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+12, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - EngineMarshallData( l, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - EngineMarshallData( l, mArgc, mArgv ); - + + Helper::marshallEach(mArgc, mArgv, args...); + Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); @@ -1672,6 +1218,8 @@ public: // Override for when first parameter is presumably a SimObject*, in which case A will be absorbed as the callback template struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper { +private: + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleExecCallbackHelper( SimObject* pThis ) @@ -1682,457 +1230,41 @@ public: } - template< typename R, typename A > - R call( A a ) + template< typename R, typename SCB, typename ...ArgTs > + R call( SCB simCB , ArgTs ...args ) { if (Con::isMainThread()) { ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+0, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); + CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv); + mArgv[ 0 ].value->setStackStringValue(simCB); - + Helper::marshallEach(mArgc, mArgv, args...); return R( EngineUnmarshallData< R >()( _exec() ) ); } else { SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+0, NULL, true, &cb); + SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, true, &cb); evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - + mArgv[ 0 ].value->setStackStringValue(simCB); + + Helper::marshallEach(mArgc, mArgv, args...); Sim::postEvent(mThis, evt, Sim::getCurrentTime()); return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); } } - - template< typename R, typename A, typename B > - R call( A a, B b ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+1, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C > - R call( A a, B b, C c ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+2, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D > - R call( A a, B b, C c, D d ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+3, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E > - R call( A a, B b, C c, D d, E e ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+4, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > - R call( A a, B b, C c, D d, E e, F f ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+5, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > - R call( A a, B b, C c, D d, E e, F f, G g ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+6, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > - R call( A a, B b, C c, D d, E e, F f, G g, H h ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+7, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+8, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+9, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+10, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+11, mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - EngineMarshallData( l, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, true, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(a); - - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - EngineMarshallData( l, mArgc, mArgv ); - - Sim::postEvent(mThis, evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - }; // Override for when first parameter is const char* template<> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper { +private: + using Helper = engineAPI::detail::MarshallHelpers; +public: _EngineConsoleExecCallbackHelper( const char *callbackName ) { mThis = NULL; @@ -2140,498 +1272,32 @@ template<> struct _EngineConsoleExecCallbackHelper : public _BaseEn mCallbackName = StringTable->insert(callbackName); } - template< typename R > - R call() + template< typename R, typename ...ArgTs > + R call(ArgTs ...args) { if (Con::isMainThread()) { ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc, mArgv); + CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); + + Helper::marshallEach(mArgc, mArgv, args...); + return R( EngineUnmarshallData< R >()( _exec() ) ); } else { SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc, NULL, false, &cb); + SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, false, &cb); evt->populateArgs(mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); + + Helper::marshallEach(mArgc, mArgv, args...); Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); } - } - - - - template< typename R, typename A > - R call( A a ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+1, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+1, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B > - R call( A a, B b ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+2, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+2, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C > - R call( A a, B b, C c ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+3, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+3, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D > - R call( A a, B b, C c, D d ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+4, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+4, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E > - R call( A a, B b, C c, D d, E e ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+5, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+5, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > - R call( A a, B b, C c, D d, E e, F f ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+6, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+6, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > - R call( A a, B b, C c, D d, E e, F f, G g ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+7, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+7, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > - R call( A a, B b, C c, D d, E e, F f, G g, H h ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+8, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+8, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+9, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+9, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+10, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+10, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+11, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+11, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - - template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > - R call( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l ) - { - if (Con::isMainThread()) - { - ConsoleStackFrameSaver sav; sav.save(); - CSTK.reserveValues(mArgc+12, mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - EngineMarshallData( l, mArgc, mArgv ); - - return R( EngineUnmarshallData< R >()( _exec() ) ); - } - else - { - SimConsoleThreadExecCallback cb; - SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+12, NULL, false, &cb); - evt->populateArgs(mArgv); - mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - EngineMarshallData( a, mArgc, mArgv ); - EngineMarshallData( b, mArgc, mArgv ); - EngineMarshallData( c, mArgc, mArgv ); - EngineMarshallData( d, mArgc, mArgv ); - EngineMarshallData( e, mArgc, mArgv ); - EngineMarshallData( f, mArgc, mArgv ); - EngineMarshallData( g, mArgc, mArgv ); - EngineMarshallData( h, mArgc, mArgv ); - EngineMarshallData( i, mArgc, mArgv ); - EngineMarshallData( j, mArgc, mArgv ); - EngineMarshallData( k, mArgc, mArgv ); - EngineMarshallData( l, mArgc, mArgv ); - - Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); - - return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); - } - } - + } }; // Re-enable some VC warnings we disabled for this file. From b215bfb93346676aa2f2afe2e1117bdf05bac5ae Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 15:50:56 -0500 Subject: [PATCH 23/50] executef converted --- Engine/source/console/console.h | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Engine/source/console/console.h b/Engine/source/console/console.h index c1219dc86..e863c60f1 100644 --- a/Engine/source/console/console.h +++ b/Engine/source/console/console.h @@ -912,18 +912,12 @@ namespace Con /// /// @see _EngineConsoleExecCallbackHelper /// - template ConsoleValueRef executef(A a) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(); } - template ConsoleValueRef executef(A a, B b) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b); } - template ConsoleValueRef executef(A a, B b, C c) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c); } - template ConsoleValueRef executef(A a, B b, C c, D d) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e, F f) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e, f); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e, f, g); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e, f, g, h); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e, f, g, h, i); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e, f, g, h, i, j); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e, f, g, h, i, j, k); } - template ConsoleValueRef executef(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l) { _EngineConsoleExecCallbackHelper callback( a ); return callback.template call(b, c, d, e, f, g, h, i, j, k, l); } + template + ConsoleValueRef executef(R r, ArgTs ...argTs) + { + _EngineConsoleExecCallbackHelper callback( r ); + return callback.template call(argTs...); + } /// } }; From 500383591c7750035d9833d7413e3d54107d0be0 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 16:11:50 -0500 Subject: [PATCH 24/50] TSShapeConstruct commands converted --- Engine/source/console/engineAPI.h | 2 +- Engine/source/ts/tsShapeConstruct.h | 71 ++++------------------------- 2 files changed, 9 insertions(+), 64 deletions(-) diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index 896bf336a..c59b1f670 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -1154,7 +1154,7 @@ struct _BaseEngineConsoleCallbackHelper public: /// Matches up to storeArgs. - static const U32 MAX_ARGUMENTS = 11; + static constexpr U32 MAX_ARGUMENTS = 11; SimObject* mThis; S32 mInitialArgc; diff --git a/Engine/source/ts/tsShapeConstruct.h b/Engine/source/ts/tsShapeConstruct.h index 24dffe0da..f1dc86d9d 100644 --- a/Engine/source/ts/tsShapeConstruct.h +++ b/Engine/source/ts/tsShapeConstruct.h @@ -97,7 +97,8 @@ public: { eCommandType type; // Command type StringTableEntry name; // Command name - String argv[10]; // Command arguments + static constexpr U32 MAX_ARGS = 10; + String argv[MAX_ARGS]; // Command arguments S32 argc; // Number of arguments Command() : type(CmdInvalid), name(0), argc(0) { } Command( const char* _name ) @@ -105,68 +106,12 @@ public: { name = StringTable->insert( _name ); } - - // Helper functions to fill in the command arguments - inline void addArgs() { } - - template< typename A > - inline void addArgs( A a ) - { - argv[argc++] = EngineMarshallData( a ); - } - template< typename A, typename B > void addArgs( A a, B b ) - { - addArgs( a ); - addArgs( b ); - } - template< typename A, typename B, typename C > - inline void addArgs( A a, B b, C c ) - { - addArgs( a ); - addArgs( b, c ); - } - template< typename A, typename B, typename C, typename D > - inline void addArgs( A a, B b, C c, D d ) - { - addArgs( a ); - addArgs( b, c, d ); - } - template< typename A, typename B, typename C, typename D, typename E > - inline void addArgs( A a, B b, C c, D d, E e ) - { - addArgs( a ); - addArgs( b, c, d, e ); - } - template< typename A, typename B, typename C, typename D, typename E, typename F > - inline void addArgs( A a, B b, C c, D d, E e, F f ) - { - addArgs( a ); - addArgs( b, c, d, e, f ); - } - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G > - inline void addArgs( A a, B b, C c, D d, E e, F f, G g ) - { - addArgs( a ); - addArgs( b, c, d, e, f, g ); - } - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > - inline void addArgs( A a, B b, C c, D d, E e, F f, G g, H h ) - { - addArgs( a ); - addArgs( b, c, d, e, f, g, h ); - } - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > - inline void addArgs( A a, B b, C c, D d, E e, F f, G g, H h, I i ) - { - addArgs( a ); - addArgs( b, c, d, e, f, g, h, i ); - } - template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > - inline void addArgs( A a, B b, C c, D d, E e, F f, G g, H h, I i, J j ) - { - addArgs( a ); - addArgs( b, c, d, e, f, g, h, i, j ); - } + + // Helper functions to fill in the command arguments + template inline void addArgs(ArgTs ...args){ + using Helper = engineAPI::detail::MarshallHelpers; + Helper::marshallEach(argc, argv, args...); + } }; Vector mCommands; From 39bea37fa03b5096c8f20c6abc46f6c6323f8737 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 16:36:25 -0500 Subject: [PATCH 25/50] minor fixes, and converted the type table --- Engine/source/console/engineAPI.h | 16 +- Engine/source/console/engineTypeInfo.h | 392 +------------------------ Engine/source/ts/tsShapeConstruct.h | 2 +- 3 files changed, 28 insertions(+), 382 deletions(-) diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index c59b1f670..829893641 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -568,7 +568,15 @@ namespace engineAPI{ using SeqType = typename Gens::type; }; - struct MarshallHelpers { + template struct MarshallHelpers { + template static void marshallEach(S32 &argc, ArgVT *argv, const ArgTs& ...args){} + template static void marshallEach(S32 &argc, ArgVT *argv, const H& head, const Tail& ...tail){ + argv[argc++] = EngineMarshallData(head); + marshallEach(argc, argv, tail...); + } + }; + + template<> struct MarshallHelpers { template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const ArgTs& ...args){} template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const H& head, const Tail& ...tail){ EngineMarshallData(head, argc, argv); @@ -1174,7 +1182,7 @@ public: struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper { private: - using Helper = engineAPI::detail::MarshallHelpers; + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis ) @@ -1219,7 +1227,7 @@ public: template struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper { private: - using Helper = engineAPI::detail::MarshallHelpers; + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleExecCallbackHelper( SimObject* pThis ) @@ -1263,7 +1271,7 @@ public: template<> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper { private: - using Helper = engineAPI::detail::MarshallHelpers; + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleExecCallbackHelper( const char *callbackName ) { diff --git a/Engine/source/console/engineTypeInfo.h b/Engine/source/console/engineTypeInfo.h index 52d713e9e..7a9f7122c 100644 --- a/Engine/source/console/engineTypeInfo.h +++ b/Engine/source/console/engineTypeInfo.h @@ -648,395 +648,33 @@ template< typename T > const EngineFunctionTypeInfo< T > _EngineFunctionTypeTrai // Function Argument Type Infos. //-------------------------------------------------------------------------- -template< typename R > -struct _EngineArgumentTypeTable< R() > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 0; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; -#ifdef TORQUE_COMPILER_GCC - static const EngineTypeInfo* const ARGS[ 0 ]; + +#ifdef TORQUE_COMILER_GCC +#define ARGS_SIZE_SAFE(wanted) (wanted) #else - static const EngineTypeInfo* const ARGS[ 1 ]; +#define ARGS_SIZE_SAFE(wanted) (((wanted) < 1) ? 1 : (wanted)) #endif - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R > const EngineTypeInfo* const _EngineArgumentTypeTable< R() >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -#ifdef TORQUE_COMPILER_GCC -template< typename R > const EngineTypeInfo* const _EngineArgumentTypeTable< R() >::ARGS[ 0 ] = {}; -#else -template< typename R > const EngineTypeInfo* const _EngineArgumentTypeTable< R() >::ARGS[ 1 ] = {}; -#endif -template< typename R > -struct _EngineArgumentTypeTable< R( ... ) > : public _EngineArgumentTypeTable< R() > +template< typename R, typename ...ArgTs > +struct _EngineArgumentTypeTable< R( ArgTs ... ) > : public EngineArgumentTypeTable { - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A > -struct _EngineArgumentTypeTable< R( A ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 1; + static const U32 NUM_ARGUMENTS = sizeof...(ArgTs); static const bool VARIADIC = false; static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 1 ]; + static const EngineTypeInfo* const ARGS[ ARGS_SIZE_SAFE(sizeof...(ArgTs)) ]; _EngineArgumentTypeTable() : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} }; -template< typename R, typename A > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A ) >::ARGS[ 1 ] = +template< typename R, typename ...ArgTs > +const EngineTypeInfo* const _EngineArgumentTypeTable< R( ArgTs ... ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); +template< typename R, typename ...ArgTs > +const EngineTypeInfo* const _EngineArgumentTypeTable< R( ArgTs ... ) >::ARGS[ ARGS_SIZE_SAFE(sizeof...(ArgTs)) ] = { - TYPE< typename EngineTypeTraits< A >::Type >() + TYPE< typename EngineTypeTraits< ArgTs >::Type >() ... }; -template< typename R, typename A > -struct _EngineArgumentTypeTable< R( A, ... ) > : public _EngineArgumentTypeTable< R( A ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B > -struct _EngineArgumentTypeTable< R( A, B ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 2; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 2 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B ) >::ARGS[ 2 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >() -}; -template< typename R, typename A, typename B > -struct _EngineArgumentTypeTable< R( A, B, ... ) > : public _EngineArgumentTypeTable< R( A, B ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C > -struct _EngineArgumentTypeTable< R( A, B, C ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 3; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 3 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C ) >::ARGS[ 3 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >() -}; -template< typename R, typename A, typename B, typename C > -struct _EngineArgumentTypeTable< R( A, B, C, ... ) > : public _EngineArgumentTypeTable< R( A, B, C ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D > -struct _EngineArgumentTypeTable< R( A, B, C, D ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 4; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 4 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D ) >::ARGS[ 4 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D > -struct _EngineArgumentTypeTable< R( A, B, C, D, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineArgumentTypeTable< R( A, B, C, D, E ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 5; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 5 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E ) >::ARGS[ 5 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 6; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 6 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F ) >::ARGS[ 6 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >(), - TYPE< typename EngineTypeTraits< F >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E, F ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 7; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 7 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G ) >::ARGS[ 7 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >(), - TYPE< typename EngineTypeTraits< F >::Type >(), - TYPE< typename EngineTypeTraits< G >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E, F, G ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 8; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 8 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H ) >::ARGS[ 8 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >(), - TYPE< typename EngineTypeTraits< F >::Type >(), - TYPE< typename EngineTypeTraits< G >::Type >(), - TYPE< typename EngineTypeTraits< H >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 9; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 9 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I ) >::ARGS[ 9 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >(), - TYPE< typename EngineTypeTraits< F >::Type >(), - TYPE< typename EngineTypeTraits< G >::Type >(), - TYPE< typename EngineTypeTraits< H >::Type >(), - TYPE< typename EngineTypeTraits< I >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 10; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 10 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J ) >::ARGS[ 10 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >(), - TYPE< typename EngineTypeTraits< F >::Type >(), - TYPE< typename EngineTypeTraits< G >::Type >(), - TYPE< typename EngineTypeTraits< H >::Type >(), - TYPE< typename EngineTypeTraits< I >::Type >(), - TYPE< typename EngineTypeTraits< J >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 11; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 11 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K ) >::ARGS[ 11 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >(), - TYPE< typename EngineTypeTraits< F >::Type >(), - TYPE< typename EngineTypeTraits< G >::Type >(), - TYPE< typename EngineTypeTraits< H >::Type >(), - TYPE< typename EngineTypeTraits< I >::Type >(), - TYPE< typename EngineTypeTraits< J >::Type >(), - TYPE< typename EngineTypeTraits< K >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K ) > -{ - static const bool VARIADIC = true; - _EngineArgumentTypeTable() {} -}; - -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K, L ) > : public EngineArgumentTypeTable -{ - static const U32 NUM_ARGUMENTS = 12; - static const bool VARIADIC = false; - static const EngineTypeInfo* const RETURN; - static const EngineTypeInfo* const ARGS[ 12 ]; - - _EngineArgumentTypeTable() - : EngineArgumentTypeTable( TYPE< typename EngineTypeTraits< R >::Type >(), NUM_ARGUMENTS, ARGS ) {} -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K, L ) >::RETURN = TYPE< typename EngineTypeTraits< R >::Type >(); -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -const EngineTypeInfo* const _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K, L ) >::ARGS[ 12 ] = -{ - TYPE< typename EngineTypeTraits< A >::Type >(), - TYPE< typename EngineTypeTraits< B >::Type >(), - TYPE< typename EngineTypeTraits< C >::Type >(), - TYPE< typename EngineTypeTraits< D >::Type >(), - TYPE< typename EngineTypeTraits< E >::Type >(), - TYPE< typename EngineTypeTraits< F >::Type >(), - TYPE< typename EngineTypeTraits< G >::Type >(), - TYPE< typename EngineTypeTraits< H >::Type >(), - TYPE< typename EngineTypeTraits< I >::Type >(), - TYPE< typename EngineTypeTraits< J >::Type >(), - TYPE< typename EngineTypeTraits< K >::Type >(), - TYPE< typename EngineTypeTraits< L >::Type >() -}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K, L, ... ) > : public _EngineArgumentTypeTable< R( A, B, C, D, E, F, G, H, I, J, K, L ) > +template< typename R, typename ... ArgTs > +struct _EngineArgumentTypeTable< R( ArgTs ..., ... ) > : public _EngineArgumentTypeTable< R( ArgTs ... ) > { static const bool VARIADIC = true; _EngineArgumentTypeTable() {} diff --git a/Engine/source/ts/tsShapeConstruct.h b/Engine/source/ts/tsShapeConstruct.h index f1dc86d9d..78c3a8f9f 100644 --- a/Engine/source/ts/tsShapeConstruct.h +++ b/Engine/source/ts/tsShapeConstruct.h @@ -109,7 +109,7 @@ public: // Helper functions to fill in the command arguments template inline void addArgs(ArgTs ...args){ - using Helper = engineAPI::detail::MarshallHelpers; + using Helper = engineAPI::detail::MarshallHelpers; Helper::marshallEach(argc, argv, args...); } }; From 1048b7d5351ae8e17412748c9d2119c8b0a65167 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 16:48:26 -0500 Subject: [PATCH 26/50] finished variadic conversion --- Engine/source/console/engineTypes.h | 56 +++-------------------------- 1 file changed, 4 insertions(+), 52 deletions(-) diff --git a/Engine/source/console/engineTypes.h b/Engine/source/console/engineTypes.h index 65e81e5d6..321e39686 100644 --- a/Engine/source/console/engineTypes.h +++ b/Engine/source/console/engineTypes.h @@ -284,58 +284,10 @@ template< typename T > const EngineTypeInfo* const _EngineFunctionTypeTraits< T // are not guaranteed to be any meaningful value or base types to the engine type system. #define T( x ) typename EngineTypeTraits< x >::ValueType -template< typename R > -struct _EngineTypeTraits< R() > : public _EngineFunctionTypeTraits< T( R )() > {}; -template< typename R > -struct _EngineTypeTraits< R( ... ) > : public _EngineFunctionTypeTraits< T( R )( ... ) > {}; -template< typename R, typename A > -struct _EngineTypeTraits< R( A ) > : public _EngineFunctionTypeTraits< T( R )( T( A ) ) > {}; -template< typename R, typename A > -struct _EngineTypeTraits< R( A, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), ... ) > {}; -template< typename R, typename A, typename B > -struct _EngineTypeTraits< R( A, B ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ) ) > {}; -template< typename R, typename A, typename B > -struct _EngineTypeTraits< R( A, B, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), ... ) > {}; -template< typename R, typename A, typename B, typename C > -struct _EngineTypeTraits< R( A, B, C ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ) ) > {}; -template< typename R, typename A, typename B, typename C > -struct _EngineTypeTraits< R( A, B, C, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D > -struct _EngineTypeTraits< R( A, B, C, D ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D > -struct _EngineTypeTraits< R( A, B, C, D, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineTypeTraits< R( A, B, C, D, E ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E > -struct _EngineTypeTraits< R( A, B, C, D, E, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineTypeTraits< R( A, B, C, D, E, F ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F > -struct _EngineTypeTraits< R( A, B, C, D, E, F, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ), ... ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K, L ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ), T( L ) ) > {}; -template< typename R, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > -struct _EngineTypeTraits< R( A, B, C, D, E, F, G, H, I, J, K, L, ... ) > : public _EngineFunctionTypeTraits< T( R )( T( A ), T( B ), T( C ), T( D ), T( E ), T( F ), T( G ), T( H ), T( I ), T( J ), T( K ), T( L ), ... ) > {}; +template +struct _EngineTypeTraits< R(ArgTs ...) > : public _EngineFunctionTypeTraits {}; +template +struct _EngineTypeTraits< R(ArgTs ..., ...) > : public _EngineFunctionTypeTraits {}; #undef T From 9773f18a888a67600d1b16945ee7da17fd427e95 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 18:06:36 -0500 Subject: [PATCH 27/50] tabs to spaces --- Engine/source/platform/platformNet.h | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Engine/source/platform/platformNet.h b/Engine/source/platform/platformNet.h index 4e8de1d70..c07c2d9f6 100644 --- a/Engine/source/platform/platformNet.h +++ b/Engine/source/platform/platformNet.h @@ -78,8 +78,8 @@ struct NetAddress bool isSameAddress(const NetAddress &other) const { - if (type != other.type) - return false; + if (type != other.type) + return false; switch (type) { @@ -102,32 +102,32 @@ struct NetAddress bool isSameAddressAndPort(const NetAddress &other) const { - if (type != other.type) - return false; + if (type != other.type) + return false; - switch (type) - { - case NetAddress::IPAddress: - return (dMemcmp(other.address.ipv4.netNum, address.ipv4.netNum, 4) == 0) && other.port == port; - break; - case NetAddress::IPV6Address: - return (dMemcmp(other.address.ipv6.netNum, address.ipv6.netNum, 16) == 0) && other.port == port; - break; - case NetAddress::IPBroadcastAddress: - return true; - break; - case NetAddress::IPV6MulticastAddress: - return true; - break; - } + switch (type) + { + case NetAddress::IPAddress: + return (dMemcmp(other.address.ipv4.netNum, address.ipv4.netNum, 4) == 0) && other.port == port; + break; + case NetAddress::IPV6Address: + return (dMemcmp(other.address.ipv6.netNum, address.ipv6.netNum, 16) == 0) && other.port == port; + break; + case NetAddress::IPBroadcastAddress: + return true; + break; + case NetAddress::IPV6MulticastAddress: + return true; + break; + } - return false; + return false; } bool isEqual(const NetAddress &other) const { - if (type != other.type) - return false; + if (type != other.type) + return false; switch (type) { @@ -193,7 +193,7 @@ struct Net WouldBlock, NotASocket, UnknownError, - NeedHostLookup + NeedHostLookup }; enum ConnectionState { @@ -214,11 +214,11 @@ struct Net static bool smMulticastEnabled; static bool smIpv4Enabled; static bool smIpv6Enabled; - - static ConnectionNotifyEvent* smConnectionNotify; - static ConnectionAcceptedEvent* smConnectionAccept; - static ConnectionReceiveEvent* smConnectionReceive; - static PacketReceiveEvent* smPacketReceive; + + static ConnectionNotifyEvent* smConnectionNotify; + static ConnectionAcceptedEvent* smConnectionAccept; + static ConnectionReceiveEvent* smConnectionReceive; + static PacketReceiveEvent* smPacketReceive; static bool init(); From f55fc7f336ee34f0510a335b784427015c24db60 Mon Sep 17 00:00:00 2001 From: Thomas Dickerson Date: Fri, 6 Jan 2017 22:57:08 -0500 Subject: [PATCH 28/50] Fixed StaticShape onUnmount Somebody made a typo and didn't test if it compiled before committing... --- Engine/source/T3D/staticShape.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/T3D/staticShape.cpp b/Engine/source/T3D/staticShape.cpp index 1ffd5436c..c48a96aa1 100644 --- a/Engine/source/T3D/staticShape.cpp +++ b/Engine/source/T3D/staticShape.cpp @@ -240,7 +240,7 @@ void StaticShape::setTransform(const MatrixF& mat) setMaskBits(PositionMask); } -void StaticShape::onUnmount(ShapeBase*,S32) +void StaticShape::onUnmount(SceneObject*,S32) { // Make sure the client get's the final server pos. setMaskBits(PositionMask); From 1c2b096a7286d1b7d722a72877d44c3f908a41c1 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 6 Jan 2017 23:10:14 -0500 Subject: [PATCH 29/50] Whitespace consistency --- Engine/source/console/console.h | 68 +-- Engine/source/console/engineAPI.h | 274 +++++------ Engine/source/console/engineFunctions.h | 54 +-- Engine/source/gfx/video/videoCapture.cpp | 2 +- Engine/source/gui/core/guiCanvas.cpp | 488 +++++++++---------- Engine/source/gui/editor/guiEditCtrl.cpp | 24 +- Engine/source/gui/editor/guiMenuBar.cpp | 248 +++++----- Engine/source/lighting/lightManager.cpp | 14 +- Engine/source/scene/sceneContainer.cpp | 6 +- Engine/source/sim/actionMap.cpp | 582 +++++++++++------------ Engine/source/ts/tsShapeConstruct.h | 14 +- 11 files changed, 887 insertions(+), 887 deletions(-) diff --git a/Engine/source/console/console.h b/Engine/source/console/console.h index e863c60f1..f2d56c843 100644 --- a/Engine/source/console/console.h +++ b/Engine/source/console/console.h @@ -95,8 +95,8 @@ struct ConsoleLogEntry Script, GUI, Network, - GGConnect, - NUM_TYPE + GGConnect, + NUM_TYPE } mType; /// Indicates the actual log entry. @@ -897,28 +897,28 @@ template struct _EngineConsoleExecCallbackHelper; namespace Con { - /// @name Console Execution - executef - /// { - /// - /// Implements a script function thunk which automatically converts parameters to relevant console types. - /// Can be used as follows: - /// - Con::executef("functionName", ...); - /// - Con::executef(mySimObject, "functionName", ...); - /// - /// NOTE: if you get a rather cryptic template error coming through here, most likely you are trying to - /// convert a parameter which EngineMarshallType does not have a specialization for. - /// Another problem can occur if you do not include "console/simBase.h" and "console/engineAPI.h" - /// since _EngineConsoleExecCallbackHelper and SimConsoleThreadExecCallback are required. - /// - /// @see _EngineConsoleExecCallbackHelper - /// - template - ConsoleValueRef executef(R r, ArgTs ...argTs) - { - _EngineConsoleExecCallbackHelper callback( r ); - return callback.template call(argTs...); - } - /// } + /// @name Console Execution - executef + /// { + /// + /// Implements a script function thunk which automatically converts parameters to relevant console types. + /// Can be used as follows: + /// - Con::executef("functionName", ...); + /// - Con::executef(mySimObject, "functionName", ...); + /// + /// NOTE: if you get a rather cryptic template error coming through here, most likely you are trying to + /// convert a parameter which EngineMarshallType does not have a specialization for. + /// Another problem can occur if you do not include "console/simBase.h" and "console/engineAPI.h" + /// since _EngineConsoleExecCallbackHelper and SimConsoleThreadExecCallback are required. + /// + /// @see _EngineConsoleExecCallbackHelper + /// + template + ConsoleValueRef executef(R r, ArgTs ...argTs) + { + _EngineConsoleExecCallbackHelper callback( r ); + return callback.template call(argTs...); + } + /// } }; extern void expandEscape(char *dest, const char *src); @@ -1143,19 +1143,19 @@ class ConsoleStackFrameSaver { public: - bool mSaved; + bool mSaved; - ConsoleStackFrameSaver() : mSaved(false) - { - } + ConsoleStackFrameSaver() : mSaved(false) + { + } - ~ConsoleStackFrameSaver() - { - restore(); - } + ~ConsoleStackFrameSaver() + { + restore(); + } - void save(); - void restore(); + void save(); + void restore(); }; diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index 829893641..79decae13 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -339,14 +339,14 @@ struct EngineUnmarshallData< ConsoleValueRef > template struct _EngineTrampoline { - struct Args {}; + struct Args {}; }; template< typename R, typename ...ArgTs > struct _EngineTrampoline< R( ArgTs ... ) > { - typedef std::tuple Args; - std::tuple argT; + typedef std::tuple Args; + std::tuple argT; }; template< typename T > @@ -363,21 +363,21 @@ template< typename R, typename ...ArgTs > struct _EngineFunctionTrampoline< R(ArgTs...) > : public _EngineFunctionTrampolineBase< R(ArgTs...) > { private: - using Super = _EngineFunctionTrampolineBase< R(ArgTs...) >; - using ArgsType = typename Super::Args; - - template struct Seq {}; - template struct Gens : Gens {}; - template struct Gens<0, I...>{ typedef Seq type; }; - - template - static R dispatchHelper(typename Super::FunctionType fn, const ArgsType& args, Seq) { - return R( fn(std::get(args) ...) ); - } + using Super = _EngineFunctionTrampolineBase< R(ArgTs...) >; + using ArgsType = typename Super::Args; + + template struct Seq {}; + template struct Gens : Gens {}; + template struct Gens<0, I...>{ typedef Seq type; }; + + template + static R dispatchHelper(typename Super::FunctionType fn, const ArgsType& args, Seq) { + return R( fn(std::get(args) ...) ); + } - using SeqType = typename Gens::type; + using SeqType = typename Gens::type; public: - static R jmp(typename Super::FunctionType fn, const ArgsType& args ) + static R jmp(typename Super::FunctionType fn, const ArgsType& args ) { return dispatchHelper(fn, args, SeqType()); } @@ -394,25 +394,25 @@ struct _EngineMethodTrampoline {}; template< typename Frame, typename R, typename ...ArgTs > struct _EngineMethodTrampoline< Frame, R(ArgTs ...) > : public _EngineMethodTrampolineBase< R(ArgTs ...) > { - using FunctionType = R( typename Frame::ObjectType*, ArgTs ...); + using FunctionType = R( typename Frame::ObjectType*, ArgTs ...); private: - using Super = _EngineMethodTrampolineBase< R(ArgTs ...) >; - using ArgsType = typename _EngineFunctionTrampolineBase< R(ArgTs ...) >::Args; - - template struct Seq {}; - template struct Gens : Gens {}; - template struct Gens<0, I...>{ typedef Seq type; }; - - template - static R dispatchHelper(Frame f, const ArgsType& args, Seq) { - return R( f._exec(std::get(args) ...) ); - } - - using SeqType = typename Gens::type; + using Super = _EngineMethodTrampolineBase< R(ArgTs ...) >; + using ArgsType = typename _EngineFunctionTrampolineBase< R(ArgTs ...) >::Args; + + template struct Seq {}; + template struct Gens : Gens {}; + template struct Gens<0, I...>{ typedef Seq type; }; + + template + static R dispatchHelper(Frame f, const ArgsType& args, Seq) { + return R( f._exec(std::get(args) ...) ); + } + + using SeqType = typename Gens::type; public: static R jmp( typename Frame::ObjectType* object, const ArgsType& args ) { - + Frame f; f.object = object; return dispatchHelper(f, args, SeqType()); @@ -515,13 +515,13 @@ struct _EngineConsoleThunkType< void > struct _EngineConsoleThunkCountArgs { - template U32 operator()(ArgTs... args){ - return sizeof...(ArgTs); - } - - operator U32() const{ // FIXME: WHAT IS THIS?? I'm pretty sure it's incorrect, and it's the version that is invoked by all the macros - return 0; - } + template U32 operator()(ArgTs... args){ + return sizeof...(ArgTs); + } + + operator U32() const{ // FIXME: WHAT IS THIS?? I'm pretty sure it's incorrect, and it's the version that is invoked by all the macros + return 0; + } }; @@ -529,61 +529,61 @@ struct _EngineConsoleThunkCountArgs // Encapsulation of a legacy console function invocation. namespace engineAPI{ - namespace detail{ - template - struct ThunkHelpers { - using SelfType = ThunkHelpers; - using FunctionType = R(*)(ArgTs...); - template using MethodType = R(Frame::*)(ArgTs ...) const; - template using IthArgType = typename std::tuple_element >::type; - - template struct Seq {}; - template struct Gens : Gens {}; - template struct Gens<0, I...>{ typedef Seq type; }; - - typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static constexpr S32 NUM_ARGS = sizeof...(ArgTs) + startArgc; - - template - static IthArgType getRealArgValue(S32 argc, ConsoleValueRef *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs) - { - if((startArgc + index) < argc) - { - return EngineUnmarshallData< IthArgType >()( argv[ startArgc + index ] ); - } else { - return std::get(defaultArgs.mArgs); - } - } - - template - static R dispatchHelper(S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs, Seq){ - return fn(SelfType::getRealArgValue(argc, argv, defaultArgs) ...); - } - - template - static R dispatchHelper(S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs, Seq){ - return (frame->*fn)(SelfType::getRealArgValue(argc, argv, defaultArgs) ...); - } - - using SeqType = typename Gens::type; - }; - - template struct MarshallHelpers { - template static void marshallEach(S32 &argc, ArgVT *argv, const ArgTs& ...args){} - template static void marshallEach(S32 &argc, ArgVT *argv, const H& head, const Tail& ...tail){ - argv[argc++] = EngineMarshallData(head); - marshallEach(argc, argv, tail...); - } - }; - - template<> struct MarshallHelpers { - template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const ArgTs& ...args){} - template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const H& head, const Tail& ...tail){ - EngineMarshallData(head, argc, argv); - marshallEach(argc, argv, tail...); - } - }; - } + namespace detail{ + template + struct ThunkHelpers { + using SelfType = ThunkHelpers; + using FunctionType = R(*)(ArgTs...); + template using MethodType = R(Frame::*)(ArgTs ...) const; + template using IthArgType = typename std::tuple_element >::type; + + template struct Seq {}; + template struct Gens : Gens {}; + template struct Gens<0, I...>{ typedef Seq type; }; + + typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; + static constexpr S32 NUM_ARGS = sizeof...(ArgTs) + startArgc; + + template + static IthArgType getRealArgValue(S32 argc, ConsoleValueRef *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs) + { + if((startArgc + index) < argc) + { + return EngineUnmarshallData< IthArgType >()( argv[ startArgc + index ] ); + } else { + return std::get(defaultArgs.mArgs); + } + } + + template + static R dispatchHelper(S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs, Seq){ + return fn(SelfType::getRealArgValue(argc, argv, defaultArgs) ...); + } + + template + static R dispatchHelper(S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs, Seq){ + return (frame->*fn)(SelfType::getRealArgValue(argc, argv, defaultArgs) ...); + } + + using SeqType = typename Gens::type; + }; + + template struct MarshallHelpers { + template static void marshallEach(S32 &argc, ArgVT *argv, const ArgTs& ...args){} + template static void marshallEach(S32 &argc, ArgVT *argv, const H& head, const Tail& ...tail){ + argv[argc++] = EngineMarshallData(head); + marshallEach(argc, argv, tail...); + } + }; + + template<> struct MarshallHelpers { + template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const ArgTs& ...args){} + template static void marshallEach(S32 &argc, ConsoleValueRef *argv, const H& head, const Tail& ...tail){ + EngineMarshallData(head, argc, argv); + marshallEach(argc, argv, tail...); + } + }; + } } template< S32 startArgc, typename T > @@ -593,22 +593,22 @@ template< S32 startArgc, typename R, typename ...ArgTs > struct _EngineConsoleThunk< startArgc, R(ArgTs...) > { private: - using Helper = engineAPI::detail::ThunkHelpers; - using SeqType = typename Helper::SeqType; + using Helper = engineAPI::detail::ThunkHelpers; + using SeqType = typename Helper::SeqType; public: - typedef typename Helper::FunctionType FunctionType; - typedef typename Helper::ReturnType ReturnType; - template using MethodType = typename Helper::template MethodType; - static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; - + typedef typename Helper::FunctionType FunctionType; + typedef typename Helper::ReturnType ReturnType; + template using MethodType = typename Helper::template MethodType; + static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; + static ReturnType thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) { - return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType())); + return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType())); } template< typename Frame > - static ReturnType thunk( S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) + static ReturnType thunk( S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) { - return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType())); + return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType())); } }; @@ -616,23 +616,23 @@ public: template struct _EngineConsoleThunk { private: - using Helper = engineAPI::detail::ThunkHelpers; - using SeqType = typename Helper::SeqType; + using Helper = engineAPI::detail::ThunkHelpers; + using SeqType = typename Helper::SeqType; public: - typedef typename Helper::FunctionType FunctionType; - typedef typename Helper::ReturnType ReturnType; - template using MethodType = typename Helper::template MethodType; - static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; - - static void thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) - { - Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType()); - } - template< typename Frame > - static void thunk( S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) - { - Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType()); - } + typedef typename Helper::FunctionType FunctionType; + typedef typename Helper::ReturnType ReturnType; + template using MethodType = typename Helper::template MethodType; + static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; + + static void thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) + { + Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType()); + } + template< typename Frame > + static void thunk( S32 argc, ConsoleValueRef *argv, MethodType fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) + { + Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType()); + } }; @@ -1182,7 +1182,7 @@ public: struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper { private: - using Helper = engineAPI::detail::MarshallHelpers; + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis ) @@ -1191,7 +1191,7 @@ public: mArgc = mInitialArgc = pThis ? 2 : 1 ; mCallbackName = callbackName; } - + template< typename R, typename ...ArgTs > R call(ArgTs ...args) { @@ -1200,9 +1200,9 @@ public: ConsoleStackFrameSaver sav; sav.save(); CSTK.reserveValues(mArgc + sizeof...(ArgTs), mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - Helper::marshallEach(mArgc, mArgv, args...); - + + Helper::marshallEach(mArgc, mArgv, args...); + return R( EngineUnmarshallData< R >()( _exec() ) ); } else @@ -1211,9 +1211,9 @@ public: SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc + sizeof...(ArgTs), NULL, false, &cb); evt->populateArgs(mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - Helper::marshallEach(mArgc, mArgv, args...); - + + Helper::marshallEach(mArgc, mArgv, args...); + Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); @@ -1227,7 +1227,7 @@ public: template struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper { private: - using Helper = engineAPI::detail::MarshallHelpers; + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleExecCallbackHelper( SimObject* pThis ) @@ -1247,7 +1247,7 @@ public: CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv); mArgv[ 0 ].value->setStackStringValue(simCB); - Helper::marshallEach(mArgc, mArgv, args...); + Helper::marshallEach(mArgc, mArgv, args...); return R( EngineUnmarshallData< R >()( _exec() ) ); } @@ -1257,8 +1257,8 @@ public: SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, true, &cb); evt->populateArgs(mArgv); mArgv[ 0 ].value->setStackStringValue(simCB); - - Helper::marshallEach(mArgc, mArgv, args...); + + Helper::marshallEach(mArgc, mArgv, args...); Sim::postEvent(mThis, evt, Sim::getCurrentTime()); @@ -1271,7 +1271,7 @@ public: template<> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper { private: - using Helper = engineAPI::detail::MarshallHelpers; + using Helper = engineAPI::detail::MarshallHelpers; public: _EngineConsoleExecCallbackHelper( const char *callbackName ) { @@ -1288,9 +1288,9 @@ public: ConsoleStackFrameSaver sav; sav.save(); CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - Helper::marshallEach(mArgc, mArgv, args...); - + + Helper::marshallEach(mArgc, mArgv, args...); + return R( EngineUnmarshallData< R >()( _exec() ) ); } else @@ -1299,8 +1299,8 @@ public: SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, false, &cb); evt->populateArgs(mArgv); mArgv[ 0 ].value->setStackStringValue(mCallbackName); - - Helper::marshallEach(mArgc, mArgv, args...); + + Helper::marshallEach(mArgc, mArgv, args...); Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); return R( EngineUnmarshallData< R >()( cb.waitForResult() ) ); diff --git a/Engine/source/console/engineFunctions.h b/Engine/source/console/engineFunctions.h index 4346b39cf..08249ec16 100644 --- a/Engine/source/console/engineFunctions.h +++ b/Engine/source/console/engineFunctions.h @@ -93,35 +93,35 @@ struct _EngineFunctionDefaultArguments {}; template struct _EngineFunctionDefaultArguments< void(ArgTs...) > : public EngineFunctionDefaultArguments { - template using DefVST = typename EngineTypeTraits::DefaultArgumentValueStoreType; - std::tuple ...> mArgs; + template using DefVST = typename EngineTypeTraits::DefaultArgumentValueStoreType; + std::tuple ...> mArgs; private: - using SelfType = _EngineFunctionDefaultArguments< void(ArgTs...) >; - - template struct Seq {}; - template struct Gens : Gens {}; - - template struct Gens<0, I...>{ typedef Seq type; }; - - template - static void copyHelper(std::tuple ...> &args, std::tuple ...> &defaultArgs, Seq) { - constexpr size_t offset = (sizeof...(ArgTs) - sizeof...(TailTs)); - std::tie(std::get(args)...) = defaultArgs; - } - - template using MaybeSelfEnabled = typename std::enable_if::type; - - template static MaybeSelfEnabled tailInit(TailTs ...tail) { - std::tuple...> argsT; - std::tuple...> tailT = std::make_tuple(tail...); - SelfType::copyHelper(argsT, tailT, typename Gens::type()); - return argsT; - }; - + using SelfType = _EngineFunctionDefaultArguments< void(ArgTs...) >; + + template struct Seq {}; + template struct Gens : Gens {}; + + template struct Gens<0, I...>{ typedef Seq type; }; + + template + static void copyHelper(std::tuple ...> &args, std::tuple ...> &defaultArgs, Seq) { + constexpr size_t offset = (sizeof...(ArgTs) - sizeof...(TailTs)); + std::tie(std::get(args)...) = defaultArgs; + } + + template using MaybeSelfEnabled = typename std::enable_if::type; + + template static MaybeSelfEnabled tailInit(TailTs ...tail) { + std::tuple...> argsT; + std::tuple...> tailT = std::make_tuple(tail...); + SelfType::copyHelper(argsT, tailT, typename Gens::type()); + return argsT; + }; + public: - template _EngineFunctionDefaultArguments(TailTs ...tail) - : EngineFunctionDefaultArguments({sizeof...(TailTs)}), mArgs(SelfType::tailInit(tail...)) - {} + template _EngineFunctionDefaultArguments(TailTs ...tail) + : EngineFunctionDefaultArguments({sizeof...(TailTs)}), mArgs(SelfType::tailInit(tail...)) + {} }; #pragma pack( pop ) diff --git a/Engine/source/gfx/video/videoCapture.cpp b/Engine/source/gfx/video/videoCapture.cpp index 0af46af10..8f7b7e52e 100644 --- a/Engine/source/gfx/video/videoCapture.cpp +++ b/Engine/source/gfx/video/videoCapture.cpp @@ -340,7 +340,7 @@ DefineEngineFunction( stopVideoCapture, void, (),, DefineEngineFunction( playJournalToVideo, void, ( const char *journalFile, const char *videoFile, const char *encoder, F32 framerate, Point2I resolution ), - ( nullAsType(), "THEORA", 30.0f, Point2I::Zero ), + ( nullAsType(), "THEORA", 30.0f, Point2I::Zero ), "Load a journal file and capture it video.\n" "@ingroup Rendering\n" ) { diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index 400e50d73..0c91ec54f 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -52,42 +52,42 @@ IMPLEMENT_CONOBJECT(GuiCanvas); ConsoleDocClass( GuiCanvas, - "@brief A canvas on which rendering occurs.\n\n" + "@brief A canvas on which rendering occurs.\n\n" - "@section GuiCanvas_contents What a GUICanvas Can Contain...\n\n" + "@section GuiCanvas_contents What a GUICanvas Can Contain...\n\n" - "@subsection GuiCanvas_content_contentcontrol Content Control\n" - "A content control is the top level GuiControl for a screen. This GuiControl " - "will be the parent control for all other GuiControls on that particular " - "screen.\n\n" + "@subsection GuiCanvas_content_contentcontrol Content Control\n" + "A content control is the top level GuiControl for a screen. This GuiControl " + "will be the parent control for all other GuiControls on that particular " + "screen.\n\n" - "@subsection GuiCanvas_content_dialogs Dialogs\n\n" + "@subsection GuiCanvas_content_dialogs Dialogs\n\n" - "A dialog is essentially another screen, only it gets overlaid on top of the " - "current content control, and all input goes to the dialog. This is most akin " - "to the \"Open File\" dialog box found in most operating systems. When you " - "choose to open a file, and the \"Open File\" dialog pops up, you can no longer " - "send input to the application, and must complete or cancel the open file " - "request. Torque keeps track of layers of dialogs. The dialog with the highest " - "layer is on top and will get all the input, unless the dialog is " - "modeless, which is a profile option.\n\n" + "A dialog is essentially another screen, only it gets overlaid on top of the " + "current content control, and all input goes to the dialog. This is most akin " + "to the \"Open File\" dialog box found in most operating systems. When you " + "choose to open a file, and the \"Open File\" dialog pops up, you can no longer " + "send input to the application, and must complete or cancel the open file " + "request. Torque keeps track of layers of dialogs. The dialog with the highest " + "layer is on top and will get all the input, unless the dialog is " + "modeless, which is a profile option.\n\n" - "@see GuiControlProfile\n\n" + "@see GuiControlProfile\n\n" - "@section GuiCanvas_dirty Dirty Rectangles\n\n" + "@section GuiCanvas_dirty Dirty Rectangles\n\n" - "The GuiCanvas is based on dirty regions. " - "Every frame the canvas paints only the areas of the canvas that are 'dirty' " - "or need updating. In most cases, this only is the area under the mouse cursor. " - "This is why if you look in guiCanvas.cc the call to glClear is commented out. " - - "What you will see is a black screen, except in the dirty regions, where the " - "screen will be painted normally. If you are making an animated GuiControl " - "you need to add your control to the dirty areas of the canvas.\n\n" + "The GuiCanvas is based on dirty regions. " + "Every frame the canvas paints only the areas of the canvas that are 'dirty' " + "or need updating. In most cases, this only is the area under the mouse cursor. " + "This is why if you look in guiCanvas.cc the call to glClear is commented out. " + + "What you will see is a black screen, except in the dirty regions, where the " + "screen will be painted normally. If you are making an animated GuiControl " + "you need to add your control to the dirty areas of the canvas.\n\n" - "@see GuiControl\n\n" + "@see GuiControl\n\n" - "@ingroup GuiCore\n"); + "@ingroup GuiCore\n"); ColorI gCanvasClearColor( 255, 0, 255 ); ///< For GFX->clear @@ -209,29 +209,29 @@ bool GuiCanvas::onAdd() //If we're recording, store the intial video resolution if (Journal::IsRecording()) { - Journal::Write(vm.resolution.x); - Journal::Write(vm.resolution.y); - Journal::Write(vm.fullScreen); + Journal::Write(vm.resolution.x); + Journal::Write(vm.resolution.y); + Journal::Write(vm.fullScreen); } //If we're playing, read the intial video resolution from the journal if (Journal::IsPlaying()) { - Journal::Read(&vm.resolution.x); - Journal::Read(&vm.resolution.y); - Journal::Read(&vm.fullScreen); + Journal::Read(&vm.resolution.x); + Journal::Read(&vm.resolution.y); + Journal::Read(&vm.fullScreen); } if (a && a->mType != NullDevice) { mPlatformWindow = WindowManager->createWindow(newDevice, vm); - //Disable window resizing if recording ir playing a journal - if (Journal::IsRecording() || Journal::IsPlaying()) - mPlatformWindow->lockSize(true); - - // Set a minimum on the window size so people can't break us by resizing tiny. - mPlatformWindow->setMinimumWindowSize(Point2I(640,480)); + //Disable window resizing if recording ir playing a journal + if (Journal::IsRecording() || Journal::IsPlaying()) + mPlatformWindow->lockSize(true); + + // Set a minimum on the window size so people can't break us by resizing tiny. + mPlatformWindow->setMinimumWindowSize(Point2I(640,480)); // Now, we have to hook in our event callbacks so we'll get // appropriate events from the window. @@ -326,12 +326,12 @@ CanvasSizeChangeSignal GuiCanvas::smCanvasSizeChangeSignal; void GuiCanvas::handleResize( WindowId did, S32 width, S32 height ) { getCanvasSizeChangeSignal().trigger(this); - if (Journal::IsPlaying() && mPlatformWindow) - { - mPlatformWindow->lockSize(false); - mPlatformWindow->setSize(Point2I(width, height)); - mPlatformWindow->lockSize(true); - } + if (Journal::IsPlaying() && mPlatformWindow) + { + mPlatformWindow->lockSize(false); + mPlatformWindow->setSize(Point2I(width, height)); + mPlatformWindow->lockSize(true); + } // Notify the scripts if ( isMethod( "onResize" ) ) @@ -342,9 +342,9 @@ void GuiCanvas::handlePaintEvent(WindowId did) { bool canRender = mPlatformWindow->isVisible() && GFX->allowRender() && !GFX->canCurrentlyRender(); - // Do the screenshot first. + // Do the screenshot first. if ( gScreenShot != NULL && gScreenShot->isPending() && canRender ) - gScreenShot->capture( this ); + gScreenShot->capture( this ); // If the video capture is waiting for a canvas, start the capture if ( VIDCAP->isWaitingForCanvas() && canRender ) @@ -560,19 +560,19 @@ bool GuiCanvas::tabNext(void) //save the old GuiControl *oldResponder = mFirstResponder; - GuiControl* newResponder = ctrl->findNextTabable(mFirstResponder); + GuiControl* newResponder = ctrl->findNextTabable(mFirstResponder); if ( !newResponder ) newResponder = ctrl->findFirstTabable(); - if ( newResponder && newResponder != oldResponder ) - { - newResponder->setFirstResponder(); + if ( newResponder && newResponder != oldResponder ) + { + newResponder->setFirstResponder(); // CodeReview Can this get killed? Note tabPrev code. BJG - 3/25/07 -// if ( oldResponder ) -// oldResponder->onLoseFirstResponder(); +// if ( oldResponder ) +// oldResponder->onLoseFirstResponder(); return true; - } + } } return false; } @@ -585,30 +585,30 @@ bool GuiCanvas::tabPrev(void) //save the old GuiControl *oldResponder = mFirstResponder; - GuiControl* newResponder = ctrl->findPrevTabable(mFirstResponder); - if ( !newResponder ) + GuiControl* newResponder = ctrl->findPrevTabable(mFirstResponder); + if ( !newResponder ) newResponder = ctrl->findLastTabable(); - if ( newResponder && newResponder != oldResponder ) - { - newResponder->setFirstResponder(); - + if ( newResponder && newResponder != oldResponder ) + { + newResponder->setFirstResponder(); + // CodeReview As with tabNext() above, looks like this can now go. DAW - 7/05/09 - //if ( oldResponder ) - // oldResponder->onLoseFirstResponder(); + //if ( oldResponder ) + // oldResponder->onLoseFirstResponder(); return true; - } + } } return false; } bool GuiCanvas::processInputEvent(InputEventInfo &inputEvent) { - // First call the general input handler (on the extremely off-chance that it will be handled): - if (mFirstResponder && mFirstResponder->onInputEvent(inputEvent)) + // First call the general input handler (on the extremely off-chance that it will be handled): + if (mFirstResponder && mFirstResponder->onInputEvent(inputEvent)) { - return(true); + return(true); } switch (inputEvent.deviceType) @@ -1786,9 +1786,9 @@ void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */) addUpdateRegion(pos - Point2I(2, 2), Point2I(cext.x + 4, cext.y + 4)); } - mLastCursorEnabled = cursorVisible; - mLastCursor = mouseCursor; - mLastCursorPt = cursorPos; + mLastCursorEnabled = cursorVisible; + mLastCursor = mouseCursor; + mLastCursorPt = cursorPos; // Begin GFX PROFILE_START(GFXBeginScene); @@ -1830,7 +1830,7 @@ void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */) resetUpdateRegions(); - // Make sure we have a clean matrix state + // Make sure we have a clean matrix state // before we start rendering anything! GFX->setWorldMatrix( MatrixF::Identity ); GFX->setViewMatrix( MatrixF::Identity ); @@ -2039,46 +2039,46 @@ void GuiCanvas::resetUpdateRegions() void GuiCanvas::setFirstResponder( GuiControl* newResponder ) { - GuiControl* oldResponder = mFirstResponder; - Parent::setFirstResponder( newResponder ); + GuiControl* oldResponder = mFirstResponder; + Parent::setFirstResponder( newResponder ); if( oldResponder == mFirstResponder ) return; - if( oldResponder && ( oldResponder != newResponder ) ) - oldResponder->onLoseFirstResponder(); + if( oldResponder && ( oldResponder != newResponder ) ) + oldResponder->onLoseFirstResponder(); if( newResponder && ( newResponder != oldResponder ) ) newResponder->onGainFirstResponder(); } DefineEngineMethod( GuiCanvas, getContent, S32, (),, - "@brief Get the GuiControl which is being used as the content.\n\n" + "@brief Get the GuiControl which is being used as the content.\n\n" - "@tsexample\n" - "Canvas.getContent();\n" - "@endtsexample\n\n" + "@tsexample\n" + "Canvas.getContent();\n" + "@endtsexample\n\n" - "@return ID of current content control") + "@return ID of current content control") { - GuiControl *ctrl = object->getContentControl(); + GuiControl *ctrl = object->getContentControl(); if(ctrl) return ctrl->getId(); return -1; } DefineEngineMethod( GuiCanvas, setContent, void, (GuiControl* ctrl),, - "@brief Set the content of the canvas to a specified control.\n\n" + "@brief Set the content of the canvas to a specified control.\n\n" - "@param ctrl ID or name of GuiControl to set content to\n\n" + "@param ctrl ID or name of GuiControl to set content to\n\n" - "@tsexample\n" - "Canvas.setContent(PlayGui);\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.setContent(PlayGui);\n" + "@endtsexample\n\n") { - // Not using old error reporting until we modify the engineAPI - mperry + // Not using old error reporting until we modify the engineAPI - mperry - //GuiControl *gui = NULL; + //GuiControl *gui = NULL; // if(argv[2][0]) // { // if (!Sim::findObject(argv[2], gui)) @@ -2088,11 +2088,11 @@ DefineEngineMethod( GuiCanvas, setContent, void, (GuiControl* ctrl),, // } // } - if(!ctrl) - { - Con::errorf("GuiCanvas::setContent - Invalid control specified')"); - return; - } + if(!ctrl) + { + Con::errorf("GuiCanvas::setContent - Invalid control specified')"); + return; + } //set the new content control object->setContentControl(ctrl); @@ -2111,11 +2111,11 @@ ConsoleDocFragment _pushDialog( ); DefineConsoleMethod( GuiCanvas, pushDialog, void, (const char * ctrlName, S32 layer, bool center), ( 0, false), "(GuiControl ctrl, int layer=0, bool center=false)" - "@hide") + "@hide") { GuiControl *gui; - if (! Sim::findObject(ctrlName, gui)) + if (! Sim::findObject(ctrlName, gui)) { Con::printf("pushDialog(): Invalid control: %s", ctrlName); return; @@ -2148,7 +2148,7 @@ ConsoleDocFragment _popDialog2( ); DefineConsoleMethod( GuiCanvas, popDialog, void, (GuiControl * gui), (nullAsType()), "(GuiControl ctrl=NULL)" - "@hide") + "@hide") { if (gui) object->popDialogControl(gui); @@ -2157,160 +2157,160 @@ DefineConsoleMethod( GuiCanvas, popDialog, void, (GuiControl * gui), (nullAsType } ConsoleDocFragment _popLayer1( - "@brief Removes the top most layer of dialogs\n\n" - "@tsexample\n" - "Canvas.popLayer();\n" - "@endtsexample\n\n", - "GuiCanvas", - "void popLayer();" + "@brief Removes the top most layer of dialogs\n\n" + "@tsexample\n" + "Canvas.popLayer();\n" + "@endtsexample\n\n", + "GuiCanvas", + "void popLayer();" ); ConsoleDocFragment _popLayer2( - "@brief Removes a specified layer of dialogs\n\n" - "@param layer Number of the layer to pop\n\n" - "@tsexample\n" - "Canvas.popLayer(1);\n" - "@endtsexample\n\n", - "GuiCanvas", - "void popLayer(S32 layer);" + "@brief Removes a specified layer of dialogs\n\n" + "@param layer Number of the layer to pop\n\n" + "@tsexample\n" + "Canvas.popLayer(1);\n" + "@endtsexample\n\n", + "GuiCanvas", + "void popLayer(S32 layer);" ); DefineConsoleMethod( GuiCanvas, popLayer, void, (S32 layer), (0), "(int layer)" - "@hide") + "@hide") { object->popDialogControl(layer); } DefineEngineMethod( GuiCanvas, cursorOn, void, (),, - "@brief Turns on the mouse cursor.\n\n" - "@tsexample\n" - "Canvas.cursorOn();\n" - "@endtsexample\n\n") + "@brief Turns on the mouse cursor.\n\n" + "@tsexample\n" + "Canvas.cursorOn();\n" + "@endtsexample\n\n") { - object->setCursorON(true); + object->setCursorON(true); } DefineEngineMethod( GuiCanvas, cursorOff, void, (),, - "@brief Turns on the mouse off.\n\n" - "@tsexample\n" - "Canvas.cursorOff();\n" - "@endtsexample\n\n") + "@brief Turns on the mouse off.\n\n" + "@tsexample\n" + "Canvas.cursorOff();\n" + "@endtsexample\n\n") { - object->setCursorON(false); + object->setCursorON(false); } DefineEngineMethod( GuiCanvas, setCursor, void, (GuiCursor* cursor),, - "@brief Sets the cursor for the canvas.\n\n" + "@brief Sets the cursor for the canvas.\n\n" - "@param cursor Name of the GuiCursor to use\n\n" + "@param cursor Name of the GuiCursor to use\n\n" - "@tsexample\n" - "Canvas.setCursor(\"DefaultCursor\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.setCursor(\"DefaultCursor\");\n" + "@endtsexample\n\n") { - if(!cursor) - { - Con::errorf("GuiCanvas::setCursor - Invalid GuiCursor name or ID"); - return; - } - object->setCursor(cursor); + if(!cursor) + { + Con::errorf("GuiCanvas::setCursor - Invalid GuiCursor name or ID"); + return; + } + object->setCursor(cursor); } DefineEngineMethod( GuiCanvas, renderFront, void, ( bool enable ),, - "@brief This turns on/off front-buffer rendering.\n\n" + "@brief This turns on/off front-buffer rendering.\n\n" - "@param enable True if all rendering should be done to the front buffer\n\n" + "@param enable True if all rendering should be done to the front buffer\n\n" - "@tsexample\n" - "Canvas.renderFront(false);\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.renderFront(false);\n" + "@endtsexample\n\n") { - object->setRenderFront(enable); + object->setRenderFront(enable); } DefineEngineMethod( GuiCanvas, showCursor, void, (),, - "@brief Enable rendering of the cursor.\n\n" + "@brief Enable rendering of the cursor.\n\n" - "@tsexample\n" - "Canvas.showCursor();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.showCursor();\n" + "@endtsexample\n\n") { - object->showCursor(true); + object->showCursor(true); } DefineEngineMethod( GuiCanvas, hideCursor, void, (),, - "@brief Disable rendering of the cursor.\n\n" + "@brief Disable rendering of the cursor.\n\n" - "@tsexample\n" - "Canvas.hideCursor();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.hideCursor();\n" + "@endtsexample\n\n") { - object->showCursor(false); + object->showCursor(false); } DefineEngineMethod( GuiCanvas, isCursorOn, bool, (),, - "@brief Determines if mouse cursor is enabled.\n\n" + "@brief Determines if mouse cursor is enabled.\n\n" - "@tsexample\n" - "// Is cursor on?\n" - "if(Canvas.isCursorOn())\n" - " echo(\"Canvas cursor is on\");\n" - "@endtsexample\n\n" - "@return Returns true if the cursor is on.\n\n") + "@tsexample\n" + "// Is cursor on?\n" + "if(Canvas.isCursorOn())\n" + " echo(\"Canvas cursor is on\");\n" + "@endtsexample\n\n" + "@return Returns true if the cursor is on.\n\n") { - return object->isCursorON(); + return object->isCursorON(); } DefineEngineMethod( GuiCanvas, isCursorShown, bool, (),, - "@brief Determines if mouse cursor is rendering.\n\n" + "@brief Determines if mouse cursor is rendering.\n\n" - "@tsexample\n" - "// Is cursor rendering?\n" - "if(Canvas.isCursorShown())\n" - " echo(\"Canvas cursor is rendering\");\n" - "@endtsexample\n\n" - "@return Returns true if the cursor is rendering.\n\n") + "@tsexample\n" + "// Is cursor rendering?\n" + "if(Canvas.isCursorShown())\n" + " echo(\"Canvas cursor is rendering\");\n" + "@endtsexample\n\n" + "@return Returns true if the cursor is rendering.\n\n") { - return object->isCursorShown(); + return object->isCursorShown(); } DefineEngineMethod( GuiCanvas, repaint, void, ( S32 elapsedMS ), (0), - "@brief Force canvas to redraw.\n" + "@brief Force canvas to redraw.\n" "If the elapsed time is greater than the time since the last paint " "then the repaint will be skipped.\n" "@param elapsedMS The optional elapsed time in milliseconds.\n\n" - "@tsexample\n" - "Canvas.repaint();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.repaint();\n" + "@endtsexample\n\n") { - object->repaint(elapsedMS < 0 ? 0 : elapsedMS); + object->repaint(elapsedMS < 0 ? 0 : elapsedMS); } DefineEngineMethod( GuiCanvas, reset, void, (),, - "@brief Reset the update regions for the canvas.\n\n" + "@brief Reset the update regions for the canvas.\n\n" - "@tsexample\n" - "Canvas.reset();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.reset();\n" + "@endtsexample\n\n") { - object->resetUpdateRegions(); + object->resetUpdateRegions(); } DefineEngineMethod( GuiCanvas, getCursorPos, Point2I, (),, - "@brief Get the current position of the cursor in screen-space. Note that this position" + "@brief Get the current position of the cursor in screen-space. Note that this position" " might be outside the Torque window. If you want to get the position within the Canvas," " call screenToClient on the result.\n\n" "@see Canvas::screenToClient()\n\n" - "@param param Description\n\n" - "@tsexample\n" - "%cursorPos = Canvas.getCursorPos();\n" - "@endtsexample\n\n" - "@return Screen coordinates of mouse cursor, in format \"X Y\"") + "@param param Description\n\n" + "@tsexample\n" + "%cursorPos = Canvas.getCursorPos();\n" + "@endtsexample\n\n" + "@return Screen coordinates of mouse cursor, in format \"X Y\"") { - return object->getCursorPos(); + return object->getCursorPos(); } ConsoleDocFragment _setCursorPos1( @@ -2334,21 +2334,21 @@ ConsoleDocFragment _setCursorPos2( ); DefineConsoleMethod( GuiCanvas, setCursorPos, void, (Point2I pos), , "(Point2I pos)" - "@hide") + "@hide") { object->setCursorPos(pos); } DefineEngineMethod( GuiCanvas, getMouseControl, S32, (),, - "@brief Gets the gui control under the mouse.\n\n" - "@tsexample\n" - "%underMouse = Canvas.getMouseControl();\n" - "@endtsexample\n\n" + "@brief Gets the gui control under the mouse.\n\n" + "@tsexample\n" + "%underMouse = Canvas.getMouseControl();\n" + "@endtsexample\n\n" - "@return ID of the gui control, if one was found. NULL otherwise") + "@return ID of the gui control, if one was found. NULL otherwise") { - GuiControl* control = object->getMouseControl(); + GuiControl* control = object->getMouseControl(); if (control) return control->getId(); @@ -2356,18 +2356,18 @@ DefineEngineMethod( GuiCanvas, getMouseControl, S32, (),, } DefineEngineFunction(excludeOtherInstance, bool, (const char* appIdentifer),, - "@brief Used to exclude/prevent all other instances using the same identifier specified\n\n" + "@brief Used to exclude/prevent all other instances using the same identifier specified\n\n" - "@note Not used on OSX, Xbox, or in Win debug builds\n\n" + "@note Not used on OSX, Xbox, or in Win debug builds\n\n" - "@param appIdentifier Name of the app set up for exclusive use.\n" + "@param appIdentifier Name of the app set up for exclusive use.\n" - "@return False if another app is running that specified the same appIdentifier\n\n" + "@return False if another app is running that specified the same appIdentifier\n\n" - "@ingroup Platform\n" - "@ingroup GuiCore") + "@ingroup Platform\n" + "@ingroup GuiCore") { - // mac/360 can only run one instance in general. + // mac/360 can only run one instance in general. #if !defined(TORQUE_OS_MAC) && !defined(TORQUE_OS_XENON) && !defined(TORQUE_DEBUG) && !defined(TORQUE_OS_LINUX) return Platform::excludeOtherInstances(appIdentifer); #else @@ -2377,82 +2377,82 @@ DefineEngineFunction(excludeOtherInstance, bool, (const char* appIdentifer),, } DefineEngineMethod( GuiCanvas, getExtent, Point2I, (),, - "@brief Returns the dimensions of the canvas\n\n" + "@brief Returns the dimensions of the canvas\n\n" - "@tsexample\n" - "%extent = Canvas.getExtent();\n" - "@endtsexample\n\n" + "@tsexample\n" + "%extent = Canvas.getExtent();\n" + "@endtsexample\n\n" - "@return Width and height of canvas. Formatted as numerical values in a single string \"# #\"") + "@return Width and height of canvas. Formatted as numerical values in a single string \"# #\"") { - return object->getExtent(); + return object->getExtent(); } DefineEngineMethod( GuiCanvas, setWindowTitle, void, ( const char* newTitle),, - "@brief Change the title of the OS window.\n\n" + "@brief Change the title of the OS window.\n\n" - "@param newTitle String containing the new name\n\n" + "@param newTitle String containing the new name\n\n" - "@tsexample\n" - "Canvas.setWindowTitle(\"Documentation Rocks!\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.setWindowTitle(\"Documentation Rocks!\");\n" + "@endtsexample\n\n") { - object->setWindowTitle(newTitle); + object->setWindowTitle(newTitle); } DefineEngineMethod( GuiCanvas, findFirstMatchingMonitor, S32, (const char* name),, - "@brief Find the first monitor index that matches the given name.\n\n" + "@brief Find the first monitor index that matches the given name.\n\n" "The actual match algorithm depends on the implementation.\n" "@param name The name to search for.\n\n" - "@return The number of monitors attached to the system, including the default monoitor.") + "@return The number of monitors attached to the system, including the default monoitor.") { return PlatformWindowManager::get()->findFirstMatchingMonitor(name); } DefineEngineMethod( GuiCanvas, getMonitorCount, S32, (),, - "@brief Gets the number of monitors attached to the system.\n\n" + "@brief Gets the number of monitors attached to the system.\n\n" - "@return The number of monitors attached to the system, including the default monoitor.") + "@return The number of monitors attached to the system, including the default monoitor.") { return PlatformWindowManager::get()->getMonitorCount(); } DefineEngineMethod( GuiCanvas, getMonitorName, const char*, (S32 index),, - "@brief Gets the name of the requested monitor.\n\n" + "@brief Gets the name of the requested monitor.\n\n" "@param index The monitor index.\n\n" - "@return The name of the requested monitor.") + "@return The name of the requested monitor.") { return PlatformWindowManager::get()->getMonitorName(index); } DefineEngineMethod( GuiCanvas, getMonitorRect, RectI, (S32 index),, - "@brief Gets the region of the requested monitor.\n\n" + "@brief Gets the region of the requested monitor.\n\n" "@param index The monitor index.\n\n" - "@return The rectangular region of the requested monitor.") + "@return The rectangular region of the requested monitor.") { return PlatformWindowManager::get()->getMonitorRect(index); } DefineEngineMethod( GuiCanvas, getVideoMode, const char*, (),, - "@brief Gets the current screen mode as a string.\n\n" + "@brief Gets the current screen mode as a string.\n\n" - "The return string will contain 5 values (width, height, fullscreen, bitdepth, refreshRate). " - "You will need to parse out each one for individual use.\n\n" + "The return string will contain 5 values (width, height, fullscreen, bitdepth, refreshRate). " + "You will need to parse out each one for individual use.\n\n" - "@tsexample\n" - "%screenWidth = getWord(Canvas.getVideoMode(), 0);\n" - "%screenHeight = getWord(Canvas.getVideoMode(), 1);\n" - "%isFullscreen = getWord(Canvas.getVideoMode(), 2);\n" - "%bitdepth = getWord(Canvas.getVideoMode(), 3);\n" - "%refreshRate = getWord(Canvas.getVideoMode(), 4);\n" - "@endtsexample\n\n" + "@tsexample\n" + "%screenWidth = getWord(Canvas.getVideoMode(), 0);\n" + "%screenHeight = getWord(Canvas.getVideoMode(), 1);\n" + "%isFullscreen = getWord(Canvas.getVideoMode(), 2);\n" + "%bitdepth = getWord(Canvas.getVideoMode(), 3);\n" + "%refreshRate = getWord(Canvas.getVideoMode(), 4);\n" + "@endtsexample\n\n" - "@return String formatted with screen width, screen height, screen mode, bit depth, and refresh rate.") + "@return String formatted with screen width, screen height, screen mode, bit depth, and refresh rate.") { - // Grab the video mode. + // Grab the video mode. if (!object->getPlatformWindow()) return ""; @@ -2463,17 +2463,17 @@ DefineEngineMethod( GuiCanvas, getVideoMode, const char*, (),, DefineEngineMethod( GuiCanvas, getModeCount, S32, (),, - "@brief Gets the number of modes available on this device.\n\n" + "@brief Gets the number of modes available on this device.\n\n" - "@param param Description\n\n" + "@param param Description\n\n" - "@tsexample\n" - "%modeCount = Canvas.getModeCount()\n" - "@endtsexample\n\n" + "@tsexample\n" + "%modeCount = Canvas.getModeCount()\n" + "@endtsexample\n\n" - "@return The number of video modes supported by the device") + "@return The number of video modes supported by the device") { - if (!object->getPlatformWindow()) + if (!object->getPlatformWindow()) return 0; // Grab the available mode list from the device. @@ -2485,12 +2485,12 @@ DefineEngineMethod( GuiCanvas, getModeCount, S32, (),, } DefineEngineMethod( GuiCanvas, getMode, const char*, (S32 modeId),, - "@brief Gets information on the specified mode of this device.\n\n" - "@param modeId Index of the mode to get data from.\n" - "@return A video mode string given an adapter and mode index.\n\n" - "@see GuiCanvas::getVideoMode()") + "@brief Gets information on the specified mode of this device.\n\n" + "@param modeId Index of the mode to get data from.\n" + "@return A video mode string given an adapter and mode index.\n\n" + "@see GuiCanvas::getVideoMode()") { - if (!object->getPlatformWindow()) + if (!object->getPlatformWindow()) return 0; // Grab the available mode list from the device. @@ -2515,14 +2515,14 @@ DefineEngineMethod( GuiCanvas, getMode, const char*, (S32 modeId),, DefineEngineMethod( GuiCanvas, toggleFullscreen, void, (),, - "@brief toggle canvas from fullscreen to windowed mode or back.\n\n" + "@brief toggle canvas from fullscreen to windowed mode or back.\n\n" - "@tsexample\n" - "// If we are in windowed mode, the following will put is in fullscreen\n" - "Canvas.toggleFullscreen();" - "@endtsexample\n\n") + "@tsexample\n" + "// If we are in windowed mode, the following will put is in fullscreen\n" + "Canvas.toggleFullscreen();" + "@endtsexample\n\n") { - if (Platform::getWebDeployment()) + if (Platform::getWebDeployment()) return; if (!object->getPlatformWindow()) @@ -2693,7 +2693,7 @@ DefineConsoleMethod( GuiCanvas, setVideoMode, void, "\\param fullscreen Specify true to run fullscreen or false to run in a window\n" "\\param bitDepth [optional] The desired bit-depth. Defaults to the current setting. This parameter is ignored if you are running in a window.\n" "\\param refreshRate [optional] The desired refresh rate. Defaults to the current setting. This parameter is ignored if you are running in a window" - "\\param antialiasLevel [optional] The level of anti-aliasing to apply 0 = none" ) + "\\param antialiasLevel [optional] The level of anti-aliasing to apply 0 = none" ) { if (!object->getPlatformWindow()) return; diff --git a/Engine/source/gui/editor/guiEditCtrl.cpp b/Engine/source/gui/editor/guiEditCtrl.cpp index 5c4c09fb3..aa002f05d 100644 --- a/Engine/source/gui/editor/guiEditCtrl.cpp +++ b/Engine/source/gui/editor/guiEditCtrl.cpp @@ -716,16 +716,16 @@ void GuiEditCtrl::onRender(Point2I offset, const RectI &updateRect) ctOffset = getCurrentAddSet()->localToGlobalCoord(Point2I(0,0)); RectI box(ctOffset.x, ctOffset.y, cext.x, cext.y); - box.inset( -5, -5 ); + box.inset( -5, -5 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); + box.inset( 1, 1 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); + box.inset( 1, 1 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); + box.inset( 1, 1 ); + drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); + box.inset( 1, 1 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); - drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); } Vector::iterator i; bool multisel = mSelectedControls.size() > 1; @@ -2481,16 +2481,16 @@ DefineConsoleMethod( GuiEditCtrl, getContentControl, S32, (), , "() - Return the DefineConsoleMethod( GuiEditCtrl, setContentControl, void, (GuiControl *ctrl ), , "( GuiControl ctrl ) - Set the toplevel control to edit in the GUI editor." ) { - if (ctrl) - object->setContentControl(ctrl); + if (ctrl) + object->setContentControl(ctrl); } //----------------------------------------------------------------------------- DefineConsoleMethod( GuiEditCtrl, addNewCtrl, void, (GuiControl *ctrl), , "(GuiControl ctrl)") { - if (ctrl) - object->addNewControl(ctrl); + if (ctrl) + object->addNewControl(ctrl); } //----------------------------------------------------------------------------- @@ -2518,7 +2518,7 @@ DefineConsoleMethod( GuiEditCtrl, clearSelection, void, (), , "Clear selected co DefineConsoleMethod( GuiEditCtrl, select, void, (GuiControl *ctrl), , "(GuiControl ctrl)") { - if (ctrl) + if (ctrl) object->setSelection(ctrl, false); } @@ -2526,7 +2526,7 @@ DefineConsoleMethod( GuiEditCtrl, select, void, (GuiControl *ctrl), , "(GuiContr DefineConsoleMethod( GuiEditCtrl, setCurrentAddSet, void, (GuiControl *addSet), , "(GuiControl ctrl)") { - if (addSet) + if (addSet) object->setCurrentAddSet(addSet); } diff --git a/Engine/source/gui/editor/guiMenuBar.cpp b/Engine/source/gui/editor/guiMenuBar.cpp index ea16d4728..688531a87 100644 --- a/Engine/source/gui/editor/guiMenuBar.cpp +++ b/Engine/source/gui/editor/guiMenuBar.cpp @@ -81,8 +81,8 @@ ConsoleDocClass( GuiMenuBar, "@tsexample\n" "new GuiMenuBar(newMenuBar)\n" "{\n" - " Padding = \"0\";\n" - " //Properties not specific to this control have been omitted from this example.\n" + " Padding = \"0\";\n" + " //Properties not specific to this control have been omitted from this example.\n" "};\n\n" "// Add a menu to the menu bar\n" "newMenuBar.addMenu(0,\"New Menu\");\n\n" @@ -105,7 +105,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMouseInMenu, void, (bool isInMenu),( isInMenu "// Mouse enters or persists within the menu, causing the callback to occur.\n" "GuiMenuBar::onMouseInMenu(%this,%hasLeftMenu)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" @@ -119,14 +119,14 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuSelect, void, ( S32 menuId, const char* me "// A menu has been selected, causing the callback to occur.\n" "GuiMenuBar::onMenuSelect(%this,%menuId,%menuText)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" ); IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( S32 menuId, const char* menuText, S32 menuItemId, const char* menuItemText ), - ( menuId, menuText, menuItemId, menuItemText ), + ( menuId, menuText, menuItemId, menuItemText ), "@brief Called whenever an item in a menu is selected.\n\n" "@param menuId Index id of the menu which contains the selected menu item\n" "@param menuText Text of the menu which contains the selected menu item\n\n" @@ -136,7 +136,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( S32 menuId, const char "// A menu item has been selected, causing the callback to occur.\n" "GuiMenuBar::onMenuItemSelect(%this,%menuId,%menuText,%menuItemId,%menuItemText)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" @@ -149,7 +149,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( S32 submenuId, const ch "@tsexample\n" "GuiMenuBar::onSubmenuSelect(%this,%submenuId,%submenuText)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" @@ -216,7 +216,7 @@ DefineEngineMethod(GuiMenuBar, addMenu, void, (const char* menuText, S32 menuId) } DefineEngineMethod(GuiMenuBar, addMenuItem, void, (const char* targetMenu, const char* menuItemText, S32 menuItemId, const char* accelerator, int checkGroup, const char *cmd), - ("","",0,nullAsType(),-1,""), + ("","",0,nullAsType(),-1,""), "@brief Adds a menu item to the specified menu. The menu argument can be either the text of a menu or its id.\n\n" "@param menu Menu name or menu Id to add the new item to.\n" "@param menuItemText Text for the new menu item.\n" @@ -637,7 +637,7 @@ DefineEngineMethod(GuiMenuBar, setMenuItemSubmenuState, void, (const char* menuT } DefineEngineMethod(GuiMenuBar, addSubmenuItem, void, (const char* menuTarget, const char* menuItem, const char* submenuItemText, - int submenuItemId, const char* accelerator, int checkGroup),, + int submenuItemId, const char* accelerator, int checkGroup),, "@brief Adds a menu item to the specified menu. The menu argument can be either the text of a menu or its id.\n\n" "@param menuTarget Menu to affect a submenu in\n" "@param menuItem Menu item to affect\n" @@ -814,21 +814,21 @@ void GuiMenuBar::addMenu(const char *menuText, U32 menuId) GuiMenuBar::Menu *GuiMenuBar::findMenu(const char *menu) { - if(dIsdigit(menu[0])) - { - U32 id = dAtoi(menu); + if(dIsdigit(menu[0])) + { + U32 id = dAtoi(menu); for (U32 i = 0; i < mMenuList.size(); ++i) if (id == mMenuList[i]->id) return mMenuList[i]; - return NULL; - } - else - { + return NULL; + } + else + { for (U32 i = 0; i < mMenuList.size(); ++i) if (!dStricmp(menu, mMenuList[i]->text)) return mMenuList[i]; - return NULL; - } + return NULL; + } } GuiMenuBar::MenuItem *GuiMenuBar::findMenuItem(Menu *menu, const char *menuItem) @@ -981,13 +981,13 @@ GuiMenuBar::MenuItem *GuiMenuBar::findSubmenuItem(Menu *menu, const char *menuIt U32 id = dAtoi(menuItem); for(MenuItem *walk = menu->firstMenuItem; walk; walk = walk->nextMenuItem) if(id == walk->id) - { - if(walk->isSubmenu && walk->submenu) - { + { + if(walk->isSubmenu && walk->submenu) + { return GuiMenuBar::findMenuItem(walk->submenu, submenuItem); - } - return NULL; - } + } + return NULL; + } return NULL; } else @@ -995,13 +995,13 @@ GuiMenuBar::MenuItem *GuiMenuBar::findSubmenuItem(Menu *menu, const char *menuIt // Search by name for(MenuItem *walk = menu->firstMenuItem; walk; walk = walk->nextMenuItem) if(!dStricmp(menuItem, walk->text)) - { - if(walk->isSubmenu && walk->submenu) - { + { + if(walk->isSubmenu && walk->submenu) + { return GuiMenuBar::findMenuItem(walk->submenu, submenuItem); - } - return NULL; - } + } + return NULL; + } return NULL; } } @@ -1021,7 +1021,7 @@ void GuiMenuBar::addSubmenuItem(Menu *menu, MenuItem *submenu, const char *text, if(submenu && !submenu->isSubmenu) { Con::errorf("GuiMenuBar::addSubmenuItem: Attempting to add menuitem '%s' to an invalid submenu",text); - return; + return; } // allocate the new menu item @@ -1074,7 +1074,7 @@ void GuiMenuBar::removeSubmenuItem(MenuItem *menuItem, MenuItem *submenuItem) if(menuItem && !menuItem->isSubmenu) { Con::errorf("GuiMenuBar::removeSubmenuItem: Attempting to remove submenuitem '%s' from an invalid submenu",submenuItem->text); - return; + return; } GuiMenuBar::removeMenuItem(menuItem->submenu, submenuItem); @@ -1087,7 +1087,7 @@ void GuiMenuBar::clearSubmenuItems(MenuItem *menuitem) if(menuitem && !menuitem->isSubmenu) { Con::errorf("GuiMenuBar::clearSubmenuItems: Attempting to clear an invalid submenu"); - return; + return; } while(menuitem->submenu->firstMenuItem) @@ -1175,33 +1175,33 @@ void GuiMenuBar::onPreRender() if (!mMenuList[i]->visible) continue; - // Bounds depends on if there is a bitmap to be drawn or not + // Bounds depends on if there is a bitmap to be drawn or not if (mMenuList[i]->bitmapIndex == -1) - { + { // Text only mMenuList[i]->bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2)); } else - { + { // Will the bitmap and text be draw? if (!mMenuList[i]->drawBitmapOnly) - { + { // Draw the bitmap and the text RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); - } else - { + } else + { // Only the bitmap will be drawn RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); - } - } + } + } curX += mMenuList[i]->bounds.extent.x; } - mouseOverMenu = NULL; - mouseDownMenu = NULL; + mouseOverMenu = NULL; + mouseDownMenu = NULL; } } @@ -1222,35 +1222,35 @@ void GuiMenuBar::checkMenuMouseMove(const GuiEvent &event) void GuiMenuBar::onMouseMove(const GuiEvent &event) { Menu *hit = findHitMenu(event.mousePoint); - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) + if(hit != mouseOverMenu) + { + // If we need to, reset the mouse over menu counter and indicate + // that we should track it. + if(hit) mMouseOverCounter = 0; - if(!mCountMouseOver) - { + if(!mCountMouseOver) + { // We've never started the counter, so start it. if(hit) mCountMouseOver = true; - } + } - mouseOverMenu = hit; - setUpdate(); - } + mouseOverMenu = hit; + setUpdate(); + } } void GuiMenuBar::onMouseLeave(const GuiEvent &event) { if(mouseOverMenu) - setUpdate(); - mouseOverMenu = NULL; + setUpdate(); + mouseOverMenu = NULL; // As we've left the control, don't track how long the mouse has been // within it. if(mCountMouseOver && mMouseOverCounter >= mMouseHoverAmount) { - onMouseInMenu_callback(false); // Last parameter indicates if we've entered or left the menu + onMouseInMenu_callback(false); // Last parameter indicates if we've entered or left the menu } mCountMouseOver = false; mMouseOverCounter = 0; @@ -1259,38 +1259,38 @@ void GuiMenuBar::onMouseLeave(const GuiEvent &event) void GuiMenuBar::onMouseDragged(const GuiEvent &event) { Menu *hit = findHitMenu(event.mousePoint); - - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) + + if(hit != mouseOverMenu) + { + // If we need to, reset the mouse over menu counter and indicate + // that we should track it. + if(hit) mMouseOverCounter = 0; - if(!mCountMouseOver) - { + if(!mCountMouseOver) + { // We've never started the counter, so start it. if(hit) mCountMouseOver = true; - } + } - mouseOverMenu = hit; + mouseOverMenu = hit; mouseDownMenu = hit; - setUpdate(); + setUpdate(); onAction(); - } + } } void GuiMenuBar::onMouseDown(const GuiEvent &event) { mouseDownMenu = mouseOverMenu = findHitMenu(event.mousePoint); - setUpdate(); + setUpdate(); onAction(); } void GuiMenuBar::onMouseUp(const GuiEvent &event) { mouseDownMenu = NULL; - setUpdate(); + setUpdate(); } void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) @@ -1320,20 +1320,20 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) start.x = mMenuList[i]->bounds.point.x + mHorizontalMargin; start.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - mProfile->mFont->getHeight()) / 2; - // Draw the border + // Draw the border if (mMenuList[i]->drawBorder) - { + { RectI highlightBounds = bounds; highlightBounds.inset(1,1); if (mMenuList[i] == mouseDownMenu) renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL ); else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); - } + } - // Do we draw a bitmap? + // Do we draw a bitmap? if (mMenuList[i]->bitmapIndex != -1) - { + { S32 index = mMenuList[i]->bitmapIndex * 3; if (mMenuList[i] == mouseDownMenu) ++index; @@ -1342,24 +1342,24 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) RectI rect = mProfile->mBitmapArrayRects[index]; - Point2I bitmapstart(start); + Point2I bitmapstart(start); bitmapstart.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - rect.extent.y) / 2; drawUtil->clearBitmapModulation(); drawUtil->drawBitmapSR( mProfile->mTextureObject, offset + bitmapstart, rect); - // Should we also draw the text? + // Should we also draw the text? if (!mMenuList[i]->drawBitmapOnly) - { + { start.x += mBitmapMargin; drawUtil->setBitmapModulation( fontColor ); drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } - } else - { + } + } else + { drawUtil->setBitmapModulation( fontColor ); drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } + } } renderChildControls( offset, updateRect ); @@ -1381,7 +1381,7 @@ void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator continue; } EventDescriptor accelEvent; - ActionMap::createEventDescriptor(item->accelerator, &accelEvent); + ActionMap::createEventDescriptor(item->accelerator, &accelEvent); //now we have a modifier, and a key, add them to the canvas inputGenerator.addAcceleratorKey( this, item->cmd, accelEvent.eventCode, accelEvent.flags); @@ -1412,7 +1412,7 @@ void GuiMenuBar::acceleratorKeyPress(U32 index) { // first, call the script callback for menu selection: onMenuSelect_callback(mMenuList[i]->id, mMenuList[i]->text); - + if(item->visible) menuItemSelected(mMenuList[i], item); return; @@ -1551,15 +1551,15 @@ void GuiMenuTextListCtrl::onMouseUp(const GuiEvent &event) void GuiMenuTextListCtrl::onCellHighlighted(Point2I cell) { - // If this text list control is part of a submenu, then don't worry about - // passing this along - if(!isSubMenu) - { - RectI globalbounds(getBounds()); - Point2I globalpoint = localToGlobalCoord(globalbounds.point); - globalbounds.point = globalpoint; - mMenuBarCtrl->highlightedMenuItem(cell.y, globalbounds, mCellSize); - } + // If this text list control is part of a submenu, then don't worry about + // passing this along + if(!isSubMenu) + { + RectI globalbounds(getBounds()); + Point2I globalpoint = localToGlobalCoord(globalbounds.point); + globalbounds.point = globalpoint; + mMenuBarCtrl->highlightedMenuItem(cell.y, globalbounds, mCellSize); + } } //------------------------------------------------------------------------------ @@ -1582,9 +1582,9 @@ bool GuiSubmenuBackgroundCtrl::pointInControl(const Point2I& parentCoordPoint) S32 yt = parentCoordPoint.y - getTop(); if(findHitControl(Point2I(xt,yt)) == this) - return false; + return false; else - return true; + return true; // return xt >= 0 && yt >= 0 && xt < getWidth() && yt < getHeight(); } @@ -1609,7 +1609,7 @@ void GuiMenuBar::onSleep() void GuiMenuBar::closeMenu() { // First close any open submenu - closeSubmenu(); + closeSubmenu(); // Get the selection from the text list: S32 selectionIndex = mTextList->getSelectedCell().y; @@ -1657,25 +1657,25 @@ void GuiMenuBar::highlightedMenuItem(S32 selectionIndex, const RectI& bounds, Po } if(list) - { + { // If the highlighted item has changed... if(mouseOverSubmenu != list) - { + { closeSubmenu(); mouseOverSubmenu = NULL; // Check if this is a submenu. If so, open the submenu. if(list->isSubmenu) - { - // If there are submenu items, then open the submenu + { + // If there are submenu items, then open the submenu if(list->submenu->firstMenuItem) - { - mouseOverSubmenu = list; - onSubmenuAction(selstore, bounds, cellSize); - } - } - } - } + { + mouseOverSubmenu = list; + onSubmenuAction(selstore, bounds, cellSize); + } + } + } + } } } @@ -1745,11 +1745,11 @@ void GuiMenuBar::onAction() 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(walk->isSubmenu) - isSubmenu = 2; + // 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(walk->isSubmenu) + isSubmenu = 2; char bitmapIndex = 1; if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) @@ -1861,8 +1861,8 @@ void GuiMenuBar::onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2 char buf[512]; - // Can't have submenus within submenus. - char isSubmenu = 1; + // Can't have submenus within submenus. + char isSubmenu = 1; char bitmapIndex = 1; if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) @@ -1916,7 +1916,7 @@ void GuiMenuBar::onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2 void GuiMenuBar::closeSubmenu() { if(!mSubmenuBackground || !mSubmenuTextList) - return; + return; // Get the selection from the text list: S32 selectionIndex = mSubmenuTextList->getSelectedCell().y; @@ -1934,8 +1934,8 @@ void GuiMenuBar::closeSubmenu() if ( selectionIndex != -1 ) { MenuItem *list = NULL; - if(mouseOverSubmenu) - { + if(mouseOverSubmenu) + { list = mouseOverSubmenu->submenu->firstMenuItem; while(selectionIndex && list) @@ -1943,7 +1943,7 @@ void GuiMenuBar::closeSubmenu() list = list->nextMenuItem; selectionIndex--; } - } + } if(list) menuItemSelected(list->submenuParentMenu, list); } @@ -1981,13 +1981,13 @@ void GuiMenuBar::processTick() { // If we're at a particular number of ticks, notify the script function if(mMouseOverCounter < mMouseHoverAmount) - { + { ++mMouseOverCounter; - } else if(mMouseOverCounter == mMouseHoverAmount) - { + } else if(mMouseOverCounter == mMouseHoverAmount) + { ++mMouseOverCounter; - onMouseInMenu_callback(true); // Last parameter indicates if we've entered or left the menu - } + onMouseInMenu_callback(true); // Last parameter indicates if we've entered or left the menu + } } } diff --git a/Engine/source/lighting/lightManager.cpp b/Engine/source/lighting/lightManager.cpp index 2f8ddd5ee..58f0949c2 100644 --- a/Engine/source/lighting/lightManager.cpp +++ b/Engine/source/lighting/lightManager.cpp @@ -306,7 +306,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, GFXShaderConstHandle *lightInvRadiusSqSC, GFXShaderConstHandle *lightSpotDirSC, GFXShaderConstHandle *lightSpotAngleSC, - GFXShaderConstHandle *lightSpotFalloffSC, + GFXShaderConstHandle *lightSpotFalloffSC, GFXShaderConstBuffer *shaderConsts ) { PROFILE_SCOPE( LightManager_Update4LightConsts ); @@ -317,7 +317,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, lightInvRadiusSqSC->isValid() || lightSpotDirSC->isValid() || lightSpotAngleSC->isValid() || - lightSpotFalloffSC->isValid() ) + lightSpotFalloffSC->isValid() ) { PROFILE_SCOPE( LightManager_Update4LightConsts_setLights ); @@ -326,7 +326,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, static AlignedArray lightColors( 4, sizeof( Point4F ) ); static Point4F lightInvRadiusSq; static Point4F lightSpotAngle; - static Point4F lightSpotFalloff; + static Point4F lightSpotFalloff; F32 range; // Need to clear the buffers so that we don't leak @@ -359,10 +359,10 @@ void LightManager::_update4LightConsts( const SceneData &sgData, lightSpotDirs[2][i] = lightDir.z; if ( light->getType() == LightInfo::Spot ) - { + { lightSpotAngle[i] = mCos( mDegToRad( light->getOuterConeAngle() / 2.0f ) ); - lightSpotFalloff[i] = 1.0f / getMax( F32_MIN, mCos( mDegToRad( light->getInnerConeAngle() / 2.0f ) ) - lightSpotAngle[i] ); - } + lightSpotFalloff[i] = 1.0f / getMax( F32_MIN, mCos( mDegToRad( light->getInnerConeAngle() / 2.0f ) ) - lightSpotAngle[i] ); + } // Prescale the light color by the brightness to // avoid doing this in the shader. @@ -379,7 +379,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, shaderConsts->setSafe( lightSpotDirSC, lightSpotDirs ); shaderConsts->setSafe( lightSpotAngleSC, lightSpotAngle ); - shaderConsts->setSafe( lightSpotFalloffSC, lightSpotFalloff ); + shaderConsts->setSafe( lightSpotFalloffSC, lightSpotFalloff ); } diff --git a/Engine/source/scene/sceneContainer.cpp b/Engine/source/scene/sceneContainer.cpp index fbcd485aa..7ccb8b0b6 100644 --- a/Engine/source/scene/sceneContainer.cpp +++ b/Engine/source/scene/sceneContainer.cpp @@ -892,7 +892,7 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en *info = ri; info->point.interpolate(start, end, info->t); currentT = ri.t; - info->distance = (start - info->point).len(); + info->distance = (start - info->point).len(); } } } @@ -991,7 +991,7 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en *info = ri; info->point.interpolate(start, end, info->t); currentT = ri.t; - info->distance = (start - info->point).len(); + info->distance = (start - info->point).len(); } } } @@ -1088,7 +1088,7 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en *info = ri; info->point.interpolate(start, end, info->t); currentT = ri.t; - info->distance = (start - info->point).len(); + info->distance = (start - info->point).len(); } } } diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index a1b5c6ac2..88bcde89e 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -36,138 +36,138 @@ IMPLEMENT_CONOBJECT(ActionMap); ConsoleDocClass( ActionMap, - "@brief ActionMaps assign platform input events to console commands.\n\n" + "@brief ActionMaps assign platform input events to console commands.\n\n" - "Any platform input event can be bound in a single, generic way. In theory, the game doesn't need to know if the event came from the keyboard, mouse, joystick " - "or some other input device. This allows users of the game to map keys and actions according to their own preferences. " - "Game action maps are arranged in a stack for processing so individual parts of the game can define specific " - "actions. For example, when the player jumps into a vehicle it could push a vehicle action map and pop the default player action map.\n\n" + "Any platform input event can be bound in a single, generic way. In theory, the game doesn't need to know if the event came from the keyboard, mouse, joystick " + "or some other input device. This allows users of the game to map keys and actions according to their own preferences. " + "Game action maps are arranged in a stack for processing so individual parts of the game can define specific " + "actions. For example, when the player jumps into a vehicle it could push a vehicle action map and pop the default player action map.\n\n" - "@section ActionMap_creation Creating an ActionMap\n" + "@section ActionMap_creation Creating an ActionMap\n" - "The input system allows for the creation of multiple ActionMaps, so long as they have unique names and do not already exist. It's a simple " - "three step process.\n\n" - "1. Check to see if the ActionMap exists\n" - "2. Delete it if it exists\n" - "3. Instantiate the ActionMap\n\n" + "The input system allows for the creation of multiple ActionMaps, so long as they have unique names and do not already exist. It's a simple " + "three step process.\n\n" + "1. Check to see if the ActionMap exists\n" + "2. Delete it if it exists\n" + "3. Instantiate the ActionMap\n\n" - "The following is an example of how to create a new ActionMap:\n" + "The following is an example of how to create a new ActionMap:\n" - "@tsexample\n" - "if ( isObject( moveMap ) )\n" - " moveMap.delete();\n" - "new ActionMap(moveMap);" - "@endtsexample\n\n\n" - - "@section ActionMap_binding Binding Functions\n" - "Once you have created an ActionMap, you can start binding functionality to events. Currently, Torque 3D supports the following devices out of the box\n\n" - "* Mouse\n\n" - "* Keyboard\n\n" - "* Joystick/Gamepad\n\n" - "* Xbox 360 Controller\n\n" + "@tsexample\n" + "if ( isObject( moveMap ) )\n" + " moveMap.delete();\n" + "new ActionMap(moveMap);" + "@endtsexample\n\n\n" + + "@section ActionMap_binding Binding Functions\n" + "Once you have created an ActionMap, you can start binding functionality to events. Currently, Torque 3D supports the following devices out of the box\n\n" + "* Mouse\n\n" + "* Keyboard\n\n" + "* Joystick/Gamepad\n\n" + "* Xbox 360 Controller\n\n" - "The two most commonly used binding methods are bind() and bindCmd(). Both are similar in that they will bind functionality to a device and event, " + "The two most commonly used binding methods are bind() and bindCmd(). Both are similar in that they will bind functionality to a device and event, " "but different in how the event is interpreted. With bind(), " - "you specify a device, action to bind, then a function to be called when the event happens.\n\n" + "you specify a device, action to bind, then a function to be called when the event happens.\n\n" - "@tsexample\n" - "// Simple function that prints to console\n" - "// %val - Sent by the device letting the user know\n" - "// if an input was pressed (true) or released (false)\n" - "function testInput(%val)\n" - "{\n" - " if(%val)\n" - " echo(\"Key is down\");\n" - " else\n" - " echo(\"Key was released\");\n" - "}\n\n" - "// Bind the \'K\' key to the testInput function\n" - "moveMap.bind(keyboard, \"k\", testInput);\n\n" - "@endtsexample\n\n\n" + "@tsexample\n" + "// Simple function that prints to console\n" + "// %val - Sent by the device letting the user know\n" + "// if an input was pressed (true) or released (false)\n" + "function testInput(%val)\n" + "{\n" + " if(%val)\n" + " echo(\"Key is down\");\n" + " else\n" + " echo(\"Key was released\");\n" + "}\n\n" + "// Bind the \'K\' key to the testInput function\n" + "moveMap.bind(keyboard, \"k\", testInput);\n\n" + "@endtsexample\n\n\n" - "bindCmd is an alternative method for binding commands. This function is similar to bind(), " + "bindCmd is an alternative method for binding commands. This function is similar to bind(), " "except two functions are set to be called when the event is processed.\n\n" - "One will be called when the event is activated (input down), while the other is activated when the event is broken (input release). " + "One will be called when the event is activated (input down), while the other is activated when the event is broken (input release). " "When using bindCmd(), pass the functions as strings rather than the function names.\n\n" - "@tsexample\n" - "// Print to the console when the spacebar is pressed\n" - "function onSpaceDown()\n" - "{\n" - " echo(\"Space bar down!\");\n" - "}\n\n" + "@tsexample\n" + "// Print to the console when the spacebar is pressed\n" + "function onSpaceDown()\n" + "{\n" + " echo(\"Space bar down!\");\n" + "}\n\n" - "// Print to the console when the spacebar is released\n" - "function onSpaceUp()\n" - "{\n" - " echo(\"Space bar up!\");\n" - "}\n\n" + "// Print to the console when the spacebar is released\n" + "function onSpaceUp()\n" + "{\n" + " echo(\"Space bar up!\");\n" + "}\n\n" - "// Bind the commands onSpaceDown and onSpaceUp to spacebar events\n" - "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" - "@endtsexample\n\n" - - "@section ActionMap_switching Switching ActionMaps\n" - "Let's say you want to have different ActionMaps activated based on game play situations. A classic example would be first person shooter controls and racing controls " - "in the same game. On foot, spacebar may cause your player to jump. In a vehicle, it may cause some kind of \"turbo charge\". You simply need to push/pop the ActionMaps appropriately:\n\n" + "// Bind the commands onSpaceDown and onSpaceUp to spacebar events\n" + "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" + "@endtsexample\n\n" + + "@section ActionMap_switching Switching ActionMaps\n" + "Let's say you want to have different ActionMaps activated based on game play situations. A classic example would be first person shooter controls and racing controls " + "in the same game. On foot, spacebar may cause your player to jump. In a vehicle, it may cause some kind of \"turbo charge\". You simply need to push/pop the ActionMaps appropriately:\n\n" - "First, create two separate ActionMaps:\n\n" - "@tsexample\n" - "// Create the two ActionMaps\n" - "if ( isObject( moveMap ) )\n" - " moveMap.delete();\n" - "new ActionMap(moveMap);\n\n" - "if ( isObject( carMap ) )\n" - " carMap.delete();\n" - "new ActionMap(carMap);\n\n" - "@endtsexample\n\n" + "First, create two separate ActionMaps:\n\n" + "@tsexample\n" + "// Create the two ActionMaps\n" + "if ( isObject( moveMap ) )\n" + " moveMap.delete();\n" + "new ActionMap(moveMap);\n\n" + "if ( isObject( carMap ) )\n" + " carMap.delete();\n" + "new ActionMap(carMap);\n\n" + "@endtsexample\n\n" - "Next, create the two separate functions. Both will be bound to spacebar, but not the same ActionMap:\n\n" - "@tsexample\n" - "// Print to the console the player is jumping\n" - "function playerJump(%val)\n" - "{\n" - " if(%val)\n" - " echo(\"Player jumping!\");\n" - "}\n\n" - "// Print to the console the vehicle is charging\n" - "function turboCharge()\n" - "{\n" - " if(%val)\n" - " echo(\"Vehicle turbo charging!\");\n" - "}\n" - "@endtsexample\n\n" - - "You are now ready to bind functions to your ActionMaps' devices:\n\n" + "Next, create the two separate functions. Both will be bound to spacebar, but not the same ActionMap:\n\n" + "@tsexample\n" + "// Print to the console the player is jumping\n" + "function playerJump(%val)\n" + "{\n" + " if(%val)\n" + " echo(\"Player jumping!\");\n" + "}\n\n" + "// Print to the console the vehicle is charging\n" + "function turboCharge()\n" + "{\n" + " if(%val)\n" + " echo(\"Vehicle turbo charging!\");\n" + "}\n" + "@endtsexample\n\n" + + "You are now ready to bind functions to your ActionMaps' devices:\n\n" - "@tsexample\n" - "// Bind the spacebar to the playerJump function\n" - "// when moveMap is the active ActionMap\n" - "moveMap.bind(keyboard, \"space\", playerJump);\n\n" - "// Bind the spacebar to the turboCharge function\n" - "// when carMap is the active ActionMap\n" - "carMap.bind(keyboard, \"space\", turboCharge);\n" - "@endtsexample\n" + "@tsexample\n" + "// Bind the spacebar to the playerJump function\n" + "// when moveMap is the active ActionMap\n" + "moveMap.bind(keyboard, \"space\", playerJump);\n\n" + "// Bind the spacebar to the turboCharge function\n" + "// when carMap is the active ActionMap\n" + "carMap.bind(keyboard, \"space\", turboCharge);\n" + "@endtsexample\n" - "Finally, you can use the push() and pop() commands on each ActionMap to toggle activation. To activate an ActionMap, use push():\n\n" + "Finally, you can use the push() and pop() commands on each ActionMap to toggle activation. To activate an ActionMap, use push():\n\n" - "@tsexample\n" - "// Make moveMap the active action map\n" - "// You should now be able to activate playerJump with spacebar\n" - "moveMap.push();\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Make moveMap the active action map\n" + "// You should now be able to activate playerJump with spacebar\n" + "moveMap.push();\n" + "@endtsexample\n\n" - "To switch ActionMaps, first pop() the old one. Then you can push() the new one:\n\n" + "To switch ActionMaps, first pop() the old one. Then you can push() the new one:\n\n" - "@tsexample\n" - "// Deactivate moveMap\n" - "moveMap.pop();\n\n" - "// Activate carMap\n" - "carMap.push();\n\n" - "@endtsexample\n\n\n" + "@tsexample\n" + "// Deactivate moveMap\n" + "moveMap.pop();\n\n" + "// Activate carMap\n" + "carMap.push();\n\n" + "@endtsexample\n\n\n" - "@ingroup Input" - + "@ingroup Input" + ); // This is used for determing keys that have ascii codes for the foreign keyboards. IsAlpha doesn't work on foreign keys. @@ -775,32 +775,32 @@ const char* ActionMap::getBinding( const char* command ) // const char* ActionMap::getCommand( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - { - if ( mapNode->flags & Node::BindCmd ) - { - S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2; - char* returnString = Con::getReturnBuffer( bufferLen ); - dSprintf( returnString, bufferLen, "%s\t%s", - ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ), - ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) ); - return( returnString ); - } - else - return( mapNode->consoleFunction ); - } - } - } + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + { + if ( mapNode->flags & Node::BindCmd ) + { + S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2; + char* returnString = Con::getReturnBuffer( bufferLen ); + dSprintf( returnString, bufferLen, "%s\t%s", + ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ), + ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) ); + return( returnString ); + } + else + return( mapNode->consoleFunction ); + } + } + } - return( "" ); + return( "" ); } //------------------------------------------------------------------------------ @@ -808,92 +808,92 @@ const char* ActionMap::getCommand( const char* device, const char* action ) // Obviously, this should only be used for axes. bool ActionMap::isInverted( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - return( mapNode->flags & Node::Inverted ); - } - } + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + return( mapNode->flags & Node::Inverted ); + } + } - Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); - return( false ); + Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); + return( false ); } //------------------------------------------------------------------------------ F32 ActionMap::getScale( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - { - if ( mapNode->flags & Node::HasScale ) - return( mapNode->scaleFactor ); + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + { + if ( mapNode->flags & Node::HasScale ) + return( mapNode->scaleFactor ); else return( 1.0f ); } - } - } + } + } - Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); - return( 1.0f ); + Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); + return( 1.0f ); } //------------------------------------------------------------------------------ const char* ActionMap::getDeadZone( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - { - if ( mapNode->flags & Node::HasDeadZone ) + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + { + if ( mapNode->flags & Node::HasDeadZone ) { - char buf[64]; - dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd ); - char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 ); - dStrcpy( returnString, buf ); - return( returnString ); - } - else - return( "0 0" ); - } - } - } + char buf[64]; + dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd ); + char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 ); + dStrcpy( returnString, buf ); + return( returnString ); + } + else + return( "0 0" ); + } + } + } - Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); - return( "" ); + Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); + return( "" ); } //------------------------------------------------------------------------------ const char* ActionMap::buildActionString( const InputEventInfo* event ) { - const char* modifierString = getModifierString( event->modifier ); + const char* modifierString = getModifierString( event->modifier ); - char objectBuffer[64]; - if ( !getKeyString( event->objInst, objectBuffer ) ) - return( "" ); + char objectBuffer[64]; + if ( !getKeyString( event->objInst, objectBuffer ) ) + return( "" ); - U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2; - char* returnString = Con::getReturnBuffer( returnLen ); - dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer ); - return( returnString ); + U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2; + char* returnString = Con::getReturnBuffer( returnLen ); + dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer ); + return( returnString ); } //------------------------------------------------------------------------------ @@ -989,15 +989,15 @@ bool ActionMap::getDeviceName(const U32 deviceType, const U32 deviceInstance, ch //------------------------------------------------------------------------------ const char* ActionMap::getModifierString(const U32 modifiers) { - U32 realModifiers = modifiers; - if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT ) - realModifiers |= SI_SHIFT; - if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL ) - realModifiers |= SI_CTRL; - if ( modifiers & SI_LALT || modifiers & SI_RALT ) - realModifiers |= SI_ALT; - if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT ) - realModifiers |= SI_MAC_OPT; + U32 realModifiers = modifiers; + if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT ) + realModifiers |= SI_SHIFT; + if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL ) + realModifiers |= SI_CTRL; + if ( modifiers & SI_LALT || modifiers & SI_RALT ) + realModifiers |= SI_ALT; + if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT ) + realModifiers |= SI_MAC_OPT; switch (realModifiers & (SI_SHIFT|SI_CTRL|SI_ALT|SI_MAC_OPT)) { @@ -1820,19 +1820,19 @@ static ConsoleDocFragment _ActionMapbind1( "@param command The function to bind to the action. Function must have a single boolean argument.\n" "@return True if the binding was successful, false if the device was unknown or description failed.\n\n" "@tsexample\n" - "// Simple function that prints to console\n" - "// %val - Sent by the device letting the user know\n" - "// if an input was pressed (true) or released (false)\n" - "function testInput(%val)\n" - "{\n" - " if(%val)\n" - " echo(\"Key is down\");\n" - " else\n" - " echo(\"Key was released\");\n" - "}\n\n" - "// Bind the \'K\' key to the testInput function\n" - "moveMap.bind(keyboard, k, testInput);\n\n" - "@endtsexample\n\n\n", + "// Simple function that prints to console\n" + "// %val - Sent by the device letting the user know\n" + "// if an input was pressed (true) or released (false)\n" + "function testInput(%val)\n" + "{\n" + " if(%val)\n" + " echo(\"Key is down\");\n" + " else\n" + " echo(\"Key was released\");\n" + "}\n\n" + "// Bind the \'K\' key to the testInput function\n" + "moveMap.bind(keyboard, k, testInput);\n\n" + "@endtsexample\n\n\n", "ActionMap", "bool bind( string device, string action, string command );"); @@ -1854,22 +1854,22 @@ static ConsoleDocFragment _ActionMapbind2( "@param command The function bound to the action. Must take in a single argument.\n" "@return True if the binding was successful, false if the device was unknown or description failed.\n\n" "@tsexample\n" - "// Simple function that adjusts the pitch of the camera based on the " + "// Simple function that adjusts the pitch of the camera based on the " "mouse's movement along the X axis.\n" - "function testPitch(%val)\n" - "{\n" - " %pitchAdj = getMouseAdjustAmount(%val);\n" - " $mvPitch += %pitchAdj;\n" - "}\n\n" - "// Bind the mouse's X axis to the testPitch function\n" - "// DI is flagged, meaning input is inverted and has a deadzone\n" - "%this.bind( mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\n" - "@endtsexample\n\n\n", + "function testPitch(%val)\n" + "{\n" + " %pitchAdj = getMouseAdjustAmount(%val);\n" + " $mvPitch += %pitchAdj;\n" + "}\n\n" + "// Bind the mouse's X axis to the testPitch function\n" + "// DI is flagged, meaning input is inverted and has a deadzone\n" + "%this.bind( mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\n" + "@endtsexample\n\n\n", "ActionMap", "bool bind( string device, string action, string flag, string deadZone, string scale, string command );"); ConsoleMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier spec, mod...], command )" - "@hide") + "@hide") { StringStackWrapper args(argc - 2, argv + 2); return object->processBind( args.count(), args, NULL ); @@ -1918,7 +1918,7 @@ static ConsoleDocFragment _ActionMapbindObj2( "bool bindObj( string device, string action, string flag, string deadZone, string scale, string command, SimObjectID object );"); ConsoleMethod( ActionMap, bindObj, bool, 6, 11, "(device, action, [modifier spec, mod...], command, object)" - "@hide") + "@hide") { SimObject* simObject = Sim::findObject(argv[argc - 1]); if ( simObject == NULL ) @@ -1941,20 +1941,20 @@ DefineEngineMethod( ActionMap, bindCmd, bool, ( const char* device, const char* "@param makeCmd The command to execute when the device/action is made.\n" "@param breakCmd [optional] The command to execute when the device or action is unmade.\n" "@return True the bind was successful, false if the device was unknown or description failed.\n" - "@tsexample\n" - "// Print to the console when the spacebar is pressed\n" - "function onSpaceDown()\n" - "{\n" - " echo(\"Space bar down!\");\n" - "}\n\n" - "// Print to the console when the spacebar is released\n" - "function onSpaceUp()\n" - "{\n" - " echo(\"Space bar up!\");\n" - "}\n\n" + "@tsexample\n" + "// Print to the console when the spacebar is pressed\n" + "function onSpaceDown()\n" + "{\n" + " echo(\"Space bar down!\");\n" + "}\n\n" + "// Print to the console when the spacebar is released\n" + "function onSpaceUp()\n" + "{\n" + " echo(\"Space bar up!\");\n" + "}\n\n" "// Bind the commands onSpaceDown() and onSpaceUp() to spacebar events\n\n" - "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" - "@endtsexample\n\n") + "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" + "@endtsexample\n\n") { return object->processBindCmd( device, action, makeCmd, breakCmd ); } @@ -1964,9 +1964,9 @@ DefineEngineMethod( ActionMap, unbind, bool, ( const char* device, const char* a "@param device The device to unbind from. Can be a keyboard, mouse, joystick or a gamepad.\n" "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n" "@return True if the unbind was successful, false if the device was unknown or description failed.\n\n" - "@tsexample\n" - "moveMap.unbind(\"keyboard\", \"space\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "moveMap.unbind(\"keyboard\", \"space\");\n" + "@endtsexample\n\n") { return object->processUnbind( device, action ); } @@ -1977,7 +1977,7 @@ DefineEngineMethod( ActionMap, unbindObj, bool, ( const char* device, const char "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n" "@param obj The object to perform unbind against.\n" "@return True if the unbind was successful, false if the device was unknown or description failed.\n" - "@tsexample\n" + "@tsexample\n" "moveMap.unbindObj(\"keyboard\", \"numpad1\", \"rangeChange\", %player);" "@endtsexample\n\n\n") { @@ -1996,10 +1996,10 @@ DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ) "@param fileName The file path to save the ActionMap to. If a filename is not specified " " the ActionMap will be dumped to the console.\n" "@param append Whether to write the ActionMap at the end of the file or overwrite it.\n" - "@tsexample\n" - "// Write out the actionmap into the config.cs file\n" + "@tsexample\n" + "// Write out the actionmap into the config.cs file\n" "moveMap.save( \"scripts/client/config.cs\" );" - "@endtsexample\n\n") + "@endtsexample\n\n") { char buffer[1024]; @@ -2015,7 +2015,7 @@ DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ) DefineEngineFunction( getCurrentActionMap, ActionMap*, (),, "@brief Returns the current %ActionMap.\n" "@see ActionMap" - "@ingroup Input") + "@ingroup Input") { SimSet* pActionMapSet = Sim::getActiveActionMapSet(); return dynamic_cast< ActionMap* >( pActionMapSet->last() ); @@ -2024,10 +2024,10 @@ DefineEngineFunction( getCurrentActionMap, ActionMap*, (),, DefineEngineMethod( ActionMap, push, void, (),, "@brief Push the ActionMap onto the %ActionMap stack.\n\n" "Activates an ActionMap and placees it at the top of the ActionMap stack.\n\n" - "@tsexample\n" - "// Make moveMap the active action map\n" - "moveMap.push();\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Make moveMap the active action map\n" + "moveMap.push();\n" + "@endtsexample\n\n" "@see ActionMap") { SimSet* pActionMapSet = Sim::getActiveActionMapSet(); @@ -2037,10 +2037,10 @@ DefineEngineMethod( ActionMap, push, void, (),, DefineEngineMethod( ActionMap, pop, void, (),, "@brief Pop the ActionMap off the %ActionMap stack.\n\n" "Deactivates an %ActionMap and removes it from the @ActionMap stack.\n" - "@tsexample\n" - "// Deactivate moveMap\n" - "moveMap.pop();\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Deactivate moveMap\n" + "moveMap.pop();\n" + "@endtsexample\n\n" "@see ActionMap") { SimSet* pActionMapSet = Sim::getActiveActionMapSet(); @@ -2053,20 +2053,20 @@ DefineEngineMethod( ActionMap, getBinding, const char*, ( const char* command ), "@param command The function to search bindings for.\n" "@return The binding against the specified command. Returns an empty string(\"\") " "if a binding wasn't found.\n" - "@tsexample\n" - "// Find what the function \"jump()\" is bound to in moveMap\n" - "%bind = moveMap.getBinding( \"jump\" );\n\n" - "if ( %bind !$= \"\" )\n" - "{\n" - "// Find out what device is used in the binding\n" - " %device = getField( %bind, 0 );\n\n" - "// Find out what action (such as a key) is used in the binding\n" - " %action = getField( %bind, 1 );\n" - "}\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Find what the function \"jump()\" is bound to in moveMap\n" + "%bind = moveMap.getBinding( \"jump\" );\n\n" + "if ( %bind !$= \"\" )\n" + "{\n" + "// Find out what device is used in the binding\n" + " %device = getField( %bind, 0 );\n\n" + "// Find out what action (such as a key) is used in the binding\n" + " %action = getField( %bind, 1 );\n" + "}\n" + "@endtsexample\n\n" "@see getField") { - return object->getBinding( command ); + return object->getBinding( command ); } DefineEngineMethod( ActionMap, getCommand, const char*, ( const char* device, const char* action ),, @@ -2074,15 +2074,15 @@ DefineEngineMethod( ActionMap, getCommand, const char*, ( const char* device, co "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n" "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return The command against the specified device and action.\n" - "@tsexample\n" - "// Find what function is bound to a device\'s action\n" - "// In this example, \"jump()\" was assigned to the space key in another script\n" - "%command = moveMap.getCommand(\"keyboard\", \"space\");\n\n" - "// Should print \"jump\" in the console\n" - "echo(%command)\n" - "@endtsexample\n\n") + "@tsexample\n" + "// Find what function is bound to a device\'s action\n" + "// In this example, \"jump()\" was assigned to the space key in another script\n" + "%command = moveMap.getCommand(\"keyboard\", \"space\");\n\n" + "// Should print \"jump\" in the console\n" + "echo(%command)\n" + "@endtsexample\n\n") { - return object->getCommand( device, action ); + return object->getCommand( device, action ); } DefineEngineMethod( ActionMap, isInverted, bool, ( const char* device, const char* action ),, @@ -2091,12 +2091,12 @@ DefineEngineMethod( ActionMap, isInverted, bool, ( const char* device, const cha "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n" "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return True if the specified device and action is inverted.\n" - "@tsexample\n" + "@tsexample\n" "%if ( moveMap.isInverted( \"mouse\", \"xaxis\"))\n" " echo(\"Mouse's xAxis is inverted\");" - "@endtsexample\n\n") + "@endtsexample\n\n") { - return object->isInverted( device, action ); + return object->isInverted( device, action ); } DefineEngineMethod( ActionMap, getScale, F32, ( const char* device, const char* action ),, @@ -2104,11 +2104,11 @@ DefineEngineMethod( ActionMap, getScale, F32, ( const char* device, const char* "@param device The device that was bound. Can be keyboard, mouse, joystick or gamepad.\n" "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return Any scaling applied to the specified device and action.\n" - "@tsexample\n" - "%scale = %moveMap.getScale( \"gamepad\", \"thumbrx\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "%scale = %moveMap.getScale( \"gamepad\", \"thumbrx\");\n" + "@endtsexample\n\n") { - return object->getScale( device, action ); + return object->getScale( device, action ); } DefineEngineMethod( ActionMap, getDeadZone, const char*, ( const char* device, const char* action ),, @@ -2117,11 +2117,11 @@ DefineEngineMethod( ActionMap, getDeadZone, const char*, ( const char* device, c "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return The dead zone for the specified device and action. Returns \"0 0\" if there is no dead zone " "or an empty string(\"\") if the mapping was not found.\n" - "@tsexample\n" - "%deadZone = moveMap.getDeadZone( \"gamepad\", \"thumbrx\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "%deadZone = moveMap.getDeadZone( \"gamepad\", \"thumbrx\");\n" + "@endtsexample\n\n") { - return object->getDeadZone( device, action ); + return object->getDeadZone( device, action ); } //------------------------------------------------------------------------------ diff --git a/Engine/source/ts/tsShapeConstruct.h b/Engine/source/ts/tsShapeConstruct.h index 78c3a8f9f..f3de7f490 100644 --- a/Engine/source/ts/tsShapeConstruct.h +++ b/Engine/source/ts/tsShapeConstruct.h @@ -97,7 +97,7 @@ public: { eCommandType type; // Command type StringTableEntry name; // Command name - static constexpr U32 MAX_ARGS = 10; + static constexpr U32 MAX_ARGS = 10; String argv[MAX_ARGS]; // Command arguments S32 argc; // Number of arguments Command() : type(CmdInvalid), name(0), argc(0) { } @@ -106,12 +106,12 @@ public: { name = StringTable->insert( _name ); } - - // Helper functions to fill in the command arguments - template inline void addArgs(ArgTs ...args){ - using Helper = engineAPI::detail::MarshallHelpers; - Helper::marshallEach(argc, argv, args...); - } + + // Helper functions to fill in the command arguments + template inline void addArgs(ArgTs ...args){ + using Helper = engineAPI::detail::MarshallHelpers; + Helper::marshallEach(argc, argv, args...); + } }; Vector mCommands; From bfa2b5e9638b8f915303476e8dde999ded4fe13d Mon Sep 17 00:00:00 2001 From: Azaezel Date: Tue, 10 Jan 2017 08:02:08 -0600 Subject: [PATCH 30/50] adress #1914 --- Engine/source/renderInstance/renderMeshMgr.cpp | 2 +- Engine/source/renderInstance/renderPrePassMgr.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/source/renderInstance/renderMeshMgr.cpp b/Engine/source/renderInstance/renderMeshMgr.cpp index 476c5e9b8..ce27a09c2 100644 --- a/Engine/source/renderInstance/renderMeshMgr.cpp +++ b/Engine/source/renderInstance/renderMeshMgr.cpp @@ -245,7 +245,7 @@ void RenderMeshMgr::render(SceneRenderState * state) if ( passRI->accuTex != lastAccuTex ) { sgData.accuTex = passRI->accuTex; - lastAccuTex = lastAccuTex; + lastAccuTex = passRI->accuTex; dirty = true; } diff --git a/Engine/source/renderInstance/renderPrePassMgr.cpp b/Engine/source/renderInstance/renderPrePassMgr.cpp index 2c3f2c4c2..23e44f6ed 100644 --- a/Engine/source/renderInstance/renderPrePassMgr.cpp +++ b/Engine/source/renderInstance/renderPrePassMgr.cpp @@ -480,7 +480,7 @@ void RenderPrePassMgr::render( SceneRenderState *state ) if (passRI->accuTex != lastAccuTex) { sgData.accuTex = passRI->accuTex; - lastAccuTex = lastAccuTex; + lastAccuTex = passRI->accuTex; dirty = true; } From d64e2a7019dc5d57c81da29b120a8b632f670d9c Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Tue, 10 Jan 2017 23:20:48 -0500 Subject: [PATCH 31/50] Removed constexpr use to support VS2013 --- Engine/source/console/consoleTypes.h | 2 +- Engine/source/console/engineAPI.h | 8 ++++---- Engine/source/console/engineFunctions.h | 3 +-- Engine/source/ts/tsShapeConstruct.h | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Engine/source/console/consoleTypes.h b/Engine/source/console/consoleTypes.h index 8b64d4fa1..1285a213d 100644 --- a/Engine/source/console/consoleTypes.h +++ b/Engine/source/console/consoleTypes.h @@ -39,7 +39,7 @@ #include "console/engineStructs.h" #endif -template constexpr T nullAsType(){ return nullptr; } +template inline const T nullAsType(){ return nullptr; } /// @file /// Legacy TS-based console type definitions. diff --git a/Engine/source/console/engineAPI.h b/Engine/source/console/engineAPI.h index 79decae13..049cce54d 100644 --- a/Engine/source/console/engineAPI.h +++ b/Engine/source/console/engineAPI.h @@ -542,7 +542,7 @@ namespace engineAPI{ template struct Gens<0, I...>{ typedef Seq type; }; typedef typename _EngineConsoleThunkType< R >::ReturnType ReturnType; - static constexpr S32 NUM_ARGS = sizeof...(ArgTs) + startArgc; + static const S32 NUM_ARGS = sizeof...(ArgTs) + startArgc; template static IthArgType getRealArgValue(S32 argc, ConsoleValueRef *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs) @@ -599,7 +599,7 @@ public: typedef typename Helper::FunctionType FunctionType; typedef typename Helper::ReturnType ReturnType; template using MethodType = typename Helper::template MethodType; - static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; + static const S32 NUM_ARGS = Helper::NUM_ARGS; static ReturnType thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) { @@ -622,7 +622,7 @@ public: typedef typename Helper::FunctionType FunctionType; typedef typename Helper::ReturnType ReturnType; template using MethodType = typename Helper::template MethodType; - static constexpr S32 NUM_ARGS = Helper::NUM_ARGS; + static const S32 NUM_ARGS = Helper::NUM_ARGS; static void thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) { @@ -1162,7 +1162,7 @@ struct _BaseEngineConsoleCallbackHelper public: /// Matches up to storeArgs. - static constexpr U32 MAX_ARGUMENTS = 11; + static const U32 MAX_ARGUMENTS = 11; SimObject* mThis; S32 mInitialArgc; diff --git a/Engine/source/console/engineFunctions.h b/Engine/source/console/engineFunctions.h index 08249ec16..cbe5b1971 100644 --- a/Engine/source/console/engineFunctions.h +++ b/Engine/source/console/engineFunctions.h @@ -105,8 +105,7 @@ private: template static void copyHelper(std::tuple ...> &args, std::tuple ...> &defaultArgs, Seq) { - constexpr size_t offset = (sizeof...(ArgTs) - sizeof...(TailTs)); - std::tie(std::get(args)...) = defaultArgs; + std::tie(std::get(args)...) = defaultArgs; } template using MaybeSelfEnabled = typename std::enable_if::type; diff --git a/Engine/source/ts/tsShapeConstruct.h b/Engine/source/ts/tsShapeConstruct.h index f3de7f490..7826e0507 100644 --- a/Engine/source/ts/tsShapeConstruct.h +++ b/Engine/source/ts/tsShapeConstruct.h @@ -97,7 +97,7 @@ public: { eCommandType type; // Command type StringTableEntry name; // Command name - static constexpr U32 MAX_ARGS = 10; + static const U32 MAX_ARGS = 10; String argv[MAX_ARGS]; // Command arguments S32 argc; // Number of arguments Command() : type(CmdInvalid), name(0), argc(0) { } From f05a552c61c35c2fbc428462dc71b36ab4919d54 Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Wed, 11 Jan 2017 18:03:21 -0500 Subject: [PATCH 32/50] Optionally include a CMake configurations file from the project directory to support configuration changes that don't have to alter the whole engine repo --- Tools/CMake/torque3d.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tools/CMake/torque3d.cmake b/Tools/CMake/torque3d.cmake index 44591dd94..a8220a545 100644 --- a/Tools/CMake/torque3d.cmake +++ b/Tools/CMake/torque3d.cmake @@ -742,6 +742,12 @@ if(MSVC) endforeach() endif() +############################################################################### +# Project-specific configuration: +############################################################################### + +include(${TORQUE_APP_DIR}/${PROJECT_NAME}.cmake OPTIONAL) + ############################################################################### # Installation ############################################################################### From bcc5459818e6c57decbd68af4cf55f299ffad93c Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Wed, 11 Jan 2017 23:34:46 -0500 Subject: [PATCH 33/50] whitespace --- Engine/source/console/fieldBrushObject.cpp | 24 +- Engine/source/console/fileSystemFunctions.cpp | 150 ++-- Engine/source/console/persistenceManager.cpp | 62 +- Engine/source/console/scriptFilename.cpp | 22 +- Engine/source/console/scriptObjects.cpp | 84 +-- Engine/source/console/sim.cpp | 22 +- Engine/source/console/simDictionary.cpp | 8 +- Engine/source/console/simDictionary.h | 2 +- Engine/source/console/simEvents.cpp | 8 +- Engine/source/console/simManager.cpp | 10 +- Engine/source/console/simObject.cpp | 20 +- Engine/source/console/simObject.h | 2 +- Engine/source/console/simObjectMemento.cpp | 46 +- Engine/source/console/simObjectMemento.h | 2 +- Engine/source/console/simPersistSet.cpp | 14 +- Engine/source/console/simSerialize.cpp | 14 +- Engine/source/console/stringStack.cpp | 2 +- Engine/source/console/telnetConsole.cpp | 12 +- Engine/source/console/telnetDebugger.cpp | 30 +- Engine/source/console/typeValidators.cpp | 56 +- Engine/source/environment/river.cpp | 228 +++---- Engine/source/gfx/gl/gfxGLStateBlock.cpp | 32 +- Engine/source/gfx/video/videoCapture.cpp | 2 +- .../source/gui/buttons/guiIconButtonCtrl.cpp | 32 +- .../gui/buttons/guiToggleButtonCtrl.cpp | 2 +- Engine/source/gui/containers/guiFormCtrl.cpp | 2 +- Engine/source/gui/containers/guiPaneCtrl.cpp | 16 +- .../source/gui/containers/guiRolloutCtrl.cpp | 14 +- .../source/gui/containers/guiWindowCtrl.cpp | 16 +- Engine/source/gui/controls/guiListBoxCtrl.cpp | 134 ++-- Engine/source/gui/controls/guiMLTextCtrl.cpp | 52 +- Engine/source/gui/controls/guiPopUpCtrl.cpp | 162 ++--- Engine/source/gui/controls/guiPopUpCtrlEx.cpp | 298 ++++---- Engine/source/gui/controls/guiTextCtrl.cpp | 40 +- .../source/gui/controls/guiTextEditCtrl.cpp | 136 ++-- .../source/gui/controls/guiTreeViewCtrl.cpp | 364 +++++----- Engine/source/gui/core/guiCanvas.cpp | 488 ++++++------- Engine/source/gui/editor/guiEditCtrl.cpp | 24 +- Engine/source/gui/editor/guiMenuBar.cpp | 248 +++---- .../gui/editor/guiParticleGraphCtrl.cpp | 640 +++++++++--------- .../source/gui/game/guiChunkedBitmapCtrl.cpp | 4 +- Engine/source/gui/worldEditor/undoActions.cpp | 22 +- Engine/source/lighting/lightManager.cpp | 14 +- Engine/source/navigation/navMesh.cpp | 8 +- Engine/source/platform/menus/popupMenu.cpp | 18 +- Engine/source/platform/profiler.cpp | 44 +- Engine/source/platformMac/macFileIO.mm | 2 +- .../renderInstance/renderPrePassMgr.cpp | 2 +- Engine/source/scene/sceneContainer.cpp | 6 +- Engine/source/sim/actionMap.cpp | 582 ++++++++-------- 50 files changed, 2111 insertions(+), 2111 deletions(-) diff --git a/Engine/source/console/fieldBrushObject.cpp b/Engine/source/console/fieldBrushObject.cpp index d0eaf541c..484178dec 100644 --- a/Engine/source/console/fieldBrushObject.cpp +++ b/Engine/source/console/fieldBrushObject.cpp @@ -109,15 +109,15 @@ void FieldBrushObject::destroyFields() static char replacebuf[1024]; static char* suppressSpaces(const char* in_pname) { - U32 i = 0; - char chr; - do - { - chr = in_pname[i]; - replacebuf[i++] = (chr != 32) ? chr : '_'; - } while(chr); + U32 i = 0; + char chr; + do + { + chr = in_pname[i]; + replacebuf[i++] = (chr != 32) ? chr : '_'; + } while(chr); - return replacebuf; + return replacebuf; } //----------------------------------------------------------------------------- @@ -125,7 +125,7 @@ static char* suppressSpaces(const char* in_pname) //----------------------------------------------------------------------------- DefineConsoleMethod(FieldBrushObject, queryGroups, const char*, (const char* simObjName), , "(simObject) Query available static-field groups for selected object./\n" "@param simObject Object to query static-field groups on.\n" - "@return Space-seperated static-field group list.") + "@return Space-seperated static-field group list.") { // Fetch selected object. SimObject* pSimObject = dynamic_cast( Sim::findObject( simObjName ) ); @@ -194,7 +194,7 @@ DefineConsoleMethod(FieldBrushObject, queryGroups, const char*, (const char* sim DefineConsoleMethod(FieldBrushObject, queryFields, const char*, (const char* simObjName, const char* groupList), (""), "(simObject, [groupList]) Query available static-fields for selected object./\n" "@param simObject Object to query static-fields on.\n" "@param groupList groups to filter static-fields against.\n" - "@return Space-seperated static-field list.") + "@return Space-seperated static-field list.") { // Fetch selected object. SimObject* pSimObject = dynamic_cast( Sim::findObject( simObjName ) ); @@ -369,7 +369,7 @@ DefineConsoleMethod(FieldBrushObject, queryFields, const char*, (const char* sim DefineConsoleMethod(FieldBrushObject, copyFields, void, (const char* simObjName, const char* pFieldList), (""), "(simObject, [fieldList]) Copy selected static-fields for selected object./\n" "@param simObject Object to copy static-fields from.\n" "@param fieldList fields to filter static-fields against.\n" - "@return No return value.") + "@return No return value.") { // Fetch selected object. SimObject* pSimObject = dynamic_cast( Sim::findObject( simObjName ) ); @@ -502,7 +502,7 @@ void FieldBrushObject::copyFields( SimObject* pSimObject, const char* fieldList //----------------------------------------------------------------------------- DefineConsoleMethod(FieldBrushObject, pasteFields, void, (const char* simObjName), , "(simObject) Paste copied static-fields to selected object./\n" "@param simObject Object to paste static-fields to.\n" - "@return No return value.") + "@return No return value.") { // Fetch selected object. SimObject* pSimObject = dynamic_cast( Sim::findObject( simObjName ) ); diff --git a/Engine/source/console/fileSystemFunctions.cpp b/Engine/source/console/fileSystemFunctions.cpp index d5ee048ca..d8531ff7c 100644 --- a/Engine/source/console/fileSystemFunctions.cpp +++ b/Engine/source/console/fileSystemFunctions.cpp @@ -210,7 +210,7 @@ DefineEngineFunction( findNextFile, String, ( const char* pattern ), ( "" ), //----------------------------------------------------------------------------- DefineEngineFunction( getFileCount, S32, ( const char* pattern, bool recurse ), ( "", true ), - "@brief Returns the number of files in the directory tree that match the given patterns\n\n" + "@brief Returns the number of files in the directory tree that match the given patterns\n\n" "This function differs from getFileCountMultiExpr() in that it supports a single search " "pattern being passed in.\n\n" @@ -246,7 +246,7 @@ DefineEngineFunction( getFileCount, S32, ( const char* pattern, bool recurse ), //----------------------------------------------------------------------------- DefineEngineFunction(findFirstFileMultiExpr, String, ( const char* pattern, bool recurse ), ( "", true), - "@brief Returns the first file in the directory system matching the given patterns.\n\n" + "@brief Returns the first file in the directory system matching the given patterns.\n\n" "Use the corresponding findNextFileMultiExpr() to step through " "the results. If you're only interested in the number of files returned by the " @@ -259,10 +259,10 @@ DefineEngineFunction(findFirstFileMultiExpr, String, ( const char* pattern, bool "call to findFirstFile() and findFirstFileMultiExpr() initiates a new search and renders " "a previous search invalid.\n\n" - "@param pattern The path and file name pattern to match against, such as *.cs. Separate " + "@param pattern The path and file name pattern to match against, such as *.cs. Separate " "multiple patterns with TABs. For example: \"*.cs\" TAB \"*.dso\"\n" - "@param recurse If true, the search will exhaustively recurse into subdirectories " - "of the given path and match the given filename patterns.\n" + "@param recurse If true, the search will exhaustively recurse into subdirectories " + "of the given path and match the given filename patterns.\n" "@return String of the first matching file path, or an empty string if no matching " "files were found.\n\n" @@ -280,7 +280,7 @@ DefineEngineFunction(findFirstFileMultiExpr, String, ( const char* pattern, bool "@see findNextFileMultiExpr()" "@see getFileCountMultiExpr()" "@see findFirstFile()" - "@ingroup FileSearches") + "@ingroup FileSearches") { S32 numResults = buildFileList(pattern, recurse, true); @@ -302,7 +302,7 @@ DefineEngineFunction(findFirstFileMultiExpr, String, ( const char* pattern, bool DefineEngineFunction(findNextFileMultiExpr, String, ( const char* pattern ), (""), "@brief Returns the next file matching a search begun in findFirstFileMultiExpr().\n\n" - "@param pattern The path and file name pattern to match against. This is optional " + "@param pattern The path and file name pattern to match against. This is optional " "and may be left out as it is not used by the code. It is here for legacy reasons.\n" "@return String of the next matching file path, or an empty string if no matching " "files were found.\n\n" @@ -319,7 +319,7 @@ DefineEngineFunction(findNextFileMultiExpr, String, ( const char* pattern ), ("" "@endtsexample\n\n" "@see findFirstFileMultiExpr()" - "@ingroup FileSearches") + "@ingroup FileSearches") { if ( sgFindFilesPos + 1 > sgFindFilesResults.size() ) return String(); @@ -328,16 +328,16 @@ DefineEngineFunction(findNextFileMultiExpr, String, ( const char* pattern ), ("" } DefineEngineFunction(getFileCountMultiExpr, S32, ( const char* pattern, bool recurse ), ( "", true), - "@brief Returns the number of files in the directory tree that match the given patterns\n\n" + "@brief Returns the number of files in the directory tree that match the given patterns\n\n" "If you're interested in a list of files that match the given patterns and not just " "the number of files, use findFirstFileMultiExpr() and findNextFileMultiExpr().\n\n" - "@param pattern The path and file name pattern to match against, such as *.cs. Separate " + "@param pattern The path and file name pattern to match against, such as *.cs. Separate " "multiple patterns with TABs. For example: \"*.cs\" TAB \"*.dso\"\n" - "@param recurse If true, the search will exhaustively recurse into subdirectories " - "of the given path and match the given filename pattern.\n" - "@return Number of files located using the patterns\n\n" + "@param recurse If true, the search will exhaustively recurse into subdirectories " + "of the given path and match the given filename pattern.\n" + "@return Number of files located using the patterns\n\n" "@tsexample\n" "// Count all DTS or Collada models\n" @@ -347,7 +347,7 @@ DefineEngineFunction(getFileCountMultiExpr, S32, ( const char* pattern, bool rec "@see findFirstFileMultiExpr()" "@see findNextFileMultiExpr()" - "@ingroup FileSearches") + "@ingroup FileSearches") { S32 numResults = buildFileList(pattern, recurse, true); @@ -399,14 +399,14 @@ DefineEngineFunction(isFile, bool, ( const char* fileName ),, } DefineEngineFunction( IsDirectory, bool, ( const char* directory ),, - "@brief Determines if a specified directory exists or not\n\n" + "@brief Determines if a specified directory exists or not\n\n" - "@param directory String containing path in the form of \"foo/bar\"\n" + "@param directory String containing path in the form of \"foo/bar\"\n" "@return Returns true if the directory was found.\n" - "@note Do not include a trailing slash '/'.\n" + "@note Do not include a trailing slash '/'.\n" - "@ingroup FileSystem") + "@ingroup FileSystem") { String dir(Torque::Path::CleanSeparators(directory)); Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), dir.c_str()); @@ -416,12 +416,12 @@ DefineEngineFunction( IsDirectory, bool, ( const char* directory ),, } DefineEngineFunction(isWriteableFileName, bool, ( const char* fileName ),, - "@brief Determines if a file name can be written to using File I/O\n\n" + "@brief Determines if a file name can be written to using File I/O\n\n" - "@param fileName Name and path of file to check\n" - "@return Returns true if the file can be written to.\n" + "@param fileName Name and path of file to check\n" + "@return Returns true if the file can be written to.\n" - "@ingroup FileSystem") + "@ingroup FileSystem") { String filename(Torque::Path::CleanSeparators(fileName)); Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), filename.c_str()); @@ -434,32 +434,32 @@ DefineEngineFunction(isWriteableFileName, bool, ( const char* fileName ),, } DefineEngineFunction(startFileChangeNotifications, void, (),, - "@brief Start watching resources for file changes\n\n" + "@brief Start watching resources for file changes\n\n" "Typically this is called during initializeCore().\n\n" "@see stopFileChangeNotifications()\n" - "@ingroup FileSystem") + "@ingroup FileSystem") { Torque::FS::StartFileChangeNotifications(); } DefineEngineFunction(stopFileChangeNotifications, void, (),, - "@brief Stop watching resources for file changes\n\n" + "@brief Stop watching resources for file changes\n\n" "Typically this is called during shutdownCore().\n\n" "@see startFileChangeNotifications()\n" - "@ingroup FileSystem") + "@ingroup FileSystem") { Torque::FS::StopFileChangeNotifications(); } DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), ( "", 0 ), - "@brief Gathers a list of directories starting at the given path.\n\n" + "@brief Gathers a list of directories starting at the given path.\n\n" - "@param path String containing the path of the directory\n" - "@param depth Depth of search, as in how many subdirectories to parse through\n" - "@return Tab delimited string containing list of directories found during search, \"\" if no files were found\n" + "@param path String containing the path of the directory\n" + "@param depth Depth of search, as in how many subdirectories to parse through\n" + "@return Tab delimited string containing list of directories found during search, \"\" if no files were found\n" - "@ingroup FileSystem") + "@ingroup FileSystem") { // Grab the full path. char fullpath[1024]; @@ -508,23 +508,23 @@ DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ), } DefineEngineFunction(fileSize, S32, ( const char* fileName ),, - "@brief Determines the size of a file on disk\n\n" + "@brief Determines the size of a file on disk\n\n" - "@param fileName Name and path of the file to check\n" - "@return Returns filesize in bytes, or -1 if no file\n" + "@param fileName Name and path of the file to check\n" + "@return Returns filesize in bytes, or -1 if no file\n" - "@ingroup FileSystem") + "@ingroup FileSystem") { Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName); return Platform::getFileSize( sgScriptFilenameBuffer ); } DefineEngineFunction( fileModifiedTime, String, ( const char* fileName ),, - "@brief Returns a platform specific formatted string with the last modified time for the file.\n\n" + "@brief Returns a platform specific formatted string with the last modified time for the file.\n\n" - "@param fileName Name and path of file to check\n" - "@return Formatted string (OS specific) containing modified time, \"9/3/2010 12:33:47 PM\" for example\n" - "@ingroup FileSystem") + "@param fileName Name and path of file to check\n" + "@return Formatted string (OS specific) containing modified time, \"9/3/2010 12:33:47 PM\" for example\n" + "@ingroup FileSystem") { Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName); @@ -566,12 +566,12 @@ DefineEngineFunction( fileCreatedTime, String, ( const char* fileName ),, } DefineEngineFunction(fileDelete, bool, ( const char* path ),, - "@brief Delete a file from the hard drive\n\n" + "@brief Delete a file from the hard drive\n\n" - "@param path Name and path of the file to delete\n" - "@note THERE IS NO RECOVERY FROM THIS. Deleted file is gone for good.\n" - "@return True if file was successfully deleted\n" - "@ingroup FileSystem") + "@param path Name and path of the file to delete\n" + "@note THERE IS NO RECOVERY FROM THIS. Deleted file is gone for good.\n" + "@return True if file was successfully deleted\n" + "@ingroup FileSystem") { static char fileName[1024]; static char sandboxFileName[1024]; @@ -586,11 +586,11 @@ DefineEngineFunction(fileDelete, bool, ( const char* path ),, //---------------------------------------------------------------- DefineEngineFunction(fileExt, String, ( const char* fileName ),, - "@brief Get the extension of a file\n\n" + "@brief Get the extension of a file\n\n" - "@param fileName Name and path of file\n" - "@return String containing the extension, such as \".exe\" or \".cs\"\n" - "@ingroup FileSystem") + "@param fileName Name and path of file\n" + "@return String containing the extension, such as \".exe\" or \".cs\"\n" + "@ingroup FileSystem") { const char *ret = dStrrchr(fileName, '.'); if(ret) @@ -626,11 +626,11 @@ DefineEngineFunction(fileBase, String, ( const char* fileName ),, } DefineEngineFunction(fileName, String, ( const char* fileName ),, - "@brief Get only the file name of a path and file name string (removes path)\n\n" + "@brief Get only the file name of a path and file name string (removes path)\n\n" - "@param fileName Name and path of file to check\n" - "@return String containing the file name, minus the path\n" - "@ingroup FileSystem") + "@param fileName Name and path of file to check\n" + "@return String containing the file name, minus the path\n" + "@ingroup FileSystem") { S32 pathLen = dStrlen( fileName ); FrameTemp szPathCopy( pathLen + 1); @@ -649,11 +649,11 @@ DefineEngineFunction(fileName, String, ( const char* fileName ),, } DefineEngineFunction(filePath, String, ( const char* fileName ),, - "@brief Get the path of a file (removes name and extension)\n\n" + "@brief Get the path of a file (removes name and extension)\n\n" - "@param fileName Name and path of file to check\n" - "@return String containing the path, minus name and extension\n" - "@ingroup FileSystem") + "@param fileName Name and path of file to check\n" + "@return String containing the path, minus name and extension\n" + "@ingroup FileSystem") { S32 pathLen = dStrlen( fileName ); FrameTemp szPathCopy( pathLen + 1); @@ -672,10 +672,10 @@ DefineEngineFunction(filePath, String, ( const char* fileName ),, } DefineEngineFunction(getWorkingDirectory, String, (),, - "@brief Reports the current directory\n\n" + "@brief Reports the current directory\n\n" - "@return String containing full file path of working directory\n" - "@ingroup FileSystem") + "@return String containing full file path of working directory\n" + "@ingroup FileSystem") { return Platform::getCurrentDirectory(); } @@ -687,13 +687,13 @@ DefineEngineFunction(getWorkingDirectory, String, (),, // are not currently built with TORQUE_TOOLS defined. DefineEngineFunction(makeFullPath, String, ( const char* path, const char* cwd ), ( "", ""), - "@brief Converts a relative file path to a full path\n\n" + "@brief Converts a relative file path to a full path\n\n" - "For example, \"./console.log\" becomes \"C:/Torque/t3d/examples/FPS Example/game/console.log\"\n" - "@param path Name of file or path to check\n" + "For example, \"./console.log\" becomes \"C:/Torque/t3d/examples/FPS Example/game/console.log\"\n" + "@param path Name of file or path to check\n" "@param cwd Optional current working directory from which to build the full path.\n" - "@return String containing non-relative directory of path\n" - "@ingroup FileSystem") + "@return String containing non-relative directory of path\n" + "@ingroup FileSystem") { static const U32 bufSize = 512; char *buf = Con::getReturnBuffer(bufSize); @@ -702,25 +702,25 @@ DefineEngineFunction(makeFullPath, String, ( const char* path, const char* cwd ) } DefineEngineFunction(makeRelativePath, String, ( const char* path, const char* to ), ( "", ""), - "@brief Turns a full or local path to a relative one\n\n" + "@brief Turns a full or local path to a relative one\n\n" "For example, \"./game/art\" becomes \"game/art\"\n" "@param path Full path (may include a file) to convert\n" "@param to Optional base path used for the conversion. If not supplied the current " "working directory is used.\n" - "@returns String containing relative path\n" - "@ingroup FileSystem") + "@returns String containing relative path\n" + "@ingroup FileSystem") { return Platform::makeRelativePathName( path, dStrlen(to) > 1 ? to : NULL ); } DefineEngineFunction(pathConcat, String, ( const char* path, const char* file), ( "", ""), - "@brief Combines two separate strings containing a file path and file name together into a single string\n\n" + "@brief Combines two separate strings containing a file path and file name together into a single string\n\n" - "@param path String containing file path\n" - "@param file String containing file name\n" - "@return String containing concatenated file name and path\n" - "@ingroup FileSystem") + "@param path String containing file path\n" + "@param file String containing file name\n" + "@return String containing concatenated file name and path\n" + "@ingroup FileSystem") { static const U32 bufSize = 1024; char *buf = Con::getReturnBuffer(bufSize); @@ -731,10 +731,10 @@ DefineEngineFunction(pathConcat, String, ( const char* path, const char* file), //----------------------------------------------------------------------------- DefineEngineFunction(getExecutableName, String, (),, - "@brief Gets the name of the game's executable\n\n" + "@brief Gets the name of the game's executable\n\n" - "@return String containing this game's executable name\n" - "@ingroup FileSystem") + "@return String containing this game's executable name\n" + "@ingroup FileSystem") { return Platform::getExecutableName(); } diff --git a/Engine/source/console/persistenceManager.cpp b/Engine/source/console/persistenceManager.cpp index 322626801..7db907475 100644 --- a/Engine/source/console/persistenceManager.cpp +++ b/Engine/source/console/persistenceManager.cpp @@ -34,22 +34,22 @@ IMPLEMENT_CONOBJECT(PersistenceManager); ConsoleDocClass( PersistenceManager, - "@brief this class manages updating SimObjects in the file they were " - "created in non-destructively (mostly aimed at datablocks and materials).\n\n" + "@brief this class manages updating SimObjects in the file they were " + "created in non-destructively (mostly aimed at datablocks and materials).\n\n" - "Basic scripting interface:\n\n" - " - Creation: new PersistenceManager(FooManager);\n" - " - Flag objects as dirty: FooManager.setDirty();\n" - " - Remove objects from dirty list: FooManager.removeDirty();\n" - " - List all currently dirty objects: FooManager.listDirty();\n" - " - Check to see if an object is dirty: FooManager.isDirty();\n" - " - Save dirty objects to their files: FooManager.saveDirty();\n\n" - "@note Dirty objects don't update their files until saveDirty() is " - "called so you can change their properties after you flag them as dirty\n\n" - "@note Currently only used by editors, not intended for actual game development\n\n" - "@ingroup Console\n" - "@ingroup Editors\n" - "@internal"); + "Basic scripting interface:\n\n" + " - Creation: new PersistenceManager(FooManager);\n" + " - Flag objects as dirty: FooManager.setDirty();\n" + " - Remove objects from dirty list: FooManager.removeDirty();\n" + " - List all currently dirty objects: FooManager.listDirty();\n" + " - Check to see if an object is dirty: FooManager.isDirty();\n" + " - Save dirty objects to their files: FooManager.saveDirty();\n\n" + "@note Dirty objects don't update their files until saveDirty() is " + "called so you can change their properties after you flag them as dirty\n\n" + "@note Currently only used by editors, not intended for actual game development\n\n" + "@ingroup Console\n" + "@ingroup Editors\n" + "@internal"); PersistenceManager::PersistenceManager() { @@ -890,7 +890,7 @@ PersistenceManager::ParsedObject* PersistenceManager::findParsedObject(SimObject { const ParsedProperty &prop = testObj->properties[j]; - if ( dStrcmp( prop.name, "internalName" ) == 0 && + if ( dStrcmp( prop.name, "internalName" ) == 0 && dStrcmp( prop.value, object->getInternalName() ) == 0 ) return testObj; else if ( dStrcmp(prop.name, "internalName") == 0) @@ -2037,24 +2037,24 @@ bool PersistenceManager::saveDirtyObject(SimObject* object) const char *name = object->getName(); if (name) { - Con::errorf("PersistenceManager::saveDirtyObject(): Unable to open %s to save %s %s (%d)", - dirtyObject.fileName, object->getClassName(), name, object->getId()); - } - else - { - Con::errorf("PersistenceManager::saveDirtyObject(): Unable to open %s to save %s (%d)", - dirtyObject.fileName, object->getClassName(), object->getId()); - } + Con::errorf("PersistenceManager::saveDirtyObject(): Unable to open %s to save %s %s (%d)", + dirtyObject.fileName, object->getClassName(), name, object->getId()); + } + else + { + Con::errorf("PersistenceManager::saveDirtyObject(): Unable to open %s to save %s (%d)", + dirtyObject.fileName, object->getClassName(), object->getId()); + } - return false; - } + return false; + } // if the file exists then lets update and save - if(mCurrentFile) - { - updateObject(object); + if(mCurrentFile) + { + updateObject(object); saveDirtyFile(); - } + } break; } @@ -2230,7 +2230,7 @@ DefineConsoleMethod( PersistenceManager, removeDirty, void, ( const char * objNa "Remove a SimObject from the dirty list.") { SimObject *dirtyObject = NULL; - if (dStrcmp( objName,"")!=0) + if (dStrcmp( objName,"")!=0) { if (!Sim::findObject(objName, dirtyObject)) { diff --git a/Engine/source/console/scriptFilename.cpp b/Engine/source/console/scriptFilename.cpp index 60c81f200..7a72756af 100644 --- a/Engine/source/console/scriptFilename.cpp +++ b/Engine/source/console/scriptFilename.cpp @@ -343,10 +343,10 @@ bool collapseScriptFilename(char *filename, U32 size, const char *src) //----------------------------------------------------------------------------- ConsoleFunction(expandFilename, const char*, 2, 2, "(string filename)" - "@brief Grabs the full path of a specified file\n\n" - "@param filename Name of the local file to locate\n" - "@return String containing the full filepath on disk\n" - "@ingroup FileSystem") + "@brief Grabs the full path of a specified file\n\n" + "@param filename Name of the local file to locate\n" + "@return String containing the full filepath on disk\n" + "@ingroup FileSystem") { TORQUE_UNUSED(argc); static const U32 bufSize = 1024; @@ -356,9 +356,9 @@ ConsoleFunction(expandFilename, const char*, 2, 2, "(string filename)" } ConsoleFunction(expandOldFilename, const char*, 2, 2, "(string filename)" - "@brief Retrofits a filepath that uses old Torque style\n\n" - "@return String containing filepath with new formatting\n" - "@ingroup FileSystem") + "@brief Retrofits a filepath that uses old Torque style\n\n" + "@return String containing filepath with new formatting\n" + "@ingroup FileSystem") { TORQUE_UNUSED(argc); static const U32 bufSize = 1024; @@ -372,7 +372,7 @@ ConsoleFunction(expandOldFilename, const char*, 2, 2, "(string filename)" //----------------------------------------------------------------------------- ConsoleToolFunction(collapseFilename, const char*, 2, 2, "(string filename)" - "@internal Editor use only") + "@internal Editor use only") { TORQUE_UNUSED(argc); static const U32 bufSize = 1024; @@ -382,7 +382,7 @@ ConsoleToolFunction(collapseFilename, const char*, 2, 2, "(string filename)" } ConsoleToolFunction(setScriptPathExpando, void, 3, 4, "(string expando, string path[, bool toolsOnly])" - "@internal Editor use only") + "@internal Editor use only") { if(argc == 4) Con::setScriptPathExpando(argv[1], argv[2], dAtob(argv[3])); @@ -391,13 +391,13 @@ ConsoleToolFunction(setScriptPathExpando, void, 3, 4, "(string expando, string p } ConsoleToolFunction(removeScriptPathExpando, void, 2, 2, "(string expando)" - "@internal Editor use only") + "@internal Editor use only") { Con::removeScriptPathExpando(argv[1]); } ConsoleToolFunction(isScriptPathExpando, bool, 2, 2, "(string expando)" - "@internal Editor use only") + "@internal Editor use only") { return Con::isScriptPathExpando(argv[1]); } diff --git a/Engine/source/console/scriptObjects.cpp b/Engine/source/console/scriptObjects.cpp index e5916fb64..6218e4e3d 100644 --- a/Engine/source/console/scriptObjects.cpp +++ b/Engine/source/console/scriptObjects.cpp @@ -53,13 +53,13 @@ ConsoleDocClass( ScriptObject, ); IMPLEMENT_CALLBACK( ScriptObject, onAdd, void, ( SimObjectId ID ), ( ID ), - "Called when this ScriptObject is added to the system.\n" - "@param ID Unique object ID assigned when created (%this in script).\n" + "Called when this ScriptObject is added to the system.\n" + "@param ID Unique object ID assigned when created (%this in script).\n" ); IMPLEMENT_CALLBACK( ScriptObject, onRemove, void, ( SimObjectId ID ), ( ID ), - "Called when this ScriptObject is removed from the system.\n" - "@param ID Unique object ID assigned when created (%this in script).\n" + "Called when this ScriptObject is removed from the system.\n" + "@param ID Unique object ID assigned when created (%this in script).\n" ); ScriptObject::ScriptObject() @@ -105,18 +105,18 @@ ConsoleDocClass( ScriptTickObject, ); IMPLEMENT_CALLBACK( ScriptTickObject, onInterpolateTick, void, ( F32 delta ), ( delta ), - "This is called every frame, but only if the object is set to process ticks.\n" - "@param delta The time delta for this frame.\n" + "This is called every frame, but only if the object is set to process ticks.\n" + "@param delta The time delta for this frame.\n" ); IMPLEMENT_CALLBACK( ScriptTickObject, onProcessTick, void, (), (), - "Called once every 32ms if this object is set to process ticks.\n" + "Called once every 32ms if this object is set to process ticks.\n" ); IMPLEMENT_CALLBACK( ScriptTickObject, onAdvanceTime, void, ( F32 timeDelta ), ( timeDelta ), - "This is called every frame regardless if the object is set to process ticks, but only " + "This is called every frame regardless if the object is set to process ticks, but only " "if the callOnAdvanceTime property is set to true.\n" - "@param timeDelta The time delta for this frame.\n" + "@param timeDelta The time delta for this frame.\n" "@see callOnAdvanceTime\n" ); @@ -188,37 +188,37 @@ DefineEngineMethod( ScriptTickObject, isProcessingTicks, bool, ( ),, IMPLEMENT_CONOBJECT(ScriptGroup); ConsoleDocClass( ScriptGroup, - "@brief Essentially a SimGroup, but with onAdd and onRemove script callbacks.\n\n" + "@brief Essentially a SimGroup, but with onAdd and onRemove script callbacks.\n\n" - "@tsexample\n" - "// First container, SimGroup containing a ScriptGroup\n" - "new SimGroup(Scenes)\n" - "{\n" - " // Subcontainer, ScriptGroup containing variables\n" - " // related to a cut scene and a starting WayPoint\n" - " new ScriptGroup(WelcomeScene)\n" - " {\n" - " class = \"Scene\";\n" - " pathName = \"Pathx\";\n" - " description = \"A small orc village set in the Hardesty mountains. This town and its surroundings will be used to illustrate some the Torque Game Engine\'s features.\";\n" - " pathTime = \"0\";\n" - " title = \"Welcome to Orc Town\";\n\n" - " new WayPoint(start)\n" - " {\n" - " position = \"163.873 -103.82 208.354\";\n" - " rotation = \"0.136165 -0.0544916 0.989186 44.0527\";\n" - " scale = \"1 1 1\";\n" - " dataBlock = \"WayPointMarker\";\n" - " team = \"0\";\n" - " };\n" - " };\n" - "};\n" - "@endtsexample\n\n" + "@tsexample\n" + "// First container, SimGroup containing a ScriptGroup\n" + "new SimGroup(Scenes)\n" + "{\n" + " // Subcontainer, ScriptGroup containing variables\n" + " // related to a cut scene and a starting WayPoint\n" + " new ScriptGroup(WelcomeScene)\n" + " {\n" + " class = \"Scene\";\n" + " pathName = \"Pathx\";\n" + " description = \"A small orc village set in the Hardesty mountains. This town and its surroundings will be used to illustrate some the Torque Game Engine\'s features.\";\n" + " pathTime = \"0\";\n" + " title = \"Welcome to Orc Town\";\n\n" + " new WayPoint(start)\n" + " {\n" + " position = \"163.873 -103.82 208.354\";\n" + " rotation = \"0.136165 -0.0544916 0.989186 44.0527\";\n" + " scale = \"1 1 1\";\n" + " dataBlock = \"WayPointMarker\";\n" + " team = \"0\";\n" + " };\n" + " };\n" + "};\n" + "@endtsexample\n\n" - "@see SimGroup\n" + "@see SimGroup\n" - "@ingroup Console\n" - "@ingroup Scripting" + "@ingroup Console\n" + "@ingroup Scripting" ); ScriptGroup::ScriptGroup() @@ -226,13 +226,13 @@ ScriptGroup::ScriptGroup() } IMPLEMENT_CALLBACK( ScriptGroup, onAdd, void, ( SimObjectId ID ), ( ID ), - "Called when this ScriptGroup is added to the system.\n" - "@param ID Unique object ID assigned when created (%this in script).\n" + "Called when this ScriptGroup is added to the system.\n" + "@param ID Unique object ID assigned when created (%this in script).\n" ); IMPLEMENT_CALLBACK( ScriptGroup, onRemove, void, ( SimObjectId ID ), ( ID ), - "Called when this ScriptObject is removed from the system.\n" - "@param ID Unique object ID assigned when created (%this in script).\n" + "Called when this ScriptObject is removed from the system.\n" + "@param ID Unique object ID assigned when created (%this in script).\n" ); bool ScriptGroup::onAdd() @@ -248,7 +248,7 @@ bool ScriptGroup::onAdd() void ScriptGroup::onRemove() { // Call onRemove in script! - onRemove_callback(getId()); + onRemove_callback(getId()); Parent::onRemove(); } diff --git a/Engine/source/console/sim.cpp b/Engine/source/console/sim.cpp index e0465050f..0ea902b5c 100644 --- a/Engine/source/console/sim.cpp +++ b/Engine/source/console/sim.cpp @@ -139,7 +139,7 @@ DefineConsoleFunction( spawnObject, S32, ( const char * spawnClass , const char * spawnProperties , const char * spawnScript ),("","","","") ,"spawnObject(class [, dataBlock, name, properties, script])" - "@hide") + "@hide") { SimObject* spawnObject = Sim::spawnObject(spawnClass, spawnDataBlock, spawnName, spawnProperties, spawnScript); @@ -203,12 +203,12 @@ ConsoleFunction(schedule, S32, 4, 0, "schedule(time, refobject|0, command, nextNameObject; - obj->nextNameObject = (SimObject*)-1; + obj->nextNameObject = (SimObject*)-1; hashEntryCount--; Mutex::unlockMutex(mutex); @@ -164,7 +164,7 @@ void SimNameDictionary::remove(SimObject* obj) root.erase(name); #endif Mutex::unlockMutex(mutex); -} +} //---------------------------------------------------------------------------- @@ -279,7 +279,7 @@ void SimManagerNameDictionary::remove(SimObject* obj) if(*walk == obj) { *walk = obj->nextManagerNameObject; - obj->nextManagerNameObject = (SimObject*)-1; + obj->nextManagerNameObject = (SimObject*)-1; hashEntryCount--; Mutex::unlockMutex(mutex); @@ -293,7 +293,7 @@ void SimManagerNameDictionary::remove(SimObject* obj) root.erase(name); #endif Mutex::unlockMutex(mutex); -} +} //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- diff --git a/Engine/source/console/simDictionary.h b/Engine/source/console/simDictionary.h index bbfb0f385..1247d504e 100644 --- a/Engine/source/console/simDictionary.h +++ b/Engine/source/console/simDictionary.h @@ -61,7 +61,7 @@ struct StringTableEntryEq } }; -typedef std::unordered_map StringDictDef; +typedef std::unordered_map StringDictDef; typedef std::unordered_map SimObjectIdDictDef; #endif diff --git a/Engine/source/console/simEvents.cpp b/Engine/source/console/simEvents.cpp index bc1e1789c..ab87f5f0b 100644 --- a/Engine/source/console/simEvents.cpp +++ b/Engine/source/console/simEvents.cpp @@ -39,10 +39,10 @@ SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject) mArgv[i].value = new ConsoleValue(); mArgv[i].value->type = ConsoleValue::TypeInternalString; mArgv[i].value->init(); - if (argv) - { - mArgv[i].value->setStringValue((const char*)argv[i]); - } + if (argv) + { + mArgv[i].value->setStringValue((const char*)argv[i]); + } } } diff --git a/Engine/source/console/simManager.cpp b/Engine/source/console/simManager.cpp index a216c09b6..06027cdfe 100644 --- a/Engine/source/console/simManager.cpp +++ b/Engine/source/console/simManager.cpp @@ -93,7 +93,7 @@ static void shutdownEventQueue() U32 postEvent(SimObject *destObject, SimEvent* event,U32 time) { - AssertFatal(time == -1 || time >= getCurrentTime(), + AssertFatal(time == -1 || time >= getCurrentTime(), "Sim::postEvent() - Event time must be greater than or equal to the current time." ); AssertFatal(destObject, "Sim::postEvent() - Destination object for event doesn't exist."); @@ -256,7 +256,7 @@ void advanceToTime(SimTime targetTime) event->process(obj); delete event; } - gCurrentTime = targetTime; + gCurrentTime = targetTime; Mutex::unlockMutex(gEventQueueMutex); } @@ -393,7 +393,7 @@ SimObject* findObject(const char* name) SimObject* findObject(SimObjectId id) { - return gIdDictionary->find(id); + return gIdDictionary->find(id); } SimObject *spawnObject(String spawnClass, String spawnDataBlock, String spawnName, @@ -600,7 +600,7 @@ SimDataBlockGroup::SimDataBlockGroup() S32 QSORT_CALLBACK SimDataBlockGroup::compareModifiedKey(const void* a,const void* b) { - const SimDataBlock* dba = *((const SimDataBlock**)a); + const SimDataBlock* dba = *((const SimDataBlock**)a); const SimDataBlock* dbb = *((const SimDataBlock**)b); return dba->getModifiedKey() - dbb->getModifiedKey(); @@ -612,6 +612,6 @@ void SimDataBlockGroup::sort() if(mLastModifiedKey != SimDataBlock::getNextModifiedKey()) { mLastModifiedKey = SimDataBlock::getNextModifiedKey(); - dQsort(objectList.address(),objectList.size(),sizeof(SimObject *),compareModifiedKey); + dQsort(objectList.address(),objectList.size(),sizeof(SimObject *),compareModifiedKey); } } diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index b07bc6840..73a1ffa3d 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -81,7 +81,7 @@ SimObject::SimObject() mFlags.set( ModStaticFields | ModDynamicFields ); mFieldDictionary = NULL; - mCanSaveFieldDictionary = true; + mCanSaveFieldDictionary = true; mClassName = NULL; mSuperClassName = NULL; @@ -592,7 +592,7 @@ void SimObject::setDeclarationLine(U32 lineNumber) bool SimObject::registerObject() { AssertFatal( !mFlags.test( Added ), "reigsterObject - Object already registered!"); - mFlags.clear(Deleted | Removed); + mFlags.clear(Deleted | Removed); if(smForceId) { @@ -609,11 +609,11 @@ bool SimObject::registerObject() AssertFatal(Sim::gIdDictionary && Sim::gNameDictionary, "SimObject::registerObject - tried to register an object before Sim::init()!"); - Sim::gIdDictionary->insert(this); + Sim::gIdDictionary->insert(this); Sim::gNameDictionary->insert(this); - // Notify object + // Notify object bool ret = onAdd(); if(!ret) @@ -661,10 +661,10 @@ void SimObject::deleteObject() void SimObject::_destroySelf() { - AssertFatal( !isDeleted(), "SimObject::destroySelf - Object has already been deleted" ); - AssertFatal( !isRemoved(), "SimObject::destroySelf - Object in the process of being removed" ); + AssertFatal( !isDeleted(), "SimObject::destroySelf - Object has already been deleted" ); + AssertFatal( !isRemoved(), "SimObject::destroySelf - Object in the process of being removed" ); - mFlags.set( Deleted ); + mFlags.set( Deleted ); if( mFlags.test( Added ) ) unregisterObject(); @@ -1308,7 +1308,7 @@ void SimObject::dumpClassHierarchy() while(pRep) { Con::warnf("%s ->", pRep->getClassName()); - pRep = pRep->getParentClass(); + pRep = pRep->getParentClass(); } } @@ -1376,7 +1376,7 @@ bool SimObject::isChildOfGroup(SimGroup* pGroup) if(pGroup == dynamic_cast(this)) return true; - SimGroup* temp = mGroup; + SimGroup* temp = mGroup; while(temp) { if(temp == pGroup) @@ -2884,7 +2884,7 @@ DefineConsoleMethod( SimObject, isMemberOfClass, bool, ( const char* className ) return true; } - pRep = pRep->getParentClass(); + pRep = pRep->getParentClass(); } return false; diff --git a/Engine/source/console/simObject.h b/Engine/source/console/simObject.h index 8a38e8675..6cba1beff 100644 --- a/Engine/source/console/simObject.h +++ b/Engine/source/console/simObject.h @@ -826,7 +826,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks virtual bool readObject(Stream *stream); /// Set whether fields created at runtime should be saved. Default is true. - void setCanSaveDynamicFields( bool bCanSave ) { mCanSaveFieldDictionary = bCanSave; } + void setCanSaveDynamicFields( bool bCanSave ) { mCanSaveFieldDictionary = bCanSave; } /// Get whether fields created at runtime should be saved. Default is true. bool getCanSaveDynamicFields( ) { return mCanSaveFieldDictionary;} diff --git a/Engine/source/console/simObjectMemento.cpp b/Engine/source/console/simObjectMemento.cpp index 839ae0846..ef2e8f732 100644 --- a/Engine/source/console/simObjectMemento.cpp +++ b/Engine/source/console/simObjectMemento.cpp @@ -30,7 +30,7 @@ SimObjectMemento::SimObjectMemento() : mState( NULL ), - mIsDatablock( false ) + mIsDatablock( false ) { } @@ -45,16 +45,16 @@ void SimObjectMemento::save( SimObject *object ) dFree( mState ); mObjectName = String::EmptyString; - // Use a stream to save the state. + // Use a stream to save the state. MemStream stream( 256 ); U32 writeFlags = 0; - SimDataBlock* db = dynamic_cast(object); - if( !db ) - stream.write( sizeof( "return " ) - 1, "return " ); - else + SimDataBlock* db = dynamic_cast(object); + if( !db ) + stream.write( sizeof( "return " ) - 1, "return " ); + else { - mIsDatablock = true; + mIsDatablock = true; // Cull the datablock name from the output so that // we can easily replace it in case the datablock's name @@ -64,7 +64,7 @@ void SimObjectMemento::save( SimObject *object ) writeFlags |= SimObject::NoName; } - + object->write( stream, 0, writeFlags ); stream.write( (UTF8)0 ); @@ -82,9 +82,9 @@ SimObject *SimObjectMemento::restore() const // TODO: We could potentially make this faster by // caching the CodeBlock generated from the string - SimObject* object; - if( !mIsDatablock ) - { + SimObject* object; + if( !mIsDatablock ) + { // Set the redefine behavior to automatically giving // the new objects unique names. This will restore the // old names if they are still available or give reasonable @@ -95,22 +95,22 @@ SimObject *SimObjectMemento::restore() const // Read the object. - const UTF8* result = Con::evaluate( mState ); + const UTF8* result = Con::evaluate( mState ); // Restore the redefine behavior. Con::setVariable( "$Con::redefineBehavior", oldRedefineBehavior ); - if ( !result || !result[ 0 ] ) - return NULL; + if ( !result || !result[ 0 ] ) + return NULL; // Look up the object. - U32 objectId = dAtoi( result ); - object = Sim::findObject( objectId ); - } - else - { + U32 objectId = dAtoi( result ); + object = Sim::findObject( objectId ); + } + else + { String objectName = mObjectName; // For datablocks, it's getting a little complicated. Datablock definitions cannot be used @@ -140,16 +140,16 @@ SimObject *SimObjectMemento::restore() const dStrcpy( &tempBuffer[ numCharsToLeftParen + uniqueNameLen ], &mState[ numCharsToLeftParen ] ); } - Con::evaluate( tempBuffer ); + Con::evaluate( tempBuffer ); if( tempBuffer != mState ) dFree( tempBuffer ); if( objectName == String::EmptyString ) - return NULL; + return NULL; - object = Sim::findObject( objectName ); - } + object = Sim::findObject( objectName ); + } return object; } diff --git a/Engine/source/console/simObjectMemento.h b/Engine/source/console/simObjectMemento.h index 8fc029726..45b8a9e4d 100644 --- a/Engine/source/console/simObjectMemento.h +++ b/Engine/source/console/simObjectMemento.h @@ -42,7 +42,7 @@ protected: /// The captured object's name. String mObjectName; - bool mIsDatablock; + bool mIsDatablock; public: diff --git a/Engine/source/console/simPersistSet.cpp b/Engine/source/console/simPersistSet.cpp index 1fe272478..2dea6416e 100644 --- a/Engine/source/console/simPersistSet.cpp +++ b/Engine/source/console/simPersistSet.cpp @@ -29,13 +29,13 @@ IMPLEMENT_CONOBJECT( SimPersistSet ); ConsoleDocClass( SimPersistSet, - "@brief A SimSet that can be safely persisted.\n\n" - "Uses SimPersistIDs to reference objects in the set " - "while persisted on disk. This allows the set to resolve " - "its references no matter whether they are loaded before or " - "after the set is created.\n\n" - "Not intended for game development, for editors or internal use only.\n\n " - "@internal"); + "@brief A SimSet that can be safely persisted.\n\n" + "Uses SimPersistIDs to reference objects in the set " + "while persisted on disk. This allows the set to resolve " + "its references no matter whether they are loaded before or " + "after the set is created.\n\n" + "Not intended for game development, for editors or internal use only.\n\n " + "@internal"); //----------------------------------------------------------------------------- diff --git a/Engine/source/console/simSerialize.cpp b/Engine/source/console/simSerialize.cpp index e3f64be4c..6a7a84b17 100644 --- a/Engine/source/console/simSerialize.cpp +++ b/Engine/source/console/simSerialize.cpp @@ -213,18 +213,18 @@ SimObject *loadObjectStream(Stream *stream) //----------------------------------------------------------------------------- DefineEngineFunction(saveObject, bool, ( SimObject *object, const char *filename ),, - "@brief Serialize the object to a file.\n\n" - "@param object The object to serialize.\n" - "@param filename The file name and path.\n" - "@ingroup Console\n") + "@brief Serialize the object to a file.\n\n" + "@param object The object to serialize.\n" + "@param filename The file name and path.\n" + "@ingroup Console\n") { return object && Sim::saveObject(object, filename); } DefineEngineFunction(loadObject, SimObject*, ( const char *filename ),, - "@brief Loads a serialized object from a file.\n\n" - "@param Name and path to text file containing the object\n" - "@ingroup Console\n") + "@brief Loads a serialized object from a file.\n\n" + "@param Name and path to text file containing the object\n" + "@ingroup Console\n") { return Sim::loadObjectStream(filename); } diff --git a/Engine/source/console/stringStack.cpp b/Engine/source/console/stringStack.cpp index 45fd83740..681de2898 100644 --- a/Engine/source/console/stringStack.cpp +++ b/Engine/source/console/stringStack.cpp @@ -121,7 +121,7 @@ bool ConsoleValueStack::reserveValues(U32 count, ConsoleValueRef *outValues) //Con::printf("[%i]CSTK reserveValues %i", mStackPos, count); for (U32 i=0; isetTelnetParameters(port, consolePass, listenPass, remoteEcho); + TelConsole->setTelnetParameters(port, consolePass, listenPass, remoteEcho); } static void telnetCallback(U32 level, const char *consoleLine) { TORQUE_UNUSED(level); if (TelConsole) - TelConsole->processConsoleLine(consoleLine); + TelConsole->processConsoleLine(consoleLine); } TelnetConsole::TelnetConsole() @@ -121,9 +121,9 @@ void TelnetConsole::setTelnetParameters(S32 port, const char *telnetPassword, co mAcceptPort = port; if(mAcceptPort != -1 && mAcceptPort != 0) { - NetAddress address; - Net::getIdealListenAddress(&address); - address.port = mAcceptPort; + NetAddress address; + Net::getIdealListenAddress(&address); + address.port = mAcceptPort; mAcceptSocket = Net::openSocket(); Net::bindAddress(address, mAcceptSocket); diff --git a/Engine/source/console/telnetDebugger.cpp b/Engine/source/console/telnetDebugger.cpp index 8f95aaf9f..7db6e9710 100644 --- a/Engine/source/console/telnetDebugger.cpp +++ b/Engine/source/console/telnetDebugger.cpp @@ -115,8 +115,8 @@ MODULE_END; DefineConsoleFunction( dbgSetParameters, void, (S32 port, const char * password, bool waitForClient ), (false), "( int port, string password, bool waitForClient )" "Open a debug server port on the specified port, requiring the specified password, " - "and optionally waiting for the debug client to connect.\n" - "@internal Primarily used for Torsion and other debugging tools") + "and optionally waiting for the debug client to connect.\n" + "@internal Primarily used for Torsion and other debugging tools") { if (TelDebugger) { @@ -126,17 +126,17 @@ DefineConsoleFunction( dbgSetParameters, void, (S32 port, const char * password, DefineConsoleFunction( dbgIsConnected, bool, (), , "()" "Returns true if a script debugging client is connected else return false.\n" - "@internal Primarily used for Torsion and other debugging tools") + "@internal Primarily used for Torsion and other debugging tools") { return TelDebugger && TelDebugger->isConnected(); } DefineConsoleFunction( dbgDisconnect, void, (), , "()" "Forcibly disconnects any attached script debugging client.\n" - "@internal Primarily used for Torsion and other debugging tools") + "@internal Primarily used for Torsion and other debugging tools") { if (TelDebugger) - TelDebugger->disconnect(); + TelDebugger->disconnect(); } static void debuggerConsumer(U32 level, const char *line) @@ -244,9 +244,9 @@ void TelnetDebugger::setDebugParameters(S32 port, const char *password, bool wai mAcceptPort = port; if(mAcceptPort != -1 && mAcceptPort != 0) { - NetAddress address; - Net::getIdealListenAddress(&address); - address.port = mAcceptPort; + NetAddress address; + Net::getIdealListenAddress(&address); + address.port = mAcceptPort; mAcceptSocket = Net::openSocket(); Net::bindAddress(address, mAcceptSocket); @@ -588,7 +588,7 @@ void TelnetDebugger::addAllBreakpoints(CodeBlock *code) // TODO: This assumes that the OS file names are case // insensitive... Torque needs a dFilenameCmp() function. if( dStricmp( cur->fileName, code->name ) == 0 ) - { + { cur->code = code; // Find the fist breakline starting from and @@ -741,7 +741,7 @@ void TelnetDebugger::removeBreakpoint(const char *fileName, S32 line) { Breakpoint *brk = *bp; *bp = brk->next; - if ( brk->code ) + if ( brk->code ) brk->code->clearBreakpoint(brk->lineNumber); dFree(brk->testExpression); delete brk; @@ -754,7 +754,7 @@ void TelnetDebugger::removeAllBreakpoints() while(walk) { Breakpoint *temp = walk->next; - if ( walk->code ) + if ( walk->code ) walk->code->clearBreakpoint(walk->lineNumber); dFree(walk->testExpression); delete walk; @@ -792,10 +792,10 @@ void TelnetDebugger::setBreakOnNextStatement( bool enabled ) for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile) walk->clearAllBreaks(); for(Breakpoint *w = mBreakpoints; w; w = w->next) - { - if ( w->code ) + { + if ( w->code ) w->code->setBreakpoint(w->lineNumber); - } + } mBreakOnNextStatement = false; } } @@ -848,7 +848,7 @@ void TelnetDebugger::debugStepOut() setBreakOnNextStatement( false ); mStackPopBreakIndex = gEvalState.getStackDepth() - 1; if ( mStackPopBreakIndex == 0 ) - mStackPopBreakIndex = -1; + mStackPopBreakIndex = -1; mProgramPaused = false; send("RUNNING\r\n"); } diff --git a/Engine/source/console/typeValidators.cpp b/Engine/source/console/typeValidators.cpp index 11249daf7..6b2ea7475 100644 --- a/Engine/source/console/typeValidators.cpp +++ b/Engine/source/console/typeValidators.cpp @@ -49,42 +49,42 @@ void TypeValidator::consoleError(SimObject *object, const char *format, ...) void FRangeValidator::validateType(SimObject *object, void *typePtr) { - F32 *v = (F32 *) typePtr; - if(*v < minV || *v > maxV) - { - consoleError(object, "Must be between %g and %g", minV, maxV); - if(*v < minV) - *v = minV; - else if(*v > maxV) - *v = maxV; - } + F32 *v = (F32 *) typePtr; + if(*v < minV || *v > maxV) + { + consoleError(object, "Must be between %g and %g", minV, maxV); + if(*v < minV) + *v = minV; + else if(*v > maxV) + *v = maxV; + } } void IRangeValidator::validateType(SimObject *object, void *typePtr) { - S32 *v = (S32 *) typePtr; - if(*v < minV || *v > maxV) - { - consoleError(object, "Must be between %d and %d", minV, maxV); - if(*v < minV) - *v = minV; - else if(*v > maxV) - *v = maxV; - } + S32 *v = (S32 *) typePtr; + if(*v < minV || *v > maxV) + { + consoleError(object, "Must be between %d and %d", minV, maxV); + if(*v < minV) + *v = minV; + else if(*v > maxV) + *v = maxV; + } } void IRangeValidatorScaled::validateType(SimObject *object, void *typePtr) { - S32 *v = (S32 *) typePtr; - *v /= factor; - if(*v < minV || *v > maxV) - { - consoleError(object, "Scaled value must be between %d and %d", minV, maxV); - if(*v < minV) - *v = minV; - else if(*v > maxV) - *v = maxV; - } + S32 *v = (S32 *) typePtr; + *v /= factor; + if(*v < minV || *v > maxV) + { + consoleError(object, "Scaled value must be between %d and %d", minV, maxV); + if(*v < minV) + *v = minV; + else if(*v > maxV) + *v = maxV; + } } void Point3NormalizeValidator::validateType(SimObject *object, void *typePtr) diff --git a/Engine/source/environment/river.cpp b/Engine/source/environment/river.cpp index 73c63a4ca..2ac9f2b97 100644 --- a/Engine/source/environment/river.cpp +++ b/Engine/source/environment/river.cpp @@ -77,12 +77,12 @@ ConsoleDocClass( River, #define NODE_RADIUS 15.0f static U32 gIdxArray[6][2][3] = { - { { 0, 4, 5 }, { 0, 5, 1 }, }, // Top Face - { { 2, 6, 4 }, { 2, 4, 0 }, }, // Left Face - { { 1, 5, 7 }, { 1, 7, 3 }, }, // Right Face - { { 2, 3, 7 }, { 2, 7, 6 }, }, // Bottom Face - { { 0, 1, 3 }, { 0, 3, 2 }, }, // Front Face - { { 4, 6, 7 }, { 4, 7, 5 }, }, // Back Face + { { 0, 4, 5 }, { 0, 5, 1 }, }, // Top Face + { { 2, 6, 4 }, { 2, 4, 0 }, }, // Left Face + { { 1, 5, 7 }, { 1, 7, 3 }, }, // Right Face + { { 2, 3, 7 }, { 2, 7, 6 }, }, // Bottom Face + { { 0, 1, 3 }, { 0, 3, 2 }, }, // Front Face + { { 4, 6, 7 }, { 4, 7, 5 }, }, // Back Face }; struct RiverHitSegment @@ -93,10 +93,10 @@ struct RiverHitSegment static S32 QSORT_CALLBACK compareHitSegments(const void* a,const void* b) { - const RiverHitSegment *fa = (RiverHitSegment*)a; - const RiverHitSegment *fb = (RiverHitSegment*)b; + const RiverHitSegment *fa = (RiverHitSegment*)a; + const RiverHitSegment *fb = (RiverHitSegment*)b; - return mSign(fb->t - fa->t); + return mSign(fb->t - fa->t); } static Point3F sSegmentPointComparePoints[4]; @@ -655,17 +655,17 @@ void River::consoleInit() Parent::consoleInit(); Con::addVariable( "$River::EditorOpen", TypeBool, &River::smEditorOpen, "For editor use.\n" - "@ingroup Editors\n" ); + "@ingroup Editors\n" ); Con::addVariable( "$River::showWalls", TypeBool, &River::smShowWalls, "For editor use.\n" - "@ingroup Editors\n" ); + "@ingroup Editors\n" ); Con::addVariable( "$River::showNodes", TypeBool, &River::smShowNodes, "For editor use.\n" - "@ingroup Editors\n"); + "@ingroup Editors\n"); Con::addVariable( "$River::showSpline", TypeBool, &River::smShowSpline, "For editor use.\n" - "@ingroup Editors\n" ); + "@ingroup Editors\n" ); Con::addVariable( "$River::showRiver", TypeBool, &River::smShowRiver, "For editor use.\n" - "@ingroup Editors\n" ); - Con::addVariable( "$River::showWireframe", TypeBool, &River::smWireframe, "For editor use.\n" - "@ingroup Editors\n"); + "@ingroup Editors\n" ); + Con::addVariable( "$River::showWireframe", TypeBool, &River::smWireframe, "For editor use.\n" + "@ingroup Editors\n"); } bool River::addNodeFromField( void *object, const char *index, const char *data ) @@ -816,7 +816,7 @@ void River::innerRender( SceneRenderState *state ) _makeRenderBatches( camPosition ); - if ( !River::smShowRiver ) + if ( !River::smShowRiver ) return; // If no material... we're done. @@ -851,7 +851,7 @@ void River::innerRender( SceneRenderState *state ) U32 vertCount = ( endVert - startVert ) + 1; U32 idxCount = ( endIdx - startIdx ) + 1; U32 triangleCount = idxCount / 3; - + AssertFatal( startVert < mLowVertCount, "River, bad draw call!" ); AssertFatal( startVert + vertCount <= mLowVertCount, "River, bad draw call!" ); AssertFatal( triangleCount <= mLowTriangleCount, "River, bad draw call!" ); @@ -962,7 +962,7 @@ U32 River::packUpdate(NetConnection * con, U32 mask, BitStream * stream) stream->write( mSegmentsPerBatch ); stream->write( mDepthScale ); stream->write( mMaxDivisionSize ); - stream->write( mColumnCount ); + stream->write( mColumnCount ); stream->write( mFlowMagnitude ); stream->write( mLodDistance ); @@ -1045,7 +1045,7 @@ void River::unpackUpdate(NetConnection * con, BitStream * stream) // RiverMask if(stream->readFlag()) { - MatrixF ObjectMatrix; + MatrixF ObjectMatrix; stream->readAffineTransform(&ObjectMatrix); Parent::setTransform(ObjectMatrix); @@ -1053,7 +1053,7 @@ void River::unpackUpdate(NetConnection * con, BitStream * stream) stream->read( &mSegmentsPerBatch ); stream->read( &mDepthScale ); stream->read( &mMaxDivisionSize ); - stream->read( &mColumnCount ); + stream->read( &mColumnCount ); stream->read( &mFlowMagnitude ); stream->read( &mLodDistance ); @@ -1198,56 +1198,56 @@ void River::setScale( const VectorF &scale ) bool River::castRay(const Point3F &s, const Point3F &e, RayInfo* info) { - Point3F start = s; - Point3F end = e; - mObjToWorld.mulP(start); - mObjToWorld.mulP(end); + Point3F start = s; + Point3F end = e; + mObjToWorld.mulP(start); + mObjToWorld.mulP(end); - F32 out = 1.0f; // The output fraction/percentage along the line defined by s and e - VectorF norm(0.0f, 0.0f, 0.0f); // The normal of the face intersected + F32 out = 1.0f; // The output fraction/percentage along the line defined by s and e + VectorF norm(0.0f, 0.0f, 0.0f); // The normal of the face intersected - Vector hitSegments; + Vector hitSegments; - for ( U32 i = 0; i < mSegments.size(); i++ ) - { - const RiverSegment &segment = mSegments[i]; + for ( U32 i = 0; i < mSegments.size(); i++ ) + { + const RiverSegment &segment = mSegments[i]; - F32 t; - VectorF n; + F32 t; + VectorF n; - if ( segment.worldbounds.collideLine( start, end, &t, &n ) ) - { - hitSegments.increment(); - hitSegments.last().t = t; - hitSegments.last().idx = i; - } - } + if ( segment.worldbounds.collideLine( start, end, &t, &n ) ) + { + hitSegments.increment(); + hitSegments.last().t = t; + hitSegments.last().idx = i; + } + } - dQsort( hitSegments.address(), hitSegments.size(), sizeof(RiverHitSegment), compareHitSegments ); + dQsort( hitSegments.address(), hitSegments.size(), sizeof(RiverHitSegment), compareHitSegments ); U32 idx0, idx1, idx2; F32 t; - for ( U32 i = 0; i < hitSegments.size(); i++ ) - { - U32 segIdx = hitSegments[i].idx; - const RiverSegment &segment = mSegments[segIdx]; + for ( U32 i = 0; i < hitSegments.size(); i++ ) + { + U32 segIdx = hitSegments[i].idx; + const RiverSegment &segment = mSegments[segIdx]; - // Each segment has 6 faces - for ( U32 j = 0; j < 6; j++ ) - { - if ( j == 4 && segIdx != 0 ) - continue; + // Each segment has 6 faces + for ( U32 j = 0; j < 6; j++ ) + { + if ( j == 4 && segIdx != 0 ) + continue; - if ( j == 5 && segIdx != mSegments.size() - 1 ) - continue; + if ( j == 5 && segIdx != mSegments.size() - 1 ) + continue; - // Each face has 2 triangles - for ( U32 k = 0; k < 2; k++ ) - { - idx0 = gIdxArray[j][k][0]; - idx1 = gIdxArray[j][k][1]; - idx2 = gIdxArray[j][k][2]; + // Each face has 2 triangles + for ( U32 k = 0; k < 2; k++ ) + { + idx0 = gIdxArray[j][k][0]; + idx1 = gIdxArray[j][k][1]; + idx2 = gIdxArray[j][k][2]; const Point3F &v0 = segment[idx0]; const Point3F &v1 = segment[idx1]; @@ -1257,40 +1257,40 @@ bool River::castRay(const Point3F &s, const Point3F &e, RayInfo* info) v2, v1, v0, NULL, &t ) ) - continue; + continue; - if ( t >= 0.0f && t < 1.0f && t < out ) - { - out = t; + if ( t >= 0.0f && t < 1.0f && t < out ) + { + out = t; // optimize this, can be calculated easily within // the collision test norm = PlaneF( v0, v1, v2 ); - } - } - } + } + } + } - if (out >= 0.0f && out < 1.0f) - break; - } + if (out >= 0.0f && out < 1.0f) + break; + } - if (out >= 0.0f && out < 1.0f) - { - info->t = out; - info->normal = norm; - info->point.interpolate(start, end, out); - info->face = -1; - info->object = this; + if (out >= 0.0f && out < 1.0f) + { + info->t = out; + info->normal = norm; + info->point.interpolate(start, end, out); + info->face = -1; + info->object = this; - return true; - } + return true; + } - return false; + return false; } bool River::collideBox(const Point3F &start, const Point3F &end, RayInfo* info) { - return false; + return false; } bool River::buildPolyList( PolyListContext context, AbstractPolyList* polyList, const Box3F& box, const SphereF& sphere ) @@ -1656,8 +1656,8 @@ void River::_generateVerts() // These will depend on the level of subdivision per segment // calculated below. mHighVertCount = 0; - mHighTriangleCount = 0; - + mHighTriangleCount = 0; + // Calculate the number of row/column subdivisions per each // RiverSegment. @@ -1671,18 +1671,18 @@ void River::_generateVerts() mColumnCount = mCeil( greatestWidth / mMaxDivisionSize ); - for ( U32 i = 0; i < mSegments.size(); i++ ) - { + for ( U32 i = 0; i < mSegments.size(); i++ ) + { RiverSegment &segment = mSegments[i]; const RiverSlice *slice = segment.slice0; - const RiverSlice *nextSlice = segment.slice1; + const RiverSlice *nextSlice = segment.slice1; - // Calculate the size of divisions in the forward direction ( p00 -> p01 ) - F32 segLength = (nextSlice->p1 - slice->p1).len(); + // Calculate the size of divisions in the forward direction ( p00 -> p01 ) + F32 segLength = (nextSlice->p1 - slice->p1).len(); - // A division count of one is actually NO subdivision, - // the segment corners are the only verts in this segment. - U32 numRows = 1; + // A division count of one is actually NO subdivision, + // the segment corners are the only verts in this segment. + U32 numRows = 1; if ( segLength > 0.0f ) numRows = mCeil( segLength / mMaxDivisionSize ); @@ -1693,33 +1693,33 @@ void River::_generateVerts() // column data member we initialize all segments in the river to // the same (River::mColumnCount) - // Calculate the size of divisions in the right direction ( p00 -> p10 ) - // F32 segWidth = ( ( p11 - p01 ).len() + ( p10 - p00 ).len() ) * 0.5f; + // Calculate the size of divisions in the right direction ( p00 -> p10 ) + // F32 segWidth = ( ( p11 - p01 ).len() + ( p10 - p00 ).len() ) * 0.5f; - // U32 numColumns = 5; - //F32 columnSize = segWidth / numColumns; + // U32 numColumns = 5; + //F32 columnSize = segWidth / numColumns; - //while ( columnSize > mMaxDivisionSize ) - //{ - // numColumns++; - // columnSize = segWidth / numColumns; - //} - + //while ( columnSize > mMaxDivisionSize ) + //{ + // numColumns++; + // columnSize = segWidth / numColumns; + //} + // Save the calculated numb of columns / rows for this segment. segment.columns = mColumnCount; segment.rows = numRows; - + // Save the corresponding number of verts/prims segment.numVerts = ( 1 + mColumnCount ) * ( 1 + numRows ); segment.numTriangles = mColumnCount * numRows * 2; - mHighVertCount += segment.numVerts; - mHighTriangleCount += segment.numTriangles; - } + mHighVertCount += segment.numVerts; + mHighTriangleCount += segment.numTriangles; + } // Number of low detail verts/prims. - mLowVertCount = mSlices.size() * 2; - mLowTriangleCount = mSegments.size() * 2; + mLowVertCount = mSlices.size() * 2; + mLowTriangleCount = mSegments.size() * 2; // Allocate the low detail VertexBuffer, // this will stay in memory and will never need to change. @@ -1728,8 +1728,8 @@ void River::_generateVerts() GFXWaterVertex *lowVertPtr = mVB_low.lock(); U32 vertCounter = 0; - // The texCoord.y value start/end for a segment - // as we loop through them. + // The texCoord.y value start/end for a segment + // as we loop through them. F32 textCoordV = 0; // @@ -1760,7 +1760,7 @@ void River::_generateVerts() { // Increment the textCoordV for the next slice. F32 segLen = ( mSlices[i+1].p1 - slice.p1 ).len(); - textCoordV += segLen; + textCoordV += segLen; } } @@ -1771,8 +1771,8 @@ void River::_generateVerts() // // Create the low-detail prim buffer(s) - // - mPB_low.set( GFX, mLowTriangleCount * 3, mLowTriangleCount, GFXBufferTypeStatic ); + // + mPB_low.set( GFX, mLowTriangleCount * 3, mLowTriangleCount, GFXBufferTypeStatic ); U16 *lowIdxBuff; mPB_low.lock(&lowIdxBuff); @@ -1784,13 +1784,13 @@ void River::_generateVerts() U32 offset = 0; // Fill the low-detail PrimitiveBuffer - for ( U32 i = 0; i < mSegments.size(); i++ ) - { + for ( U32 i = 0; i < mSegments.size(); i++ ) + { //const RiverSegment &segment = mSegments[i]; - + // Two triangles formed by the corner points of this segment // into the the low detail primitive buffer. - p00 = offset; + p00 = offset; p01 = p00 + 2; p11 = p01 + 1; p10 = p00 + 1; diff --git a/Engine/source/gfx/gl/gfxGLStateBlock.cpp b/Engine/source/gfx/gl/gfxGLStateBlock.cpp index 87d2b5953..1a104ab27 100644 --- a/Engine/source/gfx/gl/gfxGLStateBlock.cpp +++ b/Engine/source/gfx/gl/gfxGLStateBlock.cpp @@ -40,32 +40,32 @@ GFXGLStateBlock::GFXGLStateBlock(const GFXStateBlockDesc& desc) : mCachedHashValue(desc.getHashValue()) { if( !GFXGL->mCapabilities.samplerObjects ) - return; + return; static Map mSamplersMap; - for(int i = 0; i < TEXTURE_STAGE_COUNT; ++i) - { - GLuint &id = mSamplerObjects[i]; - GFXSamplerStateDesc &ssd = mDesc.samplers[i]; + for(int i = 0; i < TEXTURE_STAGE_COUNT; ++i) + { + GLuint &id = mSamplerObjects[i]; + GFXSamplerStateDesc &ssd = mDesc.samplers[i]; Map::Iterator itr = mSamplersMap.find(ssd); if(itr == mSamplersMap.end()) { - glGenSamplers(1, &id); + glGenSamplers(1, &id); - glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 1) ); - glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]); - glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]); - glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]); - glSamplerParameteri(id, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]); - if(static_cast< GFXGLDevice* >( GFX )->supportsAnisotropic() ) - glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, ssd.maxAnisotropy); + glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, minificationFilter(ssd.minFilter, ssd.mipFilter, 1) ); + glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, GFXGLTextureFilter[ssd.magFilter]); + glSamplerParameteri(id, GL_TEXTURE_WRAP_S, GFXGLTextureAddress[ssd.addressModeU]); + glSamplerParameteri(id, GL_TEXTURE_WRAP_T, GFXGLTextureAddress[ssd.addressModeV]); + glSamplerParameteri(id, GL_TEXTURE_WRAP_R, GFXGLTextureAddress[ssd.addressModeW]); + if(static_cast< GFXGLDevice* >( GFX )->supportsAnisotropic() ) + glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, ssd.maxAnisotropy); mSamplersMap[ssd] = id; } else id = itr->value; - } + } } GFXGLStateBlock::~GFXGLStateBlock() @@ -171,9 +171,9 @@ void GFXGLStateBlock::activate(const GFXGLStateBlock* oldState) for (U32 i = 0; i < getMin(getOwningDevice()->getNumSamplers(), (U32) TEXTURE_STAGE_COUNT); i++) { if(!oldState || oldState->mSamplerObjects[i] != mSamplerObjects[i]) - glBindSampler(i, mSamplerObjects[i] ); + glBindSampler(i, mSamplerObjects[i] ); } - } + } // TODO: states added for detail blend } diff --git a/Engine/source/gfx/video/videoCapture.cpp b/Engine/source/gfx/video/videoCapture.cpp index 230baf501..8d5f0ce61 100644 --- a/Engine/source/gfx/video/videoCapture.cpp +++ b/Engine/source/gfx/video/videoCapture.cpp @@ -340,7 +340,7 @@ DefineEngineFunction( stopVideoCapture, void, (),, DefineEngineFunction( playJournalToVideo, void, ( const char *journalFile, const char *videoFile, const char *encoder, F32 framerate, Point2I resolution ), - ( NULL, "THEORA", 30.0f, Point2I::Zero ), + ( NULL, "THEORA", 30.0f, Point2I::Zero ), "Load a journal file and capture it video.\n" "@ingroup Rendering\n" ) { diff --git a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp index b4aed4ec7..f37d69a4c 100644 --- a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp @@ -59,21 +59,21 @@ ConsoleDocClass( GuiIconButtonCtrl, "has been clicked.\n\n" "@tsexample\n" - "new GuiIconButtonCtrl(TestIconButton)\n" - "{\n" - " buttonMargin = \"4 4\";\n" - " iconBitmap = \"art/gui/lagIcon.png\";\n" - " iconLocation = \"Center\";\n" - " sizeIconToButton = \"0\";\n" - " makeIconSquare = \"1\";\n" - " textLocation = \"Bottom\";\n" - " textMargin = \"-2\";\n" - " autoSize = \"0\";\n" - " text = \"Lag Icon\";\n" - " textID = \"\"STR_LAG\"\";\n" - " buttonType = \"PushButton\";\n" - " profile = \"GuiIconButtonProfile\";\n" - "};\n" + "new GuiIconButtonCtrl(TestIconButton)\n" + "{\n" + " buttonMargin = \"4 4\";\n" + " iconBitmap = \"art/gui/lagIcon.png\";\n" + " iconLocation = \"Center\";\n" + " sizeIconToButton = \"0\";\n" + " makeIconSquare = \"1\";\n" + " textLocation = \"Bottom\";\n" + " textMargin = \"-2\";\n" + " autoSize = \"0\";\n" + " text = \"Lag Icon\";\n" + " textID = \"\"STR_LAG\"\";\n" + " buttonType = \"PushButton\";\n" + " profile = \"GuiIconButtonProfile\";\n" + "};\n" "@endtsexample\n\n" "@see GuiControl\n" @@ -130,7 +130,7 @@ void GuiIconButtonCtrl::initPersistFields() addField( "sizeIconToButton", TypeBool, Offset( mFitBitmapToButton, GuiIconButtonCtrl ),"If true, the icon will be scaled to be the same size as the button.\n"); addField( "makeIconSquare", TypeBool, Offset( mMakeIconSquare, GuiIconButtonCtrl ),"If true, will make sure the icon is square.\n"); addField( "textLocation", TYPEID< TextLocation >(), Offset( mTextLocation, GuiIconButtonCtrl ),"Where to place the text on the control.\n" - "Options are 0 (None), 1 (Bottom), 2 (Right), 3 (Top), 4 (Left), 5 (Center).\n"); + "Options are 0 (None), 1 (Bottom), 2 (Right), 3 (Top), 4 (Left), 5 (Center).\n"); addField( "textMargin", TypeS32, Offset( mTextMargin, GuiIconButtonCtrl ),"Margin between the icon and the text.\n"); addField( "autoSize", TypeBool, Offset( mAutoSize, GuiIconButtonCtrl ),"If true, the text and icon will be automatically sized to the size of the control.\n"); Parent::initPersistFields(); diff --git a/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp b/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp index e5aa4b0f5..7168f58ca 100644 --- a/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp @@ -60,7 +60,7 @@ void GuiToggleButtonCtrl::onPreRender() // If we have a script variable, make sure we're in sync if ( mConsoleVariable[0] ) - mStateOn = Con::getBoolVariable( mConsoleVariable ); + mStateOn = Con::getBoolVariable( mConsoleVariable ); } void GuiToggleButtonCtrl::onRender(Point2I offset, diff --git a/Engine/source/gui/containers/guiFormCtrl.cpp b/Engine/source/gui/containers/guiFormCtrl.cpp index e87bcb6d2..bbd9a7f9e 100644 --- a/Engine/source/gui/containers/guiFormCtrl.cpp +++ b/Engine/source/gui/containers/guiFormCtrl.cpp @@ -158,7 +158,7 @@ void GuiFormCtrl::addObject(SimObject *newObj ) GuiControl* parent = getParent(); if ( parent ) - parent->addObject( newObj ); + parent->addObject( newObj ); return; } diff --git a/Engine/source/gui/containers/guiPaneCtrl.cpp b/Engine/source/gui/containers/guiPaneCtrl.cpp index 1637b0b30..c42fc9e51 100644 --- a/Engine/source/gui/containers/guiPaneCtrl.cpp +++ b/Engine/source/gui/containers/guiPaneCtrl.cpp @@ -108,7 +108,7 @@ bool GuiPaneControl::onWake() } if(mCaptionID && *mCaptionID != 0) - setCaptionID(mCaptionID); + setCaptionID(mCaptionID); mProfile->constructBitmapArray(); if(mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size()) @@ -131,19 +131,19 @@ bool GuiPaneControl::onWake() void GuiPaneControl::setCaptionID(const char *id) { - S32 n = Con::getIntVariable(id, -1); - if(n != -1) - { - mCaptionID = StringTable->insert(id); - setCaptionID(n); - } + S32 n = Con::getIntVariable(id, -1); + if(n != -1) + { + mCaptionID = StringTable->insert(id); + setCaptionID(n); + } } //----------------------------------------------------------------------------- void GuiPaneControl::setCaptionID(S32 id) { - mCaption = getGUIString(id); + mCaption = getGUIString(id); } //----------------------------------------------------------------------------- diff --git a/Engine/source/gui/containers/guiRolloutCtrl.cpp b/Engine/source/gui/containers/guiRolloutCtrl.cpp index ea5201021..6f2272d9a 100644 --- a/Engine/source/gui/containers/guiRolloutCtrl.cpp +++ b/Engine/source/gui/containers/guiRolloutCtrl.cpp @@ -462,9 +462,9 @@ void GuiRolloutCtrl::processTick() newHeight -= mAnimateStep; if( !mIsAnimating ) - { + { mIsExpanded = false; - } + } } else // We're expanding ourself (Showing our contents) { @@ -559,13 +559,13 @@ void GuiRolloutCtrl::onRender( Point2I offset, const RectI &updateRect ) if ( pChild ) { if ( !mIsExpanded && !mIsAnimating && pChild->isVisible() ) - { + { pChild->setVisible( false ); - } + } else if ( (mIsExpanded || mIsAnimating) && !pChild->isVisible() ) - { + { pChild->setVisible( true ); - } + } } renderChildControls( offset, updateRect ); @@ -614,7 +614,7 @@ DefineEngineMethod( GuiRolloutCtrl, toggleCollapse, void, (),, if( object->isExpanded() ) object->collapse(); else - object->expand(); + object->expand(); } //----------------------------------------------------------------------------- diff --git a/Engine/source/gui/containers/guiWindowCtrl.cpp b/Engine/source/gui/containers/guiWindowCtrl.cpp index 84be45148..2957ec7ec 100644 --- a/Engine/source/gui/containers/guiWindowCtrl.cpp +++ b/Engine/source/gui/containers/guiWindowCtrl.cpp @@ -231,7 +231,7 @@ void GuiWindowCtrl::moveFromCollapseGroup() parent->mCollapseGroupVec[groupVec].first()->mCollapseGroupNum = -1; parent->mCollapseGroupVec[groupVec].erase(U32(0)); parent->mCollapseGroupVec[groupVec].setSize(groupVecCount - 1); - parent->mCollapseGroupVec.erase(groupVec); + parent->mCollapseGroupVec.erase(groupVec); } } @@ -381,7 +381,7 @@ void GuiWindowCtrl::refreshCollapseGroups() if( !parent ) return; - CollapseGroupNumVec collapseGroupNumVec; + CollapseGroupNumVec collapseGroupNumVec; // iterate through the collided array, renumbering the windows pointers S32 assignGroupNum = 0; @@ -463,7 +463,7 @@ void GuiWindowCtrl::handleCollapseGroup() if( !parent ) return; - CollapseGroupNumVec collapseGroupNumVec; + CollapseGroupNumVec collapseGroupNumVec; if( mIsCollapsed ) // minimize window up to its header bar { @@ -529,7 +529,7 @@ void GuiWindowCtrl::handleCollapseGroup() if((*iter)->mCollapseGroupNum > mCollapseGroupNum) { Point2I newChildPosition = (*iter)->getPosition(); - newChildPosition.y += moveChildYBy; + newChildPosition.y += moveChildYBy; (*iter)->resize(newChildPosition, (*iter)->getExtent()); } } @@ -547,7 +547,7 @@ bool GuiWindowCtrl::resizeCollapseGroup(bool resizeX, bool resizeY, Point2I resi if( !parent ) return false; - CollapseGroupNumVec collapseGroupNumVec; + CollapseGroupNumVec collapseGroupNumVec; bool canResize = true; CollapseGroupNumVec::iterator iter = parent->mCollapseGroupVec[mCollapseGroup].begin(); @@ -980,7 +980,7 @@ void GuiWindowCtrl::onMouseDragged(const GuiEvent &event) moveWithCollapseGroup(newPosition); if(mCanCollapse && mCollapseGroup >= 0 && mResizeWindow == true ) - { + { // Resize the window if allowed if( newExtent.y >= getMinExtent().y && newExtent.x >= getMinExtent().x) { @@ -1212,7 +1212,7 @@ void GuiWindowCtrl::onMouseUp(const GuiEvent &event) // We're either moving out of a collapse group or moving to another one // Not valid for windows not previously in a group if( mCollapseGroup >= 0 && - (snapType == -1 || (hitWindow && snapType >= 0 && mCollapseGroup != hitWindow->mCollapseGroup))) + (snapType == -1 || (hitWindow && snapType >= 0 && mCollapseGroup != hitWindow->mCollapseGroup))) moveFromCollapseGroup(); // No window to connect to @@ -1830,7 +1830,7 @@ void GuiWindowCtrl::parentResized(const RectI &oldParentRect, const RectI &newPa // Only for collpasing groups, if were not, then do it like normal windows if( mCanCollapse && mCollapseGroup >= 0 ) - { + { bool resizeMe = false; // Only the group window should control positioning diff --git a/Engine/source/gui/controls/guiListBoxCtrl.cpp b/Engine/source/gui/controls/guiListBoxCtrl.cpp index 22108ee3d..5deab67fc 100644 --- a/Engine/source/gui/controls/guiListBoxCtrl.cpp +++ b/Engine/source/gui/controls/guiListBoxCtrl.cpp @@ -52,9 +52,9 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onMouseDragged, void, (),(), "@tsexample\n" "// Mouse is dragged across the control, causing the callback to occur.\n" "GuiListBoxCtrl::onMouseDragged(%this)\n" - " {\n" - " // Code to run whenever the mouse is dragged across the control\n" - " }\n" + " {\n" + " // Code to run whenever the mouse is dragged across the control\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -64,9 +64,9 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onClearSelection, void, (),(), "@tsexample\n" "// A selected item is cleared, causing the callback to occur.\n" "GuiListBoxCtrl::onClearSelection(%this)\n" - " {\n" - " // Code to run whenever a selected item is cleared\n" - " }\n" + " {\n" + " // Code to run whenever a selected item is cleared\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -78,9 +78,9 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onUnSelect, void, ( S32 index, const char* i "@tsexample\n" "// A selected item is unselected, causing the callback to occur\n" "GuiListBoxCtrl::onUnSelect(%this, %indexId, %itemText)\n" - " {\n" - " // Code to run whenever a selected list item is unselected\n" - " }\n" + " {\n" + " // Code to run whenever a selected list item is unselected\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -92,9 +92,9 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onSelect, void, ( S32 index , const char* it "@tsexample\n" "// An item in the list is selected, causing the callback to occur\n" "GuiListBoxCtrl::onSelect(%this, %index, %itemText)\n" - " {\n" - " // Code to run whenever an item in the list is selected\n" - " }\n" + " {\n" + " // Code to run whenever an item in the list is selected\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -104,9 +104,9 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onDoubleClick, void, (),(), "@tsexample\n" "// An item in the list is double clicked, causing the callback to occur.\n" "GuiListBoxCtrl::onDoubleClick(%this)\n" - " {\n" - " // Code to run whenever an item in the control has been double clicked\n" - " }\n" + " {\n" + " // Code to run whenever an item in the control has been double clicked\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -121,9 +121,9 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onMouseUp, void, ( S32 itemHit, S32 mouseCli "@tsexample\n" "// Mouse was previously clicked down, and now has been released, causing the callback to occur.\n" "GuiListBoxCtrl::onMouseUp(%this, %itemHit, %mouseClickCount)\n" - " {\n" - " // Code to call whenever the mouse has been clicked and released on the control\n" - " }\n" + " {\n" + " // Code to call whenever the mouse has been clicked and released on the control\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -133,9 +133,9 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, onDeleteKey, void, (),(), "@tsexample\n" "// The delete key on the keyboard has been pressed while this control is in focus, causing the callback to occur.\n" "GuiListBoxCtrl::onDeleteKey(%this)\n" - " {\n" - " // Code to call whenever the delete key is pressed\n" - " }\n" + " {\n" + " // Code to call whenever the delete key is pressed\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -146,10 +146,10 @@ IMPLEMENT_CALLBACK( GuiListBoxCtrl, isObjectMirrored, bool, ( const char* indexI "@tsexample\n" "// Engine has requested of the script level to determine if a list entry is mirrored or not.\n" "GuiListBoxCtrl::isObjectMirrored(%this, %indexIdString)\n" - " {\n" - " // Perform code required to check and see if the list item at the index id is mirrored or not.\n" - " return %isMirrored;\n" - " }\n" + " {\n" + " // Perform code required to check and see if the list item at the index id is mirrored or not.\n" + " return %isMirrored;\n" + " }\n" "@endtsexample\n\n" "@return A boolean value on if the list item is mirrored or not.\n\n" "@see GuiControl\n\n" @@ -234,7 +234,7 @@ void GuiListBoxCtrl::clearItems() // Free our vector lists mItems.clear(); mSelectedItems.clear(); - mFilteredItems.clear(); + mFilteredItems.clear(); } DefineEngineMethod( GuiListBoxCtrl, clearSelection, void, (),, @@ -1511,8 +1511,8 @@ void GuiListBoxCtrl::_mirror() break; } } - - for ( U32 j = 0; j < mFilteredItems.size(); j++ ) + + for ( U32 j = 0; j < mFilteredItems.size(); j++ ) { if ( (SimObjectId)(uintptr_t)(mFilteredItems[j]->itemData) == curId ) { @@ -1571,37 +1571,37 @@ DefineEngineMethod( GuiListBoxCtrl, addFilteredItem, void, (const char* newItem) "@endtsexample\n\n" "@see GuiControl") { - String item(newItem); - if( item == String::EmptyString ) - return; + String item(newItem); + if( item == String::EmptyString ) + return; - object->addFilteredItem( item ); + object->addFilteredItem( item ); } void GuiListBoxCtrl::addFilteredItem( String item ) { - // Delete from selected items list - for ( S32 i = 0; i < mSelectedItems.size(); i++ ) - { - String itemText = mSelectedItems[i]->itemText; - if ( dStrcmp( itemText.c_str(), item.c_str() ) == 0 ) - { - mSelectedItems.erase_fast( i ); - break; - } - } + // Delete from selected items list + for ( S32 i = 0; i < mSelectedItems.size(); i++ ) + { + String itemText = mSelectedItems[i]->itemText; + if ( dStrcmp( itemText.c_str(), item.c_str() ) == 0 ) + { + mSelectedItems.erase_fast( i ); + break; + } + } - for ( S32 i = 0; i < mItems.size(); i++ ) - { - String itemText = mItems[i]->itemText; - if( dStrcmp( itemText.c_str(), item.c_str() ) == 0 ) - { - mItems[i]->isSelected = false; - mFilteredItems.push_front( mItems[i] ); - mItems.erase( &mItems[i] ); - break; - } - } + for ( S32 i = 0; i < mItems.size(); i++ ) + { + String itemText = mItems[i]->itemText; + if( dStrcmp( itemText.c_str(), item.c_str() ) == 0 ) + { + mItems[i]->isSelected = false; + mFilteredItems.push_front( mItems[i] ); + mItems.erase( &mItems[i] ); + break; + } + } } DefineEngineMethod( GuiListBoxCtrl, removeFilteredItem, void, ( const char* itemName ),, @@ -1615,23 +1615,23 @@ DefineEngineMethod( GuiListBoxCtrl, removeFilteredItem, void, ( const char* item "@endtsexample\n\n" "@see GuiControl") { - String item(itemName); - if( item == String::EmptyString ) - return; + String item(itemName); + if( item == String::EmptyString ) + return; - object->removeFilteredItem( item ); + object->removeFilteredItem( item ); } void GuiListBoxCtrl::removeFilteredItem( String item ) { - for ( S32 i = 0; i < mFilteredItems.size(); i++ ) - { - String itemText = mFilteredItems[i]->itemText; - if( dStrcmp( itemText.c_str(), item.c_str() ) == 0 ) - { - mItems.push_front( mFilteredItems[i] ); - mFilteredItems.erase( &mFilteredItems[i] ); - break; - } - } + for ( S32 i = 0; i < mFilteredItems.size(); i++ ) + { + String itemText = mFilteredItems[i]->itemText; + if( dStrcmp( itemText.c_str(), item.c_str() ) == 0 ) + { + mItems.push_front( mFilteredItems[i] ); + mFilteredItems.erase( &mFilteredItems[i] ); + break; + } + } } \ No newline at end of file diff --git a/Engine/source/gui/controls/guiMLTextCtrl.cpp b/Engine/source/gui/controls/guiMLTextCtrl.cpp index 1a4f64814..6cfdf4354 100644 --- a/Engine/source/gui/controls/guiMLTextCtrl.cpp +++ b/Engine/source/gui/controls/guiMLTextCtrl.cpp @@ -66,9 +66,9 @@ IMPLEMENT_CALLBACK( GuiMLTextCtrl, onURL, void, ( const char* url ),( url ), "@tsexample\n" "// A URL address was clicked on in the control, causing the callback to occur.\n" "GuiMLTextCtrl::onUrl(%this,%url)\n" - " {\n" - " // Code to run whenever a URL was clicked on\n" - " }\n" + " {\n" + " // Code to run whenever a URL was clicked on\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -80,9 +80,9 @@ IMPLEMENT_CALLBACK( GuiMLTextCtrl, onResize, void, ( S32 width, S32 maxY ),( wid "@tsexample\n" "// Control size changed, causing the callback to occur.\n" "GuiMLTextCtrl::onResize(%this,%width,%maxY)\n" - " {\n" - " // Code to call when the control size changes\n" - " }\n" + " {\n" + " // Code to call when the control size changes\n" + " }\n" "@endtsexample\n\n" "@see GuiControl\n\n" ); @@ -191,17 +191,17 @@ DefineEngineMethod( GuiMLTextCtrl, scrollToBottom, void, (),, } DefineEngineFunction(StripMLControlChars, const char*, (const char* inString),, - "@brief Strip TorqueML control characters from the specified string, returning a 'clean' version.\n\n" - "@param inString String to strip TorqueML control characters from.\n" - "@tsexample\n" - "// Define the string to strip TorqueML control characters from\n" - "%string = \"How Now Brown Cow\";\n\n" - "// Request the stripped version of the string\n" - "%strippedString = StripMLControlChars(%string);\n" - "@endtsexample\n\n" - "@return Version of the inputted string with all TorqueML characters removed.\n\n" - "@see References\n\n" - "@ingroup GuiCore") + "@brief Strip TorqueML control characters from the specified string, returning a 'clean' version.\n\n" + "@param inString String to strip TorqueML control characters from.\n" + "@tsexample\n" + "// Define the string to strip TorqueML control characters from\n" + "%string = \"How Now Brown Cow\";\n\n" + "// Request the stripped version of the string\n" + "%strippedString = StripMLControlChars(%string);\n" + "@endtsexample\n\n" + "@return Version of the inputted string with all TorqueML characters removed.\n\n" + "@see References\n\n" + "@ingroup GuiCore") { return GuiMLTextCtrl::stripControlChars(inString); } @@ -293,7 +293,7 @@ void GuiMLTextCtrl::initPersistFields() addField("deniedSound", TypeSFXTrackName, Offset(mDeniedSound, GuiMLTextCtrl), "If the text will not fit in the control, the deniedSound is played."); addField("text", TypeCaseString, Offset( mInitialText, GuiMLTextCtrl ), "Text to display in this control."); addField("useURLMouseCursor", TypeBool, Offset(mUseURLMouseCursor, GuiMLTextCtrl), "If true, the mouse cursor will turn into a hand cursor while over a link in the text.\n" - "This is dependant on the markup language used by the GuiMLTextCtrl\n"); + "This is dependant on the markup language used by the GuiMLTextCtrl\n"); endGroup( "Text" ); @@ -649,9 +649,9 @@ void GuiMLTextCtrl::ensureCursorOnScreen() // If our parent isn't a scroll control, or we're not the only control // in the content region, bail... GuiControl* pParent = getParent(); - GuiScrollCtrl *sc = dynamic_cast(pParent); - if(!sc) - return; + GuiScrollCtrl *sc = dynamic_cast(pParent); + if(!sc) + return; // Ok. Now we know that our parent is a scroll control. Let's find the // top of the cursor, and it's bottom. We can then scroll the parent control @@ -661,7 +661,7 @@ void GuiMLTextCtrl::ensureCursorOnScreen() ColorI color; getCursorPositionAndColor(cursorTopP, cursorBottomP, color); - sc->scrollRectVisible(RectI(cursorTopP.x, cursorTopP.y, 1, cursorBottomP.y - cursorTopP.y)); + sc->scrollRectVisible(RectI(cursorTopP.x, cursorTopP.y, 1, cursorBottomP.y - cursorTopP.y)); } //-------------------------------------- @@ -840,7 +840,7 @@ void GuiMLTextCtrl::onMouseUp(const GuiEvent& event) // Convert URL from UTF16 to UTF8. UTF8* url = mTextBuffer.createSubstring8(mHitURL->textStart, mHitURL->len); - onURL_callback(url); + onURL_callback(url); delete[] url; mHitURL = NULL; @@ -1018,7 +1018,7 @@ void GuiMLTextCtrl::scrollToTag( U32 id ) Con::warnf( ConsoleLogEntry::General, "GuiMLTextCtrl::scrollToTag - tag id %d not found!", id ); return; } - pappy->scrollRectVisible(RectI(0, tag->y, 1, 1)); + pappy->scrollRectVisible(RectI(0, tag->y, 1, 1)); } //-------------------------------------------------------------------------- @@ -1028,7 +1028,7 @@ void GuiMLTextCtrl::scrollToTop() GuiScrollCtrl *pappy = dynamic_cast(getParent()); if ( !pappy ) return; - pappy->scrollRectVisible(RectI(0,0,0,0)); + pappy->scrollRectVisible(RectI(0,0,0,0)); } //-------------------------------------------------------------------------- @@ -2134,7 +2134,7 @@ textemit: emitNewLine(mScanPos); setHeight( mMaxY ); onResize_callback( getWidth(), mMaxY ); - + //make sure the cursor is still visible - this handles if we're a child of a scroll ctrl... ensureCursorOnScreen(); } diff --git a/Engine/source/gui/controls/guiPopUpCtrl.cpp b/Engine/source/gui/controls/guiPopUpCtrl.cpp index aabce4d11..beb9fbcc8 100644 --- a/Engine/source/gui/controls/guiPopUpCtrl.cpp +++ b/Engine/source/gui/controls/guiPopUpCtrl.cpp @@ -233,31 +233,31 @@ void GuiPopupTextListCtrl::onRenderCell(Point2I offset, Point2I cell, bool selec IMPLEMENT_CONOBJECT(GuiPopUpMenuCtrl); ConsoleDocClass( GuiPopUpMenuCtrl, - "@brief A control that allows to select a value from a drop-down list.\n\n" + "@brief A control that allows to select a value from a drop-down list.\n\n" - "For a nearly identical GUI with additional features, use GuiPopUpMenuCtrlEx.\n\n" + "For a nearly identical GUI with additional features, use GuiPopUpMenuCtrlEx.\n\n" - "@tsexample\n" - "new GuiPopUpMenuCtrl()\n" - "{\n" - " maxPopupHeight = \"200\";\n" - " sbUsesNAColor = \"0\";\n" - " reverseTextList = \"0\";\n" - " bitmapBounds = \"16 16\";\n" - " maxLength = \"1024\";\n" - " position = \"56 31\";\n" - " extent = \"64 64\";\n" - " minExtent = \"8 2\";\n" - " profile = \"GuiPopUpMenuProfile\";\n" - " tooltipProfile = \"GuiToolTipProfile\";\n" - "};\n" - "@endtsexample\n\n" + "@tsexample\n" + "new GuiPopUpMenuCtrl()\n" + "{\n" + " maxPopupHeight = \"200\";\n" + " sbUsesNAColor = \"0\";\n" + " reverseTextList = \"0\";\n" + " bitmapBounds = \"16 16\";\n" + " maxLength = \"1024\";\n" + " position = \"56 31\";\n" + " extent = \"64 64\";\n" + " minExtent = \"8 2\";\n" + " profile = \"GuiPopUpMenuProfile\";\n" + " tooltipProfile = \"GuiToolTipProfile\";\n" + "};\n" + "@endtsexample\n\n" - "@note This is definitely going to be deprecated soon.\n\n" + "@note This is definitely going to be deprecated soon.\n\n" - "@see GuiPopUpMenuCtrlEx for more features and better explanations.\n" + "@see GuiPopUpMenuCtrlEx for more features and better explanations.\n" - "@ingroup GuiControls\n"); + "@ingroup GuiControls\n"); GuiPopUpMenuCtrl::GuiPopUpMenuCtrl(void) { @@ -279,7 +279,7 @@ GuiPopUpMenuCtrl::GuiPopUpMenuCtrl(void) mReverseTextList = false; // Added - Don't reverse text list if displaying up mBitmapName = StringTable->insert(""); // Added mBitmapBounds.set(16, 16); // Added - mIdMax = -1; + mIdMax = -1; } //------------------------------------------------------------------------------ @@ -302,11 +302,11 @@ void GuiPopUpMenuCtrl::initPersistFields(void) //------------------------------------------------------------------------------ DefineConsoleMethod( GuiPopUpMenuCtrl, add, void, (const char * name, S32 idNum, U32 scheme), ("", -1, 0), "(string name, int idNum, int scheme=0)") { - object->addEntry(name, idNum, scheme); + object->addEntry(name, idNum, scheme); } DefineConsoleMethod( GuiPopUpMenuCtrl, addScheme, void, (U32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL), , - "(int id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL)") + "(int id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL)") { object->addScheme( id, fontColor, fontColorHL, fontColorSEL ); @@ -492,43 +492,43 @@ void GuiPopUpMenuCtrl::clear() setText(""); mSelIndex = -1; mRevNum = 0; - mIdMax = -1; + mIdMax = -1; } //------------------------------------------------------------------------------ void GuiPopUpMenuCtrl::clearEntry( S32 entry ) -{ - if( entry == -1 ) - return; +{ + if( entry == -1 ) + return; - U32 i = 0; - for ( ; i < mEntries.size(); i++ ) + U32 i = 0; + for ( ; i < mEntries.size(); i++ ) { if ( mEntries[i].id == entry ) break; } - mEntries.erase( i ); + mEntries.erase( i ); - if( mEntries.size() <= 0 ) - { - mEntries.setSize(0); - setText(""); - mSelIndex = -1; - mRevNum = 0; - } - else - { - if (entry < mSelIndex) - { - mSelIndex--; - } - else if( entry == mSelIndex ) - { - setText(""); - mSelIndex = -1; - } - } + if( mEntries.size() <= 0 ) + { + mEntries.setSize(0); + setText(""); + mSelIndex = -1; + mRevNum = 0; + } + else + { + if (entry < mSelIndex) + { + mSelIndex--; + } + else if( entry == mSelIndex ) + { + setText(""); + mSelIndex = -1; + } + } } //------------------------------------------------------------------------------ @@ -620,21 +620,21 @@ void GuiPopUpMenuCtrl::addEntry( const char *buf, S32 id, U32 scheme ) //Con::printf( "GuiPopupMenuCtrlEx::addEntry - Invalid buffer!" ); return; } - - // Ensure that there are no other entries with exactly the same name - for ( U32 i = 0; i < mEntries.size(); i++ ) + + // Ensure that there are no other entries with exactly the same name + for ( U32 i = 0; i < mEntries.size(); i++ ) { if ( dStrcmp( mEntries[i].buf, buf ) == 0 ) return; } - // If we don't give an id, create one from mIdMax - if( id == -1 ) - id = mIdMax + 1; - - // Increase mIdMax when an id is greater than it - if( id > mIdMax ) - mIdMax = id; + // If we don't give an id, create one from mIdMax + if( id == -1 ) + id = mIdMax + 1; + + // Increase mIdMax when an id is greater than it + if( id > mIdMax ) + mIdMax = id; Entry e; dStrcpy( e.buf, buf ); @@ -802,28 +802,28 @@ void GuiPopUpMenuCtrl::setFirstSelected( bool bNotifyScript ) setText( mEntries[0].buf ); } - // Execute the popup console command: - if( bNotifyScript ) + // Execute the popup console command: + if( bNotifyScript ) { if ( isMethod( "onSelect" ) ) Con::executef( this, "onSelect", Con::getIntArg( mEntries[ mSelIndex ].id ), mEntries[mSelIndex].buf ); - execConsoleCallback(); - } - } - else - { - if ( mReplaceText ) // Only change the displayed text if appropriate. - setText(""); - - mSelIndex = -1; - - if( bNotifyScript ) - { - Con::executef( this, "onCancel" ); execConsoleCallback(); } - } + } + else + { + if ( mReplaceText ) // Only change the displayed text if appropriate. + setText(""); + + mSelIndex = -1; + + if( bNotifyScript ) + { + Con::executef( this, "onCancel" ); + execConsoleCallback(); + } + } } //------------------------------------------------------------------------------ @@ -1278,11 +1278,11 @@ void GuiPopUpMenuCtrl::onAction() if ( setScroll ) { // Resize the text list - Point2I cellSize; - mTl->getCellSize( cellSize ); - cellSize.x = width - mSc->scrollBarThickness() - sbBorder; - mTl->setCellSize( cellSize ); - mTl->setWidth( cellSize.x ); + Point2I cellSize; + mTl->getCellSize( cellSize ); + cellSize.x = width - mSc->scrollBarThickness() - sbBorder; + mTl->setCellSize( cellSize ); + mTl->setWidth( cellSize.x ); if ( mSelIndex ) mTl->scrollCellVisible( Point2I( 0, mSelIndex ) ); @@ -1315,7 +1315,7 @@ void GuiPopUpMenuCtrl::addChildren() else { // Use the children's profile rather than the parent's profile, if it exists. - mSc->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile ); + mSc->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile ); } mSc->setField( "hScrollBar", "AlwaysOff" ); diff --git a/Engine/source/gui/controls/guiPopUpCtrlEx.cpp b/Engine/source/gui/controls/guiPopUpCtrlEx.cpp index 0d90b9d73..510576f8a 100644 --- a/Engine/source/gui/controls/guiPopUpCtrlEx.cpp +++ b/Engine/source/gui/controls/guiPopUpCtrlEx.cpp @@ -30,27 +30,27 @@ #include "console/engineAPI.h" ConsoleDocClass( GuiPopUpMenuCtrlEx, - "@brief A control that allows to select a value from a drop-down list.\n\n" + "@brief A control that allows to select a value from a drop-down list.\n\n" - "This is essentially a GuiPopUpMenuCtrl, but with quite a few more features.\n\n" + "This is essentially a GuiPopUpMenuCtrl, but with quite a few more features.\n\n" - "@tsexample\n" - "new GuiPopUpMenuCtrlEx()\n" - "{\n" - " maxPopupHeight = \"200\";\n" - " sbUsesNAColor = \"0\";\n" - " reverseTextList = \"0\";\n" - " bitmapBounds = \"16 16\";\n" - " hotTrackCallback = \"0\";\n" - " extent = \"64 64\";\n" - " profile = \"GuiDefaultProfile\";\n" - " tooltipProfile = \"GuiToolTipProfile\";\n" - "};\n" - "@endtsexample\n\n" + "@tsexample\n" + "new GuiPopUpMenuCtrlEx()\n" + "{\n" + " maxPopupHeight = \"200\";\n" + " sbUsesNAColor = \"0\";\n" + " reverseTextList = \"0\";\n" + " bitmapBounds = \"16 16\";\n" + " hotTrackCallback = \"0\";\n" + " extent = \"64 64\";\n" + " profile = \"GuiDefaultProfile\";\n" + " tooltipProfile = \"GuiToolTipProfile\";\n" + "};\n" + "@endtsexample\n\n" - "@see GuiPopUpMenuCtrl\n" + "@see GuiPopUpMenuCtrl\n" - "@ingroup GuiControls\n"); + "@ingroup GuiControls\n"); static ColorI colorWhite(255,255,255); // Added @@ -331,7 +331,7 @@ GuiPopUpMenuCtrlEx::GuiPopUpMenuCtrlEx(void) mBitmapName = StringTable->insert(""); // Added mBitmapBounds.set(16, 16); // Added mHotTrackItems = false; - mIdMax = -1; + mIdMax = -1; } //------------------------------------------------------------------------------ @@ -355,13 +355,13 @@ void GuiPopUpMenuCtrlEx::initPersistFields(void) //------------------------------------------------------------------------------ ConsoleDocFragment _GuiPopUpMenuCtrlExAdd( - "@brief Adds an entry to the list\n\n" - "@param name String containing the name of the entry\n" - "@param idNum Numerical value assigned to the name\n" - "@param scheme Optional ID associated with a scheme " - "for font coloring, highlight coloring, and selection coloring\n\n", - "GuiPopUpMenuCtrlEx", - "void add(string name, S32 idNum, S32 scheme=0);" + "@brief Adds an entry to the list\n\n" + "@param name String containing the name of the entry\n" + "@param idNum Numerical value assigned to the name\n" + "@param scheme Optional ID associated with a scheme " + "for font coloring, highlight coloring, and selection coloring\n\n", + "GuiPopUpMenuCtrlEx", + "void add(string name, S32 idNum, S32 scheme=0);" ); DefineConsoleMethod( GuiPopUpMenuCtrlEx, add, void, (const char * name, S32 idNum, U32 scheme), ("", -1, 0), "(string name, int idNum, int scheme=0)") @@ -370,23 +370,23 @@ DefineConsoleMethod( GuiPopUpMenuCtrlEx, add, void, (const char * name, S32 idNu } DefineEngineMethod( GuiPopUpMenuCtrlEx, addCategory, void, (const char* text),, - "@brief Add a category to the list.\n\n" + "@brief Add a category to the list.\n\n" - "Acts as a separator between entries, allowing for sub-lists\n\n" + "Acts as a separator between entries, allowing for sub-lists\n\n" - "@param text Name of the new category\n\n") + "@param text Name of the new category\n\n") { - object->addEntry(text, -1, 0); + object->addEntry(text, -1, 0); } DefineEngineMethod( GuiPopUpMenuCtrlEx, addScheme, void, (S32 id, ColorI fontColor, ColorI fontColorHL, ColorI fontColorSEL),, - "@brief Create a new scheme and add it to the list of choices for when a new text entry is added.\n\n" - "@param id Numerical id associated with this scheme\n" - "@param fontColor The base text font color. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n" - "@param fontColorHL Color of text when being highlighted. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n" - "@param fontColorSel Color of text when being selected. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n") + "@brief Create a new scheme and add it to the list of choices for when a new text entry is added.\n\n" + "@param id Numerical id associated with this scheme\n" + "@param fontColor The base text font color. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n" + "@param fontColorHL Color of text when being highlighted. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n" + "@param fontColorSel Color of text when being selected. Formatted as \"Red Green Blue\", each a numerical between 0 and 255.\n") { - /*ColorI fontColor, fontColorHL, fontColorSEL; + /*ColorI fontColor, fontColorHL, fontColorSEL; U32 r, g, b; char buf[64]; @@ -457,127 +457,127 @@ DefineEngineMethod( GuiPopUpMenuCtrlEx, addScheme, void, (S32 id, ColorI fontCol //} DefineEngineMethod( GuiPopUpMenuCtrlEx, setText, void, ( const char* text),, - "@brief Set the current text to a specified value.\n\n" - "@param text String containing new text to set\n\n") + "@brief Set the current text to a specified value.\n\n" + "@param text String containing new text to set\n\n") { - object->setText(text); + object->setText(text); } DefineEngineMethod( GuiPopUpMenuCtrlEx, getText, const char*, (),, - "@brief Get the.\n\n" + "@brief Get the.\n\n" - "Detailed description\n\n" + "Detailed description\n\n" - "@param param Description\n\n" + "@param param Description\n\n" - "@tsexample\n" - "// Comment\n" - "code();\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Comment\n" + "code();\n" + "@endtsexample\n\n" - "@return Returns current text in string format") + "@return Returns current text in string format") { - return object->getText(); + return object->getText(); } DefineEngineMethod( GuiPopUpMenuCtrlEx, clear, void, (),, - "@brief Clear the popup list.\n\n") + "@brief Clear the popup list.\n\n") { - object->clear(); + object->clear(); } DefineEngineMethod( GuiPopUpMenuCtrlEx, sort, void, (),, - "@brief Sort the list alphabetically.\n\n") + "@brief Sort the list alphabetically.\n\n") { - object->sort(); + object->sort(); } DefineEngineMethod( GuiPopUpMenuCtrlEx, sortID, void, (),, - "@brief Sort the list by ID.\n\n") + "@brief Sort the list by ID.\n\n") { - object->sortID(); + object->sortID(); } DefineEngineMethod( GuiPopUpMenuCtrlEx, forceOnAction, void, (),, - "@brief Manually for the onAction function, which updates everything in this control.\n\n") + "@brief Manually for the onAction function, which updates everything in this control.\n\n") { - object->onAction(); + object->onAction(); } DefineEngineMethod( GuiPopUpMenuCtrlEx, forceClose, void, (),, - "@brief Manually force this control to collapse and close.\n\n") + "@brief Manually force this control to collapse and close.\n\n") { - object->closePopUp(); + object->closePopUp(); } DefineEngineMethod( GuiPopUpMenuCtrlEx, getSelected, S32, (),, - "@brief Get the current selection of the menu.\n\n" - "@return Returns the ID of the currently selected entry") + "@brief Get the current selection of the menu.\n\n" + "@return Returns the ID of the currently selected entry") { - return object->getSelected(); + return object->getSelected(); } ConsoleDocFragment _GuiPopUpMenuCtrlExsetSelected( - "brief Manually set an entry as selected int his control\n\n" - "@param id The ID of the entry to select\n" - "@param scripCallback Optional boolean that forces the script callback if true\n", - "GuiPopUpMenuCtrlEx", - "setSelected(int id, bool scriptCallback=true);" + "brief Manually set an entry as selected int his control\n\n" + "@param id The ID of the entry to select\n" + "@param scripCallback Optional boolean that forces the script callback if true\n", + "GuiPopUpMenuCtrlEx", + "setSelected(int id, bool scriptCallback=true);" ); DefineConsoleMethod( GuiPopUpMenuCtrlEx, setSelected, void, (S32 id, bool scriptCallback), (true), "(int id, [scriptCallback=true])" - "@hide") + "@hide") { object->setSelected( id, scriptCallback ); } ConsoleDocFragment _GuiPopUpMenuCtrlExsetFirstSelected( - "brief Manually set the selection to the first entry\n\n" - "@param scripCallback Optional boolean that forces the script callback if true\n", - "GuiPopUpMenuCtrlEx", - "setSelected(bool scriptCallback=true);" + "brief Manually set the selection to the first entry\n\n" + "@param scripCallback Optional boolean that forces the script callback if true\n", + "GuiPopUpMenuCtrlEx", + "setSelected(bool scriptCallback=true);" ); DefineConsoleMethod( GuiPopUpMenuCtrlEx, setFirstSelected, void, (bool scriptCallback), (true), "([scriptCallback=true])" - "@hide") + "@hide") { object->setFirstSelected( scriptCallback ); } DefineEngineMethod( GuiPopUpMenuCtrlEx, setNoneSelected, void, ( S32 param),, - "@brief Clears selection in the menu.\n\n") + "@brief Clears selection in the menu.\n\n") { - object->setNoneSelected(); + object->setNoneSelected(); } DefineEngineMethod( GuiPopUpMenuCtrlEx, getTextById, const char*, (S32 id),, - "@brief Get the text of an entry based on an ID.\n\n" - "@param id The ID assigned to the entry being queried\n\n" - "@return String contained by the specified entry, NULL if empty or bad ID") + "@brief Get the text of an entry based on an ID.\n\n" + "@param id The ID assigned to the entry being queried\n\n" + "@return String contained by the specified entry, NULL if empty or bad ID") { - return(object->getTextById(id)); + return(object->getTextById(id)); } DefineConsoleMethod( GuiPopUpMenuCtrlEx, getColorById, ColorI, (S32 id), , - "@brief Get color of an entry's box\n\n" - "@param id ID number of entry to query\n\n" - "@return ColorI in the format of \"Red Green Blue Alpha\", each of with is a value between 0 - 255") + "@brief Get color of an entry's box\n\n" + "@param id ID number of entry to query\n\n" + "@return ColorI in the format of \"Red Green Blue Alpha\", each of with is a value between 0 - 255") { ColorI color; object->getColoredBox(color, id); - return color; + return color; } DefineConsoleMethod( GuiPopUpMenuCtrlEx, setEnumContent, void, ( const char * className, const char * enumName ), , - "@brief This fills the popup with a classrep's field enumeration type info.\n\n" + "@brief This fills the popup with a classrep's field enumeration type info.\n\n" "More of a helper function than anything. If console access to the field list is added, " "at least for the enumerated types, then this should go away.\n\n" - "@param class Name of the class containing the enum\n" - "@param enum Name of the enum value to acces\n") + "@param class Name of the class containing the enum\n" + "@param enum Name of the enum value to acces\n") { AbstractClassRep * classRep = AbstractClassRep::getClassList(); @@ -630,24 +630,24 @@ DefineConsoleMethod( GuiPopUpMenuCtrlEx, setEnumContent, void, ( const char * cl //------------------------------------------------------------------------------ DefineConsoleMethod( GuiPopUpMenuCtrlEx, findText, S32, (const char * text), , "(string text)" "Returns the id of the first entry containing the specified text or -1 if not found." - "@param text String value used for the query\n\n" - "@return Numerical ID of entry containing the text.") + "@param text String value used for the query\n\n" + "@return Numerical ID of entry containing the text.") { return( object->findText( text ) ); } //------------------------------------------------------------------------------ DefineConsoleMethod( GuiPopUpMenuCtrlEx, size, S32, (), , - "@brief Get the size of the menu\n\n" - "@return Number of entries in the menu\n") + "@brief Get the size of the menu\n\n" + "@return Number of entries in the menu\n") { return( object->getNumEntries() ); } //------------------------------------------------------------------------------ DefineConsoleMethod( GuiPopUpMenuCtrlEx, replaceText, void, (S32 boolVal), , - "@brief Flag that causes each new text addition to replace the current entry\n\n" - "@param True to turn on replacing, false to disable it") + "@brief Flag that causes each new text addition to replace the current entry\n\n" + "@param True to turn on replacing, false to disable it") { object->replaceText(boolVal); } @@ -697,43 +697,43 @@ void GuiPopUpMenuCtrlEx::clear() setText(""); mSelIndex = -1; mRevNum = 0; - mIdMax = -1; + mIdMax = -1; } //------------------------------------------------------------------------------ void GuiPopUpMenuCtrlEx::clearEntry( S32 entry ) { - if( entry == -1 ) - return; + if( entry == -1 ) + return; - U32 i = 0; - for ( ; i < mEntries.size(); i++ ) + U32 i = 0; + for ( ; i < mEntries.size(); i++ ) { if ( mEntries[i].id == entry ) break; } - mEntries.erase( i ); + mEntries.erase( i ); - if( mEntries.size() <= 0 ) - { - mEntries.setSize(0); - setText(""); - mSelIndex = -1; - mRevNum = 0; - } - else - { - if( entry == mSelIndex ) - { - setText(""); - mSelIndex = -1; - } - else - { - mSelIndex--; - } - } + if( mEntries.size() <= 0 ) + { + mEntries.setSize(0); + setText(""); + mSelIndex = -1; + mRevNum = 0; + } + else + { + if( entry == mSelIndex ) + { + setText(""); + mSelIndex = -1; + } + else + { + mSelIndex--; + } + } } //------------------------------------------------------------------------------ @@ -797,9 +797,9 @@ void GuiPopUpMenuCtrlEx::sort() if( size > 0 ) dQsort( mEntries.address(), size, sizeof(Entry), textCompare); - // Entries need to re-Id themselves - for( U32 i = 0; i < mEntries.size(); i++ ) - mEntries[i].id = i; + // Entries need to re-Id themselves + for( U32 i = 0; i < mEntries.size(); i++ ) + mEntries[i].id = i; } // Added to sort by entry ID @@ -810,9 +810,9 @@ void GuiPopUpMenuCtrlEx::sortID() if( size > 0 ) dQsort( mEntries.address(), size, sizeof(Entry), idCompare); - // Entries need to re-Id themselves - for( U32 i = 0; i < mEntries.size(); i++ ) - mEntries[i].id = i; + // Entries need to re-Id themselves + for( U32 i = 0; i < mEntries.size(); i++ ) + mEntries[i].id = i; } //------------------------------------------------------------------------------ @@ -823,21 +823,21 @@ void GuiPopUpMenuCtrlEx::addEntry(const char *buf, S32 id, U32 scheme) //Con::printf( "GuiPopupMenuCtrlEx::addEntry - Invalid buffer!" ); return; } - - // Ensure that there are no other entries with exactly the same name - for ( U32 i = 0; i < mEntries.size(); i++ ) + + // Ensure that there are no other entries with exactly the same name + for ( U32 i = 0; i < mEntries.size(); i++ ) { if ( dStrcmp( mEntries[i].buf, buf ) == 0 ) return; } - // If we don't give an id, create one from mIdMax - if( id == -1 ) - id = mIdMax + 1; - - // Increase mIdMax when an id is greater than it - if( id > mIdMax ) - mIdMax = id; + // If we don't give an id, create one from mIdMax + if( id == -1 ) + id = mIdMax + 1; + + // Increase mIdMax when an id is greater than it + if( id > mIdMax ) + mIdMax = id; Entry e; dStrcpy( e.buf, buf ); @@ -992,20 +992,20 @@ void GuiPopUpMenuCtrlEx::setFirstSelected( bool bNotifyScript ) if ( isMethod( "onSelect" ) ) Con::executef( this, "onSelect", idval, mEntries[mSelIndex].buf ); - // Execute the popup console command: - if ( bNotifyScript ) - execConsoleCallback(); + // Execute the popup console command: + if ( bNotifyScript ) + execConsoleCallback(); } - else - { - if ( mReplaceText ) // Only change the displayed text if appropriate. - setText(""); - - mSelIndex = -1; + else + { + if ( mReplaceText ) // Only change the displayed text if appropriate. + setText(""); + + mSelIndex = -1; - if ( bNotifyScript ) - Con::executef( this, "onCancel" ); - } + if ( bNotifyScript ) + Con::executef( this, "onCancel" ); + } } //------------------------------------------------------------------------------ @@ -1500,11 +1500,11 @@ void GuiPopUpMenuCtrlEx::onAction() if ( setScroll ) { // Resize the text list - Point2I cellSize; - mTl->getCellSize( cellSize ); - cellSize.x = width - mSc->scrollBarThickness() - sbBorder; - mTl->setCellSize( cellSize ); - mTl->setWidth( cellSize.x ); + Point2I cellSize; + mTl->getCellSize( cellSize ); + cellSize.x = width - mSc->scrollBarThickness() - sbBorder; + mTl->setCellSize( cellSize ); + mTl->setWidth( cellSize.x ); if ( mSelIndex ) mTl->scrollCellVisible( Point2I( 0, mSelIndex ) ); @@ -1536,7 +1536,7 @@ void GuiPopUpMenuCtrlEx::addChildren() else { // Use the children's profile rather than the parent's profile, if it exists. - mSc->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile ); + mSc->setControlProfile( mProfile->getChildrenProfile() ? mProfile->getChildrenProfile() : mProfile ); } mSc->setField( "hScrollBar", "AlwaysOff" ); mSc->setField( "vScrollBar", "dynamic" ); diff --git a/Engine/source/gui/controls/guiTextCtrl.cpp b/Engine/source/gui/controls/guiTextCtrl.cpp index e1079d8e0..e8c9057f1 100644 --- a/Engine/source/gui/controls/guiTextCtrl.cpp +++ b/Engine/source/gui/controls/guiTextCtrl.cpp @@ -37,13 +37,13 @@ ConsoleDocClass( GuiTextCtrl, "@brief GUI control object this displays a single line of text, without TorqueML.\n\n" "@tsexample\n" - " new GuiTextCtrl()\n" - " {\n" - " text = \"Hello World\";\n" - " textID = \"\"STR_HELLO\"\";\n" - " maxlength = \"1024\";\n" - " //Properties not specific to this control have been omitted from this example.\n" - " };\n" + " new GuiTextCtrl()\n" + " {\n" + " text = \"Hello World\";\n" + " textID = \"\"STR_HELLO\"\";\n" + " maxlength = \"1024\";\n" + " //Properties not specific to this control have been omitted from this example.\n" + " };\n" "@endtsexample\n\n" "@see GuiControl\n" @@ -84,7 +84,7 @@ DefineEngineMethod( GuiTextCtrl, setTextID, void, (const char* textID),, "@see GuiControl" "@see Localization") { - object->setTextID( textID ); + object->setTextID( textID ); } void GuiTextCtrl::initPersistFields() @@ -117,7 +117,7 @@ void GuiTextCtrl::inspectPostApply() { Parent::inspectPostApply(); if(mInitialTextID && *mInitialTextID != 0) - setTextID(mInitialTextID); + setTextID(mInitialTextID); else if( mConsoleVariable[ 0 ] ) setText( getVariable() ); else @@ -135,7 +135,7 @@ bool GuiTextCtrl::onWake() return false; } if(mInitialTextID && *mInitialTextID != 0) - setTextID(mInitialTextID); + setTextID(mInitialTextID); if ( mConsoleVariable[0] ) { @@ -202,19 +202,19 @@ void GuiTextCtrl::setText(const char *txt) void GuiTextCtrl::setTextID(const char *id) { - S32 n = Con::getIntVariable(id, -1); - if(n != -1) - { - mInitialTextID = StringTable->insert(id); - setTextID(n); - } + S32 n = Con::getIntVariable(id, -1); + if(n != -1) + { + mInitialTextID = StringTable->insert(id); + setTextID(n); + } } void GuiTextCtrl::setTextID(S32 id) { - const UTF8 *str = getGUIString(id); - if(str) - setText((const char*)str); - //mInitialTextID = id; + const UTF8 *str = getGUIString(id); + if(str) + setText((const char*)str); + //mInitialTextID = id; } void GuiTextCtrl::onPreRender() diff --git a/Engine/source/gui/controls/guiTextEditCtrl.cpp b/Engine/source/gui/controls/guiTextEditCtrl.cpp index 99a1342c0..9084e8d8d 100644 --- a/Engine/source/gui/controls/guiTextEditCtrl.cpp +++ b/Engine/source/gui/controls/guiTextEditCtrl.cpp @@ -46,17 +46,17 @@ ConsoleDocClass( GuiTextEditCtrl, "@tsexample\n" " new GuiTextEditCtrl(MessageHud_Edit)\n" - " {\n" - " text = \"Hello World\";\n" - " validate = \"validateCommand();\"\n" - " escapeCommand = \"escapeCommand();\";\n" - " historySize = \"5\";\n" - " tabComplete = \"true\";\n" - " deniedSound = \"DeniedSoundProfile\";\n" - " sinkAllKeyEvents = \"true\";\n" - " password = \"true\";\n" - " passwordMask = \"*\";\n" - " //Properties not specific to this control have been omitted from this example.\n" + " {\n" + " text = \"Hello World\";\n" + " validate = \"validateCommand();\"\n" + " escapeCommand = \"escapeCommand();\";\n" + " historySize = \"5\";\n" + " tabComplete = \"true\";\n" + " deniedSound = \"DeniedSoundProfile\";\n" + " sinkAllKeyEvents = \"true\";\n" + " password = \"true\";\n" + " passwordMask = \"*\";\n" + " //Properties not specific to this control have been omitted from this example.\n" " };\n" "@endtsexample\n\n" @@ -72,9 +72,9 @@ IMPLEMENT_CALLBACK( GuiTextEditCtrl, onTabComplete, void, (const char* val),( va "@tsexample\n" "// Tab key has been pressed, causing the callback to occur.\n" "GuiTextEditCtrl::onTabComplete(%this,%val)\n" - " {\n" - " //Code to run when the onTabComplete callback occurs\n" - " }\n" + " {\n" + " //Code to run when the onTabComplete callback occurs\n" + " }\n" "@endtsexample\n\n" "@see GuiTextCtrl\n" "@see GuiControl\n\n" @@ -85,9 +85,9 @@ IMPLEMENT_CALLBACK( GuiTextEditCtrl, onReturn, void, (),(), "@tsexample\n" "// Return or Enter key was pressed, causing the callback to occur.\n" "GuiTextEditCtrl::onReturn(%this)\n" - " {\n" - " // Code to run when the onReturn callback occurs\n" - " }\n" + " {\n" + " // Code to run when the onReturn callback occurs\n" + " }\n" "@endtsexample\n\n" "@see GuiTextCtrl\n" "@see GuiControl\n\n" @@ -98,9 +98,9 @@ IMPLEMENT_CALLBACK( GuiTextEditCtrl, onValidate, void, (),(), "@tsexample\n" "// The control gets validated, causing the callback to occur\n" "GuiTextEditCtrl::onValidated(%this)\n" - " {\n" - " // Code to run when the control is validated\n" - " }\n" + " {\n" + " // Code to run when the control is validated\n" + " }\n" "@endtsexample\n\n" "@see GuiTextCtrl\n" "@see GuiControl\n\n" @@ -139,7 +139,7 @@ GuiTextEditCtrl::GuiTextEditCtrl() mHistoryBuf = NULL; #if defined(__MACOSX__) - UTF8 bullet[4] = { 0xE2, 0x80, 0xA2, 0 }; + UTF8 bullet[4] = { 0xE2, 0x80, 0xA2, 0 }; mPasswordMask = StringTable->insert( bullet ); #else @@ -710,10 +710,10 @@ bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event) case KEY_TAB: if ( mTabComplete ) { - onTabComplete_callback("1"); + onTabComplete_callback("1"); return true; } - break; // We don't want to fall through if we don't handle the TAB here. + break; // We don't want to fall through if we don't handle the TAB here. case KEY_HOME: mBlockStart = 0; @@ -779,10 +779,10 @@ bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event) } return true; - case KEY_RETURN: - case KEY_NUMPADENTER: + case KEY_RETURN: + case KEY_NUMPADENTER: - return dealWithEnter(false); + return dealWithEnter(false); default: break; @@ -998,7 +998,7 @@ bool GuiTextEditCtrl::onKeyDown(const GuiEvent &event) case KEY_RETURN: case KEY_NUMPADENTER: - return dealWithEnter(true); + return dealWithEnter(true); case KEY_UP: { @@ -1155,7 +1155,7 @@ dealWithBackspace: case KEY_TAB: if ( mTabComplete ) { - onTabComplete_callback("0"); + onTabComplete_callback("0"); return( true ); } case KEY_UP: @@ -1208,9 +1208,9 @@ bool GuiTextEditCtrl::dealWithEnter( bool clearResponder ) return true; } } - - if( clearResponder ) - clearFirstResponder(); + + if( clearResponder ) + clearFirstResponder(); return true; } @@ -1222,13 +1222,13 @@ void GuiTextEditCtrl::setFirstResponder() GuiCanvas *root = getRoot(); if (root != NULL) { - root->enableKeyboardTranslation(); + root->enableKeyboardTranslation(); - // If the native OS accelerator keys are not disabled - // then some key events like Delete, ctrl+V, etc may - // not make it down to us. - root->setNativeAcceleratorsEnabled( false ); + // If the native OS accelerator keys are not disabled + // then some key events like Delete, ctrl+V, etc may + // not make it down to us. + root->setNativeAcceleratorsEnabled( false ); } } @@ -1237,8 +1237,8 @@ void GuiTextEditCtrl::onLoseFirstResponder() GuiCanvas *root = getRoot(); if( root ) { - root->setNativeAcceleratorsEnabled( true ); - root->disableKeyboardTranslation(); + root->setNativeAcceleratorsEnabled( true ); + root->disableKeyboardTranslation(); } //execute the validate command @@ -1546,29 +1546,29 @@ void GuiTextEditCtrl::handleCharInput( U16 ascii ) //see if it's a number field if ( mProfile->mNumbersOnly ) { - if (ascii == '-') - { - //a minus sign only exists at the beginning, and only a single minus sign - if (mCursorPos != 0 && !isAllTextSelected()) - { - invalidText(); - return; - } + if (ascii == '-') + { + //a minus sign only exists at the beginning, and only a single minus sign + if (mCursorPos != 0 && !isAllTextSelected()) + { + invalidText(); + return; + } - if (mInsertOn && (mTextBuffer.getChar(0) == '-')) - { - invalidText(); - return; - } - } - // BJTODO: This is probably not unicode safe. - else if (ascii != '.' && (ascii < '0' || ascii > '9')) - { - invalidText(); - return; - } - else - validText(); + if (mInsertOn && (mTextBuffer.getChar(0) == '-')) + { + invalidText(); + return; + } + } + // BJTODO: This is probably not unicode safe. + else if (ascii != '.' && (ascii < '0' || ascii > '9')) + { + invalidText(); + return; + } + else + validText(); } //save the current state @@ -1778,22 +1778,22 @@ DefineEngineMethod( GuiTextEditCtrl, forceValidateText, void, (),, } DefineEngineMethod(GuiTextEditCtrl, invalidText, void, (bool playSound), (true), - "@brief Trigger the invalid sound and make the box red.nn" - "@param playSound Play the invalid text sound or not.n") + "@brief Trigger the invalid sound and make the box red.nn" + "@param playSound Play the invalid text sound or not.n") { - object->invalidText(playSound); + object->invalidText(playSound); } DefineEngineMethod(GuiTextEditCtrl, validText, void, (), , - "@brief Restores the box to normal color.nn") + "@brief Restores the box to normal color.nn") { - object->validText(); + object->validText(); } DefineEngineMethod(GuiTextEditCtrl, isValidText, bool, (), , - "@brief Returns if the text is set to valid or not.n" - "@Return true if text is set to valid, false if not.nn") + "@brief Returns if the text is set to valid or not.n" + "@Return true if text is set to valid, false if not.nn") { - return object->isValidText(); + return object->isValidText(); } diff --git a/Engine/source/gui/controls/guiTreeViewCtrl.cpp b/Engine/source/gui/controls/guiTreeViewCtrl.cpp index c98fc90aa..e1b20ad5f 100644 --- a/Engine/source/gui/controls/guiTreeViewCtrl.cpp +++ b/Engine/source/gui/controls/guiTreeViewCtrl.cpp @@ -43,9 +43,9 @@ IMPLEMENT_CONOBJECT(GuiTreeViewCtrl); ConsoleDocClass( GuiTreeViewCtrl, - "@brief Hierarchical list of text items with optional icons.\n\n" + "@brief Hierarchical list of text items with optional icons.\n\n" - "Can also be used to inspect SimObject hierarchies, primarily within editors.\n\n" + "Can also be used to inspect SimObject hierarchies, primarily within editors.\n\n" "GuiTreeViewCtrls can either display arbitrary user-defined trees or can be used to display SimObject hierarchies where " "each parent node in the tree is a SimSet or SimGroup and each leaf node is a SimObject.\n\n" @@ -59,30 +59,30 @@ ConsoleDocClass( GuiTreeViewCtrl, "Each item in the tree has a distinct numeric ID that is unique within its tree. The ID of the root item, which is always " "present on a tree, is 0.\n\n" - "@tsexample\n" - "new GuiTreeViewCtrl(DatablockEditorTree)\n" - "{\n" - " tabSize = \"16\";\n" - " textOffset = \"2\";\n" - " fullRowSelect = \"0\";\n" - " itemHeight = \"21\";\n" - " destroyTreeOnSleep = \"0\";\n" - " MouseDragging = \"0\";\n" - " MultipleSelections = \"1\";\n" - " DeleteObjectAllowed = \"1\";\n" - " DragToItemAllowed = \"0\";\n" - " ClearAllOnSingleSelection = \"1\";\n" - " showRoot = \"1\";\n" - " internalNamesOnly = \"0\";\n" - " objectNamesOnly = \"0\";\n" - " compareToObjectID = \"0\";\n" - " Profile = \"GuiTreeViewProfile\";\n" - " tooltipprofile = \"GuiToolTipProfile\";\n" - " hovertime = \"1000\";\n" - "};\n" - "@endtsexample\n\n" + "@tsexample\n" + "new GuiTreeViewCtrl(DatablockEditorTree)\n" + "{\n" + " tabSize = \"16\";\n" + " textOffset = \"2\";\n" + " fullRowSelect = \"0\";\n" + " itemHeight = \"21\";\n" + " destroyTreeOnSleep = \"0\";\n" + " MouseDragging = \"0\";\n" + " MultipleSelections = \"1\";\n" + " DeleteObjectAllowed = \"1\";\n" + " DragToItemAllowed = \"0\";\n" + " ClearAllOnSingleSelection = \"1\";\n" + " showRoot = \"1\";\n" + " internalNamesOnly = \"0\";\n" + " objectNamesOnly = \"0\";\n" + " compareToObjectID = \"0\";\n" + " Profile = \"GuiTreeViewProfile\";\n" + " tooltipprofile = \"GuiToolTipProfile\";\n" + " hovertime = \"1000\";\n" + "};\n" + "@endtsexample\n\n" - "@ingroup GuiContainers\n"); + "@ingroup GuiContainers\n"); IMPLEMENT_CALLBACK( GuiTreeViewCtrl, onDeleteObject, bool, ( SimObject* object ), ( object ), "" ); IMPLEMENT_CALLBACK( GuiTreeViewCtrl, isValidDragTarget, bool, ( S32 id, const char* value ), ( id, value ), "" ); @@ -511,7 +511,7 @@ void GuiTreeViewCtrl::Item::getDisplayText(U32 bufLen, char *buf) if( showInternalNameOnly() ) dSprintf( buf, bufLen, "%s", hasInternalName ? pInternalName : "(none)" ); - else if( showObjectNameOnly() ) + else if( showObjectNameOnly() ) { if( !hasObjectName && mState.test( ShowClassNameForUnnamed ) ) dSprintf( buf, bufLen, "%s", pClassName ); @@ -801,7 +801,7 @@ GuiTreeViewCtrl::GuiTreeViewCtrl() mStart = 0; mPossibleRenameItem = NULL; mRenamingItem = NULL; - mTempItem = NULL; + mTempItem = NULL; mRenameCtrl = NULL; mDraggedToItem = 0; @@ -1902,7 +1902,7 @@ void GuiTreeViewCtrl::onPreRender() if(mFlags.test(RebuildVisible)) { buildVisibleTree(); - mFlags.clear(RebuildVisible); + mFlags.clear(RebuildVisible); } } @@ -2084,39 +2084,39 @@ void GuiTreeViewCtrl::syncSelection() } else if (mVisibleItems[i]->isInspectorData()) { - if(mCompareToObjectID) - { - if (mVisibleItems[i]->getObject() && mVisibleItems[i]->getObject()->getId() == mSelected[j]) - { - // check to see if it is on the visible items list. - bool addToSelectedItems = true; - for (S32 k = 0; k < mSelectedItems.size(); k++) - { - if (mSelectedItems[k]->isInspectorData() && mSelectedItems[k]->getObject() ) - { - if (mSelected[j] == mSelectedItems[k]->getObject()->getId()) - { - // don't add it - addToSelectedItems = false; - } - } - else - { - if (mSelected[j] == mSelectedItems[k]->mId) - { - // don't add it - addToSelectedItems = false; - } - } - } - if (addToSelectedItems) - { - mVisibleItems[i]->mState.set(Item::Selected, true); - mSelectedItems.push_front(mVisibleItems[i]); - break; - } - } - } + if(mCompareToObjectID) + { + if (mVisibleItems[i]->getObject() && mVisibleItems[i]->getObject()->getId() == mSelected[j]) + { + // check to see if it is on the visible items list. + bool addToSelectedItems = true; + for (S32 k = 0; k < mSelectedItems.size(); k++) + { + if (mSelectedItems[k]->isInspectorData() && mSelectedItems[k]->getObject() ) + { + if (mSelected[j] == mSelectedItems[k]->getObject()->getId()) + { + // don't add it + addToSelectedItems = false; + } + } + else + { + if (mSelected[j] == mSelectedItems[k]->mId) + { + // don't add it + addToSelectedItems = false; + } + } + } + if (addToSelectedItems) + { + mVisibleItems[i]->mState.set(Item::Selected, true); + mSelectedItems.push_front(mVisibleItems[i]); + break; + } + } + } } } @@ -2200,14 +2200,14 @@ void GuiTreeViewCtrl::addSelection( S32 itemOrObjectId, bool update, bool isLast } const S32 itemId = item->getID(); - - // Ok, we have an item to select which isn't already selected.... + + // Ok, we have an item to select which isn't already selected.... // Do we want to allow more than one selected item? if( !mMultipleSelections ) clearSelection(); - // Add this object id to the vector of selected objectIds + // Add this object id to the vector of selected objectIds // if it is not already. bool foundMatch = false; for ( S32 i = 0; i < mSelected.size(); i++) @@ -2228,21 +2228,21 @@ void GuiTreeViewCtrl::addSelection( S32 itemOrObjectId, bool update, bool isLast // Callback Start // Set and add the selection to the selected items group - item->mState.set(Item::Selected, true); - mSelectedItems.push_front(item); + item->mState.set(Item::Selected, true); + mSelectedItems.push_front(item); if ( item->isInspectorData() && item->getObject() ) { SimObject *obj = item->getObject(); - + onAddSelection_callback( obj->getId(), isLastSelection ); } else { onAddSelection_callback( item->mId, isLastSelection ); } - // Callback end + // Callback end mFlags.set( RebuildVisible ); if( update ) @@ -2262,7 +2262,7 @@ void GuiTreeViewCtrl::onItemSelected( Item *item ) if (item->isInspectorData()) { SimObject* object = item->getObject(); - if( object ) + if( object ) onSelect_callback( object->getId() ); if( !item->isParent() && object ) onInspect_callback( object->getId() ); @@ -2590,9 +2590,9 @@ void GuiTreeViewCtrl::deleteSelection() } else { - Vector delSelection; - delSelection = mSelectedItems; - mSelectedItems.clear(); + Vector delSelection; + delSelection = mSelectedItems; + mSelectedItems.clear(); while (!delSelection.empty()) { Item * item = delSelection.front(); @@ -2600,7 +2600,7 @@ void GuiTreeViewCtrl::deleteSelection() if ( item->mParent ) _deleteItem( item ); - delSelection.pop_front(); + delSelection.pop_front(); } } @@ -2642,7 +2642,7 @@ bool GuiTreeViewCtrl::onKeyDown( const GuiEvent& event ) return true; } - //call a generic bit of script that will let the subclass know that a key was pressed + //call a generic bit of script that will let the subclass know that a key was pressed onKeyDown_callback( event.modifier, event.keyCode ); } @@ -3028,29 +3028,29 @@ void GuiTreeViewCtrl::onMouseUp(const GuiEvent &event) return; } - BitSet32 hitFlags = 0; + BitSet32 hitFlags = 0; Item *item; - bool hitCheck = _hitTest( event.mousePoint, item, hitFlags ); + bool hitCheck = _hitTest( event.mousePoint, item, hitFlags ); mRenamingItem = NULL; - if( hitCheck ) - { - if ( event.mouseClickCount == 1 && !mMouseDragged && mPossibleRenameItem != NULL ) - { - if ( item == mPossibleRenameItem ) + if( hitCheck ) + { + if ( event.mouseClickCount == 1 && !mMouseDragged && mPossibleRenameItem != NULL ) + { + if ( item == mPossibleRenameItem ) showItemRenameCtrl( item ); - } - else // If mouseUp occurs on the same item as mouse down - { - bool wasSelected = isSelected( item ); - bool multiSelect = getSelectedItemsCount() > 1; - if( wasSelected && multiSelect && item == mTempItem ) - { - clearSelection(); - addSelection( item->mId ); - } - } - } + } + else // If mouseUp occurs on the same item as mouse down + { + bool wasSelected = isSelected( item ); + bool multiSelect = getSelectedItemsCount() > 1; + if( wasSelected && multiSelect && item == mTempItem ) + { + clearSelection(); + addSelection( item->mId ); + } + } + } mPossibleRenameItem = NULL; @@ -3482,7 +3482,7 @@ void GuiTreeViewCtrl::onMouseDragged(const GuiEvent &event) if( mDragStartInSelection ) onMouseDragged_callback(); - if(!mSupportMouseDragging) + if(!mSupportMouseDragging) return; if( !mActive || !mAwake || !mVisible ) @@ -3652,7 +3652,7 @@ void GuiTreeViewCtrl::onMouseDown(const GuiEvent & event) mPossibleRenameItem = NULL; mRenamingItem = NULL; - mTempItem = NULL; + mTempItem = NULL; // if( event.modifier & SI_MULTISELECT ) @@ -3704,10 +3704,10 @@ void GuiTreeViewCtrl::onMouseDown(const GuiEvent & event) //select up for (S32 j = (mCurrentDragCell); j < firstSelectedIndex; j++) { - if( j != (firstSelectedIndex - 1) ) - addSelection(mVisibleItems[j]->mId, false, false); - else - addSelection(mVisibleItems[j]->mId, false); + if( j != (firstSelectedIndex - 1) ) + addSelection(mVisibleItems[j]->mId, false, false); + else + addSelection(mVisibleItems[j]->mId, false); } } else @@ -3715,10 +3715,10 @@ void GuiTreeViewCtrl::onMouseDown(const GuiEvent & event) // select down for (S32 j = firstSelectedIndex+1; j < (mCurrentDragCell+1); j++) { - if( j != mCurrentDragCell ) - addSelection(mVisibleItems[j]->mId, false, false); - else - addSelection(mVisibleItems[j]->mId, false); + if( j != mCurrentDragCell ) + addSelection(mVisibleItems[j]->mId, false, false); + else + addSelection(mVisibleItems[j]->mId, false); } } @@ -3736,39 +3736,39 @@ void GuiTreeViewCtrl::onMouseDown(const GuiEvent & event) } else if ( !hitFlags.test(OnImage) ) { - mTempItem = item; + mTempItem = item; bool wasSelected = isSelected( item ); bool multiSelect = getSelectedItemsCount() > 1; - - if( !wasSelected || !multiSelect ) - { - if ( mClearAllOnSingleSelection ) - clearSelection(); + + if( !wasSelected || !multiSelect ) + { + if ( mClearAllOnSingleSelection ) + clearSelection(); - if ( !wasSelected || mClearAllOnSingleSelection ) - addSelection( item->mId ); + if ( !wasSelected || mClearAllOnSingleSelection ) + addSelection( item->mId ); - if ( wasSelected && - !multiSelect && - mCanRenameObjects && - hitFlags.test(OnText) && - mFlags.test(IsEditable) && - item->isInspectorData() && - item->getObject() && + if ( wasSelected && + !multiSelect && + mCanRenameObjects && + hitFlags.test(OnText) && + mFlags.test(IsEditable) && + item->isInspectorData() && + item->getObject() && item->getObject()->isNameChangeAllowed() && - item != mRoot && - event.mouseClickCount == 1 ) - { - mPossibleRenameItem = item; + item != mRoot && + event.mouseClickCount == 1 ) + { + mPossibleRenameItem = item; - if ( isMethod( "canRenameObject" ) ) - { - if( canRenameObject_callback( item->getObject() ) ) - mPossibleRenameItem = NULL; - } - } - } + if ( isMethod( "canRenameObject" ) ) + { + if( canRenameObject_callback( item->getObject() ) ) + mPossibleRenameItem = NULL; + } + } + } } @@ -4221,7 +4221,7 @@ void GuiTreeViewCtrl::onRenderCell(Point2I offset, Point2I cell, bool, bool ) if( item->mState.test(Item::MouseOverText) ) { - fontColor = mProfile->mFontColorHL; + fontColor = mProfile->mFontColorHL; } drawer->setBitmapModulation( fontColor ); @@ -4551,9 +4551,9 @@ void GuiTreeViewCtrl::inspectorSearch(Item * item, Item * parent, SimSet * paren bool GuiTreeViewCtrl::objectSearch( const SimObject *object, Item **item ) { - for ( U32 i = 0; i < mItems.size(); i++ ) - { - Item *pItem = mItems[i]; + for ( U32 i = 0; i < mItems.size(); i++ ) + { + Item *pItem = mItems[i]; if ( !pItem ) continue; @@ -4565,16 +4565,16 @@ bool GuiTreeViewCtrl::objectSearch( const SimObject *object, Item **item ) continue; #endif - SimObject *pObj = pItem->getObject(); + SimObject *pObj = pItem->getObject(); - if ( pObj && pObj == object ) - { - *item = pItem; - return true; - } - } + if ( pObj && pObj == object ) + { + *item = pItem; + return true; + } + } - return false; + return false; } //----------------------------------------------------------------------------- @@ -4592,7 +4592,7 @@ bool GuiTreeViewCtrl::onVirtualParentBuild(Item *item, bool bForceFullUpdate) } // Skip the next stuff unless we're expanded... - if(!item->isExpanded() && !bForceFullUpdate && !( item == mRoot && !mShowRoot ) ) + if(!item->isExpanded() && !bForceFullUpdate && !( item == mRoot && !mShowRoot ) ) return true; // Verify that we have all the kids we should in here... @@ -4704,8 +4704,8 @@ S32 GuiTreeViewCtrl::findItemByName(const char *name) { if ( !mItems[i] ) continue; - if( mItems[i]->mState.test( Item::InspectorData ) ) - continue; + if( mItems[i]->mState.test( Item::InspectorData ) ) + continue; if (mItems[i] && dStrcmp(mItems[i]->getText(),name) == 0) return mItems[i]->mId; } @@ -4721,10 +4721,10 @@ S32 GuiTreeViewCtrl::findItemByValue(const char *name) { if (!mItems[i]) continue; - if( mItems[i]->mState.test( Item::InspectorData ) ) - continue; - if (mItems[i] && dStrcmp(mItems[i]->getValue(),name) == 0) - return mItems[i]->mId; + if( mItems[i]->mState.test( Item::InspectorData ) ) + continue; + if (mItems[i] && dStrcmp(mItems[i]->getValue(),name) == 0) + return mItems[i]->mId; } return 0; @@ -4874,7 +4874,7 @@ DefineEngineMethod( GuiTreeViewCtrl, insertItem, S32, ( S32 parentId, const char DefineEngineMethod( GuiTreeViewCtrl, insertObject, S32, ( S32 parentId, SimObject* obj, bool OKToEdit ), (false), "Inserts object as a child to the given parent." ) { - return object->insertObject(parentId, obj, OKToEdit); + return object->insertObject(parentId, obj, OKToEdit); } //----------------------------------------------------------------------------- @@ -4967,10 +4967,10 @@ DefineEngineMethod( GuiTreeViewCtrl, removeChildSelectionByValue, void, ( S32 pa if(parentItem) { GuiTreeViewCtrl::Item* child = parentItem->findChildByValue(value); - if(child) - { + if(child) + { object->removeSelection(child->getID()); - } + } } } @@ -5038,7 +5038,7 @@ DefineEngineMethod( GuiTreeViewCtrl, open, void, ( const char * objName, bool ok DefineEngineMethod( GuiTreeViewCtrl, setItemTooltip, bool, ( S32 itemId, const char* tooltip), , "Set the tooltip to show for the given item.\n\n" "@param itemId TreeItemID of item to set the tooltip for.\n" - "@param tooltip String tooltip to set for the item." + "@param tooltip String tooltip to set for the item." "@return True if successfully found the item, false if not") { GuiTreeViewCtrl::Item* item = object->getItem( itemId ); @@ -5228,11 +5228,11 @@ const char* GuiTreeViewCtrl::getSelectedObjectList() { S32 id = item->getObject()->getId(); //get the current length of the buffer - U32 len = dStrlen(buff); + U32 len = dStrlen(buff); //the start of the buffer where we want to write char* buffPart = buff+len; //the size of the remaining buffer (-1 cause dStrlen doesn't count the \0) - S32 size = bufSize-len-1; + S32 size = bufSize-len-1; //write it: if(size < 1) { @@ -5283,7 +5283,7 @@ DefineEngineMethod( GuiTreeViewCtrl, getTextToRoot, const char*, (S32 itemId, co "@param delimiter (Optional) delimiter to use between each branch concatenation." "@return text from the current node to the root.") { - if (!dStrcmp(delimiter, "" )) + if (!dStrcmp(delimiter, "" )) { Con::warnf("GuiTreeViewCtrl::getTextToRoot - Invalid number of arguments!"); return (""); @@ -5296,31 +5296,31 @@ DefineEngineMethod( GuiTreeViewCtrl, getSelectedItemList, const char*, (), , "@return space separated list of selected item ids.") { const U32 bufSize = 1024; - char* buff = Con::getReturnBuffer(bufSize); - dSprintf(buff, bufSize, ""); + char* buff = Con::getReturnBuffer(bufSize); + dSprintf(buff, bufSize, ""); const Vector< S32 >& selected = object->getSelected(); - for(int i = 0; i < selected.size(); i++) - { - S32 id = selected[i]; - //get the current length of the buffer - U32 len = dStrlen(buff); - //the start of the buffer where we want to write - char* buffPart = buff+len; - //the size of the remaining buffer (-1 cause dStrlen doesn't count the \0) - S32 size = bufSize-len-1; - //write it: - if(size < 1) - { - Con::errorf("GuiTreeViewCtrl::getSelectedItemList - Not enough room to return our object list"); - return buff; - } + for(int i = 0; i < selected.size(); i++) + { + S32 id = selected[i]; + //get the current length of the buffer + U32 len = dStrlen(buff); + //the start of the buffer where we want to write + char* buffPart = buff+len; + //the size of the remaining buffer (-1 cause dStrlen doesn't count the \0) + S32 size = bufSize-len-1; + //write it: + if(size < 1) + { + Con::errorf("GuiTreeViewCtrl::getSelectedItemList - Not enough room to return our object list"); + return buff; + } - dSprintf(buffPart,size,"%d ", id); - } + dSprintf(buffPart,size,"%d ", id); + } //mSelected - return buff; + return buff; } S32 GuiTreeViewCtrl::findItemByObjectId(S32 iObjId) @@ -5331,8 +5331,8 @@ S32 GuiTreeViewCtrl::findItemByObjectId(S32 iObjId) continue; SimObject* pObj = mItems[i]->getObject(); - if( pObj && pObj->getId() == iObjId ) - return mItems[i]->mId; + if( pObj && pObj->getId() == iObjId ) + return mItems[i]->mId; } return -1; @@ -5341,7 +5341,7 @@ S32 GuiTreeViewCtrl::findItemByObjectId(S32 iObjId) //------------------------------------------------------------------------------ DefineEngineMethod( GuiTreeViewCtrl, findItemByObjectId, S32, (S32 objectId), , "Find an item by its object id and returns the Tree Item ID for it.\n\n" - "@param objectId Object id you want the item id for." + "@param objectId Object id you want the item id for." "@return Tree Item Id for the given object ID.") { return(object->findItemByObjectId(objectId)); @@ -5389,7 +5389,7 @@ bool GuiTreeViewCtrl::scrollVisibleByObjectId(S32 objID) //------------------------------------------------------------------------------ DefineEngineMethod( GuiTreeViewCtrl, scrollVisibleByObjectId, S32, (S32 objectId), , "Show item by object id.\n\n" - "@param objectId Object id you want to scroll to." + "@param objectId Object id you want to scroll to." "@return True if successful, false if not.") { return(object->scrollVisibleByObjectId(objectId)); @@ -5400,7 +5400,7 @@ DefineEngineMethod( GuiTreeViewCtrl, scrollVisibleByObjectId, S32, (S32 objectId //FIXME: this clashes with SimSet.sort() DefineEngineMethod( GuiTreeViewCtrl, sort, void, (S32 parentId, bool traverseHierarchy, bool parentsFirst, bool caseSensitive), (0, false, false, true), "Sorts all items of the given parent (or root). With 'hierarchy', traverses hierarchy." - "@param parentId TreeItemID of parent/root to sort all the items under. Use 0 to sort the entire tree." + "@param parentId TreeItemID of parent/root to sort all the items under. Use 0 to sort the entire tree." "@param traverseHierarchy True to traverse the hierarchy, false to not." "@param parentsFirst True to sort the parents first." "@param caseSensitive True to pay attention to case, false to ignore it.") @@ -5531,7 +5531,7 @@ DefineEngineMethod( GuiTreeViewCtrl, isItemSelected, bool, ( S32 id ),, "@return True if the given item/object is currently selected in the tree." ) { const Vector< GuiTreeViewCtrl::Item* >& selectedItems = object->getSelectedItems(); - for( S32 i = 0; i < selectedItems.size(); ++ i ) + for( S32 i = 0; i < selectedItems.size(); ++ i ) if( selectedItems[ i ]->mId == id ) return true; diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index a3f2344f2..b671e9626 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -52,42 +52,42 @@ IMPLEMENT_CONOBJECT(GuiCanvas); ConsoleDocClass( GuiCanvas, - "@brief A canvas on which rendering occurs.\n\n" + "@brief A canvas on which rendering occurs.\n\n" - "@section GuiCanvas_contents What a GUICanvas Can Contain...\n\n" + "@section GuiCanvas_contents What a GUICanvas Can Contain...\n\n" - "@subsection GuiCanvas_content_contentcontrol Content Control\n" - "A content control is the top level GuiControl for a screen. This GuiControl " - "will be the parent control for all other GuiControls on that particular " - "screen.\n\n" + "@subsection GuiCanvas_content_contentcontrol Content Control\n" + "A content control is the top level GuiControl for a screen. This GuiControl " + "will be the parent control for all other GuiControls on that particular " + "screen.\n\n" - "@subsection GuiCanvas_content_dialogs Dialogs\n\n" + "@subsection GuiCanvas_content_dialogs Dialogs\n\n" - "A dialog is essentially another screen, only it gets overlaid on top of the " - "current content control, and all input goes to the dialog. This is most akin " - "to the \"Open File\" dialog box found in most operating systems. When you " - "choose to open a file, and the \"Open File\" dialog pops up, you can no longer " - "send input to the application, and must complete or cancel the open file " - "request. Torque keeps track of layers of dialogs. The dialog with the highest " - "layer is on top and will get all the input, unless the dialog is " - "modeless, which is a profile option.\n\n" + "A dialog is essentially another screen, only it gets overlaid on top of the " + "current content control, and all input goes to the dialog. This is most akin " + "to the \"Open File\" dialog box found in most operating systems. When you " + "choose to open a file, and the \"Open File\" dialog pops up, you can no longer " + "send input to the application, and must complete or cancel the open file " + "request. Torque keeps track of layers of dialogs. The dialog with the highest " + "layer is on top and will get all the input, unless the dialog is " + "modeless, which is a profile option.\n\n" - "@see GuiControlProfile\n\n" + "@see GuiControlProfile\n\n" - "@section GuiCanvas_dirty Dirty Rectangles\n\n" + "@section GuiCanvas_dirty Dirty Rectangles\n\n" - "The GuiCanvas is based on dirty regions. " - "Every frame the canvas paints only the areas of the canvas that are 'dirty' " - "or need updating. In most cases, this only is the area under the mouse cursor. " - "This is why if you look in guiCanvas.cc the call to glClear is commented out. " - - "What you will see is a black screen, except in the dirty regions, where the " - "screen will be painted normally. If you are making an animated GuiControl " - "you need to add your control to the dirty areas of the canvas.\n\n" + "The GuiCanvas is based on dirty regions. " + "Every frame the canvas paints only the areas of the canvas that are 'dirty' " + "or need updating. In most cases, this only is the area under the mouse cursor. " + "This is why if you look in guiCanvas.cc the call to glClear is commented out. " + + "What you will see is a black screen, except in the dirty regions, where the " + "screen will be painted normally. If you are making an animated GuiControl " + "you need to add your control to the dirty areas of the canvas.\n\n" - "@see GuiControl\n\n" + "@see GuiControl\n\n" - "@ingroup GuiCore\n"); + "@ingroup GuiCore\n"); ColorI gCanvasClearColor( 255, 0, 255 ); ///< For GFX->clear @@ -209,29 +209,29 @@ bool GuiCanvas::onAdd() //If we're recording, store the intial video resolution if (Journal::IsRecording()) { - Journal::Write(vm.resolution.x); - Journal::Write(vm.resolution.y); - Journal::Write(vm.fullScreen); + Journal::Write(vm.resolution.x); + Journal::Write(vm.resolution.y); + Journal::Write(vm.fullScreen); } //If we're playing, read the intial video resolution from the journal if (Journal::IsPlaying()) { - Journal::Read(&vm.resolution.x); - Journal::Read(&vm.resolution.y); - Journal::Read(&vm.fullScreen); + Journal::Read(&vm.resolution.x); + Journal::Read(&vm.resolution.y); + Journal::Read(&vm.fullScreen); } if (a && a->mType != NullDevice) { mPlatformWindow = WindowManager->createWindow(newDevice, vm); - //Disable window resizing if recording ir playing a journal - if (Journal::IsRecording() || Journal::IsPlaying()) - mPlatformWindow->lockSize(true); - - // Set a minimum on the window size so people can't break us by resizing tiny. - mPlatformWindow->setMinimumWindowSize(Point2I(640,480)); + //Disable window resizing if recording ir playing a journal + if (Journal::IsRecording() || Journal::IsPlaying()) + mPlatformWindow->lockSize(true); + + // Set a minimum on the window size so people can't break us by resizing tiny. + mPlatformWindow->setMinimumWindowSize(Point2I(640,480)); // Now, we have to hook in our event callbacks so we'll get // appropriate events from the window. @@ -326,12 +326,12 @@ CanvasSizeChangeSignal GuiCanvas::smCanvasSizeChangeSignal; void GuiCanvas::handleResize( WindowId did, S32 width, S32 height ) { getCanvasSizeChangeSignal().trigger(this); - if (Journal::IsPlaying() && mPlatformWindow) - { - mPlatformWindow->lockSize(false); - mPlatformWindow->setSize(Point2I(width, height)); - mPlatformWindow->lockSize(true); - } + if (Journal::IsPlaying() && mPlatformWindow) + { + mPlatformWindow->lockSize(false); + mPlatformWindow->setSize(Point2I(width, height)); + mPlatformWindow->lockSize(true); + } // Notify the scripts if ( isMethod( "onResize" ) ) @@ -342,9 +342,9 @@ void GuiCanvas::handlePaintEvent(WindowId did) { bool canRender = mPlatformWindow->isVisible() && GFX->allowRender() && !GFX->canCurrentlyRender(); - // Do the screenshot first. + // Do the screenshot first. if ( gScreenShot != NULL && gScreenShot->isPending() && canRender ) - gScreenShot->capture( this ); + gScreenShot->capture( this ); // If the video capture is waiting for a canvas, start the capture if ( VIDCAP->isWaitingForCanvas() && canRender ) @@ -560,19 +560,19 @@ bool GuiCanvas::tabNext(void) //save the old GuiControl *oldResponder = mFirstResponder; - GuiControl* newResponder = ctrl->findNextTabable(mFirstResponder); + GuiControl* newResponder = ctrl->findNextTabable(mFirstResponder); if ( !newResponder ) newResponder = ctrl->findFirstTabable(); - if ( newResponder && newResponder != oldResponder ) - { - newResponder->setFirstResponder(); + if ( newResponder && newResponder != oldResponder ) + { + newResponder->setFirstResponder(); // CodeReview Can this get killed? Note tabPrev code. BJG - 3/25/07 -// if ( oldResponder ) -// oldResponder->onLoseFirstResponder(); +// if ( oldResponder ) +// oldResponder->onLoseFirstResponder(); return true; - } + } } return false; } @@ -585,30 +585,30 @@ bool GuiCanvas::tabPrev(void) //save the old GuiControl *oldResponder = mFirstResponder; - GuiControl* newResponder = ctrl->findPrevTabable(mFirstResponder); - if ( !newResponder ) + GuiControl* newResponder = ctrl->findPrevTabable(mFirstResponder); + if ( !newResponder ) newResponder = ctrl->findLastTabable(); - if ( newResponder && newResponder != oldResponder ) - { - newResponder->setFirstResponder(); - + if ( newResponder && newResponder != oldResponder ) + { + newResponder->setFirstResponder(); + // CodeReview As with tabNext() above, looks like this can now go. DAW - 7/05/09 - //if ( oldResponder ) - // oldResponder->onLoseFirstResponder(); + //if ( oldResponder ) + // oldResponder->onLoseFirstResponder(); return true; - } + } } return false; } bool GuiCanvas::processInputEvent(InputEventInfo &inputEvent) { - // First call the general input handler (on the extremely off-chance that it will be handled): - if (mFirstResponder && mFirstResponder->onInputEvent(inputEvent)) + // First call the general input handler (on the extremely off-chance that it will be handled): + if (mFirstResponder && mFirstResponder->onInputEvent(inputEvent)) { - return(true); + return(true); } switch (inputEvent.deviceType) @@ -1786,9 +1786,9 @@ void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */) addUpdateRegion(pos - Point2I(2, 2), Point2I(cext.x + 4, cext.y + 4)); } - mLastCursorEnabled = cursorVisible; - mLastCursor = mouseCursor; - mLastCursorPt = cursorPos; + mLastCursorEnabled = cursorVisible; + mLastCursor = mouseCursor; + mLastCursorPt = cursorPos; // Begin GFX PROFILE_START(GFXBeginScene); @@ -1830,7 +1830,7 @@ void GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap /* = true */) resetUpdateRegions(); - // Make sure we have a clean matrix state + // Make sure we have a clean matrix state // before we start rendering anything! GFX->setWorldMatrix( MatrixF::Identity ); GFX->setViewMatrix( MatrixF::Identity ); @@ -2039,46 +2039,46 @@ void GuiCanvas::resetUpdateRegions() void GuiCanvas::setFirstResponder( GuiControl* newResponder ) { - GuiControl* oldResponder = mFirstResponder; - Parent::setFirstResponder( newResponder ); + GuiControl* oldResponder = mFirstResponder; + Parent::setFirstResponder( newResponder ); if( oldResponder == mFirstResponder ) return; - if( oldResponder && ( oldResponder != newResponder ) ) - oldResponder->onLoseFirstResponder(); + if( oldResponder && ( oldResponder != newResponder ) ) + oldResponder->onLoseFirstResponder(); if( newResponder && ( newResponder != oldResponder ) ) newResponder->onGainFirstResponder(); } DefineEngineMethod( GuiCanvas, getContent, S32, (),, - "@brief Get the GuiControl which is being used as the content.\n\n" + "@brief Get the GuiControl which is being used as the content.\n\n" - "@tsexample\n" - "Canvas.getContent();\n" - "@endtsexample\n\n" + "@tsexample\n" + "Canvas.getContent();\n" + "@endtsexample\n\n" - "@return ID of current content control") + "@return ID of current content control") { - GuiControl *ctrl = object->getContentControl(); + GuiControl *ctrl = object->getContentControl(); if(ctrl) return ctrl->getId(); return -1; } DefineEngineMethod( GuiCanvas, setContent, void, (GuiControl* ctrl),, - "@brief Set the content of the canvas to a specified control.\n\n" + "@brief Set the content of the canvas to a specified control.\n\n" - "@param ctrl ID or name of GuiControl to set content to\n\n" + "@param ctrl ID or name of GuiControl to set content to\n\n" - "@tsexample\n" - "Canvas.setContent(PlayGui);\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.setContent(PlayGui);\n" + "@endtsexample\n\n") { - // Not using old error reporting until we modify the engineAPI - mperry + // Not using old error reporting until we modify the engineAPI - mperry - //GuiControl *gui = NULL; + //GuiControl *gui = NULL; // if(argv[2][0]) // { // if (!Sim::findObject(argv[2], gui)) @@ -2088,11 +2088,11 @@ DefineEngineMethod( GuiCanvas, setContent, void, (GuiControl* ctrl),, // } // } - if(!ctrl) - { - Con::errorf("GuiCanvas::setContent - Invalid control specified')"); - return; - } + if(!ctrl) + { + Con::errorf("GuiCanvas::setContent - Invalid control specified')"); + return; + } //set the new content control object->setContentControl(ctrl); @@ -2111,11 +2111,11 @@ ConsoleDocFragment _pushDialog( ); DefineConsoleMethod( GuiCanvas, pushDialog, void, (const char * ctrlName, S32 layer, bool center), ( 0, false), "(GuiControl ctrl, int layer=0, bool center=false)" - "@hide") + "@hide") { GuiControl *gui; - if (! Sim::findObject(ctrlName, gui)) + if (! Sim::findObject(ctrlName, gui)) { Con::printf("pushDialog(): Invalid control: %s", ctrlName); return; @@ -2148,7 +2148,7 @@ ConsoleDocFragment _popDialog2( ); DefineConsoleMethod( GuiCanvas, popDialog, void, (GuiControl * gui), (NULL), "(GuiControl ctrl=NULL)" - "@hide") + "@hide") { if (gui) object->popDialogControl(gui); @@ -2157,160 +2157,160 @@ DefineConsoleMethod( GuiCanvas, popDialog, void, (GuiControl * gui), (NULL), "(G } ConsoleDocFragment _popLayer1( - "@brief Removes the top most layer of dialogs\n\n" - "@tsexample\n" - "Canvas.popLayer();\n" - "@endtsexample\n\n", - "GuiCanvas", - "void popLayer();" + "@brief Removes the top most layer of dialogs\n\n" + "@tsexample\n" + "Canvas.popLayer();\n" + "@endtsexample\n\n", + "GuiCanvas", + "void popLayer();" ); ConsoleDocFragment _popLayer2( - "@brief Removes a specified layer of dialogs\n\n" - "@param layer Number of the layer to pop\n\n" - "@tsexample\n" - "Canvas.popLayer(1);\n" - "@endtsexample\n\n", - "GuiCanvas", - "void popLayer(S32 layer);" + "@brief Removes a specified layer of dialogs\n\n" + "@param layer Number of the layer to pop\n\n" + "@tsexample\n" + "Canvas.popLayer(1);\n" + "@endtsexample\n\n", + "GuiCanvas", + "void popLayer(S32 layer);" ); DefineConsoleMethod( GuiCanvas, popLayer, void, (S32 layer), (0), "(int layer)" - "@hide") + "@hide") { object->popDialogControl(layer); } DefineEngineMethod( GuiCanvas, cursorOn, void, (),, - "@brief Turns on the mouse cursor.\n\n" - "@tsexample\n" - "Canvas.cursorOn();\n" - "@endtsexample\n\n") + "@brief Turns on the mouse cursor.\n\n" + "@tsexample\n" + "Canvas.cursorOn();\n" + "@endtsexample\n\n") { - object->setCursorON(true); + object->setCursorON(true); } DefineEngineMethod( GuiCanvas, cursorOff, void, (),, - "@brief Turns on the mouse off.\n\n" - "@tsexample\n" - "Canvas.cursorOff();\n" - "@endtsexample\n\n") + "@brief Turns on the mouse off.\n\n" + "@tsexample\n" + "Canvas.cursorOff();\n" + "@endtsexample\n\n") { - object->setCursorON(false); + object->setCursorON(false); } DefineEngineMethod( GuiCanvas, setCursor, void, (GuiCursor* cursor),, - "@brief Sets the cursor for the canvas.\n\n" + "@brief Sets the cursor for the canvas.\n\n" - "@param cursor Name of the GuiCursor to use\n\n" + "@param cursor Name of the GuiCursor to use\n\n" - "@tsexample\n" - "Canvas.setCursor(\"DefaultCursor\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.setCursor(\"DefaultCursor\");\n" + "@endtsexample\n\n") { - if(!cursor) - { - Con::errorf("GuiCanvas::setCursor - Invalid GuiCursor name or ID"); - return; - } - object->setCursor(cursor); + if(!cursor) + { + Con::errorf("GuiCanvas::setCursor - Invalid GuiCursor name or ID"); + return; + } + object->setCursor(cursor); } DefineEngineMethod( GuiCanvas, renderFront, void, ( bool enable ),, - "@brief This turns on/off front-buffer rendering.\n\n" + "@brief This turns on/off front-buffer rendering.\n\n" - "@param enable True if all rendering should be done to the front buffer\n\n" + "@param enable True if all rendering should be done to the front buffer\n\n" - "@tsexample\n" - "Canvas.renderFront(false);\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.renderFront(false);\n" + "@endtsexample\n\n") { - object->setRenderFront(enable); + object->setRenderFront(enable); } DefineEngineMethod( GuiCanvas, showCursor, void, (),, - "@brief Enable rendering of the cursor.\n\n" + "@brief Enable rendering of the cursor.\n\n" - "@tsexample\n" - "Canvas.showCursor();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.showCursor();\n" + "@endtsexample\n\n") { - object->showCursor(true); + object->showCursor(true); } DefineEngineMethod( GuiCanvas, hideCursor, void, (),, - "@brief Disable rendering of the cursor.\n\n" + "@brief Disable rendering of the cursor.\n\n" - "@tsexample\n" - "Canvas.hideCursor();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.hideCursor();\n" + "@endtsexample\n\n") { - object->showCursor(false); + object->showCursor(false); } DefineEngineMethod( GuiCanvas, isCursorOn, bool, (),, - "@brief Determines if mouse cursor is enabled.\n\n" + "@brief Determines if mouse cursor is enabled.\n\n" - "@tsexample\n" - "// Is cursor on?\n" - "if(Canvas.isCursorOn())\n" - " echo(\"Canvas cursor is on\");\n" - "@endtsexample\n\n" - "@return Returns true if the cursor is on.\n\n") + "@tsexample\n" + "// Is cursor on?\n" + "if(Canvas.isCursorOn())\n" + " echo(\"Canvas cursor is on\");\n" + "@endtsexample\n\n" + "@return Returns true if the cursor is on.\n\n") { - return object->isCursorON(); + return object->isCursorON(); } DefineEngineMethod( GuiCanvas, isCursorShown, bool, (),, - "@brief Determines if mouse cursor is rendering.\n\n" + "@brief Determines if mouse cursor is rendering.\n\n" - "@tsexample\n" - "// Is cursor rendering?\n" - "if(Canvas.isCursorShown())\n" - " echo(\"Canvas cursor is rendering\");\n" - "@endtsexample\n\n" - "@return Returns true if the cursor is rendering.\n\n") + "@tsexample\n" + "// Is cursor rendering?\n" + "if(Canvas.isCursorShown())\n" + " echo(\"Canvas cursor is rendering\");\n" + "@endtsexample\n\n" + "@return Returns true if the cursor is rendering.\n\n") { - return object->isCursorShown(); + return object->isCursorShown(); } DefineEngineMethod( GuiCanvas, repaint, void, ( S32 elapsedMS ), (0), - "@brief Force canvas to redraw.\n" + "@brief Force canvas to redraw.\n" "If the elapsed time is greater than the time since the last paint " "then the repaint will be skipped.\n" "@param elapsedMS The optional elapsed time in milliseconds.\n\n" - "@tsexample\n" - "Canvas.repaint();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.repaint();\n" + "@endtsexample\n\n") { - object->repaint(elapsedMS < 0 ? 0 : elapsedMS); + object->repaint(elapsedMS < 0 ? 0 : elapsedMS); } DefineEngineMethod( GuiCanvas, reset, void, (),, - "@brief Reset the update regions for the canvas.\n\n" + "@brief Reset the update regions for the canvas.\n\n" - "@tsexample\n" - "Canvas.reset();\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.reset();\n" + "@endtsexample\n\n") { - object->resetUpdateRegions(); + object->resetUpdateRegions(); } DefineEngineMethod( GuiCanvas, getCursorPos, Point2I, (),, - "@brief Get the current position of the cursor in screen-space. Note that this position" + "@brief Get the current position of the cursor in screen-space. Note that this position" " might be outside the Torque window. If you want to get the position within the Canvas," " call screenToClient on the result.\n\n" "@see Canvas::screenToClient()\n\n" - "@param param Description\n\n" - "@tsexample\n" - "%cursorPos = Canvas.getCursorPos();\n" - "@endtsexample\n\n" - "@return Screen coordinates of mouse cursor, in format \"X Y\"") + "@param param Description\n\n" + "@tsexample\n" + "%cursorPos = Canvas.getCursorPos();\n" + "@endtsexample\n\n" + "@return Screen coordinates of mouse cursor, in format \"X Y\"") { - return object->getCursorPos(); + return object->getCursorPos(); } ConsoleDocFragment _setCursorPos1( @@ -2334,21 +2334,21 @@ ConsoleDocFragment _setCursorPos2( ); DefineConsoleMethod( GuiCanvas, setCursorPos, void, (Point2I pos), , "(Point2I pos)" - "@hide") + "@hide") { object->setCursorPos(pos); } DefineEngineMethod( GuiCanvas, getMouseControl, S32, (),, - "@brief Gets the gui control under the mouse.\n\n" - "@tsexample\n" - "%underMouse = Canvas.getMouseControl();\n" - "@endtsexample\n\n" + "@brief Gets the gui control under the mouse.\n\n" + "@tsexample\n" + "%underMouse = Canvas.getMouseControl();\n" + "@endtsexample\n\n" - "@return ID of the gui control, if one was found. NULL otherwise") + "@return ID of the gui control, if one was found. NULL otherwise") { - GuiControl* control = object->getMouseControl(); + GuiControl* control = object->getMouseControl(); if (control) return control->getId(); @@ -2356,18 +2356,18 @@ DefineEngineMethod( GuiCanvas, getMouseControl, S32, (),, } DefineEngineFunction(excludeOtherInstance, bool, (const char* appIdentifer),, - "@brief Used to exclude/prevent all other instances using the same identifier specified\n\n" + "@brief Used to exclude/prevent all other instances using the same identifier specified\n\n" - "@note Not used on OSX, Xbox, or in Win debug builds\n\n" + "@note Not used on OSX, Xbox, or in Win debug builds\n\n" - "@param appIdentifier Name of the app set up for exclusive use.\n" + "@param appIdentifier Name of the app set up for exclusive use.\n" - "@return False if another app is running that specified the same appIdentifier\n\n" + "@return False if another app is running that specified the same appIdentifier\n\n" - "@ingroup Platform\n" - "@ingroup GuiCore") + "@ingroup Platform\n" + "@ingroup GuiCore") { - // mac/360 can only run one instance in general. + // mac/360 can only run one instance in general. #if !defined(TORQUE_OS_MAC) && !defined(TORQUE_OS_XENON) && !defined(TORQUE_DEBUG) && !defined(TORQUE_OS_LINUX) return Platform::excludeOtherInstances(appIdentifer); #else @@ -2377,82 +2377,82 @@ DefineEngineFunction(excludeOtherInstance, bool, (const char* appIdentifer),, } DefineEngineMethod( GuiCanvas, getExtent, Point2I, (),, - "@brief Returns the dimensions of the canvas\n\n" + "@brief Returns the dimensions of the canvas\n\n" - "@tsexample\n" - "%extent = Canvas.getExtent();\n" - "@endtsexample\n\n" + "@tsexample\n" + "%extent = Canvas.getExtent();\n" + "@endtsexample\n\n" - "@return Width and height of canvas. Formatted as numerical values in a single string \"# #\"") + "@return Width and height of canvas. Formatted as numerical values in a single string \"# #\"") { - return object->getExtent(); + return object->getExtent(); } DefineEngineMethod( GuiCanvas, setWindowTitle, void, ( const char* newTitle),, - "@brief Change the title of the OS window.\n\n" + "@brief Change the title of the OS window.\n\n" - "@param newTitle String containing the new name\n\n" + "@param newTitle String containing the new name\n\n" - "@tsexample\n" - "Canvas.setWindowTitle(\"Documentation Rocks!\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "Canvas.setWindowTitle(\"Documentation Rocks!\");\n" + "@endtsexample\n\n") { - object->setWindowTitle(newTitle); + object->setWindowTitle(newTitle); } DefineEngineMethod( GuiCanvas, findFirstMatchingMonitor, S32, (const char* name),, - "@brief Find the first monitor index that matches the given name.\n\n" + "@brief Find the first monitor index that matches the given name.\n\n" "The actual match algorithm depends on the implementation.\n" "@param name The name to search for.\n\n" - "@return The number of monitors attached to the system, including the default monoitor.") + "@return The number of monitors attached to the system, including the default monoitor.") { return PlatformWindowManager::get()->findFirstMatchingMonitor(name); } DefineEngineMethod( GuiCanvas, getMonitorCount, S32, (),, - "@brief Gets the number of monitors attached to the system.\n\n" + "@brief Gets the number of monitors attached to the system.\n\n" - "@return The number of monitors attached to the system, including the default monoitor.") + "@return The number of monitors attached to the system, including the default monoitor.") { return PlatformWindowManager::get()->getMonitorCount(); } DefineEngineMethod( GuiCanvas, getMonitorName, const char*, (S32 index),, - "@brief Gets the name of the requested monitor.\n\n" + "@brief Gets the name of the requested monitor.\n\n" "@param index The monitor index.\n\n" - "@return The name of the requested monitor.") + "@return The name of the requested monitor.") { return PlatformWindowManager::get()->getMonitorName(index); } DefineEngineMethod( GuiCanvas, getMonitorRect, RectI, (S32 index),, - "@brief Gets the region of the requested monitor.\n\n" + "@brief Gets the region of the requested monitor.\n\n" "@param index The monitor index.\n\n" - "@return The rectangular region of the requested monitor.") + "@return The rectangular region of the requested monitor.") { return PlatformWindowManager::get()->getMonitorRect(index); } DefineEngineMethod( GuiCanvas, getVideoMode, const char*, (),, - "@brief Gets the current screen mode as a string.\n\n" + "@brief Gets the current screen mode as a string.\n\n" - "The return string will contain 5 values (width, height, fullscreen, bitdepth, refreshRate). " - "You will need to parse out each one for individual use.\n\n" + "The return string will contain 5 values (width, height, fullscreen, bitdepth, refreshRate). " + "You will need to parse out each one for individual use.\n\n" - "@tsexample\n" - "%screenWidth = getWord(Canvas.getVideoMode(), 0);\n" - "%screenHeight = getWord(Canvas.getVideoMode(), 1);\n" - "%isFullscreen = getWord(Canvas.getVideoMode(), 2);\n" - "%bitdepth = getWord(Canvas.getVideoMode(), 3);\n" - "%refreshRate = getWord(Canvas.getVideoMode(), 4);\n" - "@endtsexample\n\n" + "@tsexample\n" + "%screenWidth = getWord(Canvas.getVideoMode(), 0);\n" + "%screenHeight = getWord(Canvas.getVideoMode(), 1);\n" + "%isFullscreen = getWord(Canvas.getVideoMode(), 2);\n" + "%bitdepth = getWord(Canvas.getVideoMode(), 3);\n" + "%refreshRate = getWord(Canvas.getVideoMode(), 4);\n" + "@endtsexample\n\n" - "@return String formatted with screen width, screen height, screen mode, bit depth, and refresh rate.") + "@return String formatted with screen width, screen height, screen mode, bit depth, and refresh rate.") { - // Grab the video mode. + // Grab the video mode. if (!object->getPlatformWindow()) return ""; @@ -2463,17 +2463,17 @@ DefineEngineMethod( GuiCanvas, getVideoMode, const char*, (),, DefineEngineMethod( GuiCanvas, getModeCount, S32, (),, - "@brief Gets the number of modes available on this device.\n\n" + "@brief Gets the number of modes available on this device.\n\n" - "@param param Description\n\n" + "@param param Description\n\n" - "@tsexample\n" - "%modeCount = Canvas.getModeCount()\n" - "@endtsexample\n\n" + "@tsexample\n" + "%modeCount = Canvas.getModeCount()\n" + "@endtsexample\n\n" - "@return The number of video modes supported by the device") + "@return The number of video modes supported by the device") { - if (!object->getPlatformWindow()) + if (!object->getPlatformWindow()) return 0; // Grab the available mode list from the device. @@ -2485,12 +2485,12 @@ DefineEngineMethod( GuiCanvas, getModeCount, S32, (),, } DefineEngineMethod( GuiCanvas, getMode, const char*, (S32 modeId),, - "@brief Gets information on the specified mode of this device.\n\n" - "@param modeId Index of the mode to get data from.\n" - "@return A video mode string given an adapter and mode index.\n\n" - "@see GuiCanvas::getVideoMode()") + "@brief Gets information on the specified mode of this device.\n\n" + "@param modeId Index of the mode to get data from.\n" + "@return A video mode string given an adapter and mode index.\n\n" + "@see GuiCanvas::getVideoMode()") { - if (!object->getPlatformWindow()) + if (!object->getPlatformWindow()) return 0; // Grab the available mode list from the device. @@ -2515,14 +2515,14 @@ DefineEngineMethod( GuiCanvas, getMode, const char*, (S32 modeId),, DefineEngineMethod( GuiCanvas, toggleFullscreen, void, (),, - "@brief toggle canvas from fullscreen to windowed mode or back.\n\n" + "@brief toggle canvas from fullscreen to windowed mode or back.\n\n" - "@tsexample\n" - "// If we are in windowed mode, the following will put is in fullscreen\n" - "Canvas.toggleFullscreen();" - "@endtsexample\n\n") + "@tsexample\n" + "// If we are in windowed mode, the following will put is in fullscreen\n" + "Canvas.toggleFullscreen();" + "@endtsexample\n\n") { - if (Platform::getWebDeployment()) + if (Platform::getWebDeployment()) return; if (!object->getPlatformWindow()) @@ -2693,7 +2693,7 @@ DefineConsoleMethod( GuiCanvas, setVideoMode, void, "\\param fullscreen Specify true to run fullscreen or false to run in a window\n" "\\param bitDepth [optional] The desired bit-depth. Defaults to the current setting. This parameter is ignored if you are running in a window.\n" "\\param refreshRate [optional] The desired refresh rate. Defaults to the current setting. This parameter is ignored if you are running in a window" - "\\param antialiasLevel [optional] The level of anti-aliasing to apply 0 = none" ) + "\\param antialiasLevel [optional] The level of anti-aliasing to apply 0 = none" ) { if (!object->getPlatformWindow()) return; diff --git a/Engine/source/gui/editor/guiEditCtrl.cpp b/Engine/source/gui/editor/guiEditCtrl.cpp index f972ec8ca..f71dd8ef0 100644 --- a/Engine/source/gui/editor/guiEditCtrl.cpp +++ b/Engine/source/gui/editor/guiEditCtrl.cpp @@ -716,16 +716,16 @@ void GuiEditCtrl::onRender(Point2I offset, const RectI &updateRect) ctOffset = getCurrentAddSet()->localToGlobalCoord(Point2I(0,0)); RectI box(ctOffset.x, ctOffset.y, cext.x, cext.y); - box.inset( -5, -5 ); + box.inset( -5, -5 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); + box.inset( 1, 1 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); + box.inset( 1, 1 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); + box.inset( 1, 1 ); + drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); + box.inset( 1, 1 ); drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); - box.inset( 1, 1 ); - drawer->drawRect( box, ColorI( 50, 101, 152, 128 ) ); } Vector::iterator i; bool multisel = mSelectedControls.size() > 1; @@ -2481,16 +2481,16 @@ DefineConsoleMethod( GuiEditCtrl, getContentControl, S32, (), , "() - Return the DefineConsoleMethod( GuiEditCtrl, setContentControl, void, (GuiControl *ctrl ), , "( GuiControl ctrl ) - Set the toplevel control to edit in the GUI editor." ) { - if (ctrl) - object->setContentControl(ctrl); + if (ctrl) + object->setContentControl(ctrl); } //----------------------------------------------------------------------------- DefineConsoleMethod( GuiEditCtrl, addNewCtrl, void, (GuiControl *ctrl), , "(GuiControl ctrl)") { - if (ctrl) - object->addNewControl(ctrl); + if (ctrl) + object->addNewControl(ctrl); } //----------------------------------------------------------------------------- @@ -2518,7 +2518,7 @@ DefineConsoleMethod( GuiEditCtrl, clearSelection, void, (), , "Clear selected co DefineConsoleMethod( GuiEditCtrl, select, void, (GuiControl *ctrl), , "(GuiControl ctrl)") { - if (ctrl) + if (ctrl) object->setSelection(ctrl, false); } @@ -2526,7 +2526,7 @@ DefineConsoleMethod( GuiEditCtrl, select, void, (GuiControl *ctrl), , "(GuiContr DefineConsoleMethod( GuiEditCtrl, setCurrentAddSet, void, (GuiControl *addSet), , "(GuiControl ctrl)") { - if (addSet) + if (addSet) object->setCurrentAddSet(addSet); } diff --git a/Engine/source/gui/editor/guiMenuBar.cpp b/Engine/source/gui/editor/guiMenuBar.cpp index 4a9a4cefa..1a8db3f96 100644 --- a/Engine/source/gui/editor/guiMenuBar.cpp +++ b/Engine/source/gui/editor/guiMenuBar.cpp @@ -81,8 +81,8 @@ ConsoleDocClass( GuiMenuBar, "@tsexample\n" "new GuiMenuBar(newMenuBar)\n" "{\n" - " Padding = \"0\";\n" - " //Properties not specific to this control have been omitted from this example.\n" + " Padding = \"0\";\n" + " //Properties not specific to this control have been omitted from this example.\n" "};\n\n" "// Add a menu to the menu bar\n" "newMenuBar.addMenu(0,\"New Menu\");\n\n" @@ -105,7 +105,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMouseInMenu, void, (bool isInMenu),( isInMenu "// Mouse enters or persists within the menu, causing the callback to occur.\n" "GuiMenuBar::onMouseInMenu(%this,%hasLeftMenu)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" @@ -119,14 +119,14 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuSelect, void, ( S32 menuId, const char* me "// A menu has been selected, causing the callback to occur.\n" "GuiMenuBar::onMenuSelect(%this,%menuId,%menuText)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" ); IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( S32 menuId, const char* menuText, S32 menuItemId, const char* menuItemText ), - ( menuId, menuText, menuItemId, menuItemText ), + ( menuId, menuText, menuItemId, menuItemText ), "@brief Called whenever an item in a menu is selected.\n\n" "@param menuId Index id of the menu which contains the selected menu item\n" "@param menuText Text of the menu which contains the selected menu item\n\n" @@ -136,7 +136,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onMenuItemSelect, void, ( S32 menuId, const char "// A menu item has been selected, causing the callback to occur.\n" "GuiMenuBar::onMenuItemSelect(%this,%menuId,%menuText,%menuItemId,%menuItemText)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" @@ -149,7 +149,7 @@ IMPLEMENT_CALLBACK( GuiMenuBar, onSubmenuSelect, void, ( S32 submenuId, const ch "@tsexample\n" "GuiMenuBar::onSubmenuSelect(%this,%submenuId,%submenuText)\n" "{\n" - " // Code to run when the callback occurs\n" + " // Code to run when the callback occurs\n" "}\n" "@endtsexample\n\n" "@see GuiTickCtrl\n\n" @@ -216,7 +216,7 @@ DefineEngineMethod(GuiMenuBar, addMenu, void, (const char* menuText, S32 menuId) } DefineEngineMethod(GuiMenuBar, addMenuItem, void, (const char* targetMenu, const char* menuItemText, S32 menuItemId, const char* accelerator, int checkGroup, const char *cmd), - ("","",0,NULL,-1,""), + ("","",0,NULL,-1,""), "@brief Adds a menu item to the specified menu. The menu argument can be either the text of a menu or its id.\n\n" "@param menu Menu name or menu Id to add the new item to.\n" "@param menuItemText Text for the new menu item.\n" @@ -637,7 +637,7 @@ DefineEngineMethod(GuiMenuBar, setMenuItemSubmenuState, void, (const char* menuT } DefineEngineMethod(GuiMenuBar, addSubmenuItem, void, (const char* menuTarget, const char* menuItem, const char* submenuItemText, - int submenuItemId, const char* accelerator, int checkGroup),, + int submenuItemId, const char* accelerator, int checkGroup),, "@brief Adds a menu item to the specified menu. The menu argument can be either the text of a menu or its id.\n\n" "@param menuTarget Menu to affect a submenu in\n" "@param menuItem Menu item to affect\n" @@ -814,21 +814,21 @@ void GuiMenuBar::addMenu(const char *menuText, U32 menuId) GuiMenuBar::Menu *GuiMenuBar::findMenu(const char *menu) { - if(dIsdigit(menu[0])) - { - U32 id = dAtoi(menu); + if(dIsdigit(menu[0])) + { + U32 id = dAtoi(menu); for (U32 i = 0; i < mMenuList.size(); ++i) if (id == mMenuList[i]->id) return mMenuList[i]; - return NULL; - } - else - { + return NULL; + } + else + { for (U32 i = 0; i < mMenuList.size(); ++i) if (!dStricmp(menu, mMenuList[i]->text)) return mMenuList[i]; - return NULL; - } + return NULL; + } } GuiMenuBar::MenuItem *GuiMenuBar::findMenuItem(Menu *menu, const char *menuItem) @@ -981,13 +981,13 @@ GuiMenuBar::MenuItem *GuiMenuBar::findSubmenuItem(Menu *menu, const char *menuIt U32 id = dAtoi(menuItem); for(MenuItem *walk = menu->firstMenuItem; walk; walk = walk->nextMenuItem) if(id == walk->id) - { - if(walk->isSubmenu && walk->submenu) - { + { + if(walk->isSubmenu && walk->submenu) + { return GuiMenuBar::findMenuItem(walk->submenu, submenuItem); - } - return NULL; - } + } + return NULL; + } return NULL; } else @@ -995,13 +995,13 @@ GuiMenuBar::MenuItem *GuiMenuBar::findSubmenuItem(Menu *menu, const char *menuIt // Search by name for(MenuItem *walk = menu->firstMenuItem; walk; walk = walk->nextMenuItem) if(!dStricmp(menuItem, walk->text)) - { - if(walk->isSubmenu && walk->submenu) - { + { + if(walk->isSubmenu && walk->submenu) + { return GuiMenuBar::findMenuItem(walk->submenu, submenuItem); - } - return NULL; - } + } + return NULL; + } return NULL; } } @@ -1021,7 +1021,7 @@ void GuiMenuBar::addSubmenuItem(Menu *menu, MenuItem *submenu, const char *text, if(submenu && !submenu->isSubmenu) { Con::errorf("GuiMenuBar::addSubmenuItem: Attempting to add menuitem '%s' to an invalid submenu",text); - return; + return; } // allocate the new menu item @@ -1074,7 +1074,7 @@ void GuiMenuBar::removeSubmenuItem(MenuItem *menuItem, MenuItem *submenuItem) if(menuItem && !menuItem->isSubmenu) { Con::errorf("GuiMenuBar::removeSubmenuItem: Attempting to remove submenuitem '%s' from an invalid submenu",submenuItem->text); - return; + return; } GuiMenuBar::removeMenuItem(menuItem->submenu, submenuItem); @@ -1087,7 +1087,7 @@ void GuiMenuBar::clearSubmenuItems(MenuItem *menuitem) if(menuitem && !menuitem->isSubmenu) { Con::errorf("GuiMenuBar::clearSubmenuItems: Attempting to clear an invalid submenu"); - return; + return; } while(menuitem->submenu->firstMenuItem) @@ -1175,33 +1175,33 @@ void GuiMenuBar::onPreRender() if (!mMenuList[i]->visible) continue; - // Bounds depends on if there is a bitmap to be drawn or not + // Bounds depends on if there is a bitmap to be drawn or not if (mMenuList[i]->bitmapIndex == -1) - { + { // Text only mMenuList[i]->bounds.set(curX, 0, mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() - (mVerticalMargin * 2)); } else - { + { // Will the bitmap and text be draw? if (!mMenuList[i]->drawBitmapOnly) - { + { // Draw the bitmap and the text RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mProfile->mFont->getStrWidth(mMenuList[i]->text) + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); - } else - { + } else + { // Only the bitmap will be drawn RectI *bitmapBounds = mProfile->mBitmapArrayRects.address(); mMenuList[i]->bounds.set(curX, 0, bitmapBounds[mMenuList[i]->bitmapIndex].extent.x + mBitmapMargin + (mHorizontalMargin * 2), getHeight() + (mVerticalMargin * 2)); - } - } + } + } curX += mMenuList[i]->bounds.extent.x; } - mouseOverMenu = NULL; - mouseDownMenu = NULL; + mouseOverMenu = NULL; + mouseDownMenu = NULL; } } @@ -1222,35 +1222,35 @@ void GuiMenuBar::checkMenuMouseMove(const GuiEvent &event) void GuiMenuBar::onMouseMove(const GuiEvent &event) { Menu *hit = findHitMenu(event.mousePoint); - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) + if(hit != mouseOverMenu) + { + // If we need to, reset the mouse over menu counter and indicate + // that we should track it. + if(hit) mMouseOverCounter = 0; - if(!mCountMouseOver) - { + if(!mCountMouseOver) + { // We've never started the counter, so start it. if(hit) mCountMouseOver = true; - } + } - mouseOverMenu = hit; - setUpdate(); - } + mouseOverMenu = hit; + setUpdate(); + } } void GuiMenuBar::onMouseLeave(const GuiEvent &event) { if(mouseOverMenu) - setUpdate(); - mouseOverMenu = NULL; + setUpdate(); + mouseOverMenu = NULL; // As we've left the control, don't track how long the mouse has been // within it. if(mCountMouseOver && mMouseOverCounter >= mMouseHoverAmount) { - onMouseInMenu_callback(false); // Last parameter indicates if we've entered or left the menu + onMouseInMenu_callback(false); // Last parameter indicates if we've entered or left the menu } mCountMouseOver = false; mMouseOverCounter = 0; @@ -1259,38 +1259,38 @@ void GuiMenuBar::onMouseLeave(const GuiEvent &event) void GuiMenuBar::onMouseDragged(const GuiEvent &event) { Menu *hit = findHitMenu(event.mousePoint); - - if(hit != mouseOverMenu) - { - // If we need to, reset the mouse over menu counter and indicate - // that we should track it. - if(hit) + + if(hit != mouseOverMenu) + { + // If we need to, reset the mouse over menu counter and indicate + // that we should track it. + if(hit) mMouseOverCounter = 0; - if(!mCountMouseOver) - { + if(!mCountMouseOver) + { // We've never started the counter, so start it. if(hit) mCountMouseOver = true; - } + } - mouseOverMenu = hit; + mouseOverMenu = hit; mouseDownMenu = hit; - setUpdate(); + setUpdate(); onAction(); - } + } } void GuiMenuBar::onMouseDown(const GuiEvent &event) { mouseDownMenu = mouseOverMenu = findHitMenu(event.mousePoint); - setUpdate(); + setUpdate(); onAction(); } void GuiMenuBar::onMouseUp(const GuiEvent &event) { mouseDownMenu = NULL; - setUpdate(); + setUpdate(); } void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) @@ -1320,20 +1320,20 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) start.x = mMenuList[i]->bounds.point.x + mHorizontalMargin; start.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - mProfile->mFont->getHeight()) / 2; - // Draw the border + // Draw the border if (mMenuList[i]->drawBorder) - { + { RectI highlightBounds = bounds; highlightBounds.inset(1,1); if (mMenuList[i] == mouseDownMenu) renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL ); else if (mMenuList[i] == mouseOverMenu && mouseDownMenu == NULL) renderFilledBorder(highlightBounds, mProfile->mBorderColorHL, mProfile->mFillColorHL); - } + } - // Do we draw a bitmap? + // Do we draw a bitmap? if (mMenuList[i]->bitmapIndex != -1) - { + { S32 index = mMenuList[i]->bitmapIndex * 3; if (mMenuList[i] == mouseDownMenu) ++index; @@ -1342,24 +1342,24 @@ void GuiMenuBar::onRender(Point2I offset, const RectI &updateRect) RectI rect = mProfile->mBitmapArrayRects[index]; - Point2I bitmapstart(start); + Point2I bitmapstart(start); bitmapstart.y = mMenuList[i]->bounds.point.y + (mMenuList[i]->bounds.extent.y - rect.extent.y) / 2; drawUtil->clearBitmapModulation(); drawUtil->drawBitmapSR( mProfile->mTextureObject, offset + bitmapstart, rect); - // Should we also draw the text? + // Should we also draw the text? if (!mMenuList[i]->drawBitmapOnly) - { + { start.x += mBitmapMargin; drawUtil->setBitmapModulation( fontColor ); drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } - } else - { + } + } else + { drawUtil->setBitmapModulation( fontColor ); drawUtil->drawText(mProfile->mFont, start + offset, mMenuList[i]->text, mProfile->mFontColors); - } + } } renderChildControls( offset, updateRect ); @@ -1381,7 +1381,7 @@ void GuiMenuBar::buildWindowAcceleratorMap( WindowInputGenerator &inputGenerator continue; } EventDescriptor accelEvent; - ActionMap::createEventDescriptor(item->accelerator, &accelEvent); + ActionMap::createEventDescriptor(item->accelerator, &accelEvent); //now we have a modifier, and a key, add them to the canvas inputGenerator.addAcceleratorKey( this, item->cmd, accelEvent.eventCode, accelEvent.flags); @@ -1412,7 +1412,7 @@ void GuiMenuBar::acceleratorKeyPress(U32 index) { // first, call the script callback for menu selection: onMenuSelect_callback(mMenuList[i]->id, mMenuList[i]->text); - + if(item->visible) menuItemSelected(mMenuList[i], item); return; @@ -1551,15 +1551,15 @@ void GuiMenuTextListCtrl::onMouseUp(const GuiEvent &event) void GuiMenuTextListCtrl::onCellHighlighted(Point2I cell) { - // If this text list control is part of a submenu, then don't worry about - // passing this along - if(!isSubMenu) - { - RectI globalbounds(getBounds()); - Point2I globalpoint = localToGlobalCoord(globalbounds.point); - globalbounds.point = globalpoint; - mMenuBarCtrl->highlightedMenuItem(cell.y, globalbounds, mCellSize); - } + // If this text list control is part of a submenu, then don't worry about + // passing this along + if(!isSubMenu) + { + RectI globalbounds(getBounds()); + Point2I globalpoint = localToGlobalCoord(globalbounds.point); + globalbounds.point = globalpoint; + mMenuBarCtrl->highlightedMenuItem(cell.y, globalbounds, mCellSize); + } } //------------------------------------------------------------------------------ @@ -1582,9 +1582,9 @@ bool GuiSubmenuBackgroundCtrl::pointInControl(const Point2I& parentCoordPoint) S32 yt = parentCoordPoint.y - getTop(); if(findHitControl(Point2I(xt,yt)) == this) - return false; + return false; else - return true; + return true; // return xt >= 0 && yt >= 0 && xt < getWidth() && yt < getHeight(); } @@ -1609,7 +1609,7 @@ void GuiMenuBar::onSleep() void GuiMenuBar::closeMenu() { // First close any open submenu - closeSubmenu(); + closeSubmenu(); // Get the selection from the text list: S32 selectionIndex = mTextList->getSelectedCell().y; @@ -1657,25 +1657,25 @@ void GuiMenuBar::highlightedMenuItem(S32 selectionIndex, const RectI& bounds, Po } if(list) - { + { // If the highlighted item has changed... if(mouseOverSubmenu != list) - { + { closeSubmenu(); mouseOverSubmenu = NULL; // Check if this is a submenu. If so, open the submenu. if(list->isSubmenu) - { - // If there are submenu items, then open the submenu + { + // If there are submenu items, then open the submenu if(list->submenu->firstMenuItem) - { - mouseOverSubmenu = list; - onSubmenuAction(selstore, bounds, cellSize); - } - } - } - } + { + mouseOverSubmenu = list; + onSubmenuAction(selstore, bounds, cellSize); + } + } + } + } } } @@ -1745,11 +1745,11 @@ void GuiMenuBar::onAction() 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(walk->isSubmenu) - isSubmenu = 2; + // 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(walk->isSubmenu) + isSubmenu = 2; char bitmapIndex = 1; if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) @@ -1861,8 +1861,8 @@ void GuiMenuBar::onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2 char buf[512]; - // Can't have submenus within submenus. - char isSubmenu = 1; + // Can't have submenus within submenus. + char isSubmenu = 1; char bitmapIndex = 1; if(walk->bitmapIndex >= 0 && (walk->bitmapIndex * 3 <= mProfile->mBitmapArrayRects.size())) @@ -1916,7 +1916,7 @@ void GuiMenuBar::onSubmenuAction(S32 selectionIndex, const RectI& bounds, Point2 void GuiMenuBar::closeSubmenu() { if(!mSubmenuBackground || !mSubmenuTextList) - return; + return; // Get the selection from the text list: S32 selectionIndex = mSubmenuTextList->getSelectedCell().y; @@ -1934,8 +1934,8 @@ void GuiMenuBar::closeSubmenu() if ( selectionIndex != -1 ) { MenuItem *list = NULL; - if(mouseOverSubmenu) - { + if(mouseOverSubmenu) + { list = mouseOverSubmenu->submenu->firstMenuItem; while(selectionIndex && list) @@ -1943,7 +1943,7 @@ void GuiMenuBar::closeSubmenu() list = list->nextMenuItem; selectionIndex--; } - } + } if(list) menuItemSelected(list->submenuParentMenu, list); } @@ -1981,13 +1981,13 @@ void GuiMenuBar::processTick() { // If we're at a particular number of ticks, notify the script function if(mMouseOverCounter < mMouseHoverAmount) - { + { ++mMouseOverCounter; - } else if(mMouseOverCounter == mMouseHoverAmount) - { + } else if(mMouseOverCounter == mMouseHoverAmount) + { ++mMouseOverCounter; - onMouseInMenu_callback(true); // Last parameter indicates if we've entered or left the menu - } + onMouseInMenu_callback(true); // Last parameter indicates if we've entered or left the menu + } } } diff --git a/Engine/source/gui/editor/guiParticleGraphCtrl.cpp b/Engine/source/gui/editor/guiParticleGraphCtrl.cpp index 1f9465760..8e20bfeef 100644 --- a/Engine/source/gui/editor/guiParticleGraphCtrl.cpp +++ b/Engine/source/gui/editor/guiParticleGraphCtrl.cpp @@ -43,16 +43,16 @@ GuiParticleGraphCtrl::GuiParticleGraphCtrl() for(S32 i = 0; i < MaxPlots; i++) { - mPlots[i].mGraphColor = ColorF(1.0, 1.0, 1.0); - VECTOR_SET_ASSOCIATION(mPlots[i].mGraphData); - mPlots[i].mGraphMax.x = 1; - mPlots[i].mGraphMax.y = 50; - mPlots[i].mGraphMin.x = 0; - mPlots[i].mGraphMin.y = 0; - mPlots[i].mGraphType = Polyline; - mPlots[i].mGraphName = StringTable->insert(""); - mPlots[i].mHidden = false; - mPlots[i].mGraphScale = 0.05f; + mPlots[i].mGraphColor = ColorF(1.0, 1.0, 1.0); + VECTOR_SET_ASSOCIATION(mPlots[i].mGraphData); + mPlots[i].mGraphMax.x = 1; + mPlots[i].mGraphMax.y = 50; + mPlots[i].mGraphMin.x = 0; + mPlots[i].mGraphMin.y = 0; + mPlots[i].mGraphType = Polyline; + mPlots[i].mGraphName = StringTable->insert(""); + mPlots[i].mHidden = false; + mPlots[i].mGraphScale = 0.05f; } mPlots[0].mGraphColor = ColorF(1.0f, 0.2f, 0.2f); @@ -127,87 +127,87 @@ void GuiParticleGraphCtrl::onRender(Point2I offset, const RectI &updateRect) // Fetch Draw Utility. GFXDrawUtil* pDrawUtil = GFX->getDrawUtil(); - if (mProfile->mBorder) - { - const RectI bounds = getBounds(); - RectI rect(offset.x, offset.y, bounds.extent.x, bounds.extent.y); - pDrawUtil->drawRect(rect, mProfile->mBorderColor); - } + if (mProfile->mBorder) + { + const RectI bounds = getBounds(); + RectI rect(offset.x, offset.y, bounds.extent.x, bounds.extent.y); + pDrawUtil->drawRect(rect, mProfile->mBorderColor); + } GuiControlProfile* profile = dynamic_cast(Sim::findObject("GuiDefaultProfile")); Resource font = profile->mFont; - GFXVideoMode videoMode = GFXInit::getDesktopResolution(); + GFXVideoMode videoMode = GFXInit::getDesktopResolution(); - ColorF color(1.0f, 1.0f, 1.0f, 0.5f); - pDrawUtil->drawRectFill(updateRect, color); + ColorF color(1.0f, 1.0f, 1.0f, 0.5f); + pDrawUtil->drawRectFill(updateRect, color); - for (S32 k = 0; k < MaxPlots; k++) - { - // Nothing to graph - if ((mPlots[k].mGraphData.size() == 0) || (mPlots[k].mHidden == true)) - continue; - + for (S32 k = 0; k < MaxPlots; k++) + { + // Nothing to graph + if ((mPlots[k].mGraphData.size() == 0) || (mPlots[k].mHidden == true)) + continue; + Point2F graphExtent = getGraphExtent(k); - // Adjust scale to max value + 5% so we can see high value - F32 ScaleX = (F32(getExtent().x) / (graphExtent.x*(1.00 + (mPlots[k].mGraphScale)))); - F32 ScaleY = (F32(getExtent().y) / (graphExtent.y*(1.00 + (mPlots[k].mGraphScale)))); + // Adjust scale to max value + 5% so we can see high value + F32 ScaleX = (F32(getExtent().x) / (graphExtent.x*(1.00 + (mPlots[k].mGraphScale)))); + F32 ScaleY = (F32(getExtent().y) / (graphExtent.y*(1.00 + (mPlots[k].mGraphScale)))); - if((mPlots[k].mGraphType == Point) || (mPlots[k].mGraphType == Polyline)) - { + if((mPlots[k].mGraphType == Point) || (mPlots[k].mGraphType == Polyline)) + { S32 posX; - S32 posY; - S32 lastPosX = 0; - S32 lastPosY = 0; - Point2F plotPoint; + S32 posY; + S32 lastPosX = 0; + S32 lastPosY = 0; + Point2F plotPoint; - S32 size = 32; + S32 size = 32; - for (S32 sample = 0; sample < mPlots[k].mGraphData.size(); sample++) - { - S32 temp; + for (S32 sample = 0; sample < mPlots[k].mGraphData.size(); sample++) + { + S32 temp; - temp = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample); + temp = (S32)(((F32)getExtent().x / (F32)mPlots[k].mGraphData.size()) * (F32)sample); - // calculate the point positions + // calculate the point positions plotPoint = getPlotPoint(k, sample); - posX = (S32)((plotPoint.x - mPlots[k].mGraphMin.x) * (ScaleX /(1.00 + mPlots[k].mGraphScale))); - posY = (getExtent().y) - (S32)((plotPoint.y - mPlots[k].mGraphMin.y) * ScaleY); + posX = (S32)((plotPoint.x - mPlots[k].mGraphMin.x) * (ScaleX /(1.00 + mPlots[k].mGraphScale))); + posY = (getExtent().y) - (S32)((plotPoint.y - mPlots[k].mGraphMin.y) * ScaleY); posX += getExtent().x * (mPlots[k].mGraphScale); - posY /= (1.00 + (mPlots[k].mGraphScale)); + posY /= (1.00 + (mPlots[k].mGraphScale)); posX = localToGlobalCoord(Point2I(posX, posY)).x; - posY = localToGlobalCoord(Point2I(posX, posY)).y; + posY = localToGlobalCoord(Point2I(posX, posY)).y; - // check if this isn't our first loop through, if it is we won't have starting points + // check if this isn't our first loop through, if it is we won't have starting points if(sample > 0) - { - pDrawUtil->drawLine( lastPosX, lastPosY , posX, posY , mPlots[k].mGraphColor ); - } else - { + { + pDrawUtil->drawLine( lastPosX, lastPosY , posX, posY , mPlots[k].mGraphColor ); + } else + { mPlots[k].mNutList.clear(); - } + } mPlots[k].mNutList.push_back( Point2F(posX, posY) ); - // store the last positions to be the starting points drawn into a line next loop - lastPosX = posX; - lastPosY = posY; + // store the last positions to be the starting points drawn into a line next loop + lastPosX = posX; + lastPosY = posY; //Con::printf("red %f green %f blue %f", mPlots[k].mGraphColor.red, mPlots[k].mGraphColor.green, mPlots[k].mGraphColor.blue); - if(mSelectedPoint != -1) - { - mLastSelectedPoint = mSelectedPoint; - } + if(mSelectedPoint != -1) + { + mLastSelectedPoint = mSelectedPoint; + } ColorI nutColor (mPlots[k].mGraphColor); - if(k == mSelectedPlot && sample == mLastSelectedPoint) + if(k == mSelectedPlot && sample == mLastSelectedPoint) { // grab the colors for the nut F32 red = mPlots[k].mGraphColor.red; @@ -224,51 +224,51 @@ void GuiParticleGraphCtrl::onRender(Point2I offset, const RectI &updateRect) } // draw the seleciton nut - drawNut( Point2I(posX, posY), 3, mOutlineColor, nutColor ); + drawNut( Point2I(posX, posY), 3, mOutlineColor, nutColor ); - if((mLastSelectedPoint != -1) || (mRenderAllPoints == true)) - { + if((mLastSelectedPoint != -1) || (mRenderAllPoints == true)) + { if((k == mSelectedPlot && sample == mLastSelectedPoint) || (mRenderAllPoints == true)) - { + { char number[32]; - Point2I comparePos = localToGlobalCoord(Point2I(getPosition().x, getPosition().y)); + Point2I comparePos = localToGlobalCoord(Point2I(getPosition().x, getPosition().y)); dSprintf(number, 32, "%4.3f %4.3f", plotPoint.x, plotPoint.y); S32 textWidth = (S32)font->getStrWidth((const UTF8*)number);; - textWidth /= 2; + textWidth /= 2; - if((((S32)posX - (textWidth/2)) < comparePos.x) || (((S32)posX - textWidth) <= 0)) - { + if((((S32)posX - (textWidth/2)) < comparePos.x) || (((S32)posX - textWidth) <= 0)) + { posX += (textWidth/1.5); - } else if((posX + (textWidth * 1.8)) > (comparePos.x + getExtent().x) || ((posX + textWidth) >= videoMode.resolution.x)) - { + } else if((posX + (textWidth * 1.8)) > (comparePos.x + getExtent().x) || ((posX + textWidth) >= videoMode.resolution.x)) + { posX -= (textWidth * 1.5); - } + } - if((((S32)posY) < comparePos.y) || (((S32)posY - textWidth) <= 0)) - { + if((((S32)posY) < comparePos.y) || (((S32)posY - textWidth) <= 0)) + { posY += 40; - } - - pDrawUtil->setBitmapModulation( profile->mFontColor ); - pDrawUtil->drawText( font, Point2I(posX, posY + 5) - Point2I(size >> 1, size), number ); - pDrawUtil->clearBitmapModulation(); - } - } - } - } - } + } + + pDrawUtil->setBitmapModulation( profile->mFontColor ); + pDrawUtil->drawText( font, Point2I(posX, posY + 5) - Point2I(size >> 1, size), number ); + pDrawUtil->clearBitmapModulation(); + } + } + } + } + } - if(mRenderNextGraphTooltip == true && mRenderGraphTooltip == true) - { + if(mRenderNextGraphTooltip == true && mRenderGraphTooltip == true) + { char argBuffer[1][32]; dSprintf(argBuffer[0], 32, "%s", getGraphName(mTooltipSelectedPlot)); - renderGraphTooltip(mCursorPos, argBuffer[0]); - } + renderGraphTooltip(mCursorPos, argBuffer[0]); + } } S32 GuiParticleGraphCtrl::addPlotPoint(S32 plotID, Point2F v, bool setAdded) @@ -302,44 +302,44 @@ S32 GuiParticleGraphCtrl::addPlotPoint(S32 plotID, Point2F v, bool setAdded) for(S32 i = 0; i < mPlots[plotID].mGraphData.size(); i++) { - if(mFabs(v.x - mPlots[plotID].mGraphData[i].x) < 0.001) - { - if(mAutoRemove == true) - { + if(mFabs(v.x - mPlots[plotID].mGraphData[i].x) < 0.001) + { + if(mAutoRemove == true) + { changePlotPoint(plotID, i, v); - plotChanged = true; - mPlotIndex = i; - } else - { + plotChanged = true; + mPlotIndex = i; + } else + { mPlotIndex = -1; - } - - plotAdded = true; - - break; - } else if(v.x < mPlots[plotID].mGraphData[i].x) - { + } + + plotAdded = true; + + break; + } else if(v.x < mPlots[plotID].mGraphData[i].x) + { insertPlotPoint(plotID, i, v); - plotAdded = true; - mPlotIndex = i; - break; - } + plotAdded = true; + mPlotIndex = i; + break; + } } if(plotAdded == false) { - mPlots[plotID].mGraphData.push_back( v ); - mPlotIndex = mPlots[plotID].mGraphData.size() - 1; + mPlots[plotID].mGraphData.push_back( v ); + mPlotIndex = mPlots[plotID].mGraphData.size() - 1; } if(mAutoMax == true) { // Keep record of maximum data value for scaling purposes. if(v.y > mPlots[plotID].mGraphMax.y) - mPlots[plotID].mGraphMax.y = v.y; + mPlots[plotID].mGraphMax.y = v.y; if(v.x > mPlots[plotID].mGraphMax.x) - mPlots[plotID].mGraphMax.x = v.x; + mPlots[plotID].mGraphMax.x = v.x; } if(plotChanged == true) @@ -348,8 +348,8 @@ S32 GuiParticleGraphCtrl::addPlotPoint(S32 plotID, Point2F v, bool setAdded) } else if(mPlotIndex != -1 && setAdded) { mPointWasAdded = true; - mAddedPoint = v; - mAddedPointIndex = mPlotIndex; + mAddedPoint = v; + mAddedPointIndex = mPlotIndex; } return mPlotIndex; @@ -367,10 +367,10 @@ void GuiParticleGraphCtrl::insertPlotPoint(S32 plotID, S32 i, Point2F v) { // Keep record of maximum data value for scaling purposes. if(v.y > mPlots[plotID].mGraphMax.y) - mPlots[plotID].mGraphMax.y = v.y; + mPlots[plotID].mGraphMax.y = v.y; if(v.x > mPlots[plotID].mGraphMax.x) - mPlots[plotID].mGraphMax.x = v.x; + mPlots[plotID].mGraphMax.x = v.x; } // Argument Buffer. @@ -477,7 +477,7 @@ S32 GuiParticleGraphCtrl::getPlotIndex(S32 plotID, F32 x, F32 y) compareY = mPlots[plotID].mGraphData[i].y; // - //if((x == compareX) && (y == compareY)) + //if((x == compareX) && (y == compareY)) if((mFabs(x - compareX) < 0.001) && (mFabs(y - compareY) < 0.001)) return i; } @@ -487,16 +487,16 @@ S32 GuiParticleGraphCtrl::getPlotIndex(S32 plotID, F32 x, F32 y) void GuiParticleGraphCtrl::setGraphType(S32 plotID, const char *graphType) { - AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!"); - if(!dStricmp(graphType,"Bar")) - mPlots[plotID].mGraphType = Bar; - else if(!dStricmp(graphType,"Filled")) - mPlots[plotID].mGraphType = Filled; - else if(!dStricmp(graphType,"Point")) - mPlots[plotID].mGraphType = Point; - else if(!dStricmp(graphType,"Polyline")) - mPlots[plotID].mGraphType = Polyline; - else AssertWarn(true, "Invalid graph type!"); + AssertFatal(plotID > -1 && plotID < MaxPlots, "Invalid plot specified!"); + if(!dStricmp(graphType,"Bar")) + mPlots[plotID].mGraphType = Bar; + else if(!dStricmp(graphType,"Filled")) + mPlots[plotID].mGraphType = Filled; + else if(!dStricmp(graphType,"Point")) + mPlots[plotID].mGraphType = Point; + else if(!dStricmp(graphType,"Polyline")) + mPlots[plotID].mGraphType = Polyline; + else AssertWarn(true, "Invalid graph type!"); } void GuiParticleGraphCtrl::setSelectedPlot(S32 plotID) @@ -565,8 +565,8 @@ void GuiParticleGraphCtrl::setRenderGraphTooltip(bool renderGraphTooltip) void GuiParticleGraphCtrl::drawNut(const Point2I &nut, S32 size, ColorI &outlineColor, ColorI &nutColor) { - // Fetch Draw Utility. - GFXDrawUtil* pDrawUtil = GFX->getDrawUtil(); + // Fetch Draw Utility. + GFXDrawUtil* pDrawUtil = GFX->getDrawUtil(); //Con::printf("r %d g %d b %d", nutColor.red, nutColor.green, nutColor.blue); S32 NUT_SIZE = size; @@ -588,17 +588,17 @@ Point2I GuiParticleGraphCtrl::findHitNut( Point2I hitPoint ) { for(S32 i = 0; i < MaxPlots; i++) { - if ( (mPlots[i].mGraphData.size() == 0) || (mPlots[i].mHidden == true)) + if ( (mPlots[i].mGraphData.size() == 0) || (mPlots[i].mHidden == true)) continue; for (S32 j = 0 ; j < mPlots[i].mNutList.size(); j++ ) { - if( inNut (Point2I( mPlots[i].mNutList[j].x, mPlots[i].mNutList[j].y), hitPoint.x, hitPoint.y) ) - { + if( inNut (Point2I( mPlots[i].mNutList[j].x, mPlots[i].mNutList[j].y), hitPoint.x, hitPoint.y) ) + { mTooltipSelectedPlot = i; - return Point2I(i,j); - } - } + return Point2I(i,j); + } + } } return Point2I(-1,-1); @@ -718,7 +718,7 @@ StringTableEntry GuiParticleGraphCtrl::getGraphName(S32 plotID) void GuiParticleGraphCtrl::onMouseMove(const GuiEvent &event) { mCursorPos = event.mousePoint; - + Point2I hitNut = findHitNut(event.mousePoint); if( hitNut != Point2I(-1,-1) ) @@ -745,8 +745,8 @@ void GuiParticleGraphCtrl::onMouseDown(const GuiEvent &event) if( hitNut != Point2I(-1,-1) ) { - if(event.mouseClickCount == 2) - { + if(event.mouseClickCount == 2) + { Point2F plotPoint = getPlotPoint(hitNut.x, hitNut.y); S32 point = removePlotPoint(hitNut.x, hitNut.y); @@ -755,31 +755,31 @@ void GuiParticleGraphCtrl::onMouseDown(const GuiEvent &event) dSprintf(argBuffer[0], 32, "%d", mSelectedPlot); dSprintf(argBuffer[1], 32, "%d", point); - dSprintf(argBuffer[2], 32, "%f %f", plotPoint.x, plotPoint.y); + dSprintf(argBuffer[2], 32, "%f %f", plotPoint.x, plotPoint.y); - + // Call Scripts. Con::executef(this, "onPlotPointRemoved", argBuffer[0], argBuffer[1], argBuffer[2]); - } else - { - setSelectedPlot(hitNut.x); + } else + { + setSelectedPlot(hitNut.x); setSelectedPoint(hitNut.y); - mOriginalSelectedPoint = hitNut.y; + mOriginalSelectedPoint = hitNut.y; - char argBuffer[32]; + char argBuffer[32]; dSprintf(argBuffer, 32, "%d", hitNut.y); // Call Scripts. Con::executef(this, "onPlotPointSelectedMouseDown", argBuffer); - } + } } else if( mSelectedPlot != -1 ) { - Point2F mousePos = convertToGraphCoord(mSelectedPlot, event.mousePoint); - mLastSelectedPoint = addPlotPoint(mSelectedPlot, mousePos); + Point2F mousePos = convertToGraphCoord(mSelectedPlot, event.mousePoint); + mLastSelectedPoint = addPlotPoint(mSelectedPlot, mousePos); - // Argument Buffer. + // Argument Buffer. char argBuffer[32]; dSprintf(argBuffer, 32, "%f %f", convertToGraphCoord(mSelectedPlot, event.mousePoint).x, convertToGraphCoord(mSelectedPlot, event.mousePoint).y); @@ -787,41 +787,41 @@ void GuiParticleGraphCtrl::onMouseDown(const GuiEvent &event) // Call Scripts. Con::executef(this, "onMouseDragged", argBuffer); - return; + return; } } void GuiParticleGraphCtrl::onMouseUp(const GuiEvent &event) { if(mSelectedPoint != -1) - mLastSelectedPoint = mSelectedPoint; + mLastSelectedPoint = mSelectedPoint; if(mPointWasAdded == true) { if(mSelectedPoint == -1) - { - // Argument Buffer. + { + // Argument Buffer. char argBuffer[3][32]; dSprintf(argBuffer[0], 32, "%d", mSelectedPlot); dSprintf(argBuffer[1], 32, "%f %f", mAddedPoint.x, mAddedPoint.y); - dSprintf(argBuffer[2], 32, "%d", mAddedPointIndex); + dSprintf(argBuffer[2], 32, "%d", mAddedPointIndex); // Call Scripts. Con::executef(this, "onPlotPointAdded", argBuffer[0], argBuffer[1], argBuffer[2]); - } else - { + } else + { // Argument Buffer. char argBuffer[4][32]; dSprintf(argBuffer[0], 32, "%d", mSelectedPlot); dSprintf(argBuffer[1], 32, "%f %f", mAddedPoint.x, mAddedPoint.y); - dSprintf(argBuffer[2], 32, "%d", mOriginalSelectedPoint); - dSprintf(argBuffer[3], 32, "%d", mAddedPointIndex); + dSprintf(argBuffer[2], 32, "%d", mOriginalSelectedPoint); + dSprintf(argBuffer[3], 32, "%d", mAddedPointIndex); // Call Scripts. Con::executef(this, "onPlotPointChangedUp", argBuffer[0], argBuffer[1], argBuffer[2], argBuffer[3]); - } + } } mPointWasAdded = false; @@ -835,37 +835,37 @@ void GuiParticleGraphCtrl::onMouseDragged(const GuiEvent &event) if(mSelectedPoint != -1) { - Point2F mousePos = convertToGraphCoord(mSelectedPlot, event.mousePoint); + Point2F mousePos = convertToGraphCoord(mSelectedPlot, event.mousePoint); if(mPointXMovementClamped == true) - { + { F32 prevXPos = getPlotPoint(mSelectedPlot, mSelectedPoint).x; - if(mousePos.x != prevXPos) - { - mousePos.x = prevXPos; - } - } + if(mousePos.x != prevXPos) + { + mousePos.x = prevXPos; + } + } - removePlotPoint(mSelectedPlot, mSelectedPoint); - S32 point = addPlotPoint(mSelectedPlot, mousePos); + removePlotPoint(mSelectedPlot, mSelectedPoint); + S32 point = addPlotPoint(mSelectedPlot, mousePos); if(point != -1) - { + { setSelectedPoint(point); - mLastMousePos = mousePos; + mLastMousePos = mousePos; // Argument Buffer. char argBuffer[3][32]; dSprintf(argBuffer[0], 32, "%d", mSelectedPlot); dSprintf(argBuffer[1], 32, "%f %f", mAddedPoint.x, mAddedPoint.y); - dSprintf(argBuffer[2], 32, "%d", point); + dSprintf(argBuffer[2], 32, "%d", point); // Call Scripts. Con::executef(this, "onPlotPointChangedMove", argBuffer[0], argBuffer[1], argBuffer[2]); - } else - { + } else + { point = addPlotPoint(mSelectedPlot, mLastMousePos); - } + } } // Argument Buffer. @@ -891,7 +891,7 @@ void GuiParticleGraphCtrl::onRightMouseDown(const GuiEvent &event) dSprintf(argBuffer[0], 32, "%d", mSelectedPlot); dSprintf(argBuffer[1], 32, "%d", point); - dSprintf(argBuffer[2], 32, "%f %f", plotPoint.x, plotPoint.y); + dSprintf(argBuffer[2], 32, "%f %f", plotPoint.x, plotPoint.y); // Call Scripts. Con::executef(this, "onPlotPointRemoved", argBuffer[0], argBuffer[1], argBuffer[2]); @@ -912,12 +912,12 @@ void GuiParticleGraphCtrl::onRightMouseDragged(const GuiEvent &event) Point2F plotPoint = getPlotPoint(hitNut.x, hitNut.y); S32 point = removePlotPoint(hitNut.x, hitNut.y); - // Argument Buffer. + // Argument Buffer. char argBuffer[3][32]; dSprintf(argBuffer[0], 32, "%d", mSelectedPlot); dSprintf(argBuffer[1], 32, "%d", point); - dSprintf(argBuffer[2], 32, "%f %f", plotPoint.x, plotPoint.y); + dSprintf(argBuffer[2], 32, "%f %f", plotPoint.x, plotPoint.y); // Call Scripts. Con::executef(this, "onPlotPointRemoved", argBuffer[0], argBuffer[1], argBuffer[2]); @@ -987,12 +987,12 @@ bool GuiParticleGraphCtrl::renderGraphTooltip(Point2I cursorPos, StringTableEntr RectI rect(offset, textBounds); GFX->setClipRect(rect); - // Fetch Draw Utility. - GFXDrawUtil* pDrawUtil = GFX->getDrawUtil(); + // Fetch Draw Utility. + GFXDrawUtil* pDrawUtil = GFX->getDrawUtil(); // Draw Filler bit, then border on top of that - pDrawUtil->drawRectFill(rect, ColorI(mTooltipProfile->mFillColor.red, mTooltipProfile->mFillColor.green, mTooltipProfile->mFillColor.blue, 200) ); - pDrawUtil->drawRect( rect, mTooltipProfile->mBorderColor ); + pDrawUtil->drawRectFill(rect, ColorI(mTooltipProfile->mFillColor.red, mTooltipProfile->mFillColor.green, mTooltipProfile->mFillColor.blue, 200) ); + pDrawUtil->drawRect( rect, mTooltipProfile->mBorderColor ); // Draw the text centered in the tool tip box pDrawUtil->setBitmapModulation( mTooltipProfile->mFontColor ); @@ -1006,102 +1006,102 @@ bool GuiParticleGraphCtrl::renderGraphTooltip(Point2I cursorPos, StringTableEntr DefineConsoleMethod(GuiParticleGraphCtrl, setSelectedPoint, void, (S32 point), , "(int point)" "Set the selected point on the graph.\n" - "@return No return value") + "@return No return value") { if(point >= object->mPlots[object->mSelectedPlot].mGraphData.size() || point < 0) { - Con::errorf("Invalid point to select."); - return; + Con::errorf("Invalid point to select."); + return; } object->setSelectedPoint( point ); } DefineConsoleMethod(GuiParticleGraphCtrl, setSelectedPlot, void, (S32 plotID), , "(int plotID)" "Set the selected plot (a.k.a. graph)." - "@return No return value" ) + "@return No return value" ) { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); - return; + Con::errorf("Invalid plotID."); + return; } object->setSelectedPlot( plotID ); } DefineConsoleMethod(GuiParticleGraphCtrl, clearGraph, void, (S32 plotID), , "(int plotID)" "Clear the graph of the given plot." - "@return No return value") + "@return No return value") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); - return; + Con::errorf("Invalid plotID."); + return; } object->clearGraph( plotID ); } DefineConsoleMethod(GuiParticleGraphCtrl, clearAllGraphs, void, (), , "()" "Clear all of the graphs." - "@return No return value") + "@return No return value") { object->clearAllGraphs(); } DefineConsoleMethod(GuiParticleGraphCtrl, addPlotPoint, S32, (S32 plotID, F32 x, F32 y, bool setAdded), (true), "(int plotID, float x, float y, bool setAdded = true;)" "Add a data point to the given plot." - "@return") + "@return") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); - return -2; + Con::errorf("Invalid plotID."); + return -2; } return object->addPlotPoint( plotID, Point2F(x, y), setAdded); } DefineConsoleMethod(GuiParticleGraphCtrl, insertPlotPoint, void, (S32 plotID, S32 i, F32 x, F32 y), , "(int plotID, int i, float x, float y)\n" "Insert a data point to the given plot and plot position.\n" - "@param plotID The plot you want to access\n" - "@param i The data point.\n" - "@param x,y The plot position.\n" - "@return No return value.") + "@param plotID The plot you want to access\n" + "@param i The data point.\n" + "@param x,y The plot position.\n" + "@return No return value.") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); - return; + Con::errorf("Invalid plotID."); + return; } object->insertPlotPoint( plotID, i, Point2F(x, y)); } DefineConsoleMethod(GuiParticleGraphCtrl, changePlotPoint, S32, (S32 plotID, S32 i, F32 x, F32 y), , "(int plotID, int i, float x, float y)" "Change a data point to the given plot and plot position.\n" - "@param plotID The plot you want to access\n" - "@param i The data point.\n" - "@param x,y The plot position.\n" - "@return No return value.") + "@param plotID The plot you want to access\n" + "@param i The data point.\n" + "@param x,y The plot position.\n" + "@return No return value.") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); - return -1; + Con::errorf("Invalid plotID."); + return -1; } return object->changePlotPoint( plotID, i, Point2F(x, y)); } DefineConsoleMethod(GuiParticleGraphCtrl, getSelectedPlot, S32, (), , "() " "Gets the selected Plot (a.k.a. graph).\n" - "@return The plot's ID.") + "@return The plot's ID.") { return object->getSelectedPlot(); } DefineConsoleMethod(GuiParticleGraphCtrl, getSelectedPoint, S32, (), , "()" "Gets the selected Point on the Plot (a.k.a. graph)." - "@return The last selected point ID") + "@return The last selected point ID") { - return object->getSelectedPoint(); + return object->getSelectedPoint(); } DefineConsoleMethod(GuiParticleGraphCtrl, isExistingPoint, bool, (S32 plotID, S32 samples), , "(int plotID, int samples)" @@ -1110,27 +1110,27 @@ DefineConsoleMethod(GuiParticleGraphCtrl, isExistingPoint, bool, (S32 plotID, S3 if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); + Con::errorf("Invalid plotID."); } if(samples > object->MaxDataPoints) { - Con::errorf("Invalid sample."); + Con::errorf("Invalid sample."); } return object->isExistingPoint(plotID, samples); } DefineConsoleMethod(GuiParticleGraphCtrl, getPlotPoint, Point2F, (S32 plotID, S32 samples), , "(int plotID, int samples)" "Get a data point from the plot specified, samples from the start of the graph." - "@return The data point ID") + "@return The data point ID") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); + Con::errorf("Invalid plotID."); } if(samples > object->MaxDataPoints) { - Con::errorf("Invalid sample."); + Con::errorf("Invalid sample."); } @@ -1139,26 +1139,26 @@ DefineConsoleMethod(GuiParticleGraphCtrl, getPlotPoint, Point2F, (S32 plotID, S3 DefineConsoleMethod(GuiParticleGraphCtrl, getPlotIndex, S32, (S32 plotID, F32 x, F32 y), , "(int plotID, float x, float y)\n" "Gets the index of the point passed on the plotID passed (graph ID).\n" - "@param plotID The plot you wish to check.\n" - "@param x,y The coordinates of the point to get.\n" - "@return Returns the index of the point.\n") + "@param plotID The plot you wish to check.\n" + "@param x,y The coordinates of the point to get.\n" + "@return Returns the index of the point.\n") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); + Con::errorf("Invalid plotID."); } return object->getPlotIndex(plotID, x, y); } DefineConsoleMethod(GuiParticleGraphCtrl, getGraphColor, ColorF, (S32 plotID), , "(int plotID)" "Get the color of the graph passed." - "@return Returns the color of the graph as a string of RGB values formatted as \"R G B\"") + "@return Returns the color of the graph as a string of RGB values formatted as \"R G B\"") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); + Con::errorf("Invalid plotID."); } return object->getGraphColor(plotID); @@ -1167,24 +1167,24 @@ DefineConsoleMethod(GuiParticleGraphCtrl, getGraphColor, ColorF, (S32 plotID), , DefineConsoleMethod(GuiParticleGraphCtrl, getGraphMin, Point2F, (S32 plotID), , "(int plotID) " "Get the minimum values of the graph ranges.\n" - "@return Returns the minimum of the range formatted as \"x-min y-min\"") + "@return Returns the minimum of the range formatted as \"x-min y-min\"") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); + Con::errorf("Invalid plotID."); } return object->getGraphMin(plotID); } DefineConsoleMethod(GuiParticleGraphCtrl, getGraphMax, Point2F, (S32 plotID), , "(int plotID) " - "Get the maximum values of the graph ranges.\n" - "@return Returns the maximum of the range formatted as \"x-max y-max\"") + "Get the maximum values of the graph ranges.\n" + "@return Returns the maximum of the range formatted as \"x-max y-max\"") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); + Con::errorf("Invalid plotID."); } return object->getGraphMax(plotID); @@ -1192,12 +1192,12 @@ DefineConsoleMethod(GuiParticleGraphCtrl, getGraphMax, Point2F, (S32 plotID), , DefineConsoleMethod(GuiParticleGraphCtrl, getGraphName, const char*, (S32 plotID), , "(int plotID) " "Get the name of the graph passed.\n" - "@return Returns the name of the plot") + "@return Returns the name of the plot") { if(plotID > object->MaxPlots) { - Con::errorf("Invalid plotID."); + Con::errorf("Invalid plotID."); } const U32 bufSize = 64; @@ -1208,170 +1208,170 @@ DefineConsoleMethod(GuiParticleGraphCtrl, getGraphName, const char*, (S32 plotID } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphMin, void, (S32 plotID, F32 minX, F32 minY), , "(int plotID, float minX, float minY) " - "Set the min values of the graph of plotID.\n" - "@param plotID The plot to modify\n" - "@param minX,minY The minimum bound of the value range.\n" - "@return No return value.") + "Set the min values of the graph of plotID.\n" + "@param plotID The plot to modify\n" + "@param minX,minY The minimum bound of the value range.\n" + "@return No return value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphMin(plotID, Point2F(minX, minY)); + object->setGraphMin(plotID, Point2F(minX, minY)); } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphMinX, void, (S32 plotID, F32 minX), , "(int plotID, float minX) " - "Set the min X value of the graph of plotID.\n" - "@param plotID The plot to modify.\n" - "@param minX The minimum x value.\n" - "@return No return Value.") + "Set the min X value of the graph of plotID.\n" + "@param plotID The plot to modify.\n" + "@param minX The minimum x value.\n" + "@return No return Value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphMinX(plotID, minX); + object->setGraphMinX(plotID, minX); } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphMinY, void, (S32 plotID, F32 minX), , "(int plotID, float minY) " - "Set the min Y value of the graph of plotID." - "@param plotID The plot to modify.\n" - "@param minY The minimum y value.\n" - "@return No return Value.") + "Set the min Y value of the graph of plotID." + "@param plotID The plot to modify.\n" + "@param minY The minimum y value.\n" + "@return No return Value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphMinY(plotID, minX); + object->setGraphMinY(plotID, minX); } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphMax, void, (S32 plotID, F32 maxX, F32 maxY), , "(int plotID, float maxX, float maxY) " - "Set the max values of the graph of plotID." - "@param plotID The plot to modify\n" - "@param maxX,maxY The maximum bound of the value range.\n" - "@return No return value.") + "Set the max values of the graph of plotID." + "@param plotID The plot to modify\n" + "@param maxX,maxY The maximum bound of the value range.\n" + "@return No return value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphMax(plotID, Point2F(maxX, maxY)); + object->setGraphMax(plotID, Point2F(maxX, maxY)); } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphMaxX, void, (S32 plotID, F32 maxX), , "(int plotID, float maxX)" - "Set the max X value of the graph of plotID." - "@param plotID The plot to modify.\n" - "@param maxX The maximum x value.\n" - "@return No return Value.") + "Set the max X value of the graph of plotID." + "@param plotID The plot to modify.\n" + "@param maxX The maximum x value.\n" + "@return No return Value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphMaxX(plotID, maxX); + object->setGraphMaxX(plotID, maxX); } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphMaxY, void, (S32 plotID, F32 maxX), , "(int plotID, float maxY)" - "Set the max Y value of the graph of plotID." - "@param plotID The plot to modify.\n" - "@param maxY The maximum y value.\n" - "@return No return Value.") + "Set the max Y value of the graph of plotID." + "@param plotID The plot to modify.\n" + "@param maxY The maximum y value.\n" + "@return No return Value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphMaxY(plotID, maxX); + object->setGraphMaxY(plotID, maxX); } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphHidden, void, (S32 plotID, bool isHidden), , "(int plotID, bool isHidden)" - "Set whether the graph number passed is hidden or not." - "@return No return value.") + "Set whether the graph number passed is hidden or not." + "@return No return value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphHidden(plotID, isHidden); + object->setGraphHidden(plotID, isHidden); } DefineConsoleMethod(GuiParticleGraphCtrl, setAutoGraphMax, void, (bool autoMax), , "(bool autoMax) " - "Set whether the max will automatically be set when adding points " - "(ie if you add a value over the current max, the max is increased to that value).\n" - "@return No return value.") + "Set whether the max will automatically be set when adding points " + "(ie if you add a value over the current max, the max is increased to that value).\n" + "@return No return value.") { - object->setAutoGraphMax(autoMax); + object->setAutoGraphMax(autoMax); } DefineConsoleMethod(GuiParticleGraphCtrl, setAutoRemove, void, (bool autoRemove), , "(bool autoRemove) " - "Set whether or not a point should be deleted when you drag another one over it." - "@return No return value.") + "Set whether or not a point should be deleted when you drag another one over it." + "@return No return value.") { - object->setAutoRemove(autoRemove); + object->setAutoRemove(autoRemove); } DefineConsoleMethod(GuiParticleGraphCtrl, setRenderAll, void, (bool autoRemove), , "(bool renderAll)" - "Set whether or not a position should be rendered on every point or just the last selected." - "@return No return value.") + "Set whether or not a position should be rendered on every point or just the last selected." + "@return No return value.") { - object->setRenderAll(autoRemove); + object->setRenderAll(autoRemove); } DefineConsoleMethod(GuiParticleGraphCtrl, setPointXMovementClamped, void, (bool autoRemove), , "(bool clamped)" - "Set whether the x position of the selected graph point should be clamped" - "@return No return value.") + "Set whether the x position of the selected graph point should be clamped" + "@return No return value.") { - object->setPointXMovementClamped(autoRemove); + object->setPointXMovementClamped(autoRemove); } DefineConsoleMethod(GuiParticleGraphCtrl, setRenderGraphTooltip, void, (bool autoRemove), , "(bool renderGraphTooltip)" - "Set whether or not to render the graph tooltip." - "@return No return value.") + "Set whether or not to render the graph tooltip." + "@return No return value.") { - object->setRenderGraphTooltip(autoRemove); + object->setRenderGraphTooltip(autoRemove); } DefineConsoleMethod(GuiParticleGraphCtrl, setGraphName, void, (S32 plotID, const char * graphName), , "(int plotID, string graphName) " - "Set the name of the given plot.\n" - "@param plotID The plot to modify.\n" - "@param graphName The name to set on the plot.\n" - "@return No return value.") + "Set the name of the given plot.\n" + "@param plotID The plot to modify.\n" + "@param graphName The name to set on the plot.\n" + "@return No return value.") { - if(plotID > object->MaxPlots) - { - Con::errorf("Invalid plotID."); - return; - } + if(plotID > object->MaxPlots) + { + Con::errorf("Invalid plotID."); + return; + } - object->setGraphName(plotID, graphName); + object->setGraphName(plotID, graphName); } DefineConsoleMethod(GuiParticleGraphCtrl, resetSelectedPoint, void, (), , "()" - "This will reset the currently selected point to nothing." - "@return No return value.") + "This will reset the currently selected point to nothing." + "@return No return value.") { - object->resetSelectedPoint(); + object->resetSelectedPoint(); } diff --git a/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp b/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp index 735607224..2b122f540 100644 --- a/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp +++ b/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp @@ -65,10 +65,10 @@ ConsoleDocClass( GuiChunkedBitmapCtrl, void GuiChunkedBitmapCtrl::initPersistFields() { - addGroup("GuiChunkedBitmapCtrl"); + addGroup("GuiChunkedBitmapCtrl"); addField( "bitmap", TypeFilename, Offset( mBitmapName, GuiChunkedBitmapCtrl ), "This is the bitmap to render to the control." ); addField( "useVariable", TypeBool, Offset( mUseVariable, GuiChunkedBitmapCtrl ), "This decides whether to use the \"bitmap\" file " - "or a bitmap stored in \"variable\""); + "or a bitmap stored in \"variable\""); addField( "tile", TypeBool, Offset( mTile, GuiChunkedBitmapCtrl ), "This is no longer in use"); endGroup("GuiChunkedBitmapCtrl"); Parent::initPersistFields(); diff --git a/Engine/source/gui/worldEditor/undoActions.cpp b/Engine/source/gui/worldEditor/undoActions.cpp index 6c71a0831..94495d89e 100644 --- a/Engine/source/gui/worldEditor/undoActions.cpp +++ b/Engine/source/gui/worldEditor/undoActions.cpp @@ -32,9 +32,9 @@ IMPLEMENT_CONOBJECT( MECreateUndoAction ); ConsoleDocClass( MECreateUndoAction, - "@brief Material Editor create undo instance\n\n" - "Not intended for game development, for editors or internal use only.\n\n " - "@internal"); + "@brief Material Editor create undo instance\n\n" + "Not intended for game development, for editors or internal use only.\n\n " + "@internal"); MECreateUndoAction::MECreateUndoAction( const UTF8* actionName ) : UndoAction( actionName ) @@ -62,7 +62,7 @@ DefineEngineMethod( MECreateUndoAction, addObject, void, ( SimObject* obj),, "Add the object being created to an undo action.\n" "@param obj Object being created you want to create the undo for.") { - if (obj) + if (obj) object->addObject( obj ); } @@ -117,9 +117,9 @@ void MECreateUndoAction::redo() IMPLEMENT_CONOBJECT( MEDeleteUndoAction ); ConsoleDocClass( MEDeleteUndoAction, - "@brief Material Editor delete undo instance\n\n" - "Not intended for game development, for editors or internal use only.\n\n " - "@internal"); + "@brief Material Editor delete undo instance\n\n" + "Not intended for game development, for editors or internal use only.\n\n " + "@internal"); MEDeleteUndoAction::MEDeleteUndoAction( const UTF8 *actionName ) : UndoAction( actionName ) @@ -169,7 +169,7 @@ DefineEngineMethod( MEDeleteUndoAction, deleteObject, void, ( SimObject* obj),, "Delete the object and add it to the undo action.\n" "@param obj Object to delete and add to the undo action.") { - if (obj) + if (obj) object->deleteObject( obj ); } @@ -210,9 +210,9 @@ void MEDeleteUndoAction::redo() IMPLEMENT_CONOBJECT( InspectorFieldUndoAction ); ConsoleDocClass( InspectorFieldUndoAction, - "@brief Inspector Field undo action instance\n\n" - "Not intended for game development, for editors or internal use only.\n\n " - "@internal"); + "@brief Inspector Field undo action instance\n\n" + "Not intended for game development, for editors or internal use only.\n\n " + "@internal"); InspectorFieldUndoAction::InspectorFieldUndoAction() { diff --git a/Engine/source/lighting/lightManager.cpp b/Engine/source/lighting/lightManager.cpp index f53f5284d..fdc9e7c50 100644 --- a/Engine/source/lighting/lightManager.cpp +++ b/Engine/source/lighting/lightManager.cpp @@ -306,7 +306,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, GFXShaderConstHandle *lightInvRadiusSqSC, GFXShaderConstHandle *lightSpotDirSC, GFXShaderConstHandle *lightSpotAngleSC, - GFXShaderConstHandle *lightSpotFalloffSC, + GFXShaderConstHandle *lightSpotFalloffSC, GFXShaderConstBuffer *shaderConsts ) { PROFILE_SCOPE( LightManager_Update4LightConsts ); @@ -317,7 +317,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, lightInvRadiusSqSC->isValid() || lightSpotDirSC->isValid() || lightSpotAngleSC->isValid() || - lightSpotFalloffSC->isValid() ) + lightSpotFalloffSC->isValid() ) { PROFILE_SCOPE( LightManager_Update4LightConsts_setLights ); @@ -326,7 +326,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, static AlignedArray lightColors( 4, sizeof( Point4F ) ); static Point4F lightInvRadiusSq; static Point4F lightSpotAngle; - static Point4F lightSpotFalloff; + static Point4F lightSpotFalloff; F32 range; // Need to clear the buffers so that we don't leak @@ -359,10 +359,10 @@ void LightManager::_update4LightConsts( const SceneData &sgData, lightSpotDirs[2][i] = lightDir.z; if ( light->getType() == LightInfo::Spot ) - { + { lightSpotAngle[i] = mCos( mDegToRad( light->getOuterConeAngle() / 2.0f ) ); - lightSpotFalloff[i] = 1.0f / getMax( F32_MIN, mCos( mDegToRad( light->getInnerConeAngle() / 2.0f ) ) - lightSpotAngle[i] ); - } + lightSpotFalloff[i] = 1.0f / getMax( F32_MIN, mCos( mDegToRad( light->getInnerConeAngle() / 2.0f ) ) - lightSpotAngle[i] ); + } // Prescale the light color by the brightness to // avoid doing this in the shader. @@ -379,7 +379,7 @@ void LightManager::_update4LightConsts( const SceneData &sgData, shaderConsts->setSafe( lightSpotDirSC, lightSpotDirs ); shaderConsts->setSafe( lightSpotAngleSC, lightSpotAngle ); - shaderConsts->setSafe( lightSpotFalloffSC, lightSpotFalloff ); + shaderConsts->setSafe( lightSpotFalloffSC, lightSpotFalloff ); } diff --git a/Engine/source/navigation/navMesh.cpp b/Engine/source/navigation/navMesh.cpp index 64c20a93b..2d4b0ad7e 100644 --- a/Engine/source/navigation/navMesh.cpp +++ b/Engine/source/navigation/navMesh.cpp @@ -1143,10 +1143,10 @@ void NavMesh::buildLinks() // Iterate over links for(U32 j = 0; j < mLinkIDs.size(); j++) { - if (mLinksUnsynced[j]) - { + if (mLinksUnsynced[j]) + { if(tile.box.isContained(getLinkStart(j)) || - tile.box.isContained(getLinkEnd(j))) + tile.box.isContained(getLinkEnd(j))) { // Mark tile for build. mDirtyTiles.push_back_unique(i); @@ -1161,7 +1161,7 @@ void NavMesh::buildLinks() } } } - } + } if(mDirtyTiles.size()) ctx->startTimer(RC_TIMER_TOTAL); } diff --git a/Engine/source/platform/menus/popupMenu.cpp b/Engine/source/platform/menus/popupMenu.cpp index ee8d75a82..a7fc2e989 100644 --- a/Engine/source/platform/menus/popupMenu.cpp +++ b/Engine/source/platform/menus/popupMenu.cpp @@ -54,7 +54,7 @@ PopupMenu::PopupMenu() : mCanvas(NULL) mBarTitle = StringTable->insert(""); mIsPopup = false; - mPopupGUID = sMaxPopupGUID++; + mPopupGUID = sMaxPopupGUID++; } PopupMenu::~PopupMenu() @@ -126,10 +126,10 @@ void PopupMenu::onMenuSelect() //----------------------------------------------------------------------------- void PopupMenu::handleSelectEvent(U32 popID, U32 command) -{ - if (popID == mPopupGUID && canHandleID(command)) - if (handleSelect(command)) - smSelectionEventHandled = true; +{ + if (popID == mPopupGUID && canHandleID(command)) + if (handleSelect(command)) + smSelectionEventHandled = true; } //----------------------------------------------------------------------------- @@ -138,8 +138,8 @@ void PopupMenu::onAttachToMenuBar(GuiCanvas *canvas, S32 pos, const char *title) { mCanvas = canvas; - // Attached menus must be notified of menu events - smPopupMenuEvent.notify(this, &PopupMenu::handleSelectEvent); + // Attached menus must be notified of menu events + smPopupMenuEvent.notify(this, &PopupMenu::handleSelectEvent); // Pass on to sub menus for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) @@ -160,8 +160,8 @@ void PopupMenu::onRemoveFromMenuBar(GuiCanvas *canvas) { mCanvas = NULL; - // We are no longer interested in select events, remove ourselves from the notification list in a safe way - Sim::postCurrentEvent(this, new PopUpNotifyRemoveEvent()); + // We are no longer interested in select events, remove ourselves from the notification list in a safe way + Sim::postCurrentEvent(this, new PopUpNotifyRemoveEvent()); // Pass on to sub menus for(SimSet::iterator i = mSubmenus->begin();i != mSubmenus->end();++i) diff --git a/Engine/source/platform/profiler.cpp b/Engine/source/platform/profiler.cpp index c978b9ac2..cde917b8d 100644 --- a/Engine/source/platform/profiler.cpp +++ b/Engine/source/platform/profiler.cpp @@ -724,37 +724,37 @@ DefineEngineFunction( profilerMarkerEnable, void, ( const char* markerName, bool //----------------------------------------------------------------------------- DefineEngineFunction( profilerEnable, void, ( bool enable ),, - "@brief Enables or disables the profiler.\n\n" - "Data is only gathered while the profiler is enabled.\n\n" - "@note Profiler is not available in shipping builds.\n" - "T3D has predefined profiling areas surrounded by markers, " - "but you may need to define additional markers (in C++) around areas you wish to profile," - " by using the PROFILE_START( markerName ); and PROFILE_END(); macros.\n\n" - "@ingroup Debugging\n" ) + "@brief Enables or disables the profiler.\n\n" + "Data is only gathered while the profiler is enabled.\n\n" + "@note Profiler is not available in shipping builds.\n" + "T3D has predefined profiling areas surrounded by markers, " + "but you may need to define additional markers (in C++) around areas you wish to profile," + " by using the PROFILE_START( markerName ); and PROFILE_END(); macros.\n\n" + "@ingroup Debugging\n" ) { if(gProfiler) gProfiler->enable(enable); } DefineEngineFunction(profilerDump, void, (),, - "@brief Dumps current profiling stats to the console window.\n\n" - "@note Markers disabled with profilerMarkerEnable() will be skipped over. " - "If the profiler is currently running, it will be disabled.\n" - "@ingroup Debugging") + "@brief Dumps current profiling stats to the console window.\n\n" + "@note Markers disabled with profilerMarkerEnable() will be skipped over. " + "If the profiler is currently running, it will be disabled.\n" + "@ingroup Debugging") { if(gProfiler) gProfiler->dumpToConsole(); } DefineEngineFunction( profilerDumpToFile, void, ( const char* fileName ),, - "@brief Dumps current profiling stats to a file.\n\n" - "@note If the profiler is currently running, it will be disabled.\n" - "@param fileName Name and path of file to save profiling stats to. Must use forward slashes (/). " - "Will attempt to create the file if it does not already exist.\n" - "@tsexample\n" - "profilerDumpToFile( \"C:/Torque/log1.txt\" );\n" - "@endtsexample\n\n" - "@ingroup Debugging" ) + "@brief Dumps current profiling stats to a file.\n\n" + "@note If the profiler is currently running, it will be disabled.\n" + "@param fileName Name and path of file to save profiling stats to. Must use forward slashes (/). " + "Will attempt to create the file if it does not already exist.\n" + "@tsexample\n" + "profilerDumpToFile( \"C:/Torque/log1.txt\" );\n" + "@endtsexample\n\n" + "@ingroup Debugging" ) { if(gProfiler) gProfiler->dumpToFile(fileName); @@ -762,9 +762,9 @@ DefineEngineFunction( profilerDumpToFile, void, ( const char* fileName ),, DefineEngineFunction( profilerReset, void, (),, "@brief Resets the profiler, clearing it of all its data.\n\n" - "If the profiler is currently running, it will first be disabled. " - "All markers will retain their current enabled/disabled status.\n\n" - "@ingroup Debugging" ) + "If the profiler is currently running, it will first be disabled. " + "All markers will retain their current enabled/disabled status.\n\n" + "@ingroup Debugging" ) { if(gProfiler) gProfiler->reset(); diff --git a/Engine/source/platformMac/macFileIO.mm b/Engine/source/platformMac/macFileIO.mm index 26dca66bb..7fbc3408d 100644 --- a/Engine/source/platformMac/macFileIO.mm +++ b/Engine/source/platformMac/macFileIO.mm @@ -839,7 +839,7 @@ static bool recurseDumpDirectories(const char *basePath, const char *subPath, Ve while (d = readdir(dip)) { - bool isDir; + bool isDir; isDir = false; if (d->d_type == DT_UNKNOWN) { diff --git a/Engine/source/renderInstance/renderPrePassMgr.cpp b/Engine/source/renderInstance/renderPrePassMgr.cpp index 6175c3eec..81f8782eb 100644 --- a/Engine/source/renderInstance/renderPrePassMgr.cpp +++ b/Engine/source/renderInstance/renderPrePassMgr.cpp @@ -843,7 +843,7 @@ void ProcessedPrePassMaterial::addStateBlockDesc(const GFXStateBlockDesc& desc) if ( isTranslucent ) { prePassStateBlock.setBlend( true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha ); - prePassStateBlock.setColorWrites(false, false, false, true); + prePassStateBlock.setColorWrites(false, false, false, true); } // Enable z reads, but only enable zwrites if we're not translucent. diff --git a/Engine/source/scene/sceneContainer.cpp b/Engine/source/scene/sceneContainer.cpp index b4dd2058c..298519655 100644 --- a/Engine/source/scene/sceneContainer.cpp +++ b/Engine/source/scene/sceneContainer.cpp @@ -892,7 +892,7 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en *info = ri; info->point.interpolate(start, end, info->t); currentT = ri.t; - info->distance = (start - info->point).len(); + info->distance = (start - info->point).len(); } } } @@ -991,7 +991,7 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en *info = ri; info->point.interpolate(start, end, info->t); currentT = ri.t; - info->distance = (start - info->point).len(); + info->distance = (start - info->point).len(); } } } @@ -1088,7 +1088,7 @@ bool SceneContainer::_castRay( U32 type, const Point3F& start, const Point3F& en *info = ri; info->point.interpolate(start, end, info->t); currentT = ri.t; - info->distance = (start - info->point).len(); + info->distance = (start - info->point).len(); } } } diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index e4455d458..27407e502 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -36,138 +36,138 @@ IMPLEMENT_CONOBJECT(ActionMap); ConsoleDocClass( ActionMap, - "@brief ActionMaps assign platform input events to console commands.\n\n" + "@brief ActionMaps assign platform input events to console commands.\n\n" - "Any platform input event can be bound in a single, generic way. In theory, the game doesn't need to know if the event came from the keyboard, mouse, joystick " - "or some other input device. This allows users of the game to map keys and actions according to their own preferences. " - "Game action maps are arranged in a stack for processing so individual parts of the game can define specific " - "actions. For example, when the player jumps into a vehicle it could push a vehicle action map and pop the default player action map.\n\n" + "Any platform input event can be bound in a single, generic way. In theory, the game doesn't need to know if the event came from the keyboard, mouse, joystick " + "or some other input device. This allows users of the game to map keys and actions according to their own preferences. " + "Game action maps are arranged in a stack for processing so individual parts of the game can define specific " + "actions. For example, when the player jumps into a vehicle it could push a vehicle action map and pop the default player action map.\n\n" - "@section ActionMap_creation Creating an ActionMap\n" + "@section ActionMap_creation Creating an ActionMap\n" - "The input system allows for the creation of multiple ActionMaps, so long as they have unique names and do not already exist. It's a simple " - "three step process.\n\n" - "1. Check to see if the ActionMap exists\n" - "2. Delete it if it exists\n" - "3. Instantiate the ActionMap\n\n" + "The input system allows for the creation of multiple ActionMaps, so long as they have unique names and do not already exist. It's a simple " + "three step process.\n\n" + "1. Check to see if the ActionMap exists\n" + "2. Delete it if it exists\n" + "3. Instantiate the ActionMap\n\n" - "The following is an example of how to create a new ActionMap:\n" + "The following is an example of how to create a new ActionMap:\n" - "@tsexample\n" - "if ( isObject( moveMap ) )\n" - " moveMap.delete();\n" - "new ActionMap(moveMap);" - "@endtsexample\n\n\n" - - "@section ActionMap_binding Binding Functions\n" - "Once you have created an ActionMap, you can start binding functionality to events. Currently, Torque 3D supports the following devices out of the box\n\n" - "* Mouse\n\n" - "* Keyboard\n\n" - "* Joystick/Gamepad\n\n" - "* Xbox 360 Controller\n\n" + "@tsexample\n" + "if ( isObject( moveMap ) )\n" + " moveMap.delete();\n" + "new ActionMap(moveMap);" + "@endtsexample\n\n\n" + + "@section ActionMap_binding Binding Functions\n" + "Once you have created an ActionMap, you can start binding functionality to events. Currently, Torque 3D supports the following devices out of the box\n\n" + "* Mouse\n\n" + "* Keyboard\n\n" + "* Joystick/Gamepad\n\n" + "* Xbox 360 Controller\n\n" - "The two most commonly used binding methods are bind() and bindCmd(). Both are similar in that they will bind functionality to a device and event, " + "The two most commonly used binding methods are bind() and bindCmd(). Both are similar in that they will bind functionality to a device and event, " "but different in how the event is interpreted. With bind(), " - "you specify a device, action to bind, then a function to be called when the event happens.\n\n" + "you specify a device, action to bind, then a function to be called when the event happens.\n\n" - "@tsexample\n" - "// Simple function that prints to console\n" - "// %val - Sent by the device letting the user know\n" - "// if an input was pressed (true) or released (false)\n" - "function testInput(%val)\n" - "{\n" - " if(%val)\n" - " echo(\"Key is down\");\n" - " else\n" - " echo(\"Key was released\");\n" - "}\n\n" - "// Bind the \'K\' key to the testInput function\n" - "moveMap.bind(keyboard, \"k\", testInput);\n\n" - "@endtsexample\n\n\n" + "@tsexample\n" + "// Simple function that prints to console\n" + "// %val - Sent by the device letting the user know\n" + "// if an input was pressed (true) or released (false)\n" + "function testInput(%val)\n" + "{\n" + " if(%val)\n" + " echo(\"Key is down\");\n" + " else\n" + " echo(\"Key was released\");\n" + "}\n\n" + "// Bind the \'K\' key to the testInput function\n" + "moveMap.bind(keyboard, \"k\", testInput);\n\n" + "@endtsexample\n\n\n" - "bindCmd is an alternative method for binding commands. This function is similar to bind(), " + "bindCmd is an alternative method for binding commands. This function is similar to bind(), " "except two functions are set to be called when the event is processed.\n\n" - "One will be called when the event is activated (input down), while the other is activated when the event is broken (input release). " + "One will be called when the event is activated (input down), while the other is activated when the event is broken (input release). " "When using bindCmd(), pass the functions as strings rather than the function names.\n\n" - "@tsexample\n" - "// Print to the console when the spacebar is pressed\n" - "function onSpaceDown()\n" - "{\n" - " echo(\"Space bar down!\");\n" - "}\n\n" + "@tsexample\n" + "// Print to the console when the spacebar is pressed\n" + "function onSpaceDown()\n" + "{\n" + " echo(\"Space bar down!\");\n" + "}\n\n" - "// Print to the console when the spacebar is released\n" - "function onSpaceUp()\n" - "{\n" - " echo(\"Space bar up!\");\n" - "}\n\n" + "// Print to the console when the spacebar is released\n" + "function onSpaceUp()\n" + "{\n" + " echo(\"Space bar up!\");\n" + "}\n\n" - "// Bind the commands onSpaceDown and onSpaceUp to spacebar events\n" - "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" - "@endtsexample\n\n" - - "@section ActionMap_switching Switching ActionMaps\n" - "Let's say you want to have different ActionMaps activated based on game play situations. A classic example would be first person shooter controls and racing controls " - "in the same game. On foot, spacebar may cause your player to jump. In a vehicle, it may cause some kind of \"turbo charge\". You simply need to push/pop the ActionMaps appropriately:\n\n" + "// Bind the commands onSpaceDown and onSpaceUp to spacebar events\n" + "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" + "@endtsexample\n\n" + + "@section ActionMap_switching Switching ActionMaps\n" + "Let's say you want to have different ActionMaps activated based on game play situations. A classic example would be first person shooter controls and racing controls " + "in the same game. On foot, spacebar may cause your player to jump. In a vehicle, it may cause some kind of \"turbo charge\". You simply need to push/pop the ActionMaps appropriately:\n\n" - "First, create two separate ActionMaps:\n\n" - "@tsexample\n" - "// Create the two ActionMaps\n" - "if ( isObject( moveMap ) )\n" - " moveMap.delete();\n" - "new ActionMap(moveMap);\n\n" - "if ( isObject( carMap ) )\n" - " carMap.delete();\n" - "new ActionMap(carMap);\n\n" - "@endtsexample\n\n" + "First, create two separate ActionMaps:\n\n" + "@tsexample\n" + "// Create the two ActionMaps\n" + "if ( isObject( moveMap ) )\n" + " moveMap.delete();\n" + "new ActionMap(moveMap);\n\n" + "if ( isObject( carMap ) )\n" + " carMap.delete();\n" + "new ActionMap(carMap);\n\n" + "@endtsexample\n\n" - "Next, create the two separate functions. Both will be bound to spacebar, but not the same ActionMap:\n\n" - "@tsexample\n" - "// Print to the console the player is jumping\n" - "function playerJump(%val)\n" - "{\n" - " if(%val)\n" - " echo(\"Player jumping!\");\n" - "}\n\n" - "// Print to the console the vehicle is charging\n" - "function turboCharge()\n" - "{\n" - " if(%val)\n" - " echo(\"Vehicle turbo charging!\");\n" - "}\n" - "@endtsexample\n\n" - - "You are now ready to bind functions to your ActionMaps' devices:\n\n" + "Next, create the two separate functions. Both will be bound to spacebar, but not the same ActionMap:\n\n" + "@tsexample\n" + "// Print to the console the player is jumping\n" + "function playerJump(%val)\n" + "{\n" + " if(%val)\n" + " echo(\"Player jumping!\");\n" + "}\n\n" + "// Print to the console the vehicle is charging\n" + "function turboCharge()\n" + "{\n" + " if(%val)\n" + " echo(\"Vehicle turbo charging!\");\n" + "}\n" + "@endtsexample\n\n" + + "You are now ready to bind functions to your ActionMaps' devices:\n\n" - "@tsexample\n" - "// Bind the spacebar to the playerJump function\n" - "// when moveMap is the active ActionMap\n" - "moveMap.bind(keyboard, \"space\", playerJump);\n\n" - "// Bind the spacebar to the turboCharge function\n" - "// when carMap is the active ActionMap\n" - "carMap.bind(keyboard, \"space\", turboCharge);\n" - "@endtsexample\n" + "@tsexample\n" + "// Bind the spacebar to the playerJump function\n" + "// when moveMap is the active ActionMap\n" + "moveMap.bind(keyboard, \"space\", playerJump);\n\n" + "// Bind the spacebar to the turboCharge function\n" + "// when carMap is the active ActionMap\n" + "carMap.bind(keyboard, \"space\", turboCharge);\n" + "@endtsexample\n" - "Finally, you can use the push() and pop() commands on each ActionMap to toggle activation. To activate an ActionMap, use push():\n\n" + "Finally, you can use the push() and pop() commands on each ActionMap to toggle activation. To activate an ActionMap, use push():\n\n" - "@tsexample\n" - "// Make moveMap the active action map\n" - "// You should now be able to activate playerJump with spacebar\n" - "moveMap.push();\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Make moveMap the active action map\n" + "// You should now be able to activate playerJump with spacebar\n" + "moveMap.push();\n" + "@endtsexample\n\n" - "To switch ActionMaps, first pop() the old one. Then you can push() the new one:\n\n" + "To switch ActionMaps, first pop() the old one. Then you can push() the new one:\n\n" - "@tsexample\n" - "// Deactivate moveMap\n" - "moveMap.pop();\n\n" - "// Activate carMap\n" - "carMap.push();\n\n" - "@endtsexample\n\n\n" + "@tsexample\n" + "// Deactivate moveMap\n" + "moveMap.pop();\n\n" + "// Activate carMap\n" + "carMap.push();\n\n" + "@endtsexample\n\n\n" - "@ingroup Input" - + "@ingroup Input" + ); // This is used for determing keys that have ascii codes for the foreign keyboards. IsAlpha doesn't work on foreign keys. @@ -775,32 +775,32 @@ const char* ActionMap::getBinding( const char* command ) // const char* ActionMap::getCommand( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - { - if ( mapNode->flags & Node::BindCmd ) - { - S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2; - char* returnString = Con::getReturnBuffer( bufferLen ); - dSprintf( returnString, bufferLen, "%s\t%s", - ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ), - ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) ); - return( returnString ); - } - else - return( mapNode->consoleFunction ); - } - } - } + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + { + if ( mapNode->flags & Node::BindCmd ) + { + S32 bufferLen = dStrlen( mapNode->makeConsoleCommand ) + dStrlen( mapNode->breakConsoleCommand ) + 2; + char* returnString = Con::getReturnBuffer( bufferLen ); + dSprintf( returnString, bufferLen, "%s\t%s", + ( mapNode->makeConsoleCommand ? mapNode->makeConsoleCommand : "" ), + ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) ); + return( returnString ); + } + else + return( mapNode->consoleFunction ); + } + } + } - return( "" ); + return( "" ); } //------------------------------------------------------------------------------ @@ -808,92 +808,92 @@ const char* ActionMap::getCommand( const char* device, const char* action ) // Obviously, this should only be used for axes. bool ActionMap::isInverted( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - return( mapNode->flags & Node::Inverted ); - } - } + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + return( mapNode->flags & Node::Inverted ); + } + } - Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); - return( false ); + Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); + return( false ); } //------------------------------------------------------------------------------ F32 ActionMap::getScale( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - { - if ( mapNode->flags & Node::HasScale ) - return( mapNode->scaleFactor ); + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + { + if ( mapNode->flags & Node::HasScale ) + return( mapNode->scaleFactor ); else return( 1.0f ); } - } - } + } + } - Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); - return( 1.0f ); + Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); + return( 1.0f ); } //------------------------------------------------------------------------------ const char* ActionMap::getDeadZone( const char* device, const char* action ) { - U32 deviceType; - U32 deviceInst; - if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) - { - EventDescriptor eventDescriptor; - if ( createEventDescriptor( action, &eventDescriptor ) ) - { - const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); - if ( mapNode ) - { - if ( mapNode->flags & Node::HasDeadZone ) + U32 deviceType; + U32 deviceInst; + if ( getDeviceTypeAndInstance( device, deviceType, deviceInst ) ) + { + EventDescriptor eventDescriptor; + if ( createEventDescriptor( action, &eventDescriptor ) ) + { + const ActionMap::Node* mapNode = findNode( deviceType, deviceInst, eventDescriptor.flags, eventDescriptor.eventCode ); + if ( mapNode ) + { + if ( mapNode->flags & Node::HasDeadZone ) { - char buf[64]; - dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd ); - char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 ); - dStrcpy( returnString, buf ); - return( returnString ); - } - else - return( "0 0" ); - } - } - } + char buf[64]; + dSprintf( buf, sizeof( buf ), "%g %g", mapNode->deadZoneBegin, mapNode->deadZoneEnd ); + char* returnString = Con::getReturnBuffer( dStrlen( buf ) + 1 ); + dStrcpy( returnString, buf ); + return( returnString ); + } + else + return( "0 0" ); + } + } + } - Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); - return( "" ); + Con::errorf( "The input event specified by %s %s is not in this action map!", device, action ); + return( "" ); } //------------------------------------------------------------------------------ const char* ActionMap::buildActionString( const InputEventInfo* event ) { - const char* modifierString = getModifierString( event->modifier ); + const char* modifierString = getModifierString( event->modifier ); - char objectBuffer[64]; - if ( !getKeyString( event->objInst, objectBuffer ) ) - return( "" ); + char objectBuffer[64]; + if ( !getKeyString( event->objInst, objectBuffer ) ) + return( "" ); - U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2; - char* returnString = Con::getReturnBuffer( returnLen ); - dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer ); - return( returnString ); + U32 returnLen = dStrlen( modifierString ) + dStrlen( objectBuffer ) + 2; + char* returnString = Con::getReturnBuffer( returnLen ); + dSprintf( returnString, returnLen - 1, "%s%s", modifierString, objectBuffer ); + return( returnString ); } //------------------------------------------------------------------------------ @@ -989,15 +989,15 @@ bool ActionMap::getDeviceName(const U32 deviceType, const U32 deviceInstance, ch //------------------------------------------------------------------------------ const char* ActionMap::getModifierString(const U32 modifiers) { - U32 realModifiers = modifiers; - if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT ) - realModifiers |= SI_SHIFT; - if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL ) - realModifiers |= SI_CTRL; - if ( modifiers & SI_LALT || modifiers & SI_RALT ) - realModifiers |= SI_ALT; - if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT ) - realModifiers |= SI_MAC_OPT; + U32 realModifiers = modifiers; + if ( modifiers & SI_LSHIFT || modifiers & SI_RSHIFT ) + realModifiers |= SI_SHIFT; + if ( modifiers & SI_LCTRL || modifiers & SI_RCTRL ) + realModifiers |= SI_CTRL; + if ( modifiers & SI_LALT || modifiers & SI_RALT ) + realModifiers |= SI_ALT; + if ( modifiers & SI_MAC_LOPT || modifiers & SI_MAC_ROPT ) + realModifiers |= SI_MAC_OPT; switch (realModifiers & (SI_SHIFT|SI_CTRL|SI_ALT|SI_MAC_OPT)) { @@ -1820,19 +1820,19 @@ static ConsoleDocFragment _ActionMapbind1( "@param command The function to bind to the action. Function must have a single boolean argument.\n" "@return True if the binding was successful, false if the device was unknown or description failed.\n\n" "@tsexample\n" - "// Simple function that prints to console\n" - "// %val - Sent by the device letting the user know\n" - "// if an input was pressed (true) or released (false)\n" - "function testInput(%val)\n" - "{\n" - " if(%val)\n" - " echo(\"Key is down\");\n" - " else\n" - " echo(\"Key was released\");\n" - "}\n\n" - "// Bind the \'K\' key to the testInput function\n" - "moveMap.bind(keyboard, k, testInput);\n\n" - "@endtsexample\n\n\n", + "// Simple function that prints to console\n" + "// %val - Sent by the device letting the user know\n" + "// if an input was pressed (true) or released (false)\n" + "function testInput(%val)\n" + "{\n" + " if(%val)\n" + " echo(\"Key is down\");\n" + " else\n" + " echo(\"Key was released\");\n" + "}\n\n" + "// Bind the \'K\' key to the testInput function\n" + "moveMap.bind(keyboard, k, testInput);\n\n" + "@endtsexample\n\n\n", "ActionMap", "bool bind( string device, string action, string command );"); @@ -1854,22 +1854,22 @@ static ConsoleDocFragment _ActionMapbind2( "@param command The function bound to the action. Must take in a single argument.\n" "@return True if the binding was successful, false if the device was unknown or description failed.\n\n" "@tsexample\n" - "// Simple function that adjusts the pitch of the camera based on the " + "// Simple function that adjusts the pitch of the camera based on the " "mouse's movement along the X axis.\n" - "function testPitch(%val)\n" - "{\n" - " %pitchAdj = getMouseAdjustAmount(%val);\n" - " $mvPitch += %pitchAdj;\n" - "}\n\n" - "// Bind the mouse's X axis to the testPitch function\n" - "// DI is flagged, meaning input is inverted and has a deadzone\n" - "%this.bind( mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\n" - "@endtsexample\n\n\n", + "function testPitch(%val)\n" + "{\n" + " %pitchAdj = getMouseAdjustAmount(%val);\n" + " $mvPitch += %pitchAdj;\n" + "}\n\n" + "// Bind the mouse's X axis to the testPitch function\n" + "// DI is flagged, meaning input is inverted and has a deadzone\n" + "%this.bind( mouse, \"xaxis\", \"DI\", \"-0.23 0.23\", testPitch );\n" + "@endtsexample\n\n\n", "ActionMap", "bool bind( string device, string action, string flag, string deadZone, string scale, string command );"); ConsoleMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier spec, mod...], command )" - "@hide") + "@hide") { StringStackWrapper args(argc - 2, argv + 2); return object->processBind( args.count(), args, NULL ); @@ -1918,7 +1918,7 @@ static ConsoleDocFragment _ActionMapbindObj2( "bool bindObj( string device, string action, string flag, string deadZone, string scale, string command, SimObjectID object );"); ConsoleMethod( ActionMap, bindObj, bool, 6, 11, "(device, action, [modifier spec, mod...], command, object)" - "@hide") + "@hide") { SimObject* simObject = Sim::findObject(argv[argc - 1]); if ( simObject == NULL ) @@ -1941,20 +1941,20 @@ DefineEngineMethod( ActionMap, bindCmd, bool, ( const char* device, const char* "@param makeCmd The command to execute when the device/action is made.\n" "@param breakCmd [optional] The command to execute when the device or action is unmade.\n" "@return True the bind was successful, false if the device was unknown or description failed.\n" - "@tsexample\n" - "// Print to the console when the spacebar is pressed\n" - "function onSpaceDown()\n" - "{\n" - " echo(\"Space bar down!\");\n" - "}\n\n" - "// Print to the console when the spacebar is released\n" - "function onSpaceUp()\n" - "{\n" - " echo(\"Space bar up!\");\n" - "}\n\n" + "@tsexample\n" + "// Print to the console when the spacebar is pressed\n" + "function onSpaceDown()\n" + "{\n" + " echo(\"Space bar down!\");\n" + "}\n\n" + "// Print to the console when the spacebar is released\n" + "function onSpaceUp()\n" + "{\n" + " echo(\"Space bar up!\");\n" + "}\n\n" "// Bind the commands onSpaceDown() and onSpaceUp() to spacebar events\n\n" - "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" - "@endtsexample\n\n") + "moveMap.bindCmd(keyboard, \"space\", \"onSpaceDown();\", \"onSpaceUp();\");\n" + "@endtsexample\n\n") { return object->processBindCmd( device, action, makeCmd, breakCmd ); } @@ -1964,9 +1964,9 @@ DefineEngineMethod( ActionMap, unbind, bool, ( const char* device, const char* a "@param device The device to unbind from. Can be a keyboard, mouse, joystick or a gamepad.\n" "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n" "@return True if the unbind was successful, false if the device was unknown or description failed.\n\n" - "@tsexample\n" - "moveMap.unbind(\"keyboard\", \"space\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "moveMap.unbind(\"keyboard\", \"space\");\n" + "@endtsexample\n\n") { return object->processUnbind( device, action ); } @@ -1977,7 +1977,7 @@ DefineEngineMethod( ActionMap, unbindObj, bool, ( const char* device, const char "@param action The device action to unbind from. The action is dependant upon the device. Specify a key for keyboards.\n" "@param obj The object to perform unbind against.\n" "@return True if the unbind was successful, false if the device was unknown or description failed.\n" - "@tsexample\n" + "@tsexample\n" "moveMap.unbindObj(\"keyboard\", \"numpad1\", \"rangeChange\", %player);" "@endtsexample\n\n\n") { @@ -1996,10 +1996,10 @@ DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ) "@param fileName The file path to save the ActionMap to. If a filename is not specified " " the ActionMap will be dumped to the console.\n" "@param append Whether to write the ActionMap at the end of the file or overwrite it.\n" - "@tsexample\n" - "// Write out the actionmap into the config.cs file\n" + "@tsexample\n" + "// Write out the actionmap into the config.cs file\n" "moveMap.save( \"scripts/client/config.cs\" );" - "@endtsexample\n\n") + "@endtsexample\n\n") { char buffer[1024]; @@ -2015,7 +2015,7 @@ DefineEngineMethod( ActionMap, save, void, ( const char* fileName, bool append ) DefineEngineFunction( getCurrentActionMap, ActionMap*, (),, "@brief Returns the current %ActionMap.\n" "@see ActionMap" - "@ingroup Input") + "@ingroup Input") { SimSet* pActionMapSet = Sim::getActiveActionMapSet(); return dynamic_cast< ActionMap* >( pActionMapSet->last() ); @@ -2024,10 +2024,10 @@ DefineEngineFunction( getCurrentActionMap, ActionMap*, (),, DefineEngineMethod( ActionMap, push, void, (),, "@brief Push the ActionMap onto the %ActionMap stack.\n\n" "Activates an ActionMap and placees it at the top of the ActionMap stack.\n\n" - "@tsexample\n" - "// Make moveMap the active action map\n" - "moveMap.push();\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Make moveMap the active action map\n" + "moveMap.push();\n" + "@endtsexample\n\n" "@see ActionMap") { SimSet* pActionMapSet = Sim::getActiveActionMapSet(); @@ -2037,10 +2037,10 @@ DefineEngineMethod( ActionMap, push, void, (),, DefineEngineMethod( ActionMap, pop, void, (),, "@brief Pop the ActionMap off the %ActionMap stack.\n\n" "Deactivates an %ActionMap and removes it from the @ActionMap stack.\n" - "@tsexample\n" - "// Deactivate moveMap\n" - "moveMap.pop();\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Deactivate moveMap\n" + "moveMap.pop();\n" + "@endtsexample\n\n" "@see ActionMap") { SimSet* pActionMapSet = Sim::getActiveActionMapSet(); @@ -2053,20 +2053,20 @@ DefineEngineMethod( ActionMap, getBinding, const char*, ( const char* command ), "@param command The function to search bindings for.\n" "@return The binding against the specified command. Returns an empty string(\"\") " "if a binding wasn't found.\n" - "@tsexample\n" - "// Find what the function \"jump()\" is bound to in moveMap\n" - "%bind = moveMap.getBinding( \"jump\" );\n\n" - "if ( %bind !$= \"\" )\n" - "{\n" - "// Find out what device is used in the binding\n" - " %device = getField( %bind, 0 );\n\n" - "// Find out what action (such as a key) is used in the binding\n" - " %action = getField( %bind, 1 );\n" - "}\n" - "@endtsexample\n\n" + "@tsexample\n" + "// Find what the function \"jump()\" is bound to in moveMap\n" + "%bind = moveMap.getBinding( \"jump\" );\n\n" + "if ( %bind !$= \"\" )\n" + "{\n" + "// Find out what device is used in the binding\n" + " %device = getField( %bind, 0 );\n\n" + "// Find out what action (such as a key) is used in the binding\n" + " %action = getField( %bind, 1 );\n" + "}\n" + "@endtsexample\n\n" "@see getField") { - return object->getBinding( command ); + return object->getBinding( command ); } DefineEngineMethod( ActionMap, getCommand, const char*, ( const char* device, const char* action ),, @@ -2074,15 +2074,15 @@ DefineEngineMethod( ActionMap, getCommand, const char*, ( const char* device, co "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n" "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return The command against the specified device and action.\n" - "@tsexample\n" - "// Find what function is bound to a device\'s action\n" - "// In this example, \"jump()\" was assigned to the space key in another script\n" - "%command = moveMap.getCommand(\"keyboard\", \"space\");\n\n" - "// Should print \"jump\" in the console\n" - "echo(%command)\n" - "@endtsexample\n\n") + "@tsexample\n" + "// Find what function is bound to a device\'s action\n" + "// In this example, \"jump()\" was assigned to the space key in another script\n" + "%command = moveMap.getCommand(\"keyboard\", \"space\");\n\n" + "// Should print \"jump\" in the console\n" + "echo(%command)\n" + "@endtsexample\n\n") { - return object->getCommand( device, action ); + return object->getCommand( device, action ); } DefineEngineMethod( ActionMap, isInverted, bool, ( const char* device, const char* action ),, @@ -2091,12 +2091,12 @@ DefineEngineMethod( ActionMap, isInverted, bool, ( const char* device, const cha "@param device The device that was bound. Can be a keyboard, mouse, joystick or a gamepad.\n" "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return True if the specified device and action is inverted.\n" - "@tsexample\n" + "@tsexample\n" "%if ( moveMap.isInverted( \"mouse\", \"xaxis\"))\n" " echo(\"Mouse's xAxis is inverted\");" - "@endtsexample\n\n") + "@endtsexample\n\n") { - return object->isInverted( device, action ); + return object->isInverted( device, action ); } DefineEngineMethod( ActionMap, getScale, F32, ( const char* device, const char* action ),, @@ -2104,11 +2104,11 @@ DefineEngineMethod( ActionMap, getScale, F32, ( const char* device, const char* "@param device The device that was bound. Can be keyboard, mouse, joystick or gamepad.\n" "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return Any scaling applied to the specified device and action.\n" - "@tsexample\n" - "%scale = %moveMap.getScale( \"gamepad\", \"thumbrx\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "%scale = %moveMap.getScale( \"gamepad\", \"thumbrx\");\n" + "@endtsexample\n\n") { - return object->getScale( device, action ); + return object->getScale( device, action ); } DefineEngineMethod( ActionMap, getDeadZone, const char*, ( const char* device, const char* action ),, @@ -2117,11 +2117,11 @@ DefineEngineMethod( ActionMap, getDeadZone, const char*, ( const char* device, c "@param action The device action that was bound. The action is dependant upon the device. Specify a key for keyboards.\n" "@return The dead zone for the specified device and action. Returns \"0 0\" if there is no dead zone " "or an empty string(\"\") if the mapping was not found.\n" - "@tsexample\n" - "%deadZone = moveMap.getDeadZone( \"gamepad\", \"thumbrx\");\n" - "@endtsexample\n\n") + "@tsexample\n" + "%deadZone = moveMap.getDeadZone( \"gamepad\", \"thumbrx\");\n" + "@endtsexample\n\n") { - return object->getDeadZone( device, action ); + return object->getDeadZone( device, action ); } //------------------------------------------------------------------------------ From 27e2871b01fb9fee68c3bdd3c67fa90490d2615b Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Wed, 11 Jan 2017 23:21:29 -0500 Subject: [PATCH 34/50] Replaced StringTable->insert("") with StringTable->EmptyString() --- Engine/source/T3D/fx/fxFoliageReplicator.h | 48 ++-- Engine/source/T3D/fx/fxShapeReplicator.h | 2 +- Engine/source/T3D/fx/precipitation.cpp | 8 +- Engine/source/T3D/fx/ribbon.cpp | 6 +- Engine/source/T3D/missionMarker.cpp | 14 +- Engine/source/T3D/player.cpp | 46 ++-- Engine/source/T3D/shapeBase.cpp | 214 +++++++++--------- Engine/source/console/SimXMLDocument.cpp | 172 +++++++------- Engine/source/console/astAlloc.cpp | 2 +- Engine/source/console/codeBlock.cpp | 10 +- Engine/source/console/fieldBrushObject.cpp | 4 +- Engine/source/console/persistenceManager.cpp | 2 +- .../source/gui/buttons/guiIconButtonCtrl.cpp | 4 +- .../gui/buttons/guiToggleButtonCtrl.cpp | 2 +- .../gui/buttons/guiToolboxButtonCtrl.cpp | 4 +- Engine/source/gui/containers/guiFormCtrl.cpp | 6 +- Engine/source/gui/containers/guiPaneCtrl.cpp | 2 +- .../source/gui/containers/guiWindowCtrl.cpp | 2 +- .../gui/controls/guiGameListMenuCtrl.cpp | 4 +- Engine/source/gui/controls/guiListBoxCtrl.cpp | 4 +- Engine/source/gui/controls/guiMLTextCtrl.cpp | 4 +- Engine/source/gui/controls/guiPopUpCtrl.cpp | 2 +- Engine/source/gui/controls/guiPopUpCtrlEx.cpp | 2 +- Engine/source/gui/controls/guiTextCtrl.cpp | 4 +- .../source/gui/controls/guiTextEditCtrl.cpp | 2 +- .../source/gui/controls/guiTreeViewCtrl.cpp | 6 +- .../gui/editor/guiParticleGraphCtrl.cpp | 2 +- .../source/gui/game/guiChunkedBitmapCtrl.cpp | 2 +- Engine/source/gui/worldEditor/undoActions.cpp | 10 +- Engine/source/navigation/navMesh.cpp | 4 +- Engine/source/navigation/navPath.cpp | 4 +- Engine/source/platform/menus/popupMenu.cpp | 2 +- .../platform/nativeDialogs/fileDialog.cpp | 8 +- 33 files changed, 304 insertions(+), 304 deletions(-) diff --git a/Engine/source/T3D/fx/fxFoliageReplicator.h b/Engine/source/T3D/fx/fxFoliageReplicator.h index e40554454..c9f8a0804 100644 --- a/Engine/source/T3D/fx/fxFoliageReplicator.h +++ b/Engine/source/T3D/fx/fxFoliageReplicator.h @@ -64,16 +64,16 @@ class fxFoliageItem { public: - MatrixF Transform; - F32 Width; - F32 Height; - Box3F FoliageBox; - bool Flipped; + MatrixF Transform; + F32 Width; + F32 Height; + Box3F FoliageBox; + bool Flipped; F32 SwayPhase; F32 SwayTimeRatio; - F32 LightPhase; + F32 LightPhase; F32 LightTimeRatio; - U32 LastFrameSerialID; + U32 LastFrameSerialID; }; //------------------------------------------------------------------------------ @@ -104,9 +104,9 @@ public: Box3F QuadrantBox; fxFoliageQuadrantNode* QuadrantChildNode[4]; Vector RenderList; - // Used in DrawIndexPrimitive call. - U32 startIndex; - U32 primitiveCount; + // Used in DrawIndexPrimitive call. + U32 startIndex; + U32 primitiveCount; }; @@ -152,7 +152,7 @@ protected: void CreateFoliage(void); void DestroyFoliage(void); - void DestroyFoliageItems(); + void DestroyFoliageItems(); void SyncFoliageReplicators(void); @@ -172,11 +172,11 @@ protected: Vector mReplicatedFoliage; fxFoliageRenderList mFrustumRenderSet; - GFXVertexBufferHandle mVertexBuffer; - GFXPrimitiveBufferHandle mPrimBuffer; + GFXVertexBufferHandle mVertexBuffer; + GFXPrimitiveBufferHandle mPrimBuffer; GFXShaderRef mShader; ShaderData* mShaderData; - GBitmap* mAlphaLookup; + GBitmap* mAlphaLookup; MRandomLCG RandomGen; F32 mFadeInGradient; @@ -193,8 +193,8 @@ protected: U32 mNextAllocatedNodeIdx; // Next Allocated Node Index. U32 mBillboardsAcquired; // Billboards Acquired. - // Used for alpha lookup in the pixel shader - GFXTexHandle mAlphaTexture; + // Used for alpha lookup in the pixel shader + GFXTexHandle mAlphaTexture; GFXStateBlockRef mPlacementSB; GFXStateBlockRef mRenderSB; @@ -223,15 +223,15 @@ protected: bool mDirty; - + void SetupShader(); - void SetupBuffers(); + void SetupBuffers(); void renderObject(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance*); - void renderBuffers(SceneRenderState* state); - void renderArc(const F32 fRadiusX, const F32 fRadiusY); - void renderPlacementArea(const F32 ElapsedTime); - void renderQuad(fxFoliageQuadrantNode* quadNode, const MatrixF& RenderTransform, const bool UseDebug); - void computeAlphaTex(); + void renderBuffers(SceneRenderState* state); + void renderArc(const F32 fRadiusX, const F32 fRadiusY); + void renderPlacementArea(const F32 ElapsedTime); + void renderQuad(fxFoliageQuadrantNode* quadNode, const MatrixF& RenderTransform, const bool UseDebug); + void computeAlphaTex(); public: fxFoliageReplicator(); ~fxFoliageReplicator(); @@ -325,7 +325,7 @@ public: mUseDebugInfo = false; mDebugBoxHeight = 1.0f; mSeed = 1376312589; - mFoliageFile = StringTable->insert(""); + mFoliageFile = StringTable->EmptyString(); mFoliageTexture = GFXTexHandle(); mFoliageCount = 10; mFoliageRetries = 100; diff --git a/Engine/source/T3D/fx/fxShapeReplicator.h b/Engine/source/T3D/fx/fxShapeReplicator.h index 8cd9efa4e..e83f0e113 100644 --- a/Engine/source/T3D/fx/fxShapeReplicator.h +++ b/Engine/source/T3D/fx/fxShapeReplicator.h @@ -153,7 +153,7 @@ public: { // Set Defaults. mSeed = 1376312589; - mShapeFile = StringTable->insert(""); + mShapeFile = StringTable->EmptyString(); mShapeCount = 10; mShapeRetries = 100; mInnerRadiusX = 0; diff --git a/Engine/source/T3D/fx/precipitation.cpp b/Engine/source/T3D/fx/precipitation.cpp index 19855e26f..232e8ca72 100644 --- a/Engine/source/T3D/fx/precipitation.cpp +++ b/Engine/source/T3D/fx/precipitation.cpp @@ -129,10 +129,10 @@ PrecipitationData::PrecipitationData() { soundProfile = NULL; - mDropName = StringTable->insert(""); - mDropShaderName = StringTable->insert(""); - mSplashName = StringTable->insert(""); - mSplashShaderName = StringTable->insert(""); + mDropName = StringTable->EmptyString(); + mDropShaderName = StringTable->EmptyString(); + mSplashName = StringTable->EmptyString(); + mSplashShaderName = StringTable->EmptyString(); mDropsPerSide = 4; mSplashesPerSide = 2; diff --git a/Engine/source/T3D/fx/ribbon.cpp b/Engine/source/T3D/fx/ribbon.cpp index 6ebcfc932..ef5276857 100644 --- a/Engine/source/T3D/fx/ribbon.cpp +++ b/Engine/source/T3D/fx/ribbon.cpp @@ -57,7 +57,7 @@ RibbonData::RibbonData() mUseFadeOut = false; mFadeAwayStep = 0.032f; segmentsPerUpdate = 1; - mMatName = StringTable->insert(""); + mMatName = StringTable->EmptyString(); mTileScale = 1.0f; mFixedTexcoords = false; mSegmentSkipAmount = 0; @@ -318,7 +318,7 @@ void Ribbon::processTick(const Move* move) safeDeleteObject(); return; //} - //mSegmentPoints.pop_back(); + //mSegmentPoints.pop_back(); } @@ -456,7 +456,7 @@ void Ribbon::setShaderParams() { F32 length = (F32)mDataBlock->mRibbonLength; Point3F radius(numSegments / length, numSegments, length); MaterialParameters* matParams = mRibbonMat->getMaterialParameters(); - matParams->setSafe( mRadiusSC, radius ); + matParams->setSafe( mRadiusSC, radius ); } //-------------------------------------------------------------------------- diff --git a/Engine/source/T3D/missionMarker.cpp b/Engine/source/T3D/missionMarker.cpp index 3a043b095..1480e2f1f 100644 --- a/Engine/source/T3D/missionMarker.cpp +++ b/Engine/source/T3D/missionMarker.cpp @@ -225,7 +225,7 @@ ConsoleDocClass( WayPoint, WayPoint::WayPoint() { - mName = StringTable->insert(""); + mName = StringTable->EmptyString(); } void WayPoint::setHidden(bool hidden) @@ -256,7 +256,7 @@ void WayPoint::inspectPostApply() { Parent::inspectPostApply(); if(!mName || !mName[0]) - mName = StringTable->insert(""); + mName = StringTable->EmptyString(); setMaskBits(UpdateNameMask|UpdateTeamMask); } @@ -281,7 +281,7 @@ void WayPoint::unpackUpdate(NetConnection * con, BitStream * stream) void WayPoint::initPersistFields() { - addGroup("Misc"); + addGroup("Misc"); addField("markerName", TypeCaseString, Offset(mName, WayPoint), "Unique name representing this waypoint"); endGroup("Misc"); Parent::initPersistFields(); @@ -363,7 +363,7 @@ bool SpawnSphere::onAdd() if (!isGhost()) { - onAdd_callback( getId()); + onAdd_callback( getId()); if (mAutoSpawn) spawnObject(); @@ -527,7 +527,7 @@ ConsoleDocClass( CameraBookmark, CameraBookmark::CameraBookmark() { - mName = StringTable->insert(""); + mName = StringTable->EmptyString(); } bool CameraBookmark::onAdd() @@ -571,7 +571,7 @@ void CameraBookmark::inspectPostApply() { Parent::inspectPostApply(); if(!mName || !mName[0]) - mName = StringTable->insert(""); + mName = StringTable->EmptyString(); setMaskBits(UpdateNameMask); if( isMethod("onInspectPostApply") ) @@ -595,7 +595,7 @@ void CameraBookmark::unpackUpdate(NetConnection * con, BitStream * stream) void CameraBookmark::initPersistFields() { - //addGroup("Misc"); + //addGroup("Misc"); //addField("name", TypeCaseString, Offset(mName, CameraBookmark)); //endGroup("Misc"); diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 93cd4f722..916a64c39 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -257,15 +257,15 @@ PlayerData::PlayerData() firstPersonShadows = false; // Used for third person image rendering - imageAnimPrefix = StringTable->insert(""); + imageAnimPrefix = StringTable->EmptyString(); allowImageStateAnimation = false; // Used for first person image rendering - imageAnimPrefixFP = StringTable->insert(""); + imageAnimPrefixFP = StringTable->EmptyString(); for (U32 i=0; iinsert(""); + shapeNameFP[i] = StringTable->EmptyString(); mCRCFP[i] = 0; mValidShapeFP[i] = false; } @@ -418,7 +418,7 @@ PlayerData::PlayerData() jumpTowardsNormal = true; - physicsPlayerType = StringTable->insert(""); + physicsPlayerType = StringTable->EmptyString(); dMemset( actionList, 0, sizeof(actionList) ); } @@ -6652,7 +6652,7 @@ DefineEngineMethod( Player, setActionThread, bool, ( const char* name, bool hold "@tsexample\n" "// Place the player in a sitting position after being mounted\n" "%player.setActionThread( \"sitting\", true, true );\n" - "@endtsexample\n") + "@endtsexample\n") { return object->setActionThread( name, hold, true, fsp); } @@ -6700,11 +6700,11 @@ DefineEngineMethod( Player, clearControlObject, void, (),, "Returns control to the player. This internally calls " "Player::setControlObject(0).\n" "@tsexample\n" - "%player.clearControlObject();\n" + "%player.clearControlObject();\n" "echo(%player.getControlObject()); //<-- Returns 0, player assumes control\n" "%player.setControlObject(%vehicle);\n" "echo(%player.getControlObject()); //<-- Returns %vehicle, player controls the vehicle now.\n" - "@endtsexample\n" + "@endtsexample\n" "@note If the player does not have a control object, the player will receive all moves " "from its GameConnection. If you're looking to remove control from the player itself " "(i.e. stop sending moves to the player) use GameConnection::setControlObject() to transfer " @@ -6762,63 +6762,63 @@ void Player::consoleInit() "@brief Determines if the player is rendered or not.\n\n" "Used on the client side to disable the rendering of all Player objects. This is " "mainly for the tools or debugging.\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::renderMyItems",TypeBool, &sRenderMyItems, "@brief Determines if mounted shapes are rendered or not.\n\n" "Used on the client side to disable the rendering of all Player mounted objects. This is " "mainly used for the tools or debugging.\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::renderCollision", TypeBool, &sRenderPlayerCollision, "@brief Determines if the player's collision mesh should be rendered.\n\n" "This is mainly used for the tools and debugging.\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::minWarpTicks",TypeF32,&sMinWarpTicks, "@brief Fraction of tick at which instant warp occures on the client.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::maxWarpTicks",TypeS32,&sMaxWarpTicks, "@brief When a warp needs to occur due to the client being too far off from the server, this is the " "maximum number of ticks we'll allow the client to warp to catch up.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::maxPredictionTicks",TypeS32,&sMaxPredictionTicks, "@brief Maximum number of ticks to predict on the client from the last known move obtained from the server.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::maxImpulseVelocity", TypeF32, &sMaxImpulseVelocity, "@brief The maximum velocity allowed due to a single impulse.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); // Move triggers Con::addVariable("$player::jumpTrigger", TypeS32, &sJumpTrigger, "@brief The move trigger index used for player jumping.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::crouchTrigger", TypeS32, &sCrouchTrigger, "@brief The move trigger index used for player crouching.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::proneTrigger", TypeS32, &sProneTrigger, "@brief The move trigger index used for player prone pose.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::sprintTrigger", TypeS32, &sSprintTrigger, "@brief The move trigger index used for player sprinting.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::imageTrigger0", TypeS32, &sImageTrigger0, "@brief The move trigger index used to trigger mounted image 0.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::imageTrigger1", TypeS32, &sImageTrigger1, "@brief The move trigger index used to trigger mounted image 1 or alternate fire " "on mounted image 0.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::jumpJetTrigger", TypeS32, &sJumpJetTrigger, "@brief The move trigger index used for player jump jetting.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); Con::addVariable("$player::vehicleDismountTrigger", TypeS32, &sVehicleDismountTrigger, "@brief The move trigger index used to dismount player.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); // ExtendedMove support Con::addVariable("$player::extendedMoveHeadPosRotIndex", TypeS32, &smExtendedMoveHeadPosRotIndex, "@brief The ExtendedMove position/rotation index used for head movements.\n\n" - "@ingroup GameObjects\n"); + "@ingroup GameObjects\n"); } //-------------------------------------------------------------------------- diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index 670446ab3..829a78bf6 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -152,13 +152,13 @@ ShapeBaseData::ShapeBaseData() shadowMaxVisibleDistance( 80.0f ), shadowProjectionDistance( 10.0f ), shadowSphereAdjust( 1.0f ), - shapeName( StringTable->insert("") ), - cloakTexName( StringTable->insert("") ), + shapeName( StringTable->EmptyString() ), + cloakTexName( StringTable->EmptyString() ), cubeDescId( 0 ), reflectorDesc( NULL ), debris( NULL ), debrisID( 0 ), - debrisShapeName( StringTable->insert("") ), + debrisShapeName( StringTable->EmptyString() ), explosion( NULL ), explosionID( 0 ), underwaterExplosion( NULL ), @@ -447,12 +447,12 @@ bool ShapeBaseData::_setMass( void* object, const char* index, const char* data { ShapeBaseData* shape = reinterpret_cast< ShapeBaseData* >( object ); - F32 mass = dAtof(data); + F32 mass = dAtof(data); - if (mass <= 0) - mass = 0.01f; + if (mass <= 0) + mass = 0.01f; - shape->mass = mass; + shape->mass = mass; return false; } @@ -935,8 +935,8 @@ ShapeBase::ShapeBase() mScriptThread[i].thread = 0; mScriptThread[i].state = Thread::Stop; mScriptThread[i].atEnd = false; - mScriptThread[i].timescale = 1.f; - mScriptThread[i].position = -1.f; + mScriptThread[i].timescale = 1.f; + mScriptThread[i].position = -1.f; } for (i = 0; i < MaxTriggerKeys; i++) @@ -1042,7 +1042,7 @@ bool ShapeBase::onAdd() } /* - if(mDataBlock->cloakTexName != StringTable->insert("")) + if(mDataBlock->cloakTexName != StringTable->EmptyString()) mCloakTexture = TextureHandle(mDataBlock->cloakTexName, MeshTexture, false); */ // Accumulation and environment mapping @@ -1512,8 +1512,8 @@ void ShapeBase::onCameraScopeQuery(NetConnection *cr, CameraScopeQuery * query) eyeTransform.getColumn(1, &query->orientation); // Get the visible distance. - if (getSceneManager() != NULL) - query->visibleDistance = getSceneManager()->getVisibleDistance(); + if (getSceneManager() != NULL) + query->visibleDistance = getSceneManager()->getVisibleDistance(); Parent::onCameraScopeQuery( cr, query ); } @@ -2154,18 +2154,18 @@ void ShapeBase::updateAudioPos() const char *ShapeBase::getThreadSequenceName( U32 slot ) { - Thread& st = mScriptThread[slot]; - if ( st.sequence == -1 ) - { - // Invalid Animation. - return ""; - } + Thread& st = mScriptThread[slot]; + if ( st.sequence == -1 ) + { + // Invalid Animation. + return ""; + } - // Name Index - const U32 nameIndex = getShape()->sequences[st.sequence].nameIndex; + // Name Index + const U32 nameIndex = getShape()->sequences[st.sequence].nameIndex; - // Return Name. - return getShape()->getName( nameIndex ); + // Return Name. + return getShape()->getName( nameIndex ); } bool ShapeBase::setThreadSequence(U32 slot, S32 seq, bool reset) @@ -2200,39 +2200,39 @@ bool ShapeBase::setThreadSequence(U32 slot, S32 seq, bool reset) void ShapeBase::updateThread(Thread& st) { - switch (st.state) - { - case Thread::Stop: - { - mShapeInstance->setTimeScale( st.thread, 1.f ); - mShapeInstance->setPos( st.thread, ( st.timescale > 0.f ) ? 1.0f : 0.0f ); - } // Drop through to pause state + switch (st.state) + { + case Thread::Stop: + { + mShapeInstance->setTimeScale( st.thread, 1.f ); + mShapeInstance->setPos( st.thread, ( st.timescale > 0.f ) ? 1.0f : 0.0f ); + } // Drop through to pause state - case Thread::Pause: - { - mShapeInstance->setTimeScale( st.thread, 0.f ); - } break; + case Thread::Pause: + { + mShapeInstance->setTimeScale( st.thread, 0.f ); + } break; - case Thread::Play: - { - if (st.atEnd) - { - mShapeInstance->setTimeScale(st.thread,1); - mShapeInstance->setPos( st.thread, ( st.timescale > 0.f ) ? 1.0f : 0.0f ); - mShapeInstance->setTimeScale(st.thread,0); + case Thread::Play: + { + if (st.atEnd) + { + mShapeInstance->setTimeScale(st.thread,1); + mShapeInstance->setPos( st.thread, ( st.timescale > 0.f ) ? 1.0f : 0.0f ); + mShapeInstance->setTimeScale(st.thread,0); st.state = Thread::Stop; - } - else - { - if ( st.position != -1.f ) - { - mShapeInstance->setTimeScale( st.thread, 1.f ); - mShapeInstance->setPos( st.thread, st.position ); - } + } + else + { + if ( st.position != -1.f ) + { + mShapeInstance->setTimeScale( st.thread, 1.f ); + mShapeInstance->setPos( st.thread, st.position ); + } - mShapeInstance->setTimeScale(st.thread, st.timescale ); - } - } break; + mShapeInstance->setTimeScale(st.thread, st.timescale ); + } + } break; case Thread::Destroy: { @@ -2244,7 +2244,7 @@ void ShapeBase::updateThread(Thread& st) st.thread = 0; } } break; - } + } } bool ShapeBase::stopThread(U32 slot) @@ -2297,50 +2297,50 @@ bool ShapeBase::playThread(U32 slot) bool ShapeBase::setThreadPosition( U32 slot, F32 pos ) { - Thread& st = mScriptThread[slot]; - if (st.sequence != -1) - { - setMaskBits(ThreadMaskN << slot); - st.position = pos; - st.atEnd = false; - updateThread(st); + Thread& st = mScriptThread[slot]; + if (st.sequence != -1) + { + setMaskBits(ThreadMaskN << slot); + st.position = pos; + st.atEnd = false; + updateThread(st); - return true; - } - return false; + return true; + } + return false; } bool ShapeBase::setThreadDir(U32 slot,bool forward) { - Thread& st = mScriptThread[slot]; - if (st.sequence != -1) - { - if ( ( st.timescale >= 0.f ) != forward ) - { - setMaskBits(ThreadMaskN << slot); - st.timescale *= -1.f ; - st.atEnd = false; - updateThread(st); - } - return true; - } - return false; + Thread& st = mScriptThread[slot]; + if (st.sequence != -1) + { + if ( ( st.timescale >= 0.f ) != forward ) + { + setMaskBits(ThreadMaskN << slot); + st.timescale *= -1.f ; + st.atEnd = false; + updateThread(st); + } + return true; + } + return false; } bool ShapeBase::setThreadTimeScale( U32 slot, F32 timeScale ) { - Thread& st = mScriptThread[slot]; - if (st.sequence != -1) - { - if (st.timescale != timeScale) - { - setMaskBits(ThreadMaskN << slot); - st.timescale = timeScale; - updateThread(st); - } - return true; - } - return false; + Thread& st = mScriptThread[slot]; + if (st.sequence != -1) + { + if (st.timescale != timeScale) + { + setMaskBits(ThreadMaskN << slot); + st.timescale = timeScale; + updateThread(st); + } + return true; + } + return false; } void ShapeBase::advanceThreads(F32 dt) @@ -2349,7 +2349,7 @@ void ShapeBase::advanceThreads(F32 dt) Thread& st = mScriptThread[i]; if (st.thread) { if (!mShapeInstance->getShape()->sequences[st.sequence].isCyclic() && !st.atEnd && - ( ( st.timescale > 0.f )? mShapeInstance->getPos(st.thread) >= 1.0: + ( ( st.timescale > 0.f )? mShapeInstance->getPos(st.thread) >= 1.0: mShapeInstance->getPos(st.thread) <= 0)) { st.atEnd = true; updateThread(st); @@ -4392,7 +4392,7 @@ DefineEngineMethod( ShapeBase, isEnabled, bool, (),, DefineEngineMethod(ShapeBase, blowUp, void, (),, "@brief Explodes an object into pieces.") { - object->blowUp(); + object->blowUp(); } DefineEngineMethod( ShapeBase, applyDamage, void, ( F32 amount ),, @@ -4696,22 +4696,22 @@ void ShapeBase::consoleInit() "@see ShapeBase::setDamageFlash()\n" "@see ShapeBase::getDamageFlash()\n" "@note Relies on the flash postFx.\n" - "@ingroup gameObjects\n"); + "@ingroup gameObjects\n"); Con::addVariable("SB::WODec", TypeF32, &sWhiteoutDec, "Speed to reduce the whiteout effect per tick.\n\n" "@see ShapeBase::setWhiteOut()\n" "@see ShapeBase::getWhiteOut" "@note Relies on the flash postFx.\n" - "@ingroup gameObjects\n"); + "@ingroup gameObjects\n"); Con::addVariable("SB::FullCorrectionDistance", TypeF32, &sFullCorrectionDistance, "@brief Distance at which a weapon's muzzle vector is fully corrected to match where the player is looking.\n\n" "When a weapon image has correctMuzzleVector set and the Player is in 1st person, the muzzle vector from the " "weapon is modified to match where the player is looking. Beyond the FullCorrectionDistance the muzzle vector " "is always corrected. Between FullCorrectionDistance and the player, the weapon's muzzle vector is adjusted so that " "the closer the aim point is to the player, the closer the muzzle vector is to the true (non-corrected) one.\n" - "@ingroup gameObjects\n"); + "@ingroup gameObjects\n"); Con::addVariable("SB::CloakSpeed", TypeF32, &sCloakSpeed, "@brief Time to cloak, in seconds.\n\n" - "@ingroup gameObjects\n"); + "@ingroup gameObjects\n"); } void ShapeBase::_updateHiddenMeshes() @@ -4832,17 +4832,17 @@ DefineEngineMethod( ShapeBase, getTargetName, const char*, ( S32 index ),, "@see getTargetCount()\n") { - ShapeBase *obj = dynamic_cast< ShapeBase* > ( object ); - if(obj) - { - // Try to use the client object (so we get the reskinned targets in the Material Editor) - if ((ShapeBase*)obj->getClientObject()) - obj = (ShapeBase*)obj->getClientObject(); + ShapeBase *obj = dynamic_cast< ShapeBase* > ( object ); + if(obj) + { + // Try to use the client object (so we get the reskinned targets in the Material Editor) + if ((ShapeBase*)obj->getClientObject()) + obj = (ShapeBase*)obj->getClientObject(); - return obj->getShapeInstance()->getTargetName(index); - } + return obj->getShapeInstance()->getTargetName(index); + } - return ""; + return ""; } DefineEngineMethod( ShapeBase, getTargetCount, S32, (),, @@ -4861,7 +4861,7 @@ DefineEngineMethod( ShapeBase, getTargetCount, S32, (),, if (obj->getShapeInstance() != NULL) return obj->getShapeInstance()->getTargetCount(); - } + } return -1; } @@ -4938,10 +4938,10 @@ DefineEngineMethod( ShapeBase, getModelFile, const char *, (),, "@return the shape filename\n\n" ) { - GameBaseData * datablock = object->getDataBlock(); - if( !datablock ) - return String::EmptyString; + GameBaseData * datablock = object->getDataBlock(); + if( !datablock ) + return String::EmptyString; - const char *fieldName = StringTable->insert( String("shapeFile") ); + const char *fieldName = StringTable->insert( String("shapeFile") ); return datablock->getDataField( fieldName, NULL ); } diff --git a/Engine/source/console/SimXMLDocument.cpp b/Engine/source/console/SimXMLDocument.cpp index 840f36ca8..b2960105b 100644 --- a/Engine/source/console/SimXMLDocument.cpp +++ b/Engine/source/console/SimXMLDocument.cpp @@ -49,40 +49,40 @@ ConsoleDocClass( SimXMLDocument, "// Thanks to Rex Hiebert for this example\n" "// Given the following XML\n" "\n" - "\n" - " \n" - " Triangle\n" - " Square\n" - " Circle\n" - "
\n" - " \n" - " Pyramid\n" - " Cube\n" - " Sphere\n" - "
\n" - "
\n\n" + "\n" + " \n" + " Triangle\n" + " Square\n" + " Circle\n" + "
\n" + " \n" + " Pyramid\n" + " Cube\n" + " Sphere\n" + "
\n" + "
\n\n" "// Using SimXMLDocument by itself\n" "function readXmlExample(%filename)\n" - "{\n" - " %xml = new SimXMLDocument() {};\n" - " %xml.loadFile(%filename);\n\n" - " %xml.pushChildElement(\"DataTables\");\n" - " %xml.pushFirstChildElement(\"table\");\n" - " while(true)\n" - " {\n" - " echo(\"TABLE:\" SPC %xml.attribute(\"tableName\"));\n" - " %xml.pushFirstChildElement(\"rec\");\n" - " while (true)\n" - " {\n" - " %id = %xml.attribute(\"id\");\n" - " %desc = %xml.getData();\n" - " echo(\" Shape\" SPC %id SPC %desc);\n" - " if (!%xml.nextSiblingElement(\"rec\")) break;\n" - " }\n" - " %xml.popElement();\n" - " if (!%xml.nextSiblingElement(\"table\")) break;\n" - " }\n" - "}\n\n" + "{\n" + " %xml = new SimXMLDocument() {};\n" + " %xml.loadFile(%filename);\n\n" + " %xml.pushChildElement(\"DataTables\");\n" + " %xml.pushFirstChildElement(\"table\");\n" + " while(true)\n" + " {\n" + " echo(\"TABLE:\" SPC %xml.attribute(\"tableName\"));\n" + " %xml.pushFirstChildElement(\"rec\");\n" + " while (true)\n" + " {\n" + " %id = %xml.attribute(\"id\");\n" + " %desc = %xml.getData();\n" + " echo(\" Shape\" SPC %id SPC %desc);\n" + " if (!%xml.nextSiblingElement(\"rec\")) break;\n" + " }\n" + " %xml.popElement();\n" + " if (!%xml.nextSiblingElement(\"table\")) break;\n" + " }\n" + "}\n\n" "// Thanks to Scott Peal for this example\n" "// Using FileObject in conjunction with SimXMLDocument\n" @@ -90,45 +90,45 @@ ConsoleDocClass( SimXMLDocument, "// \n" "// \n" "// \n" - "function getModelsInCatagory()\n" - "{\n" - " %file = \"./Catalog.xml\";\n" - " %fo = new FileObject();\n" - " %text = \"\";\n\n" - " if(%fo.openForRead(%file))\n" - " {\n" - " while(!%fo.isEOF())\n" - " {\n" - " %text = %text @ %fo.readLine();\n" - " if (!%fo.isEOF()) %text = %text @ \"\\n\";\n" - " }\n" - " }\n" - " else\n" - " {\n" - " echo(\"Unable to locate the file: \" @ %file);\n" - " }\n\n" - " %fo.delete();\n\n" - " %xml = new SimXMLDocument() {};\n" - " %xml.parse(%text);\n" - " // \"Get\" inside of the root element, \"Models\".\n" - " %xml.pushChildElement(0);\n\n" - " // \"Get\" into the first child element\n" - " if (%xml.pushFirstChildElement(\"Model\"))\n" - " {\n" - " while (true)\n" - " {\n" - " // \n" - " // Here, i read the element's attributes.\n" - " // You might want to save these values in an array or call the %xml.getElementValue()\n" - " // if you have a different XML structure.\n\n" - " %catagory = %xml.attribute(\"catagory\");\n" - " %name = %xml.attribute(\"name\");\n" - " %path = %xml.attribute(\"path\");\n\n" - " // now, read the next \"Model\"\n" - " if (!%xml.nextSiblingElement(\"Model\")) break;\n" - " }\n" - " }\n" - "}\n" + "function getModelsInCatagory()\n" + "{\n" + " %file = \"./Catalog.xml\";\n" + " %fo = new FileObject();\n" + " %text = \"\";\n\n" + " if(%fo.openForRead(%file))\n" + " {\n" + " while(!%fo.isEOF())\n" + " {\n" + " %text = %text @ %fo.readLine();\n" + " if (!%fo.isEOF()) %text = %text @ \"\\n\";\n" + " }\n" + " }\n" + " else\n" + " {\n" + " echo(\"Unable to locate the file: \" @ %file);\n" + " }\n\n" + " %fo.delete();\n\n" + " %xml = new SimXMLDocument() {};\n" + " %xml.parse(%text);\n" + " // \"Get\" inside of the root element, \"Models\".\n" + " %xml.pushChildElement(0);\n\n" + " // \"Get\" into the first child element\n" + " if (%xml.pushFirstChildElement(\"Model\"))\n" + " {\n" + " while (true)\n" + " {\n" + " // \n" + " // Here, i read the element's attributes.\n" + " // You might want to save these values in an array or call the %xml.getElementValue()\n" + " // if you have a different XML structure.\n\n" + " %catagory = %xml.attribute(\"catagory\");\n" + " %name = %xml.attribute(\"name\");\n" + " %path = %xml.attribute(\"path\");\n\n" + " // now, read the next \"Model\"\n" + " if (!%xml.nextSiblingElement(\"Model\")) break;\n" + " }\n" + " }\n" + "}\n" "@endtsexample\n\n" "@note SimXMLDocument is a wrapper around TinyXml, a standard XML library. If you're familiar " @@ -504,13 +504,13 @@ const char* SimXMLDocument::elementValue() { if(m_paNode.empty()) { - return StringTable->insert(""); + return StringTable->EmptyString(); } const S32 iLastElement = m_paNode.size() - 1; TiXmlElement* pNode = m_paNode[iLastElement]; if(!pNode) { - return StringTable->insert(""); + return StringTable->EmptyString(); } return pNode->Value(); @@ -545,18 +545,18 @@ const char* SimXMLDocument::attribute(const char* rAttribute) { if(m_paNode.empty()) { - return StringTable->insert(""); + return StringTable->EmptyString(); } const S32 iLastElement = m_paNode.size() - 1; TiXmlElement* pNode = m_paNode[iLastElement]; if(!pNode) { - return StringTable->insert(""); + return StringTable->EmptyString(); } if(!pNode->Attribute(rAttribute)) { - return StringTable->insert(""); + return StringTable->EmptyString(); } return pNode->Attribute(rAttribute); @@ -629,20 +629,20 @@ const char* SimXMLDocument::firstAttribute() // Get the current element if(m_paNode.empty()) { - return StringTable->insert(""); + return StringTable->EmptyString(); } const S32 iLastElement = m_paNode.size() - 1; TiXmlElement* pNode = m_paNode[iLastElement]; if(!pNode) { - return StringTable->insert(""); + return StringTable->EmptyString(); } // Gets its first attribute, if any m_CurrentAttribute = pNode->FirstAttribute(); if(!m_CurrentAttribute) { - return StringTable->insert(""); + return StringTable->EmptyString(); } return m_CurrentAttribute->Name(); @@ -666,20 +666,20 @@ const char* SimXMLDocument::lastAttribute() // Get the current element if(m_paNode.empty()) { - return StringTable->insert(""); + return StringTable->EmptyString(); } const S32 iLastElement = m_paNode.size() - 1; TiXmlElement* pNode = m_paNode[iLastElement]; if(!pNode) { - return StringTable->insert(""); + return StringTable->EmptyString(); } // Gets its last attribute, if any m_CurrentAttribute = pNode->LastAttribute(); if(!m_CurrentAttribute) { - return StringTable->insert(""); + return StringTable->EmptyString(); } return m_CurrentAttribute->Name(); @@ -703,14 +703,14 @@ const char* SimXMLDocument::nextAttribute() { if(!m_CurrentAttribute) { - return StringTable->insert(""); + return StringTable->EmptyString(); } // Gets its next attribute, if any m_CurrentAttribute = m_CurrentAttribute->Next(); if(!m_CurrentAttribute) { - return StringTable->insert(""); + return StringTable->EmptyString(); } return m_CurrentAttribute->Name(); @@ -734,14 +734,14 @@ const char* SimXMLDocument::prevAttribute() { if(!m_CurrentAttribute) { - return StringTable->insert(""); + return StringTable->EmptyString(); } // Gets its next attribute, if any m_CurrentAttribute = m_CurrentAttribute->Previous(); if(!m_CurrentAttribute) { - return StringTable->insert(""); + return StringTable->EmptyString(); } return m_CurrentAttribute->Name(); diff --git a/Engine/source/console/astAlloc.cpp b/Engine/source/console/astAlloc.cpp index 19809a1e2..fb69f49d5 100644 --- a/Engine/source/console/astAlloc.cpp +++ b/Engine/source/console/astAlloc.cpp @@ -411,7 +411,7 @@ ObjectDeclNode *ObjectDeclNode::alloc( S32 lineNumber, ExprNode *classNameExpr, if(parentObject) ret->parentObject = parentObject; else - ret->parentObject = StringTable->insert(""); + ret->parentObject = StringTable->EmptyString(); return ret; } diff --git a/Engine/source/console/codeBlock.cpp b/Engine/source/console/codeBlock.cpp index 1559f41d8..192b50f0f 100644 --- a/Engine/source/console/codeBlock.cpp +++ b/Engine/source/console/codeBlock.cpp @@ -435,7 +435,7 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) if(offset < globalSize) ste = StringTable->insert(globalStrings + offset); else - ste = StringTable->insert(""); + ste = StringTable->EmptyString(); U32 count; st.read(&count); while(count--) @@ -455,8 +455,8 @@ bool CodeBlock::read(StringTableEntry fileName, Stream &st) bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, const char *inScript, bool overrideNoDso) { - AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread"); - + AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread"); + // This will return true, but return value is ignored char *script; chompUTF8BOM( inScript, &script ); @@ -572,8 +572,8 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con ConsoleValueRef CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame) { - AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread"); - + AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread"); + // Check for a UTF8 script file char *string; chompUTF8BOM( inString, &string ); diff --git a/Engine/source/console/fieldBrushObject.cpp b/Engine/source/console/fieldBrushObject.cpp index 484178dec..407a57cb3 100644 --- a/Engine/source/console/fieldBrushObject.cpp +++ b/Engine/source/console/fieldBrushObject.cpp @@ -41,8 +41,8 @@ ConsoleDocClass( FieldBrushObject, FieldBrushObject::FieldBrushObject() { // Reset Description. - mDescription = StringTable->insert(""); - mSortName = StringTable->insert(""); + mDescription = StringTable->EmptyString(); + mSortName = StringTable->EmptyString(); } diff --git a/Engine/source/console/persistenceManager.cpp b/Engine/source/console/persistenceManager.cpp index 7db907475..c4af549ed 100644 --- a/Engine/source/console/persistenceManager.cpp +++ b/Engine/source/console/persistenceManager.cpp @@ -328,7 +328,7 @@ void PersistenceManager::parseObject() if (mParser.tokenICmp(")")) { - mCurrentObject->name = StringTable->insert(""); + mCurrentObject->name = StringTable->EmptyString(); mCurrentObject->nameLine = mParser.getCurrentLine(); mCurrentObject->namePosition = mParser.getTokenLineOffset(); diff --git a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp index f37d69a4c..e9d654d2a 100644 --- a/Engine/source/gui/buttons/guiIconButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiIconButtonCtrl.cpp @@ -85,7 +85,7 @@ ConsoleDocClass( GuiIconButtonCtrl, GuiIconButtonCtrl::GuiIconButtonCtrl() { - mBitmapName = StringTable->insert(""); + mBitmapName = StringTable->EmptyString(); mTextLocation = TextLocLeft; mIconLocation = IconLocLeft; mTextMargin = 4; @@ -94,7 +94,7 @@ GuiIconButtonCtrl::GuiIconButtonCtrl() mFitBitmapToButton = false; mMakeIconSquare = false; - mErrorBitmapName = StringTable->insert(""); + mErrorBitmapName = StringTable->EmptyString(); mErrorTextureHandle = NULL; mAutoSize = false; diff --git a/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp b/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp index 7168f58ca..a2aaaa6c9 100644 --- a/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiToggleButtonCtrl.cpp @@ -49,7 +49,7 @@ ConsoleDocClass( GuiToggleButtonCtrl, GuiToggleButtonCtrl::GuiToggleButtonCtrl() { setExtent(140, 30); - mButtonText = StringTable->insert(""); + mButtonText = StringTable->EmptyString(); mStateOn = false; mButtonType = ButtonTypeCheck; } diff --git a/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp b/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp index 9242d8aff..ad65b5782 100644 --- a/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiToolboxButtonCtrl.cpp @@ -43,7 +43,7 @@ ConsoleDocClass( GuiToolboxButtonCtrl, //------------------------------------- GuiToolboxButtonCtrl::GuiToolboxButtonCtrl() { - mNormalBitmapName = StringTable->insert(""); + mNormalBitmapName = StringTable->EmptyString(); mLoweredBitmapName = StringTable->insert("sceneeditor/client/images/buttondown"); mHoverBitmapName = StringTable->insert("sceneeditor/client/images/buttonup"); setMinExtent(Point2I(16,16)); @@ -225,4 +225,4 @@ void GuiToolboxButtonCtrl::renderButton(GFXTexHandle &texture, Point2I &offset, GFX->getDrawUtil()->drawBitmap(texture, finalOffset); renderChildControls( offset, updateRect); } -} \ No newline at end of file +} diff --git a/Engine/source/gui/containers/guiFormCtrl.cpp b/Engine/source/gui/containers/guiFormCtrl.cpp index bbd9a7f9e..f94e6c234 100644 --- a/Engine/source/gui/containers/guiFormCtrl.cpp +++ b/Engine/source/gui/containers/guiFormCtrl.cpp @@ -50,8 +50,8 @@ GuiFormCtrl::GuiFormCtrl() mCaption = "[none]"; mUseSmallCaption = false; - mContentLibrary = StringTable->insert(""); - mContent = StringTable->insert(""); + mContentLibrary = StringTable->EmptyString(); + mContent = StringTable->EmptyString(); mCanSaveFieldDictionary = true; mIsContainer = true; @@ -213,7 +213,7 @@ bool GuiFormCtrl::resize(const Point2I &newPosition, const Point2I &newExtent) static char buf[256]; mUseSmallCaption = true; - mSmallCaption = StringTable->insert(""); + mSmallCaption = StringTable->EmptyString(); S32 strlen = dStrlen((const char*)mCaption); for(S32 i=strlen; i>=0; --i) diff --git a/Engine/source/gui/containers/guiPaneCtrl.cpp b/Engine/source/gui/containers/guiPaneCtrl.cpp index c42fc9e51..4d2ae5e61 100644 --- a/Engine/source/gui/containers/guiPaneCtrl.cpp +++ b/Engine/source/gui/containers/guiPaneCtrl.cpp @@ -68,7 +68,7 @@ GuiPaneControl::GuiPaneControl() mMouseOver = false; mDepressed = false; mCaption = "A Pane"; - mCaptionID = StringTable->insert(""); + mCaptionID = StringTable->EmptyString(); mIsContainer = true; mOriginalExtents.set(10,10); diff --git a/Engine/source/gui/containers/guiWindowCtrl.cpp b/Engine/source/gui/containers/guiWindowCtrl.cpp index 2957ec7ec..df8838fa1 100644 --- a/Engine/source/gui/containers/guiWindowCtrl.cpp +++ b/Engine/source/gui/containers/guiWindowCtrl.cpp @@ -1512,7 +1512,7 @@ void GuiWindowCtrl::setCloseCommand(const char *newCmd) if (newCmd) mCloseCommand = StringTable->insert(newCmd); else - mCloseCommand = StringTable->insert(""); + mCloseCommand = StringTable->EmptyString(); } //----------------------------------------------------------------------------- diff --git a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp index 760a0246a..e64f2c7c0 100644 --- a/Engine/source/gui/controls/guiGameListMenuCtrl.cpp +++ b/Engine/source/gui/controls/guiGameListMenuCtrl.cpp @@ -38,7 +38,7 @@ GuiGameListMenuCtrl::GuiGameListMenuCtrl() VECTOR_SET_ASSOCIATION(mRows); // initialize the control callbacks - mCallbackOnA = StringTable->insert(""); + mCallbackOnA = StringTable->EmptyString(); mCallbackOnB = mCallbackOnA; mCallbackOnX = mCallbackOnA; mCallbackOnY = mCallbackOnA; @@ -572,7 +572,7 @@ StringTableEntry GuiGameListMenuCtrl::getRowLabel(S32 rowIndex) const if (! isValidRowIndex(rowIndex)) { // not a valid row index, don't do anything - return StringTable->insert(""); + return StringTable->EmptyString(); } return mRows[rowIndex]->mLabel; } diff --git a/Engine/source/gui/controls/guiListBoxCtrl.cpp b/Engine/source/gui/controls/guiListBoxCtrl.cpp index 5deab67fc..992d64903 100644 --- a/Engine/source/gui/controls/guiListBoxCtrl.cpp +++ b/Engine/source/gui/controls/guiListBoxCtrl.cpp @@ -1530,7 +1530,7 @@ void GuiListBoxCtrl::_mirror() StringTableEntry GuiListBoxCtrl::_makeMirrorItemName( SimObject *inObj ) { - StringTableEntry outName = StringTable->insert(""); + StringTableEntry outName = StringTable->EmptyString(); if ( mMakeNameCallback.isNotEmpty() ) { @@ -1634,4 +1634,4 @@ void GuiListBoxCtrl::removeFilteredItem( String item ) break; } } -} \ No newline at end of file +} diff --git a/Engine/source/gui/controls/guiMLTextCtrl.cpp b/Engine/source/gui/controls/guiMLTextCtrl.cpp index 6cfdf4354..e61a82cc5 100644 --- a/Engine/source/gui/controls/guiMLTextCtrl.cpp +++ b/Engine/source/gui/controls/guiMLTextCtrl.cpp @@ -251,7 +251,7 @@ GuiMLTextCtrl::GuiMLTextCtrl() mIsEditCtrl( false ), mCursorPosition( false ), mMaxBufferSize( -1 ), - mInitialText( StringTable->insert("") ), + mInitialText( StringTable->EmptyString() ), mSelectionActive( false ), mSelectionStart( 0 ), mSelectionEnd( 0 ), @@ -267,7 +267,7 @@ GuiMLTextCtrl::GuiMLTextCtrl() mFontList( NULL ) { mActive = true; - //mInitialText = StringTable->insert(""); + //mInitialText = StringTable->EmptyString(); Sim::findObject("InputDeniedSound", mDeniedSound); } diff --git a/Engine/source/gui/controls/guiPopUpCtrl.cpp b/Engine/source/gui/controls/guiPopUpCtrl.cpp index beb9fbcc8..af172221a 100644 --- a/Engine/source/gui/controls/guiPopUpCtrl.cpp +++ b/Engine/source/gui/controls/guiPopUpCtrl.cpp @@ -277,7 +277,7 @@ GuiPopUpMenuCtrl::GuiPopUpMenuCtrl(void) mRenderScrollInNA = false; // Added mBackgroundCancel = false; // Added mReverseTextList = false; // Added - Don't reverse text list if displaying up - mBitmapName = StringTable->insert(""); // Added + mBitmapName = StringTable->EmptyString(); // Added mBitmapBounds.set(16, 16); // Added mIdMax = -1; } diff --git a/Engine/source/gui/controls/guiPopUpCtrlEx.cpp b/Engine/source/gui/controls/guiPopUpCtrlEx.cpp index 510576f8a..3c6415117 100644 --- a/Engine/source/gui/controls/guiPopUpCtrlEx.cpp +++ b/Engine/source/gui/controls/guiPopUpCtrlEx.cpp @@ -328,7 +328,7 @@ GuiPopUpMenuCtrlEx::GuiPopUpMenuCtrlEx(void) mRenderScrollInNA = false; // Added mBackgroundCancel = false; // Added mReverseTextList = false; // Added - Don't reverse text list if displaying up - mBitmapName = StringTable->insert(""); // Added + mBitmapName = StringTable->EmptyString(); // Added mBitmapBounds.set(16, 16); // Added mHotTrackItems = false; mIdMax = -1; diff --git a/Engine/source/gui/controls/guiTextCtrl.cpp b/Engine/source/gui/controls/guiTextCtrl.cpp index e8c9057f1..8759e3973 100644 --- a/Engine/source/gui/controls/guiTextCtrl.cpp +++ b/Engine/source/gui/controls/guiTextCtrl.cpp @@ -54,8 +54,8 @@ ConsoleDocClass( GuiTextCtrl, GuiTextCtrl::GuiTextCtrl() { //default fonts - mInitialText = StringTable->insert(""); - mInitialTextID = StringTable->insert(""); + mInitialText = StringTable->EmptyString(); + mInitialTextID = StringTable->EmptyString(); mText[0] = '\0'; mMaxStrLen = GuiTextCtrl::MAX_STRING_LENGTH; } diff --git a/Engine/source/gui/controls/guiTextEditCtrl.cpp b/Engine/source/gui/controls/guiTextEditCtrl.cpp index 9084e8d8d..968fe17a6 100644 --- a/Engine/source/gui/controls/guiTextEditCtrl.cpp +++ b/Engine/source/gui/controls/guiTextEditCtrl.cpp @@ -1684,7 +1684,7 @@ DefineEngineMethod( GuiTextEditCtrl, getText, const char*, (),, "@see GuiControl") { if( !object->hasText() ) - return StringTable->insert(""); + return StringTable->EmptyString(); char *retBuffer = Con::getReturnBuffer( GuiTextEditCtrl::MAX_STRING_LENGTH ); object->getText( retBuffer ); diff --git a/Engine/source/gui/controls/guiTreeViewCtrl.cpp b/Engine/source/gui/controls/guiTreeViewCtrl.cpp index e1b20ad5f..e4fb9ab00 100644 --- a/Engine/source/gui/controls/guiTreeViewCtrl.cpp +++ b/Engine/source/gui/controls/guiTreeViewCtrl.cpp @@ -845,7 +845,7 @@ GuiTreeViewCtrl::GuiTreeViewCtrl() mClearAllOnSingleSelection = true; - mBitmapBase = StringTable->insert(""); + mBitmapBase = StringTable->EmptyString(); mTexRollover = NULL; mTexSelected = NULL; @@ -4746,13 +4746,13 @@ StringTableEntry GuiTreeViewCtrl::getTextToRoot( S32 itemId, const char * delimi if(!item) { Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getTextToRoot: invalid start item id!"); - return StringTable->insert(""); + return StringTable->EmptyString(); } if(item->isInspectorData()) { Con::errorf(ConsoleLogEntry::General, "GuiTreeViewCtrl::getTextToRoot: cannot get text to root of inspector data items"); - return StringTable->insert(""); + return StringTable->EmptyString(); } char bufferOne[1024]; diff --git a/Engine/source/gui/editor/guiParticleGraphCtrl.cpp b/Engine/source/gui/editor/guiParticleGraphCtrl.cpp index 8e20bfeef..68ecf81c4 100644 --- a/Engine/source/gui/editor/guiParticleGraphCtrl.cpp +++ b/Engine/source/gui/editor/guiParticleGraphCtrl.cpp @@ -50,7 +50,7 @@ GuiParticleGraphCtrl::GuiParticleGraphCtrl() mPlots[i].mGraphMin.x = 0; mPlots[i].mGraphMin.y = 0; mPlots[i].mGraphType = Polyline; - mPlots[i].mGraphName = StringTable->insert(""); + mPlots[i].mGraphName = StringTable->EmptyString(); mPlots[i].mHidden = false; mPlots[i].mGraphScale = 0.05f; } diff --git a/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp b/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp index 2b122f540..d0f9549e1 100644 --- a/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp +++ b/Engine/source/gui/game/guiChunkedBitmapCtrl.cpp @@ -86,7 +86,7 @@ DefineEngineMethod( GuiChunkedBitmapCtrl, setBitmap, void, (const char* filename GuiChunkedBitmapCtrl::GuiChunkedBitmapCtrl() { - mBitmapName = StringTable->insert(""); + mBitmapName = StringTable->EmptyString(); mUseVariable = false; mTile = false; } diff --git a/Engine/source/gui/worldEditor/undoActions.cpp b/Engine/source/gui/worldEditor/undoActions.cpp index 94495d89e..d88b72bcd 100644 --- a/Engine/source/gui/worldEditor/undoActions.cpp +++ b/Engine/source/gui/worldEditor/undoActions.cpp @@ -218,8 +218,8 @@ InspectorFieldUndoAction::InspectorFieldUndoAction() { mObjId = 0; mField = NULL; - mSlotName = StringTable->insert(""); - mArrayIdx = StringTable->insert(""); + mSlotName = StringTable->EmptyString(); + mArrayIdx = StringTable->EmptyString(); } InspectorFieldUndoAction::InspectorFieldUndoAction( const UTF8 *actionName ) @@ -228,8 +228,8 @@ InspectorFieldUndoAction::InspectorFieldUndoAction( const UTF8 *actionName ) mInspector = NULL; mObjId = 0; mField = NULL; - mSlotName = StringTable->insert(""); - mArrayIdx = StringTable->insert(""); + mSlotName = StringTable->EmptyString(); + mArrayIdx = StringTable->EmptyString(); } void InspectorFieldUndoAction::initPersistFields() @@ -272,4 +272,4 @@ void InspectorFieldUndoAction::undo() // Now save the previous data in this UndoAction // since an undo action must become a redo action and vice-versa mData = data; -} \ No newline at end of file +} diff --git a/Engine/source/navigation/navMesh.cpp b/Engine/source/navigation/navMesh.cpp index 2d4b0ad7e..7dbb40d6d 100644 --- a/Engine/source/navigation/navMesh.cpp +++ b/Engine/source/navigation/navMesh.cpp @@ -181,7 +181,7 @@ DefineConsoleFunction(NavMeshUpdateOne, void, (S32 meshid, S32 objid, bool remov NavMesh::NavMesh() { mTypeMask |= StaticShapeObjectType | MarkerObjectType; - mFileName = StringTable->insert(""); + mFileName = StringTable->EmptyString(); mNetFlags.clear(Ghostable); mSaveIntermediates = false; @@ -211,7 +211,7 @@ NavMesh::NavMesh() mLargeCharacters = false; mVehicles = false; - mCoverSet = StringTable->insert(""); + mCoverSet = StringTable->EmptyString(); mInnerCover = false; mCoverDist = 1.0f; mPeekDist = 0.7f; diff --git a/Engine/source/navigation/navPath.cpp b/Engine/source/navigation/navPath.cpp index a945e7f8d..9409cc193 100644 --- a/Engine/source/navigation/navPath.cpp +++ b/Engine/source/navigation/navPath.cpp @@ -170,7 +170,7 @@ const char *NavPath::getProtectedFrom(void *obj, const char *data) if(object->mFromSet) return data; else - return StringTable->insert(""); + return StringTable->EmptyString(); } const char *NavPath::getProtectedTo(void *obj, const char *data) @@ -180,7 +180,7 @@ const char *NavPath::getProtectedTo(void *obj, const char *data) if(object->mToSet) return data; else - return StringTable->insert(""); + return StringTable->EmptyString(); } IRangeValidator ValidIterations(1, S32_MAX); diff --git a/Engine/source/platform/menus/popupMenu.cpp b/Engine/source/platform/menus/popupMenu.cpp index a7fc2e989..7e8aad7ba 100644 --- a/Engine/source/platform/menus/popupMenu.cpp +++ b/Engine/source/platform/menus/popupMenu.cpp @@ -51,7 +51,7 @@ PopupMenu::PopupMenu() : mCanvas(NULL) mSubmenus = new SimSet; mSubmenus->registerObject(); - mBarTitle = StringTable->insert(""); + mBarTitle = StringTable->EmptyString(); mIsPopup = false; mPopupGUID = sMaxPopupGUID++; diff --git a/Engine/source/platform/nativeDialogs/fileDialog.cpp b/Engine/source/platform/nativeDialogs/fileDialog.cpp index 08d689585..09ed1c63e 100644 --- a/Engine/source/platform/nativeDialogs/fileDialog.cpp +++ b/Engine/source/platform/nativeDialogs/fileDialog.cpp @@ -48,10 +48,10 @@ FileDialogData::FileDialogData() if (mDefaultPath == StringTable->lookup("") || !Platform::isDirectory(mDefaultPath)) mDefaultPath = Platform::getCurrentDirectory(); - mDefaultFile = StringTable->insert(""); - mFilters = StringTable->insert(""); - mFile = StringTable->insert(""); - mTitle = StringTable->insert(""); + mDefaultFile = StringTable->EmptyString(); + mFilters = StringTable->EmptyString(); + mFile = StringTable->EmptyString(); + mTitle = StringTable->EmptyString(); mStyle = 0; From de53ac86c7e7e07389628086c58e1d94e3da4cab Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 13 Jan 2017 10:42:52 -0500 Subject: [PATCH 35/50] Somebody broke SDL when they updated it. The new version depends on AudioToolbox, so added that as dependency in torque3d.cmake --- Engine/lib/sdl/Android.mk | 0 Engine/lib/sdl/BUGS.txt | 2 +- Engine/lib/sdl/CMakeLists.txt | 183 +++-- Engine/lib/sdl/Makefile.in | 11 +- Engine/lib/sdl/Makefile.pandora | 2 +- Engine/lib/sdl/Makefile.psp | 1 + Engine/lib/sdl/Makefile.wiz | 10 +- Engine/lib/sdl/README-SDL.txt | 4 +- Engine/lib/sdl/SDL2.spec | 2 +- Engine/lib/sdl/VisualC.html | 4 +- Engine/lib/sdl/VisualC/clean.sh | 4 - Engine/lib/sdl/WhatsNew.txt | 63 ++ Engine/lib/sdl/Xcode/SDL/Info-Framework.plist | 6 +- .../Xcode/SDL/SDL.xcodeproj/project.pbxproj | 117 +-- Engine/lib/sdl/Xcode/SDL/pkg-support/SDL.info | 0 .../SDL/pkg-support/resources/ReadMe.txt | 0 .../SDLTest/SDLTest.xcodeproj/project.pbxproj | 4 +- Engine/lib/sdl/autogen.sh | 6 + Engine/lib/sdl/build-scripts/androidbuild.sh | 8 +- .../lib/sdl/build-scripts/checker-buildbot.sh | 6 +- .../sdl/build-scripts/emscripten-buildbot.sh | 7 +- Engine/lib/sdl/build-scripts/g++-fat.sh | 6 +- Engine/lib/sdl/build-scripts/gcc-fat.sh | 8 +- Engine/lib/sdl/build-scripts/install-sh | 0 Engine/lib/sdl/build-scripts/iosbuild.sh | 0 Engine/lib/sdl/build-scripts/ltmain.sh | 0 Engine/lib/sdl/build-scripts/mkinstalldirs | 0 Engine/lib/sdl/build-scripts/nacl-buildbot.sh | 0 Engine/lib/sdl/build-scripts/naclbuild.sh | 0 .../sdl/build-scripts/raspberrypi-buildbot.sh | 0 Engine/lib/sdl/build-scripts/showrev.sh | 4 +- Engine/lib/sdl/build-scripts/strip_fPIC.sh | 0 .../lib/sdl/build-scripts/update-copyright.sh | 0 Engine/lib/sdl/build-scripts/updaterev.sh | 0 Engine/lib/sdl/cmake/sdlchecks.cmake | 98 ++- Engine/lib/sdl/configure | 289 +++++++- Engine/lib/sdl/configure.in | 200 ++++- Engine/lib/sdl/debian/changelog | 6 + Engine/lib/sdl/debian/copyright | 11 - Engine/lib/sdl/debian/libsdl2-dev.install | 1 + Engine/lib/sdl/debian/rules | 0 Engine/lib/sdl/sdl2-config.cmake.in | 1 + Engine/lib/sdl/sdl2.m4 | 54 +- Engine/lib/sdl/src/audio/SDL_audiomem.h | 25 - .../sdl/src/audio/coreaudio/SDL_coreaudio.c | 698 ------------------ Engine/lib/sdl/src/audio/sdlgenaudiocvt.pl | 0 Engine/lib/sdl/src/dynapi/gendynapi.pl | 0 .../lib/sdl/src/joystick/sort_controllers.py | 0 Engine/lib/sdl/src/video/sdlgenblit.pl | 0 Engine/lib/sdl/test/Makefile.in | 16 + Engine/lib/sdl/test/autogen.sh | 0 Engine/lib/sdl/test/configure | 0 Engine/lib/sdl/test/controllermap.c | 9 +- Engine/lib/sdl/test/gcc-fat.sh | 0 Engine/lib/sdl/test/testatomic.c | 12 +- Engine/lib/sdl/test/testaudiocapture.c | 165 +++++ Engine/lib/sdl/test/testaudiohotplug.c | 28 +- Engine/lib/sdl/test/testaudioinfo.c | 12 +- Engine/lib/sdl/test/testautomation_events.c | 4 +- Engine/lib/sdl/test/testautomation_keyboard.c | 16 +- Engine/lib/sdl/test/testautomation_main.c | 4 +- Engine/lib/sdl/test/testautomation_sdltest.c | 2 +- Engine/lib/sdl/test/testautomation_stdlib.c | 44 +- Engine/lib/sdl/test/testbounds.c | 40 + Engine/lib/sdl/test/testcustomcursor.c | 216 ++++++ Engine/lib/sdl/test/testdisplayinfo.c | 7 + Engine/lib/sdl/test/testdrawchessboard.c | 2 +- Engine/lib/sdl/test/testdropfile.c | 9 +- Engine/lib/sdl/test/testfilesystem.c | 5 +- Engine/lib/sdl/test/testgamecontroller.c | 12 +- Engine/lib/sdl/test/testgles.c | 2 +- Engine/lib/sdl/test/testgles2.c | 4 +- Engine/lib/sdl/test/testime.c | 500 ++++++++++++- Engine/lib/sdl/test/testlock.c | 12 +- Engine/lib/sdl/test/testmultiaudio.c | 11 +- Engine/lib/sdl/test/testqsort.c | 108 +++ Engine/lib/sdl/test/testrendercopyex.c | 4 +- Engine/lib/sdl/test/testshape.c | 4 + Engine/lib/sdl/test/testwm2.c | 14 +- Engine/lib/sdl/test/torturethread.c | 8 +- Engine/source/.gitattributes | 5 + Tools/CMake/torque3d.cmake | 1 + 82 files changed, 2082 insertions(+), 1035 deletions(-) mode change 100644 => 100755 Engine/lib/sdl/Android.mk delete mode 100644 Engine/lib/sdl/VisualC/clean.sh mode change 100644 => 100755 Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj mode change 100644 => 100755 Engine/lib/sdl/Xcode/SDL/pkg-support/SDL.info mode change 100644 => 100755 Engine/lib/sdl/Xcode/SDL/pkg-support/resources/ReadMe.txt mode change 100644 => 100755 Engine/lib/sdl/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj mode change 100644 => 100755 Engine/lib/sdl/autogen.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/androidbuild.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/checker-buildbot.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/emscripten-buildbot.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/g++-fat.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/gcc-fat.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/install-sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/iosbuild.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/ltmain.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/mkinstalldirs mode change 100644 => 100755 Engine/lib/sdl/build-scripts/nacl-buildbot.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/naclbuild.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/raspberrypi-buildbot.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/showrev.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/strip_fPIC.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/update-copyright.sh mode change 100644 => 100755 Engine/lib/sdl/build-scripts/updaterev.sh mode change 100644 => 100755 Engine/lib/sdl/configure mode change 100644 => 100755 Engine/lib/sdl/debian/rules delete mode 100644 Engine/lib/sdl/src/audio/SDL_audiomem.h delete mode 100644 Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.c mode change 100644 => 100755 Engine/lib/sdl/src/audio/sdlgenaudiocvt.pl mode change 100644 => 100755 Engine/lib/sdl/src/dynapi/gendynapi.pl mode change 100644 => 100755 Engine/lib/sdl/src/joystick/sort_controllers.py mode change 100644 => 100755 Engine/lib/sdl/src/video/sdlgenblit.pl mode change 100644 => 100755 Engine/lib/sdl/test/autogen.sh mode change 100644 => 100755 Engine/lib/sdl/test/configure mode change 100644 => 100755 Engine/lib/sdl/test/gcc-fat.sh create mode 100644 Engine/lib/sdl/test/testaudiocapture.c create mode 100644 Engine/lib/sdl/test/testbounds.c create mode 100644 Engine/lib/sdl/test/testcustomcursor.c create mode 100644 Engine/lib/sdl/test/testqsort.c create mode 100644 Engine/source/.gitattributes diff --git a/Engine/lib/sdl/Android.mk b/Engine/lib/sdl/Android.mk old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/BUGS.txt b/Engine/lib/sdl/BUGS.txt index c5ed3af23..6a4cbb7ad 100644 --- a/Engine/lib/sdl/BUGS.txt +++ b/Engine/lib/sdl/BUGS.txt @@ -1,7 +1,7 @@ Bugs are now managed in the SDL bug tracker, here: - http://bugzilla.libsdl.org/ + https://bugzilla.libsdl.org/ You may report bugs there, and search to see if a given issue has already been reported, discussed, and maybe even fixed. diff --git a/Engine/lib/sdl/CMakeLists.txt b/Engine/lib/sdl/CMakeLists.txt index 63244a9e2..54a23f0c7 100644 --- a/Engine/lib/sdl/CMakeLists.txt +++ b/Engine/lib/sdl/CMakeLists.txt @@ -2,8 +2,19 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL source code and call cmake from there") endif() -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.5) project(SDL2 C) + +# !!! FIXME: this should probably do "MACOSX_RPATH ON" as a target property +# !!! FIXME: for the SDL2 shared library (so you get an +# !!! FIXME: install_name ("soname") of "@rpath/libSDL-whatever.dylib" +# !!! FIXME: instead of "/usr/local/lib/libSDL-whatever.dylib"), but I'm +# !!! FIXME: punting for now and leaving the existing behavior. Until this +# !!! FIXME: properly resolved, this line silences a warning in CMake 3.0+. +# !!! FIXME: remove it and this comment entirely once the problem is +# !!! FIXME: properly resolved. +#cmake_policy(SET CMP0042 OLD) + include(CheckFunctionExists) include(CheckLibraryExists) include(CheckIncludeFiles) @@ -15,6 +26,7 @@ include(CheckTypeSize) include(CheckStructHasMember) include(CMakeDependentOption) include(FindPkgConfig) +include(GNUInstallDirs) set(CMAKE_MODULE_PATH "${SDL2_SOURCE_DIR}/cmake") include(${SDL2_SOURCE_DIR}/cmake/macros.cmake) include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake) @@ -29,9 +41,9 @@ include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake) # set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. set(SDL_MAJOR_VERSION 2) set(SDL_MINOR_VERSION 0) -set(SDL_MICRO_VERSION 4) -set(SDL_INTERFACE_AGE 0) -set(SDL_BINARY_AGE 4) +set(SDL_MICRO_VERSION 5) +set(SDL_INTERFACE_AGE 1) +set(SDL_BINARY_AGE 5) set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}") # Calculate a libtool-like version number @@ -147,8 +159,10 @@ endif() # Default flags, if not set otherwise if("$ENV{CFLAGS}" STREQUAL "") - if(USE_GCC OR USE_CLANG) - set(CMAKE_C_FLAGS "-g -O3") + if(CMAKE_BUILD_TYPE STREQUAL "") + if(USE_GCC OR USE_CLANG) + set(CMAKE_C_FLAGS "-g -O3") + endif() endif() else() set(CMAKE_C_FLAGS "$ENV{CFLAGS}") @@ -183,8 +197,8 @@ endif() set(SDL_LIBS "-lSDL2") set(SDL_CFLAGS "") -# Emscripten toolchain has a nonempty default value for this, and the checks -# in this file need to change that, so remember the original value, and +# Emscripten toolchain has a nonempty default value for this, and the checks +# in this file need to change that, so remember the original value, and # restore back to that afterwards. For check_function_exists() to work in # Emscripten, this value must be at its default value. set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) @@ -192,7 +206,7 @@ set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) if(CYGWIN) # We build SDL on cygwin without the UNIX emulation layer include_directories("-I/usr/include/mingw") - set(CMAKE_REQUIRED_FLAGS "-mno-cygwin") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mno-cygwin") check_c_source_compiles("int main(int argc, char **argv) {}" HAVE_GCC_NO_CYGWIN) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) @@ -212,7 +226,7 @@ include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include) set(OPT_DEF_ASM TRUE) if(EMSCRIPTEN) # Set up default values for the currently supported set of subsystems: - # Emscripten/Javascript does not have assembly support, a dynamic library + # Emscripten/Javascript does not have assembly support, a dynamic library # loading architecture, low-level CPU inspection or multithreading. set(OPT_DEF_ASM FALSE) set(SDL_SHARED_ENABLED_BY_DEFAULT OFF) @@ -299,6 +313,8 @@ set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS}) set(SDL_SHARED ${SDL_SHARED_ENABLED_BY_DEFAULT} CACHE BOOL "Build a shared version of the library") set(SDL_STATIC ON CACHE BOOL "Build a static version of the library") +dep_option(SDL_STATIC_PIC "Static version of the library should be built with Position Independent Code" OFF "SDL_STATIC" OFF) + # General source files file(GLOB SOURCE_FILES ${SDL2_SOURCE_DIR}/src/*.c @@ -334,6 +350,24 @@ set(HAVE_ASSERTIONS ${ASSERTIONS}) # Compiler option evaluation if(USE_GCC OR USE_CLANG) + # Check for -Wall first, so later things can override pieces of it. + check_c_compiler_flag(-Wall HAVE_GCC_WALL) + if(HAVE_GCC_WALL) + list(APPEND EXTRA_CFLAGS "-Wall") + if(HAIKU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar") + endif() + endif() + + check_c_compiler_flag(-Wdeclaration-after-statement HAVE_GCC_WDECLARATION_AFTER_STATEMENT) + if(HAVE_GCC_WDECLARATION_AFTER_STATEMENT) + check_c_compiler_flag(-Werror=declaration-after-statement HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT) + if(HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT) + list(APPEND EXTRA_CFLAGS "-Werror=declaration-after-statement") + endif() + list(APPEND EXTRA_CFLAGS "-Wdeclaration-after-statement") + endif() + if(DEPENDENCY_TRACKING) check_c_source_compiles(" #if !defined(__GNUC__) || __GNUC__ < 3 @@ -375,26 +409,16 @@ if(USE_GCC OR USE_CLANG) endif() set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) - check_c_compiler_flag(-Wall HAVE_GCC_WALL) - if(HAVE_GCC_WALL) - list(APPEND EXTRA_CFLAGS "-Wall") - if(HAIKU) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar") - endif() - endif() check_c_compiler_flag(-Wshadow HAVE_GCC_WSHADOW) if(HAVE_GCC_WSHADOW) list(APPEND EXTRA_CFLAGS "-Wshadow") endif() - # --no-undefined is unsupported with clang - if(NOT USE_CLANG) - set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined") - check_c_compiler_flag("" HAVE_NO_UNDEFINED) - set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) - if(HAVE_NO_UNDEFINED) - list(APPEND EXTRA_LDFLAGS "-Wl,--no-undefined") - endif() + set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined") + check_c_compiler_flag("" HAVE_NO_UNDEFINED) + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + if(HAVE_NO_UNDEFINED) + list(APPEND EXTRA_LDFLAGS "-Wl,--no-undefined") endif() endif() @@ -773,6 +797,16 @@ if(EMSCRIPTEN) set(SOURCE_FILES ${SOURCE_FILES} ${EM_POWER_SOURCES}) set(HAVE_SDL_POWER TRUE) endif() + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + + if(CLOCK_GETTIME) + set(HAVE_CLOCK_GETTIME 1) + endif() + endif() if(SDL_VIDEO) set(SDL_VIDEO_DRIVER_EMSCRIPTEN 1) file(GLOB EM_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/emscripten/*.c) @@ -839,7 +873,7 @@ elseif(UNIX AND NOT APPLE) #include #include - int main(int argc, char **argv) + int main(int argc, char **argv) { struct kbentry kbe; kbe.kb_table = KG_CTRL; @@ -866,8 +900,24 @@ elseif(UNIX AND NOT APPLE) check_include_file("libudev.h" HAVE_LIBUDEV_H) - # !!! FIXME: this needs pkg-config to find the include path, I think. - check_include_file("dbus/dbus.h" HAVE_DBUS_DBUS_H) + if(PKG_CONFIG_FOUND) + pkg_search_module(DBUS dbus-1 dbus) + if(DBUS_FOUND) + set(HAVE_DBUS_DBUS_H TRUE) + include_directories(${DBUS_INCLUDE_DIRS}) + list(APPEND EXTRA_LIBS ${DBUS_LIBRARIES}) + endif() + + pkg_search_module(IBUS ibus-1.0 ibus) + if(IBUS_FOUND) + set(HAVE_IBUS_IBUS_H TRUE) + include_directories(${IBUS_INCLUDE_DIRS}) + list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES}) + endif() + endif() + + check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H) + endif() if(INPUT_TSLIB) @@ -936,7 +986,14 @@ elseif(UNIX AND NOT APPLE) if(RPATH) set(SDL_RLD_FLAGS "") if(BSDI OR FREEBSD OR LINUX OR NETBSD) - set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir}") + set(CMAKE_REQUIRED_FLAGS "-Wl,--enable-new-dtags") + check_c_compiler_flag("" HAVE_ENABLE_NEW_DTAGS) + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + if(HAVE_ENABLE_NEW_DTAGS) + set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir} -Wl,--enable-new-dtags") + else() + set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir}") + endif() elseif(SOLARIS) set(SDL_RLD_FLAGS "-R\${libdir}") endif() @@ -1108,7 +1165,7 @@ elseif(WINDOWS) set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) if(HAVE_DINPUT_H) set(SDL_JOYSTICK_DINPUT 1) - list(APPEND EXTRA_LIBS dinput8 dxguid) + list(APPEND EXTRA_LIBS dinput8) if(CMAKE_COMPILER_IS_MINGW) list(APPEND EXTRA_LIBS dxerr8) elseif (NOT USE_WINSDK_DIRECTX) @@ -1166,16 +1223,20 @@ elseif(APPLE) if(SDL_AUDIO) set(SDL_AUDIO_DRIVER_COREAUDIO 1) - file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.c) + file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.m) set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES}) set(HAVE_SDL_AUDIO TRUE) set(SDL_FRAMEWORK_COREAUDIO 1) - set(SDL_FRAMEWORK_AUDIOUNIT 1) + set(SDL_FRAMEWORK_AUDIOTOOLBOX 1) endif() if(SDL_JOYSTICK) set(SDL_JOYSTICK_IOKIT 1) - file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c) + if (IOS) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m) + else() + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c) + endif() set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) set(HAVE_SDL_JOYSTICK TRUE) set(SDL_FRAMEWORK_IOKIT 1) @@ -1184,7 +1245,12 @@ elseif(APPLE) if(SDL_HAPTIC) set(SDL_HAPTIC_IOKIT 1) - file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/darwin/*.c) + if (IOS) + file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/dummy/*.c) + set(SDL_HAPTIC_DUMMY 1) + else() + file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/darwin/*.c) + endif() set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES}) set(HAVE_SDL_HAPTIC TRUE) set(SDL_FRAMEWORK_IOKIT 1) @@ -1196,7 +1262,11 @@ elseif(APPLE) if(SDL_POWER) set(SDL_POWER_MACOSX 1) - file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/macosx/*.c) + if (IOS) + file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/uikit/*.m) + else() + file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/macosx/*.c) + endif() set(SOURCE_FILES ${SOURCE_FILES} ${POWER_SOURCES}) set(HAVE_SDL_POWER TRUE) set(SDL_FRAMEWORK_CARBON 1) @@ -1243,19 +1313,25 @@ elseif(APPLE) find_library(COREAUDIO CoreAudio) list(APPEND EXTRA_LIBS ${COREAUDIO}) endif() - if(SDL_FRAMEWORK_AUDIOUNIT) - find_library(AUDIOUNIT AudioUnit) - list(APPEND EXTRA_LIBS ${AUDIOUNIT}) + if(SDL_FRAMEWORK_AUDIOTOOLBOX) + find_library(AUDIOTOOLBOX AudioToolbox) + list(APPEND EXTRA_LIBS ${AUDIOTOOLBOX}) endif() # iOS hack needed - http://code.google.com/p/ios-cmake/ ? if(SDL_VIDEO) - CheckCOCOA() - if(VIDEO_OPENGL) - set(SDL_VIDEO_OPENGL 1) - set(SDL_VIDEO_OPENGL_CGL 1) - set(SDL_VIDEO_RENDER_OGL 1) - set(HAVE_VIDEO_OPENGL TRUE) + if (IOS) + set(SDL_VIDEO_DRIVER_UIKIT 1) + file(GLOB UIKITVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/uikit/*.m) + set(SOURCE_FILES ${SOURCE_FILES} ${UIKITVIDEO_SOURCES}) + else() + CheckCOCOA() + if(VIDEO_OPENGL) + set(SDL_VIDEO_OPENGL 1) + set(SDL_VIDEO_OPENGL_CGL 1) + set(SDL_VIDEO_RENDER_OGL 1) + set(HAVE_VIDEO_OPENGL TRUE) + endif() endif() endif() @@ -1442,6 +1518,9 @@ message(STATUS " EXTRA_LIBS: ${EXTRA_LIBS}") message(STATUS "") message(STATUS " Build Shared Library: ${SDL_SHARED}") message(STATUS " Build Static Library: ${SDL_STATIC}") +if(SDL_STATIC) + message(STATUS " Build Static Library with Position Independent Code: ${SDL_STATIC_PIC}") +endif() message(STATUS "") if(UNIX) message(STATUS "If something was not detected, although the libraries") @@ -1458,7 +1537,7 @@ add_library(SDL2main STATIC ${SDLMAIN_SOURCES}) set(_INSTALL_LIBS "SDL2main") if(SDL_SHARED) - add_library(SDL2 SHARED ${SOURCE_FILES}) + add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES}) if(UNIX) set_target_properties(SDL2 PROPERTIES VERSION ${LT_VERSION} @@ -1484,6 +1563,7 @@ if(SDL_STATIC) set (BUILD_SHARED_LIBS FALSE) add_library(SDL2-static STATIC ${SOURCE_FILES}) set_target_properties(SDL2-static PROPERTIES OUTPUT_NAME "SDL2") + set_target_properties(SDL2-static PROPERTIES POSITION_INDEPENDENT_CODE ${SDL_STATIC_PIC}) if(MSVC) set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB") set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB") @@ -1510,12 +1590,17 @@ endforeach() list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES}) install(FILES ${INCLUDE_FILES} DESTINATION include/SDL2) -if(NOT WINDOWS OR CYGWIN) +if(NOT (WINDOWS OR CYGWIN)) if(SDL_SHARED) + if (APPLE) + set(SOEXT "dylib") + else() + set(SOEXT "so") + endif() install(CODE " execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink - \"libSDL2-2.0.so\" \"libSDL2.so\")") - install(FILES ${SDL2_BINARY_DIR}/libSDL2.so DESTINATION "lib${LIB_SUFFIX}") + \"libSDL2-2.0.${SOEXT}\" \"libSDL2.${SOEXT}\")") + install(FILES ${SDL2_BINARY_DIR}/libSDL2.${SOEXT} DESTINATION "lib${LIB_SUFFIX}") endif() if(FREEBSD) # FreeBSD uses ${PREFIX}/libdata/pkgconfig @@ -1526,7 +1611,7 @@ if(NOT WINDOWS OR CYGWIN) endif() install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION bin) # TODO: what about the .spec file? Is it only needed for RPM creation? - install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "share/aclocal") + install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") endif() ##### Uninstall target ##### diff --git a/Engine/lib/sdl/Makefile.in b/Engine/lib/sdl/Makefile.in index b66e0f5e2..a7cbddf26 100644 --- a/Engine/lib/sdl/Makefile.in +++ b/Engine/lib/sdl/Makefile.in @@ -3,6 +3,7 @@ top_builddir = . srcdir = @srcdir@ objects = build +gen = gen prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ @@ -31,6 +32,8 @@ WINDRES = @WINDRES@ TARGET = libSDL2.la OBJECTS = @OBJECTS@ +GEN_HEADERS = @GEN_HEADERS@ +GEN_OBJECTS = @GEN_OBJECTS@ VERSION_OBJECTS = @VERSION_OBJECTS@ SDLMAIN_TARGET = libSDL2main.a @@ -39,6 +42,8 @@ SDLMAIN_OBJECTS = @SDLMAIN_OBJECTS@ SDLTEST_TARGET = libSDL2_test.a SDLTEST_OBJECTS = @SDLTEST_OBJECTS@ +WAYLAND_SCANNER = @WAYLAND_SCANNER@ + SRC_DIST = *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.in debian docs include Makefile.* sdl2-config.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in src test VisualC.html VisualC VisualC-WinRT Xcode Xcode-iOS GEN_DIST = SDL2.spec @@ -48,6 +53,7 @@ RUN_CMD_CC = @echo " CC " $@; RUN_CMD_CXX = @echo " CXX " $@; RUN_CMD_LTLINK = @echo " LTLINK" $@; RUN_CMD_RANLIB = @echo " RANLIB" $@; +RUN_CMD_GEN = @echo " GEN " $@; LIBTOOL += --quiet endif @@ -137,8 +143,8 @@ update-revision: .PHONY: all update-revision install install-bin install-hdrs install-lib install-data uninstall uninstall-bin uninstall-hdrs uninstall-lib uninstall-data clean distclean dist $(OBJECTS:.lo=.d) -$(objects)/$(TARGET): $(OBJECTS) $(VERSION_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) +$(objects)/$(TARGET): $(GEN_HEADERS) $(GEN_OBJECTS) $(OBJECTS) $(VERSION_OBJECTS) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) $(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS) $(RUN_CMD_AR)$(AR) cru $@ $(SDLMAIN_OBJECTS) @@ -200,6 +206,7 @@ uninstall-data: clean: rm -rf $(objects) + rm -rf $(gen) if test -f test/Makefile; then (cd test; $(MAKE) $@); fi distclean: clean diff --git a/Engine/lib/sdl/Makefile.pandora b/Engine/lib/sdl/Makefile.pandora index bb89d52a6..8b78f2734 100644 --- a/Engine/lib/sdl/Makefile.pandora +++ b/Engine/lib/sdl/Makefile.pandora @@ -19,7 +19,7 @@ SOURCES = ./src/*.c ./src/audio/*.c ./src/cpuinfo/*.c ./src/events/*.c \ ./src/thread/pthread/SDL_systhread.c ./src/thread/pthread/SDL_syssem.c \ ./src/thread/pthread/SDL_sysmutex.c ./src/thread/pthread/SDL_syscond.c \ ./src/joystick/linux/*.c ./src/haptic/linux/*.c ./src/timer/unix/*.c \ - ./src/atomic/linux/*.c ./src/filesystem/unix/*.c \ + ./src/atomic/*.c ./src/filesystem/unix/*.c \ ./src/video/pandora/SDL_pandora.o ./src/video/pandora/SDL_pandora_events.o ./src/video/x11/*.c diff --git a/Engine/lib/sdl/Makefile.psp b/Engine/lib/sdl/Makefile.psp index 5e7dcd29a..93fb9e447 100644 --- a/Engine/lib/sdl/Makefile.psp +++ b/Engine/lib/sdl/Makefile.psp @@ -49,6 +49,7 @@ OBJS= src/SDL.o \ src/stdlib/SDL_stdlib.o \ src/stdlib/SDL_string.o \ src/thread/SDL_thread.o \ + src/thread/generic/SDL_systls.o \ src/thread/psp/SDL_syssem.o \ src/thread/psp/SDL_systhread.o \ src/thread/psp/SDL_sysmutex.o \ diff --git a/Engine/lib/sdl/Makefile.wiz b/Engine/lib/sdl/Makefile.wiz index bb7705789..0981be853 100644 --- a/Engine/lib/sdl/Makefile.wiz +++ b/Engine/lib/sdl/Makefile.wiz @@ -9,8 +9,8 @@ STRIP = $(WIZSDK)/bin/arm-openwiz-linux-gnu-strip CFLAGS = -Wall -fPIC -I./include -I$(WIZSDK)/include -DWIZ_GLES_LITE -TARGET_STATIC = libSDL13.a -TARGET_SHARED = libSDL13.so +TARGET_STATIC = libSDL2.a +TARGET_SHARED = libSDL2.so SOURCES = ./src/*.c ./src/audio/*.c ./src/cpuinfo/*.c ./src/events/*.c \ ./src/file/*.c ./src/stdlib/*.c ./src/thread/*.c ./src/timer/*.c ./src/video/*.c \ @@ -43,7 +43,7 @@ clean: install: mkdir -p $(WIZSDK)/lib - mkdir -p $(WIZSDK)/include/SDL13 + mkdir -p $(WIZSDK)/include/SDL2 cp -f $(TARGET_STATIC) $(WIZSDK)/lib cp -f $(TARGET_SHARED).0.0.1 $(WIZSDK)/lib rm -f $(WIZSDK)/lib/$(TARGET_SHARED).0 $(WIZSDK)/lib/$(TARGET_SHARED) @@ -57,5 +57,5 @@ install: ln -s ../../toolchain/libs/$(TARGET_SHARED).0 ../../toolchain/libs/$(TARGET_SHARED) cp $(TARGET_SHARED).0.0.1 ../nehe_demos/build/$(TARGET_SHARED).0 - cp -f include/*.h $(WIZSDK)/include/SDL13/ - cp -f include/*.h ../../toolchain/include/SDL13/ + cp -f include/*.h $(WIZSDK)/include/SDL2/ + cp -f include/*.h ../../toolchain/include/SDL2/ diff --git a/Engine/lib/sdl/README-SDL.txt b/Engine/lib/sdl/README-SDL.txt index fade0b958..8eaf051f7 100644 --- a/Engine/lib/sdl/README-SDL.txt +++ b/Engine/lib/sdl/README-SDL.txt @@ -2,8 +2,8 @@ Please distribute this file with the SDL runtime environment: The Simple DirectMedia Layer (SDL for short) is a cross-platform library -designed to make it easy to write multi-media software, such as games and -emulators. +designed to make it easy to write multi-media software, such as games +and emulators. The Simple DirectMedia Layer library source code is available from: http://www.libsdl.org/ diff --git a/Engine/lib/sdl/SDL2.spec b/Engine/lib/sdl/SDL2.spec index 0fe57540f..5dfda5802 100644 --- a/Engine/lib/sdl/SDL2.spec +++ b/Engine/lib/sdl/SDL2.spec @@ -1,6 +1,6 @@ Summary: Simple DirectMedia Layer Name: SDL2 -Version: 2.0.4 +Version: 2.0.5 Release: 2 Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz URL: http://www.libsdl.org/ diff --git a/Engine/lib/sdl/VisualC.html b/Engine/lib/sdl/VisualC.html index 89035d677..0631832e8 100644 --- a/Engine/lib/sdl/VisualC.html +++ b/Engine/lib/sdl/VisualC.html @@ -21,7 +21,7 @@

There are different solution files for the various - versions of the IDE. Please use the appropiate version + versions of the IDE. Please use the appropriate version 2008, 2010, 2012 or 2013.

@@ -101,7 +101,7 @@ files to project")

Instead of adding the files to your project it is more - desireable to add them to the linker options: Project|Properties|Linker|Command + desirable to add them to the linker options: Project|Properties|Linker|Command Line and type the names of the libraries to link with in the "Additional Options:" box.  Note: This must be done for each build configuration (e.g. Release,Debug).

diff --git a/Engine/lib/sdl/VisualC/clean.sh b/Engine/lib/sdl/VisualC/clean.sh deleted file mode 100644 index fd16f9a12..000000000 --- a/Engine/lib/sdl/VisualC/clean.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -find . -type f \( -name '*.user' -o -name '*.sdf' -o -name '*.ncb' -o -name '*.suo' \) -print -delete -find . -type f \( -name '*.bmp' -o -name '*.wav' -o -name '*.dat' \) -print -delete -find . -depth -type d \( -name Win32 -o -name x64 \) -exec rm -rv {} \; diff --git a/Engine/lib/sdl/WhatsNew.txt b/Engine/lib/sdl/WhatsNew.txt index 9b7139f5d..1979ac2b3 100644 --- a/Engine/lib/sdl/WhatsNew.txt +++ b/Engine/lib/sdl/WhatsNew.txt @@ -1,6 +1,69 @@ This is a list of major changes in SDL's version history. +--------------------------------------------------------------------------- +2.0.5: +--------------------------------------------------------------------------- + +General: +* Implemented audio capture support for some platforms +* Added SDL_DequeueAudio() to retrieve audio when buffer queuing is turned on for audio capture +* Added events for dragging and dropping text +* Added events for dragging and dropping multiple items +* By default the click raising a window will not be delivered to the SDL application. You can set the hint SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH to "1" to allow that click through to the window. +* Saving a surface with an alpha channel as a BMP will use a newer BMP format that supports alpha information. You can set the hint SDL_HINT_BMP_SAVE_LEGACY_FORMAT to "1" to use the old format. +* Added SDL_GetHintBoolean() to get the boolean value of a hint +* Added SDL_RenderSetIntegerScale() to set whether to smoothly scale or use integral multiples of the viewport size when scaling the rendering output +* Added SDL_CreateRGBSurfaceWithFormat() and SDL_CreateRGBSurfaceWithFormatFrom() to create an SDL surface with a specific pixel format +* Added SDL_GetDisplayUsableBounds() which returns the area usable for windows. For example, on Mac OS X, this subtracts the area occupied by the menu bar and dock. +* Added SDL_GetWindowBordersSize() which returns the size of the window's borders around the client area +* Added a window event SDL_WINDOWEVENT_HIT_TEST when a window had a hit test that wasn't SDL_HITTEST_NORMAL (e.g. in the title bar or window frame) +* Added SDL_SetWindowResizable() to change whether a window is resizable +* Added SDL_SetWindowOpacity() and SDL_GetWindowOpacity() to affect the window transparency +* Added SDL_SetWindowModalFor() to set a window as modal for another window +* Added support for AUDIO_U16LSB and AUDIO_U16MSB to SDL_MixAudioFormat() +* Fixed flipped images when reading back from target textures when using the OpenGL renderer +* Fixed texture color modulation with SDL_BLENDMODE_NONE when using the OpenGL renderer +* Fixed bug where the alpha value of colorkeys was ignored when blitting in some cases + +Windows: +* Added a hint SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING to prevent SDL from raising a debugger exception to name threads. This exception can cause problems with .NET applications when running under a debugger. +* The hint SDL_HINT_THREAD_STACK_SIZE is now supported on Windows +* Fixed XBox controller triggers automatically being pulled at startup +* The first icon from the executable is used as the default window icon at runtime +* Fixed SDL log messages being printed twice if SDL was built with C library support +* Reset dead keys when the SDL window loses focus, so dead keys pressed in SDL applications don't affect text input into other applications. + +Mac OS X: +* Fixed selecting the dummy video driver +* The caps lock key now generates a pressed event when pressed and a released event when released, instead of a press/release event pair when pressed. +* Fixed mouse wheel events on Mac OS X 10.12 +* The audio driver has been updated to use AVFoundation for better compatibility with newer versions of Mac OS X + +Linux: +* Added support for the Fcitx IME +* Added a window event SDL_WINDOWEVENT_TAKE_FOCUS when a window manager asks the SDL window whether it wants to take focus. +* Refresh rates are now rounded instead of truncated, e.g. 59.94 Hz is rounded up to 60 Hz instead of 59. +* Added initial support for touchscreens on Raspberry Pi + +OpenBSD: +* SDL_GetBasePath() is now implemented on OpenBSD + +iOS: +* Added support for dynamically loaded objects on iOS 8 and newer + +tvOS: +* Added support for Apple TV +* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote. + +Android: +* Fixed SDL not resizing window when Android screen resolution changes +* Corrected the joystick Z axis reporting for the accelerometer + +Emscripten (running in a web browser): +* Many bug fixes and improvements + + --------------------------------------------------------------------------- 2.0.4: --------------------------------------------------------------------------- diff --git a/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist b/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist index bccaa8afc..da4183466 100644 --- a/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist +++ b/Engine/lib/sdl/Xcode/SDL/Info-Framework.plist @@ -11,7 +11,7 @@ CFBundleIconFile CFBundleIdentifier - org.libsdl.SDL2 + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -19,10 +19,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.4 + 2.0.5 CFBundleSignature SDLX CFBundleVersion - 2.0.4 + 2.0.5 diff --git a/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 9fc2a5019..1f16953cf --- a/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Engine/lib/sdl/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -7,15 +7,9 @@ objects = { /* Begin PBXBuildFile section */ - 007317A20858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */; }; - 007317A30858DECD00B2BC32 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179C0858DECD00B2BC32 /* AudioUnit.framework */; }; 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; }; - 007317A50858DECD00B2BC32 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179E0858DECD00B2BC32 /* CoreAudio.framework */; }; 007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; - 007317A90858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */; }; - 007317AA0858DECD00B2BC32 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179C0858DECD00B2BC32 /* AudioUnit.framework */; }; 007317AB0858DECD00B2BC32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; }; - 007317AC0858DECD00B2BC32 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179E0858DECD00B2BC32 /* CoreAudio.framework */; }; 007317AD0858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; 007317C30858E15000B2BC32 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; }; 00CFA89D106B4BA100758660 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; }; @@ -57,14 +51,12 @@ 04BD000912E6671800899322 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD8912E6671700899322 /* SDL_diskaudio.h */; }; 04BD001012E6671800899322 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */; }; 04BD001112E6671800899322 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD9512E6671700899322 /* SDL_dummyaudio.h */; }; - 04BD001812E6671800899322 /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDA012E6671700899322 /* SDL_coreaudio.c */; }; 04BD001912E6671800899322 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDA112E6671700899322 /* SDL_coreaudio.h */; }; 04BD002612E6671800899322 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB412E6671700899322 /* SDL_audio.c */; }; 04BD002712E6671800899322 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB512E6671700899322 /* SDL_audio_c.h */; }; 04BD002812E6671800899322 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB612E6671700899322 /* SDL_audiocvt.c */; }; 04BD002912E6671800899322 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB712E6671700899322 /* SDL_audiodev.c */; }; 04BD002A12E6671800899322 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */; }; - 04BD002B12E6671800899322 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB912E6671700899322 /* SDL_audiomem.h */; }; 04BD002C12E6671800899322 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */; }; 04BD002D12E6671800899322 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBB12E6671700899322 /* SDL_mixer.c */; }; 04BD003412E6671800899322 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC212E6671700899322 /* SDL_sysaudio.h */; }; @@ -211,14 +203,12 @@ 04BD022512E6671800899322 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD8912E6671700899322 /* SDL_diskaudio.h */; }; 04BD022C12E6671800899322 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */; }; 04BD022D12E6671800899322 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD9512E6671700899322 /* SDL_dummyaudio.h */; }; - 04BD023412E6671800899322 /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDA012E6671700899322 /* SDL_coreaudio.c */; }; 04BD023512E6671800899322 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDA112E6671700899322 /* SDL_coreaudio.h */; }; 04BD024212E6671800899322 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB412E6671700899322 /* SDL_audio.c */; }; 04BD024312E6671800899322 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB512E6671700899322 /* SDL_audio_c.h */; }; 04BD024412E6671800899322 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB612E6671700899322 /* SDL_audiocvt.c */; }; 04BD024512E6671800899322 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB712E6671700899322 /* SDL_audiodev.c */; }; 04BD024612E6671800899322 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */; }; - 04BD024712E6671800899322 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB912E6671700899322 /* SDL_audiomem.h */; }; 04BD024812E6671800899322 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */; }; 04BD024912E6671800899322 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBB12E6671700899322 /* SDL_mixer.c */; }; 04BD025012E6671800899322 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC212E6671700899322 /* SDL_sysaudio.h */; }; @@ -387,6 +377,10 @@ 04F7805D12FB74A200FC43C0 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804512FB74A200FC43C0 /* SDL_drawline.h */; }; 04F7805E12FB74A200FC43C0 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7804612FB74A200FC43C0 /* SDL_drawpoint.c */; }; 04F7805F12FB74A200FC43C0 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804712FB74A200FC43C0 /* SDL_drawpoint.h */; }; + 562C4AE91D8F496200AF9EBE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; + 562C4AEA1D8F496300AF9EBE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; + 562D3C7C1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */; }; + 562D3C7D1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */; }; 566CDE8F148F0AC200C5A9BB /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 566CDE8D148F0AC200C5A9BB /* SDL_dropevents_c.h */; }; 566CDE90148F0AC200C5A9BB /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = 566CDE8E148F0AC200C5A9BB /* SDL_dropevents.c */; }; 567E2F1C17C44BB2005F1892 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 567E2F1B17C44BB2005F1892 /* SDL_sysfilesystem.m */; }; @@ -406,6 +400,12 @@ 56A6702A185654B40007D20F /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A67020185654B40007D20F /* SDL_dynapi_overrides.h */; }; 56A6702B185654B40007D20F /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A67020185654B40007D20F /* SDL_dynapi_overrides.h */; }; 56A6702C185654B40007D20F /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A67020185654B40007D20F /* SDL_dynapi_overrides.h */; }; + 56C5237E1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; + 56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; + 56C523801D8F498B001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; + 56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; + A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; + A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; A77E6EB4167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; A77E6EB5167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA0AD09D16648D1700CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = BBFC088A164C6514003E6A99 /* SDL_gamecontroller.c */; }; @@ -563,7 +563,6 @@ DB313F7617554B71006C0E22 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDA112E6671700899322 /* SDL_coreaudio.h */; }; DB313F7717554B71006C0E22 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB512E6671700899322 /* SDL_audio_c.h */; }; DB313F7817554B71006C0E22 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */; }; - DB313F7917554B71006C0E22 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB912E6671700899322 /* SDL_audiomem.h */; }; DB313F7A17554B71006C0E22 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC212E6671700899322 /* SDL_sysaudio.h */; }; DB313F7B17554B71006C0E22 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC412E6671700899322 /* SDL_wave.h */; }; DB313F7C17554B71006C0E22 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDD612E6671700899322 /* blank_cursor.h */; }; @@ -698,7 +697,6 @@ DB313FFF17554B71006C0E22 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD7512E6671700899322 /* SDL_spinlock.c */; }; DB31400017554B71006C0E22 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD8812E6671700899322 /* SDL_diskaudio.c */; }; DB31400117554B71006C0E22 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */; }; - DB31400217554B71006C0E22 /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDA012E6671700899322 /* SDL_coreaudio.c */; }; DB31400317554B71006C0E22 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB412E6671700899322 /* SDL_audio.c */; }; DB31400417554B71006C0E22 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB612E6671700899322 /* SDL_audiocvt.c */; }; DB31400517554B71006C0E22 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB712E6671700899322 /* SDL_audiodev.c */; }; @@ -802,10 +800,7 @@ DB31406817554B71006C0E22 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628ACF159367F2005138DD /* SDL_x11xinput2.c */; }; DB31406917554B71006C0E22 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = AA9E4092163BE51E007A2AD0 /* SDL_x11messagebox.c */; }; DB31406A17554B71006C0E22 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = AABCC38C164063D200AB8930 /* SDL_cocoamessagebox.m */; }; - DB31406C17554B71006C0E22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */; }; - DB31406D17554B71006C0E22 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179C0858DECD00B2BC32 /* AudioUnit.framework */; }; DB31406E17554B71006C0E22 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; }; - DB31406F17554B71006C0E22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179E0858DECD00B2BC32 /* CoreAudio.framework */; }; DB31407017554B71006C0E22 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; }; DB31408B17554D37006C0E22 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; }; @@ -813,6 +808,7 @@ FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; FA73671E19A54140004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; + FABA34C71D8B5DB100915323 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -826,10 +822,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; - 0073179C0858DECD00B2BC32 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = ""; }; 0073179D0858DECD00B2BC32 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 0073179E0858DECD00B2BC32 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; 0073179F0858DECD00B2BC32 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; 007317C10858E15000B2BC32 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; 00794D3F09D0C461003FC8A1 /* License.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = License.txt; sourceTree = ""; }; @@ -857,14 +850,12 @@ 04BDFD8912E6671700899322 /* SDL_diskaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_diskaudio.h; sourceTree = ""; }; 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dummyaudio.c; sourceTree = ""; }; 04BDFD9512E6671700899322 /* SDL_dummyaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dummyaudio.h; sourceTree = ""; }; - 04BDFDA012E6671700899322 /* SDL_coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_coreaudio.c; sourceTree = ""; }; 04BDFDA112E6671700899322 /* SDL_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_coreaudio.h; sourceTree = ""; }; 04BDFDB412E6671700899322 /* SDL_audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audio.c; sourceTree = ""; }; 04BDFDB512E6671700899322 /* SDL_audio_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audio_c.h; sourceTree = ""; }; 04BDFDB612E6671700899322 /* SDL_audiocvt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiocvt.c; sourceTree = ""; }; 04BDFDB712E6671700899322 /* SDL_audiodev.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiodev.c; sourceTree = ""; }; 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiodev_c.h; sourceTree = ""; }; - 04BDFDB912E6671700899322 /* SDL_audiomem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiomem.h; sourceTree = ""; }; 04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiotypecvt.c; sourceTree = ""; }; 04BDFDBB12E6671700899322 /* SDL_mixer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_mixer.c; sourceTree = ""; }; 04BDFDC212E6671700899322 /* SDL_sysaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysaudio.h; sourceTree = ""; }; @@ -1027,6 +1018,8 @@ 56A6701E185654B40007D20F /* SDL_dynapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_dynapi.c; path = ../../src/dynapi/SDL_dynapi.c; sourceTree = ""; }; 56A6701F185654B40007D20F /* SDL_dynapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dynapi.h; path = ../../src/dynapi/SDL_dynapi.h; sourceTree = ""; }; 56A67020185654B40007D20F /* SDL_dynapi_overrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dynapi_overrides.h; path = ../../src/dynapi/SDL_dynapi_overrides.h; sourceTree = ""; }; + A7381E931D8B69C300B177DD /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + A7381E951D8B69D600B177DD /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = ""; }; AA0F8490178D5ECC00823F9D /* SDL_systls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systls.c; sourceTree = ""; }; AA628AC8159367B7005138DD /* SDL_rotate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_rotate.c; sourceTree = ""; }; @@ -1106,6 +1099,7 @@ F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = ""; }; F5A2EF3900C6A39A01000001 /* BUGS.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = BUGS.txt; path = ../../BUGS.txt; sourceTree = SOURCE_ROOT; }; FA73671C19A540EF004122E4 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = /System/Library/Frameworks/CoreVideo.framework; sourceTree = ""; }; + FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_coreaudio.m; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1113,11 +1107,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */, + A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */, FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */, - 007317A20858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */, - 007317A30858DECD00B2BC32 /* AudioUnit.framework in Frameworks */, 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */, - 007317A50858DECD00B2BC32 /* CoreAudio.framework in Frameworks */, 007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */, 00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */, 00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */, @@ -1129,14 +1122,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 56C5237E1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */, FA73671E19A54140004122E4 /* CoreVideo.framework in Frameworks */, - 007317A90858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */, - 007317AA0858DECD00B2BC32 /* AudioUnit.framework in Frameworks */, 007317AB0858DECD00B2BC32 /* Cocoa.framework in Frameworks */, - 007317AC0858DECD00B2BC32 /* CoreAudio.framework in Frameworks */, 007317AD0858DECD00B2BC32 /* IOKit.framework in Frameworks */, + 56C523801D8F498B001F2F30 /* CoreFoundation.framework in Frameworks */, 007317C30858E15000B2BC32 /* Carbon.framework in Frameworks */, DB31408B17554D37006C0E22 /* ForceFeedback.framework in Frameworks */, + 562C4AE91D8F496200AF9EBE /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1144,14 +1137,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */, FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */, - DB31406C17554B71006C0E22 /* AudioToolbox.framework in Frameworks */, - DB31406D17554B71006C0E22 /* AudioUnit.framework in Frameworks */, DB31406E17554B71006C0E22 /* Cocoa.framework in Frameworks */, - DB31406F17554B71006C0E22 /* CoreAudio.framework in Frameworks */, DB31407017554B71006C0E22 /* IOKit.framework in Frameworks */, + 56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */, DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */, DB31408D17554D3C006C0E22 /* ForceFeedback.framework in Frameworks */, + 562C4AEA1D8F496300AF9EBE /* AudioToolbox.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1307,7 +1300,6 @@ 04BDFDB612E6671700899322 /* SDL_audiocvt.c */, 04BDFDB712E6671700899322 /* SDL_audiodev.c */, 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */, - 04BDFDB912E6671700899322 /* SDL_audiomem.h */, 04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */, 04BDFDBB12E6671700899322 /* SDL_mixer.c */, 04BDFDC212E6671700899322 /* SDL_sysaudio.h */, @@ -1339,8 +1331,8 @@ 04BDFD9F12E6671700899322 /* coreaudio */ = { isa = PBXGroup; children = ( - 04BDFDA012E6671700899322 /* SDL_coreaudio.c */, 04BDFDA112E6671700899322 /* SDL_coreaudio.h */, + FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */, ); path = coreaudio; sourceTree = ""; @@ -1737,13 +1729,12 @@ BEC562FE0761C0E800A33029 /* Linked Frameworks */ = { isa = PBXGroup; children = ( + A7381E931D8B69C300B177DD /* AudioToolbox.framework */, + A7381E951D8B69D600B177DD /* CoreAudio.framework */, FA73671C19A540EF004122E4 /* CoreVideo.framework */, 00D0D08310675DD9004B05EF /* CoreFoundation.framework */, 007317C10858E15000B2BC32 /* Carbon.framework */, - 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */, - 0073179C0858DECD00B2BC32 /* AudioUnit.framework */, 0073179D0858DECD00B2BC32 /* Cocoa.framework */, - 0073179E0858DECD00B2BC32 /* CoreAudio.framework */, 0073179F0858DECD00B2BC32 /* IOKit.framework */, 00CFA89C106B4BA100758660 /* ForceFeedback.framework */, ); @@ -1840,7 +1831,6 @@ 04BD001912E6671800899322 /* SDL_coreaudio.h in Headers */, 04BD002712E6671800899322 /* SDL_audio_c.h in Headers */, 04BD002A12E6671800899322 /* SDL_audiodev_c.h in Headers */, - 04BD002B12E6671800899322 /* SDL_audiomem.h in Headers */, 04BD003412E6671800899322 /* SDL_sysaudio.h in Headers */, 04BD003612E6671800899322 /* SDL_wave.h in Headers */, 04BD004212E6671800899322 /* blank_cursor.h in Headers */, @@ -1996,7 +1986,6 @@ 04BD024312E6671800899322 /* SDL_audio_c.h in Headers */, 04BD024612E6671800899322 /* SDL_audiodev_c.h in Headers */, AAC070FD195606770073DCDF /* SDL_opengles2_gl2.h in Headers */, - 04BD024712E6671800899322 /* SDL_audiomem.h in Headers */, 04BD025012E6671800899322 /* SDL_sysaudio.h in Headers */, 04BD025212E6671800899322 /* SDL_wave.h in Headers */, 04BD025D12E6671800899322 /* blank_cursor.h in Headers */, @@ -2151,7 +2140,6 @@ DB313F7717554B71006C0E22 /* SDL_audio_c.h in Headers */, DB313F7817554B71006C0E22 /* SDL_audiodev_c.h in Headers */, AAC070FE195606770073DCDF /* SDL_opengles2_gl2.h in Headers */, - DB313F7917554B71006C0E22 /* SDL_audiomem.h in Headers */, DB313F7A17554B71006C0E22 /* SDL_sysaudio.h in Headers */, DB313F7B17554B71006C0E22 /* SDL_wave.h in Headers */, DB313F7C17554B71006C0E22 /* blank_cursor.h in Headers */, @@ -2323,7 +2311,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0630; + LastUpgradeCheck = 0730; TargetAttributes = { BECDF5FE0761BA81005FE872 = { DevelopmentTeam = EH385AYQ6F; @@ -2404,7 +2392,6 @@ 04BDFFFC12E6671800899322 /* SDL_spinlock.c in Sources */, 04BD000812E6671800899322 /* SDL_diskaudio.c in Sources */, 04BD001012E6671800899322 /* SDL_dummyaudio.c in Sources */, - 04BD001812E6671800899322 /* SDL_coreaudio.c in Sources */, 04BD002612E6671800899322 /* SDL_audio.c in Sources */, 04BD002812E6671800899322 /* SDL_audiocvt.c in Sources */, 04BD002912E6671800899322 /* SDL_audiodev.c in Sources */, @@ -2440,6 +2427,7 @@ 04BD00A812E6671800899322 /* SDL_string.c in Sources */, 04BD00BD12E6671800899322 /* SDL_syscond.c in Sources */, 04BD00BE12E6671800899322 /* SDL_sysmutex.c in Sources */, + FABA34C71D8B5DB100915323 /* SDL_coreaudio.m in Sources */, 04BD00C012E6671800899322 /* SDL_syssem.c in Sources */, 04BD00C112E6671800899322 /* SDL_systhread.c in Sources */, 04BD00CA12E6671800899322 /* SDL_thread.c in Sources */, @@ -2523,7 +2511,6 @@ 04BD021812E6671800899322 /* SDL_spinlock.c in Sources */, 04BD022412E6671800899322 /* SDL_diskaudio.c in Sources */, 04BD022C12E6671800899322 /* SDL_dummyaudio.c in Sources */, - 04BD023412E6671800899322 /* SDL_coreaudio.c in Sources */, 04BD024212E6671800899322 /* SDL_audio.c in Sources */, 04BD024412E6671800899322 /* SDL_audiocvt.c in Sources */, 04BD024512E6671800899322 /* SDL_audiodev.c in Sources */, @@ -2559,6 +2546,7 @@ 04BD02C012E6671800899322 /* SDL_qsort.c in Sources */, 04BD02C112E6671800899322 /* SDL_stdlib.c in Sources */, 04BD02C212E6671800899322 /* SDL_string.c in Sources */, + 562D3C7C1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */, 04BD02D712E6671800899322 /* SDL_syscond.c in Sources */, 04BD02D812E6671800899322 /* SDL_sysmutex.c in Sources */, 04BD02DA12E6671800899322 /* SDL_syssem.c in Sources */, @@ -2642,7 +2630,6 @@ DB313FFF17554B71006C0E22 /* SDL_spinlock.c in Sources */, DB31400017554B71006C0E22 /* SDL_diskaudio.c in Sources */, DB31400117554B71006C0E22 /* SDL_dummyaudio.c in Sources */, - DB31400217554B71006C0E22 /* SDL_coreaudio.c in Sources */, DB31400317554B71006C0E22 /* SDL_audio.c in Sources */, DB31400417554B71006C0E22 /* SDL_audiocvt.c in Sources */, DB31400517554B71006C0E22 /* SDL_audiodev.c in Sources */, @@ -2678,6 +2665,7 @@ DB31402417554B71006C0E22 /* SDL_qsort.c in Sources */, DB31402517554B71006C0E22 /* SDL_stdlib.c in Sources */, DB31402617554B71006C0E22 /* SDL_string.c in Sources */, + 562D3C7D1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */, DB31402717554B71006C0E22 /* SDL_syscond.c in Sources */, DB31402817554B71006C0E22 /* SDL_sysmutex.c in Sources */, DB31402917554B71006C0E22 /* SDL_syssem.c in Sources */, @@ -2767,14 +2755,31 @@ 00CFA621106A567900758660 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEPLOYMENT_POSTPROCESSING = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_ALTIVEC_EXTENSIONS = YES; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_SSE3_EXTENSIONS = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 3; GCC_SYMBOLS_PRIVATE_EXTERN = YES; - MACOSX_DEPLOYMENT_TARGET = 10.5; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; SDKROOT = macosx; STRIP_STYLE = "non-global"; }; @@ -2783,15 +2788,17 @@ 00CFA622106A567900758660 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 5.0.0; + DYLIB_CURRENT_VERSION = 5.1.0; FRAMEWORK_VERSION = A; HEADER_SEARCH_PATHS = /usr/X11R6/include; INFOPLIST_FILE = "Info-Framework.plist"; INSTALL_PATH = "@rpath"; OTHER_LDFLAGS = "-liconv"; + PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; PRODUCT_NAME = SDL2; PROVISIONING_PROFILE = ""; WRAPPER_EXTENSION = framework; @@ -2827,12 +2834,30 @@ 00CFA627106A568900758660 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_ALTIVEC_EXTENSIONS = YES; GCC_AUTO_VECTORIZATION = YES; GCC_ENABLE_SSE3_EXTENSIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_SYMBOLS_PRIVATE_EXTERN = YES; - MACOSX_DEPLOYMENT_TARGET = 10.5; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; STRIP_INSTALLED_PRODUCT = NO; @@ -2842,15 +2867,17 @@ 00CFA628106A568900758660 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 5.0.0; + DYLIB_CURRENT_VERSION = 5.1.0; FRAMEWORK_VERSION = A; HEADER_SEARCH_PATHS = /usr/X11R6/include; INFOPLIST_FILE = "Info-Framework.plist"; INSTALL_PATH = "@rpath"; OTHER_LDFLAGS = "-liconv"; + PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; PRODUCT_NAME = SDL2; PROVISIONING_PROFILE = ""; WRAPPER_EXTENSION = framework; diff --git a/Engine/lib/sdl/Xcode/SDL/pkg-support/SDL.info b/Engine/lib/sdl/Xcode/SDL/pkg-support/SDL.info old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/Xcode/SDL/pkg-support/resources/ReadMe.txt b/Engine/lib/sdl/Xcode/SDL/pkg-support/resources/ReadMe.txt old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj b/Engine/lib/sdl/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 59cdd631b..144d24ca5 --- a/Engine/lib/sdl/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj +++ b/Engine/lib/sdl/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj @@ -3934,7 +3934,7 @@ ); GCC_OPTIMIZATION_LEVEL = 0; HEADER_SEARCH_PATHS = ../../include; - MACOSX_DEPLOYMENT_TARGET = 10.5; + MACOSX_DEPLOYMENT_TARGET = 10.6; }; name = Debug; }; @@ -4060,7 +4060,7 @@ ); GCC_GENERATE_DEBUGGING_SYMBOLS = NO; HEADER_SEARCH_PATHS = ../../include; - MACOSX_DEPLOYMENT_TARGET = 10.5; + MACOSX_DEPLOYMENT_TARGET = 10.6; }; name = Release; }; diff --git a/Engine/lib/sdl/autogen.sh b/Engine/lib/sdl/autogen.sh old mode 100644 new mode 100755 index 649d7b31e..3e958e195 --- a/Engine/lib/sdl/autogen.sh +++ b/Engine/lib/sdl/autogen.sh @@ -3,6 +3,10 @@ echo "Generating build information using autoconf" echo "This may take a while ..." +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. +pushd $srcdir + # Regenerate configuration files cat acinclude/* >aclocal.m4 found=false @@ -15,5 +19,7 @@ if test x$found = xfalse; then fi (cd test; sh autogen.sh) +popd + # Run configure for this platform echo "Now you are ready to run ./configure" diff --git a/Engine/lib/sdl/build-scripts/androidbuild.sh b/Engine/lib/sdl/build-scripts/androidbuild.sh old mode 100644 new mode 100755 index 8ca3c916d..fb48e2e5b --- a/Engine/lib/sdl/build-scripts/androidbuild.sh +++ b/Engine/lib/sdl/build-scripts/androidbuild.sh @@ -87,8 +87,8 @@ else fi cp -r $SDLPATH/Android.mk $BUILDPATH/jni/SDL -sed -i "s|YourSourceHere.c|$MKSOURCES|g" $BUILDPATH/jni/src/Android.mk -sed -i "s|org\.libsdl\.app|$APP|g" $BUILDPATH/AndroidManifest.xml +sed -i -e "s|YourSourceHere.c|$MKSOURCES|g" $BUILDPATH/jni/src/Android.mk +sed -i -e "s|org\.libsdl\.app|$APP|g" $BUILDPATH/AndroidManifest.xml # Copy user sources for src in "${SOURCES[@]}" @@ -105,8 +105,8 @@ do done ACTIVITY="${folder}Activity" -sed -i "s|SDLActivity|$ACTIVITY|g" $BUILDPATH/AndroidManifest.xml -sed -i "s|SDLActivity|$APP|g" $BUILDPATH/build.xml +sed -i -e "s|SDLActivity|$ACTIVITY|g" $BUILDPATH/AndroidManifest.xml +sed -i -e "s|SDLActivity|$APP|g" $BUILDPATH/build.xml # Fill in a default Activity echo "package $APP;" > "$ACTIVITY.java" diff --git a/Engine/lib/sdl/build-scripts/checker-buildbot.sh b/Engine/lib/sdl/build-scripts/checker-buildbot.sh old mode 100644 new mode 100755 index 682e7fbbb..eb014311a --- a/Engine/lib/sdl/build-scripts/checker-buildbot.sh +++ b/Engine/lib/sdl/build-scripts/checker-buildbot.sh @@ -61,13 +61,13 @@ mkdir checker-buildbot cd checker-buildbot # You might want to do this for CMake-backed builds instead... -PATH="$CHECKERDIR:$PATH" scan-build -o analysis cmake -DCMAKE_BUILD_TYPE=Debug .. +PATH="$CHECKERDIR:$PATH" scan-build -o analysis cmake -DCMAKE_BUILD_TYPE=Debug -DASSERTIONS=enabled .. # ...or run configure without the scan-build wrapper... -#CC="$CHECKERDIR/libexec/ccc-analyzer" CFLAGS="-O0" ../configure +#CC="$CHECKERDIR/libexec/ccc-analyzer" CFLAGS="-O0" ../configure --enable-assertions=enabled # ...but this works for our buildbots just fine (EXCEPT ON LATEST MAC OS X). -#CFLAGS="-O0" PATH="$CHECKERDIR:$PATH" scan-build -o analysis ../configure +#CFLAGS="-O0" PATH="$CHECKERDIR:$PATH" scan-build -o analysis ../configure --enable-assertions=enabled rm -rf analysis PATH="$CHECKERDIR:$PATH" scan-build -o analysis $MAKE diff --git a/Engine/lib/sdl/build-scripts/emscripten-buildbot.sh b/Engine/lib/sdl/build-scripts/emscripten-buildbot.sh old mode 100644 new mode 100755 index db5fb8184..42eebb697 --- a/Engine/lib/sdl/build-scripts/emscripten-buildbot.sh +++ b/Engine/lib/sdl/build-scripts/emscripten-buildbot.sh @@ -51,13 +51,14 @@ mkdir buildbot pushd buildbot echo "Configuring..." -emconfigure ../configure --host=asmjs-unknown-emscripten --disable-assembly --disable-threads --enable-cpuinfo=false CFLAGS="-O2 -Wno-warn-absolute-paths -Wdeclaration-after-statement -Werror=declaration-after-statement" --prefix="$PWD/emscripten-sdl2-installed" +emconfigure ../configure --host=asmjs-unknown-emscripten --disable-assembly --disable-threads --enable-cpuinfo=false CFLAGS="-O2 -Wno-warn-absolute-paths -Wdeclaration-after-statement -Werror=declaration-after-statement" --prefix="$PWD/emscripten-sdl2-installed" || exit $? echo "Building..." -emmake $MAKE +emmake $MAKE || exit $? echo "Moving things around..." -emmake $MAKE install +emmake $MAKE install || exit $? + # Fix up a few things to a real install path perl -w -pi -e "s#$PWD/emscripten-sdl2-installed#/usr/local#g;" ./emscripten-sdl2-installed/lib/libSDL2.la ./emscripten-sdl2-installed/lib/pkgconfig/sdl2.pc ./emscripten-sdl2-installed/bin/sdl2-config mkdir -p ./usr diff --git a/Engine/lib/sdl/build-scripts/g++-fat.sh b/Engine/lib/sdl/build-scripts/g++-fat.sh old mode 100644 new mode 100755 index 29b04302f..0dbe99039 --- a/Engine/lib/sdl/build-scripts/g++-fat.sh +++ b/Engine/lib/sdl/build-scripts/g++-fat.sh @@ -6,11 +6,11 @@ DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer" -# Intel 32-bit compiler flags (10.5 runtime compatibility) -GCC_COMPILE_X86="g++ -arch i386 -mmacosx-version-min=10.5 \ +# Intel 32-bit compiler flags (10.6 runtime compatibility) +GCC_COMPILE_X86="g++ -arch i386 -mmacosx-version-min=10.6 \ -I/usr/local/include" -GCC_LINK_X86="-mmacosx-version-min=10.5" +GCC_LINK_X86="-mmacosx-version-min=10.6" # Intel 64-bit compiler flags (10.6 runtime compatibility) GCC_COMPILE_X64="g++ -arch x86_64 -mmacosx-version-min=10.6 \ diff --git a/Engine/lib/sdl/build-scripts/gcc-fat.sh b/Engine/lib/sdl/build-scripts/gcc-fat.sh old mode 100644 new mode 100755 index e556c1dd1..65f759d4a --- a/Engine/lib/sdl/build-scripts/gcc-fat.sh +++ b/Engine/lib/sdl/build-scripts/gcc-fat.sh @@ -6,15 +6,15 @@ DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer" -# Intel 32-bit compiler flags (10.5 runtime compatibility) -GCC_COMPILE_X86="gcc -arch i386 -mmacosx-version-min=10.5 \ +# Intel 32-bit compiler flags (10.6 runtime compatibility) +GCC_COMPILE_X86="gcc -arch i386 -mmacosx-version-min=10.6 \ -I/usr/local/include" -GCC_LINK_X86="-mmacosx-version-min=10.5" +GCC_LINK_X86="-mmacosx-version-min=10.6" # Intel 64-bit compiler flags (10.6 runtime compatibility) GCC_COMPILE_X64="gcc -arch x86_64 -mmacosx-version-min=10.6 \ --DMAC_OS_X_VERSION_MIN_REQUIRED=1050 \ +-DMAC_OS_X_VERSION_MIN_REQUIRED=1060 \ -I/usr/local/include" GCC_LINK_X64="-mmacosx-version-min=10.6" diff --git a/Engine/lib/sdl/build-scripts/install-sh b/Engine/lib/sdl/build-scripts/install-sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/iosbuild.sh b/Engine/lib/sdl/build-scripts/iosbuild.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/ltmain.sh b/Engine/lib/sdl/build-scripts/ltmain.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/mkinstalldirs b/Engine/lib/sdl/build-scripts/mkinstalldirs old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/nacl-buildbot.sh b/Engine/lib/sdl/build-scripts/nacl-buildbot.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/naclbuild.sh b/Engine/lib/sdl/build-scripts/naclbuild.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/raspberrypi-buildbot.sh b/Engine/lib/sdl/build-scripts/raspberrypi-buildbot.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/showrev.sh b/Engine/lib/sdl/build-scripts/showrev.sh old mode 100644 new mode 100755 index 2a68fe694..517992d9c --- a/Engine/lib/sdl/build-scripts/showrev.sh +++ b/Engine/lib/sdl/build-scripts/showrev.sh @@ -2,6 +2,4 @@ # # Print the current source revision, if available -# FIXME: this prints the tip, which isn't useful if you're on a different -# branch, or just not sync'd to the tip. -hg tip --template 'hg-{rev}:{node|short}' || (echo "hg-0:baadf00d"; exit 1) +hg parents --template 'hg-{rev}:{node|short}' || (echo "hg-0:baadf00d"; exit 1) diff --git a/Engine/lib/sdl/build-scripts/strip_fPIC.sh b/Engine/lib/sdl/build-scripts/strip_fPIC.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/update-copyright.sh b/Engine/lib/sdl/build-scripts/update-copyright.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/build-scripts/updaterev.sh b/Engine/lib/sdl/build-scripts/updaterev.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/cmake/sdlchecks.cmake b/Engine/lib/sdl/cmake/sdlchecks.cmake index 7ff0985fd..b10078192 100644 --- a/Engine/lib/sdl/cmake/sdlchecks.cmake +++ b/Engine/lib/sdl/cmake/sdlchecks.cmake @@ -105,7 +105,9 @@ macro(CheckALSA) if(ALSA) CHECK_INCLUDE_FILE(alsa/asoundlib.h HAVE_ASOUNDLIB_H) if(HAVE_ASOUNDLIB_H) - CHECK_LIBRARY_EXISTS(asound snd_pcm_open "" HAVE_LIBASOUND) + CHECK_LIBRARY_EXISTS(asound snd_pcm_recover "" HAVE_LIBASOUND) + endif() + if(HAVE_LIBASOUND) set(HAVE_ALSA TRUE) file(GLOB ALSA_SOURCES ${SDL2_SOURCE_DIR}/src/audio/alsa/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${ALSA_SOURCES}) @@ -537,6 +539,27 @@ macro(CheckMir) endif() endmacro() +macro(WaylandProtocolGen _SCANNER _XML _PROTL) + set(_WAYLAND_PROT_C_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-protocol.c") + set(_WAYLAND_PROT_H_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-client-protocol.h") + + add_custom_command( + OUTPUT "${_WAYLAND_PROT_H_CODE}" + DEPENDS "${_XML}" + COMMAND "${_SCANNER}" + ARGS client-header "${_XML}" "${_WAYLAND_PROT_H_CODE}" + ) + + add_custom_command( + OUTPUT "${_WAYLAND_PROT_C_CODE}" + DEPENDS "${_WAYLAND_PROT_H_CODE}" + COMMAND "${_SCANNER}" + ARGS code "${_XML}" "${_WAYLAND_PROT_C_CODE}" + ) + + set(SOURCE_FILES ${SOURCE_FILES} "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-protocol.c") +endmacro() + # Requires: # - EGL # - PkgCheckModules @@ -545,7 +568,51 @@ endmacro() # - HAVE_DLOPEN opt macro(CheckWayland) if(VIDEO_WAYLAND) - pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon) + pkg_check_modules(WAYLAND wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon) + + # We have to generate some protocol interface code for some various Wayland features. + if(WAYLAND_FOUND) + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-client + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE WAYLAND_CORE_PROTOCOL_DIR_RC + OUTPUT_VARIABLE WAYLAND_CORE_PROTOCOL_DIR + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT WAYLAND_CORE_PROTOCOL_DIR_RC EQUAL 0) + set(WAYLAND_FOUND FALSE) + endif() + endif() + + if(WAYLAND_FOUND) + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE WAYLAND_PROTOCOLS_DIR_RC + OUTPUT_VARIABLE WAYLAND_PROTOCOLS_DIR + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT WAYLAND_PROTOCOLS_DIR_RC EQUAL 0) + set(WAYLAND_FOUND FALSE) + endif() + endif() + + if(WAYLAND_FOUND) + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=wayland_scanner wayland-scanner + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE WAYLAND_SCANNER_RC + OUTPUT_VARIABLE WAYLAND_SCANNER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT WAYLAND_SCANNER_RC EQUAL 0) + set(WAYLAND_FOUND FALSE) + endif() + endif() + if(WAYLAND_FOUND) link_directories( ${WAYLAND_LIBRARY_DIRS} @@ -559,6 +626,17 @@ macro(CheckWayland) file(GLOB WAYLAND_SOURCES ${SDL2_SOURCE_DIR}/src/video/wayland/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${WAYLAND_SOURCES}) + # We have to generate some protocol interface code for some unstable Wayland features. + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols") + include_directories("${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols") + + WaylandProtocolGen("${WAYLAND_SCANNER}" "${WAYLAND_CORE_PROTOCOL_DIR}/wayland.xml" "wayland") + + foreach(_PROTL relative-pointer-unstable-v1 pointer-constraints-unstable-v1) + string(REGEX REPLACE "\\-unstable\\-.*$" "" PROTSUBDIR ${_PROTL}) + WaylandProtocolGen("${WAYLAND_SCANNER}" "${WAYLAND_PROTOCOLS_DIR}/unstable/${PROTSUBDIR}/${_PROTL}.xml" "${_PROTL}") + endforeach() + if(VIDEO_WAYLAND_QT_TOUCH) set(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1) endif() @@ -679,7 +757,6 @@ macro(CheckOpenGLX11) set(SDL_VIDEO_OPENGL 1) set(SDL_VIDEO_OPENGL_GLX 1) set(SDL_VIDEO_RENDER_OGL 1) - list(APPEND EXTRA_LIBS GL) endif() endif() endmacro() @@ -767,7 +844,8 @@ macro(CheckPTHREAD) endif() # Run some tests - set(CMAKE_REQUIRED_FLAGS "${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}") + set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}") if(CMAKE_CROSSCOMPILING) set(HAVE_PTHREADS 1) else() @@ -829,7 +907,7 @@ macro(CheckPTHREAD) int main(int argc, char** argv) { return 0; }" HAVE_PTHREAD_NP_H) check_function_exists(pthread_setname_np HAVE_PTHREAD_SETNAME_NP) check_function_exists(pthread_set_name_np HAVE_PTHREAD_SET_NAME_NP) - set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}") set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/thread/pthread/SDL_systhread.c @@ -883,7 +961,8 @@ macro(CheckUSBHID) endif() endif() - set(CMAKE_REQUIRED_FLAGS "${USB_CFLAGS}") + set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${USB_CFLAGS}") set(CMAKE_REQUIRED_LIBRARIES "${USB_LIBS}") check_c_source_compiles(" #include @@ -984,7 +1063,7 @@ macro(CheckUSBHID) set(HAVE_SDL_JOYSTICK TRUE) set(CMAKE_REQUIRED_LIBRARIES) - set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}") endif() endmacro() @@ -998,12 +1077,13 @@ macro(CheckRPI) listtostr(VIDEO_RPI_INCLUDE_DIRS VIDEO_RPI_INCLUDE_FLAGS "-I") listtostr(VIDEO_RPI_LIBRARY_DIRS VIDEO_RPI_LIBRARY_FLAGS "-L") - set(CMAKE_REQUIRED_FLAGS "${VIDEO_RPI_INCLUDE_FLAGS} ${VIDEO_RPI_LIBRARY_FLAGS}") + set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${VIDEO_RPI_INCLUDE_FLAGS} ${VIDEO_RPI_LIBRARY_FLAGS}") set(CMAKE_REQUIRED_LIBRARIES "${VIDEO_RPI_LIBS}") check_c_source_compiles(" #include int main(int argc, char **argv) {}" HAVE_VIDEO_RPI) - set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_LIBRARIES) if(SDL_VIDEO AND HAVE_VIDEO_RPI) diff --git a/Engine/lib/sdl/configure b/Engine/lib/sdl/configure old mode 100644 new mode 100755 index a41f02595..5070f6e6a --- a/Engine/lib/sdl/configure +++ b/Engine/lib/sdl/configure @@ -630,6 +630,7 @@ ac_includes_default="\ #endif" ac_subst_vars='LTLIBOBJS +WAYLAND_SCANNER EXTRA_LDFLAGS BUILD_LDFLAGS EXTRA_CFLAGS @@ -637,6 +638,8 @@ BUILD_CFLAGS SDLTEST_OBJECTS SDLMAIN_OBJECTS VERSION_OBJECTS +GEN_OBJECTS +GEN_HEADERS OBJECTS INCLUDE ac_aux_dir @@ -846,7 +849,9 @@ enable_video_opengles1 enable_video_opengles2 enable_libudev enable_dbus +enable_ime enable_ibus +enable_fcitx enable_input_tslib enable_pthreads enable_pthread_sem @@ -1584,7 +1589,9 @@ Optional Features: include OpenGL ES 2.0 support [[default=yes]] --enable-libudev enable libudev support [[default=yes]] --enable-dbus enable D-Bus support [[default=yes]] + --enable-ime enable IME support [[default=yes]] --enable-ibus enable IBus support [[default=yes]] + --enable-fcitx enable fcitx support [[default=yes]] --enable-input-tslib use the Touchscreen library for input [[default=yes]] --enable-pthreads use POSIX threads for multi-threading @@ -2683,9 +2690,9 @@ orig_CFLAGS="$CFLAGS" # SDL_MAJOR_VERSION=2 SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=4 -SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=4 +SDL_MICRO_VERSION=5 +SDL_INTERFACE_AGE=1 +SDL_BINARY_AGE=5 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION @@ -17601,7 +17608,7 @@ LIBS="$ALSA_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ALSA_LIBS" >&5 $as_echo "$ALSA_LIBS" >&6; } -min_alsa_version=0.9.0 +min_alsa_version=1.0.11 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libasound headers version >= $min_alsa_version" >&5 $as_echo_n "checking for libasound headers version >= $min_alsa_version... " >&6; } no_alsa="" @@ -18650,6 +18657,43 @@ $as_echo "$have_gcc_preferred_stack_boundary" >&6; } fi } +CheckDeclarationAfterStatement() +{ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -Wdeclaration-after-statement option" >&5 +$as_echo_n "checking for GCC -Wdeclaration-after-statement option... " >&6; } + have_gcc_declaration_after_statement=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + int x = 0; + +int +main () +{ + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + have_gcc_declaration_after_statement=yes + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_declaration_after_statement" >&5 +$as_echo "$have_gcc_declaration_after_statement" >&6; } + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_declaration_after_statement = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement" + fi +} + CheckWarnAll() { { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -Wall option" >&5 @@ -18767,9 +18811,12 @@ $as_echo_n "checking for Wayland support... " >&6; } if test x$PKG_CONFIG != xno && \ test x$video_opengl_egl = xyes && \ test x$video_opengles_v2 = xyes; then - if $PKG_CONFIG --exists wayland-client wayland-egl wayland-cursor egl xkbcommon ; then + if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon` + WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner` + WAYLAND_CORE_PROTOCOL_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-client` + WAYLAND_PROTOCOLS_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols` video_wayland=yes fi fi @@ -18785,8 +18832,11 @@ $as_echo "#define SDL_VIDEO_DRIVER_WAYLAND 1" >>confdefs.h $as_echo "#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1" >>confdefs.h fi + + WAYLAND_PROTOCOLS_UNSTABLE="relative-pointer-unstable-v1 pointer-constraints-unstable-v1" + SOURCES="$SOURCES $srcdir/src/video/wayland/*.c" - EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS" + EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)" # Check whether --enable-wayland-shared was given. if test "${enable_wayland_shared+set}" = set; then : enableval=$enable_wayland_shared; @@ -18928,7 +18978,7 @@ int main () { - MirMotionToolType tool = mir_motion_tool_type_mouse; + MirTouchAction actions = mir_touch_actions ; return 0; @@ -21604,6 +21654,23 @@ $as_echo "#define HAVE_DBUS_DBUS_H 1" >>confdefs.h fi } +CheckIME() +{ + # Check whether --enable-ime was given. +if test "${enable_ime+set}" = set; then : + enableval=$enable_ime; +else + enable_ime=yes +fi + + if test x$enable_ime = xyes; then + +$as_echo "#define SDL_USE_IME 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ime.c" + fi +} + CheckIBus() { # Check whether --enable-ibus was given. @@ -21677,7 +21744,11 @@ fi CFLAGS="$save_CFLAGS" if test x$have_ibus_ibus_h_hdr = xyes; then - if test x$enable_dbus != xyes; then + if test x$enable_ime != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for IBus." >&5 +$as_echo "$as_me: WARNING: IME support is required for IBus." >&2;} + have_ibus_ibus_h_hdr=no + elif test x$enable_dbus != xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for IBus." >&5 $as_echo "$as_me: WARNING: DBus support is required for IBus." >&2;} have_ibus_ibus_h_hdr=no @@ -21697,6 +21768,90 @@ $as_echo "#define HAVE_IBUS_IBUS_H 1" >>confdefs.h fi } +CheckFcitx() +{ + # Check whether --enable-fcitx was given. +if test "${enable_fcitx+set}" = set; then : + enableval=$enable_fcitx; +else + enable_fcitx=yes +fi + + if test x$enable_fcitx = xyes; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x$PKG_CONFIG != xno; then + FCITX_CFLAGS=`$PKG_CONFIG --cflags fcitx` + CFLAGS="$CFLAGS $FCITX_CFLAGS" + ac_fn_c_check_header_mongrel "$LINENO" "fcitx/frontend.h" "ac_cv_header_fcitx_frontend_h" "$ac_includes_default" +if test "x$ac_cv_header_fcitx_frontend_h" = xyes; then : + have_fcitx_frontend_h_hdr=yes +else + have_fcitx_frontend_h_hdr=no +fi + + + CFLAGS="$save_CFLAGS" + if test x$have_fcitx_frontend_h_hdr = xyes; then + if test x$enable_ime != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for fcitx." >&5 +$as_echo "$as_me: WARNING: IME support is required for fcitx." >&2;} + have_fcitx_frontend_h_hdr=no + elif test x$enable_dbus != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for fcitx." >&5 +$as_echo "$as_me: WARNING: DBus support is required for fcitx." >&2;} + have_fcitx_frontend_h_hdr=no + else + +$as_echo "#define HAVE_FCITX_FRONTEND_H 1" >>confdefs.h + + EXTRA_CFLAGS="$EXTRA_CFLAGS $FCITX_CFLAGS" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c" + fi + fi + fi + fi +} + CheckTslib() { # Check whether --enable-input-tslib was given. @@ -22894,6 +23049,8 @@ fi } +CheckWarnAll + case "$host" in *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*) case "$host" in @@ -22962,6 +23119,7 @@ case "$host" in *-*-minix*) ARCH=minix ;; esac CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -22982,7 +23140,9 @@ case "$host" in CheckWayland CheckLibUDev CheckDBus + CheckIME CheckIBus + CheckFcitx case $ARCH in linux) CheckInputEvents @@ -23392,6 +23552,7 @@ $as_echo "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h ARCH=ios CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -23402,7 +23563,7 @@ $as_echo "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h # Set up files for the audio library if test x$enable_audio = xyes; then - SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c" + SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m" SUMMARY_audio="${SUMMARY_audio} coreaudio" have_audio=yes fi @@ -23461,6 +23622,7 @@ $as_echo "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX" CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -23476,7 +23638,8 @@ $as_echo "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h $as_echo "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h - SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c" + SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox" SUMMARY_audio="${SUMMARY_audio} coreaudio" have_audio=yes fi @@ -23494,8 +23657,8 @@ $as_echo "#define SDL_JOYSTICK_IOKIT 1" >>confdefs.h $as_echo "#define SDL_HAPTIC_IOKIT 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/haptic/darwin/*.c" - have_haptic=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,ForceFeedback" + have_haptic=yes fi # Set up files for the power library if test x$enable_power = xyes; then @@ -23532,10 +23695,6 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit" - # If audio is used, add the AudioUnit framework - if test x$enable_audio = xyes; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit" - fi ;; *-nacl|*-pnacl) ARCH=nacl @@ -23581,6 +23740,7 @@ $as_echo "#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1" >>confdefs.h fi CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -23630,8 +23790,6 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h ;; esac -CheckWarnAll - # Verify that we have all the platform specific files we need if test x$have_joystick != xyes; then @@ -23687,6 +23845,57 @@ if test x$SDLMAIN_SOURCES = x; then fi SDLTEST_SOURCES="$srcdir/src/test/*.c" +if test x$video_wayland = xyes; then + WAYLAND_CORE_PROTOCOL_SOURCE='$(gen)/wayland-protocol.c' + WAYLAND_CORE_PROTOCOL_HEADER='$(gen)/wayland-client-protocol.h' + WAYLAND_PROTOCOLS_UNSTABLE_SOURCES=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\ + sed 's,[^ ]\+,\\$(gen)/&-protocol.c,g'` + WAYLAND_PROTOCOLS_UNSTABLE_HEADERS=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\ + sed 's,[^ ]\+,\\$(gen)/&-client-protocol.h,g'` + GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE $WAYLAND_PROTOCOLS_UNSTABLE_SOURCES" + GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER $WAYLAND_PROTOCOLS_UNSTABLE_HEADERS" + + WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS=" +$WAYLAND_CORE_PROTOCOL_SOURCE: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml + \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen) + \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) code \$< \$@" + + WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS=" +$WAYLAND_CORE_PROTOCOL_HEADER: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml + \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen) + \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) client-header \$< \$@" + + WAYLAND_CORE_PROTOCOL_OBJECT=" +\$(objects)/`echo $WAYLAND_CORE_PROTOCOL_SOURCE | sed 's/\$(gen)\/\(.*\).c$/\1.lo/'`: $WAYLAND_CORE_PROTOCOL_SOURCE + \$(RUN_CMD_CC)\$(LIBTOOL) --tag=CC --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \$< -o \$@" + + WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\ + do echo ; echo \$p | sed\ + "s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\$(gen)/&-client-protocol.h: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\ + \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\ + \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@," ; done` + + WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\ + do echo ; echo \$p | sed\ + "s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\$(gen)/&-protocol.c: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\ + \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\ + \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@," ; done` + + WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\ + do echo ; echo \$p | sed\ + "s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\\$(objects)/&-protocol.lo: \\$(gen)/&-protocol.c \\$(gen)/&-client-protocol.h\\\\ + \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@," ; done` + + WAYLAND_PROTOCOLS_DEPENDS=" +$WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS +$WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS +$WAYLAND_CORE_PROTOCOL_OBJECT +$WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS +$WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS +$WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE +" +fi + OBJECTS=`echo $SOURCES` DEPENDS=`echo $SOURCES | tr ' ' '\n'` for EXT in asm cc m c S; do @@ -23696,6 +23905,8 @@ for EXT in asm cc m c S; do \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@,g"` done +GEN_OBJECTS=`echo "$GEN_SOURCES" | sed 's,[^ ]*/\([^ ]*\)\.c,$(objects)/\1.lo,g'` + VERSION_OBJECTS=`echo $VERSION_SOURCES` VERSION_DEPENDS=`echo $VERSION_SOURCES` VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[^ ]*/\([^ ]*\)\.rc,$(objects)/\1.o,g'` @@ -23722,6 +23933,36 @@ SDLTEST_DEPENDS=`echo "$SDLTEST_DEPENDS" | sed "s,\\([^ ]*\\)/\\([^ ]*\\)\\.c,\\ if test "x$enable_rpath" = "xyes"; then if test $ARCH = bsdi -o $ARCH = freebsd -o $ARCH = linux -o $ARCH = netbsd; then SDL_RLD_FLAGS="-Wl,-rpath,\${libdir}" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker option --enable-new-dtags" >&5 +$as_echo_n "checking for linker option --enable-new-dtags... " >&6; } + have_enable_new_dtags=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--enable-new-dtags" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + have_enable_new_dtags=yes + SDL_RLD_FLAGS="$SDL_RLD_FLAGS -Wl,--enable-new-dtags" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_enable_new_dtags" >&5 +$as_echo "$have_enable_new_dtags" >&6; } fi if test $ARCH = solaris; then SDL_RLD_FLAGS="-R\${libdir}" @@ -23767,6 +24008,9 @@ fi + + + cat >Makefile.rules <<__EOF__ # Build rules for objects @@ -23778,6 +24022,7 @@ $DEPENDS $VERSION_DEPENDS $SDLMAIN_DEPENDS $SDLTEST_DEPENDS +$WAYLAND_PROTOCOLS_DEPENDS __EOF__ ac_config_files="$ac_config_files Makefile:Makefile.in:Makefile.rules sdl2-config sdl2-config.cmake SDL2.spec sdl2.pc" @@ -23810,11 +24055,21 @@ if test x$have_dbus_dbus_h_hdr = xyes; then else SUMMARY="${SUMMARY}Using dbus : NO\n" fi +if test x$enable_ime = xyes; then + SUMMARY="${SUMMARY}Using ime : YES\n" +else + SUMMARY="${SUMMARY}Using ime : NO\n" +fi if test x$have_ibus_ibus_h_hdr = xyes; then SUMMARY="${SUMMARY}Using ibus : YES\n" else SUMMARY="${SUMMARY}Using ibus : NO\n" fi +if test x$have_fcitx_frontend_h_hdr = xyes; then + SUMMARY="${SUMMARY}Using fcitx : YES\n" +else + SUMMARY="${SUMMARY}Using fcitx : NO\n" +fi ac_config_commands="$ac_config_commands summary" diff --git a/Engine/lib/sdl/configure.in b/Engine/lib/sdl/configure.in index f585d01af..37c57e288 100644 --- a/Engine/lib/sdl/configure.in +++ b/Engine/lib/sdl/configure.in @@ -20,9 +20,9 @@ dnl Set various version strings - taken gratefully from the GTk sources # SDL_MAJOR_VERSION=2 SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=4 -SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=4 +SDL_MICRO_VERSION=5 +SDL_INTERFACE_AGE=1 +SDL_BINARY_AGE=5 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION AC_SUBST(SDL_MAJOR_VERSION) @@ -770,7 +770,7 @@ CheckALSA() AC_HELP_STRING([--enable-alsa], [support the ALSA audio API [[default=yes]]]), , enable_alsa=yes) if test x$enable_audio = xyes -a x$enable_alsa = xyes; then - AM_PATH_ALSA(0.9.0, have_alsa=yes, have_alsa=no) + AM_PATH_ALSA(1.0.11, have_alsa=yes, have_alsa=no) # Restore all flags from before the ALSA detection runs CFLAGS="$alsa_save_CFLAGS" LDFLAGS="$alsa_save_LDFLAGS" @@ -1124,6 +1124,30 @@ CheckStackBoundary() fi } +dnl See if GCC's -Wdeclaration-after-statement is supported. +dnl This lets us catch things that would fail on a C89 compiler when using +dnl a modern GCC. +CheckDeclarationAfterStatement() +{ + AC_MSG_CHECKING(for GCC -Wdeclaration-after-statement option) + have_gcc_declaration_after_statement=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement" + AC_TRY_COMPILE([ + int x = 0; + ],[ + ],[ + have_gcc_declaration_after_statement=yes + ]) + AC_MSG_RESULT($have_gcc_declaration_after_statement) + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_declaration_after_statement = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement" + fi +} + dnl See if GCC's -Wall is supported. CheckWarnAll() { @@ -1177,9 +1201,12 @@ AC_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for if test x$PKG_CONFIG != xno && \ test x$video_opengl_egl = xyes && \ test x$video_opengles_v2 = xyes; then - if $PKG_CONFIG --exists wayland-client wayland-egl wayland-cursor egl xkbcommon ; then + if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon` + WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner` + WAYLAND_CORE_PROTOCOL_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-client` + WAYLAND_PROTOCOLS_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols` video_wayland=yes fi fi @@ -1190,8 +1217,11 @@ AC_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for if test x$enable_video_wayland_qt_touch = xyes; then AC_DEFINE(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH, 1, [ ]) fi + + WAYLAND_PROTOCOLS_UNSTABLE="relative-pointer-unstable-v1 pointer-constraints-unstable-v1" + SOURCES="$SOURCES $srcdir/src/video/wayland/*.c" - EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS" + EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)" AC_ARG_ENABLE(wayland-shared, AC_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [[default=maybe]]]), , enable_wayland_shared=maybe) @@ -1260,12 +1290,12 @@ AC_HELP_STRING([--enable-video-mir], [use Mir video driver [[default=yes]]]), MIR_LIBS=`$PKG_CONFIG --libs mirclient egl xkbcommon` save_CFLAGS="$CFLAGS" CFLAGS="$save_CFLAGS $MIR_CFLAGS" - - dnl This will disable Mir on Ubuntu < 14.04 + + dnl This will disable Mir if >= v0.25 is not available AC_TRY_COMPILE([ #include ],[ - MirMotionToolType tool = mir_motion_tool_type_mouse; + MirTouchAction actions = mir_touch_actions ],[ video_mir=yes ]) @@ -2230,6 +2260,18 @@ AC_HELP_STRING([--enable-dbus], [enable D-Bus support [[default=yes]]]), fi } +dnl See if the platform wanna IME support. +CheckIME() +{ + AC_ARG_ENABLE(ime, +AC_HELP_STRING([--enable-ime], [enable IME support [[default=yes]]]), + , enable_ime=yes) + if test x$enable_ime = xyes; then + AC_DEFINE(SDL_USE_IME, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ime.c" + fi +} + dnl See if the platform has libibus IME support. CheckIBus() { @@ -2250,7 +2292,10 @@ AC_HELP_STRING([--enable-ibus], [enable IBus support [[default=yes]]]), have_inotify_inotify_h_hdr=no) CFLAGS="$save_CFLAGS" if test x$have_ibus_ibus_h_hdr = xyes; then - if test x$enable_dbus != xyes; then + if test x$enable_ime != xyes; then + AC_MSG_WARN([IME support is required for IBus.]) + have_ibus_ibus_h_hdr=no + elif test x$enable_dbus != xyes; then AC_MSG_WARN([DBus support is required for IBus.]) have_ibus_ibus_h_hdr=no elif test x$have_inotify_inotify_h_hdr != xyes; then @@ -2266,6 +2311,38 @@ AC_HELP_STRING([--enable-ibus], [enable IBus support [[default=yes]]]), fi } +dnl See if the platform has fcitx IME support. +CheckFcitx() +{ + AC_ARG_ENABLE(fcitx, +AC_HELP_STRING([--enable-fcitx], [enable fcitx support [[default=yes]]]), + , enable_fcitx=yes) + if test x$enable_fcitx = xyes; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + if test x$PKG_CONFIG != xno; then + FCITX_CFLAGS=`$PKG_CONFIG --cflags fcitx` + CFLAGS="$CFLAGS $FCITX_CFLAGS" + AC_CHECK_HEADER(fcitx/frontend.h, + have_fcitx_frontend_h_hdr=yes, + have_fcitx_frontend_h_hdr=no) + CFLAGS="$save_CFLAGS" + if test x$have_fcitx_frontend_h_hdr = xyes; then + if test x$enable_ime != xyes; then + AC_MSG_WARN([IME support is required for fcitx.]) + have_fcitx_frontend_h_hdr=no + elif test x$enable_dbus != xyes; then + AC_MSG_WARN([DBus support is required for fcitx.]) + have_fcitx_frontend_h_hdr=no + else + AC_DEFINE(HAVE_FCITX_FRONTEND_H, 1, [ ]) + EXTRA_CFLAGS="$EXTRA_CFLAGS $FCITX_CFLAGS" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c" + fi + fi + fi + fi +} + dnl See if we can use the Touchscreen input library CheckTslib() { @@ -2801,6 +2878,9 @@ AC_HELP_STRING([--enable-rpath], [use an rpath when linking SDL [[default=yes]]] , enable_rpath=yes) } +dnl Do this on all platforms, before everything else (other things might want to override it). +CheckWarnAll + dnl Set up the configuration based on the host platform! case "$host" in *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*) @@ -2870,6 +2950,7 @@ case "$host" in *-*-minix*) ARCH=minix ;; esac CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -2890,7 +2971,9 @@ case "$host" in CheckWayland CheckLibUDev CheckDBus + CheckIME CheckIBus + CheckFcitx case $ARCH in linux) CheckInputEvents @@ -3196,6 +3279,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ARCH=ios CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -3206,7 +3290,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau # Set up files for the audio library if test x$enable_audio = xyes; then - SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c" + SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m" SUMMARY_audio="${SUMMARY_audio} coreaudio" have_audio=yes fi @@ -3265,6 +3349,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX" CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -3278,7 +3363,8 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau # Set up files for the audio library if test x$enable_audio = xyes; then AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ]) - SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c" + SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox" SUMMARY_audio="${SUMMARY_audio} coreaudio" have_audio=yes fi @@ -3292,8 +3378,8 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau if test x$enable_haptic = xyes; then AC_DEFINE(SDL_HAPTIC_IOKIT, 1, [ ]) SOURCES="$SOURCES $srcdir/src/haptic/darwin/*.c" - have_haptic=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,ForceFeedback" + have_haptic=yes fi # Set up files for the power library if test x$enable_power = xyes; then @@ -3324,10 +3410,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit" - # If audio is used, add the AudioUnit framework - if test x$enable_audio = xyes; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit" - fi ;; *-nacl|*-pnacl) ARCH=nacl @@ -3366,6 +3448,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau fi CheckVisibilityHidden + CheckDeclarationAfterStatement CheckDummyVideo CheckDiskAudio CheckDummyAudio @@ -3407,9 +3490,6 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ;; esac -dnl Do this on all platforms, after everything else. -CheckWarnAll - # Verify that we have all the platform specific files we need if test x$have_joystick != xyes; then @@ -3453,6 +3533,57 @@ if test x$SDLMAIN_SOURCES = x; then fi SDLTEST_SOURCES="$srcdir/src/test/*.c" +if test x$video_wayland = xyes; then + WAYLAND_CORE_PROTOCOL_SOURCE='$(gen)/wayland-protocol.c' + WAYLAND_CORE_PROTOCOL_HEADER='$(gen)/wayland-client-protocol.h' + WAYLAND_PROTOCOLS_UNSTABLE_SOURCES=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\ + sed 's,[[^ ]]\+,\\$(gen)/&-protocol.c,g'` + WAYLAND_PROTOCOLS_UNSTABLE_HEADERS=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\ + sed 's,[[^ ]]\+,\\$(gen)/&-client-protocol.h,g'` + GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE $WAYLAND_PROTOCOLS_UNSTABLE_SOURCES" + GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER $WAYLAND_PROTOCOLS_UNSTABLE_HEADERS" + + WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS=" +$WAYLAND_CORE_PROTOCOL_SOURCE: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml + \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen) + \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) code \$< \$@" + + WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS=" +$WAYLAND_CORE_PROTOCOL_HEADER: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml + \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen) + \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) client-header \$< \$@" + + WAYLAND_CORE_PROTOCOL_OBJECT=" +\$(objects)/`echo $WAYLAND_CORE_PROTOCOL_SOURCE | sed 's/\$(gen)\/\(.*\).c$/\1.lo/'`: $WAYLAND_CORE_PROTOCOL_SOURCE + \$(RUN_CMD_CC)\$(LIBTOOL) --tag=CC --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \$< -o \$@" + + WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\ + do echo ; echo \$p | sed\ + "s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\$(gen)/&-client-protocol.h: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\ + \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\ + \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@," ; done` + + WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\ + do echo ; echo \$p | sed\ + "s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\$(gen)/&-protocol.c: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\ + \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\ + \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@," ; done` + + WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\ + do echo ; echo \$p | sed\ + "s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\\$(objects)/&-protocol.lo: \\$(gen)/&-protocol.c \\$(gen)/&-client-protocol.h\\\\ + \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@," ; done` + + WAYLAND_PROTOCOLS_DEPENDS=" +$WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS +$WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS +$WAYLAND_CORE_PROTOCOL_OBJECT +$WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS +$WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS +$WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE +" +fi + OBJECTS=`echo $SOURCES` DEPENDS=`echo $SOURCES | tr ' ' '\n'` for EXT in asm cc m c S; do @@ -3462,6 +3593,8 @@ for EXT in asm cc m c S; do \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@,g"` done +GEN_OBJECTS=`echo "$GEN_SOURCES" | sed 's,[[^ ]]*/\([[^ ]]*\)\.c,$(objects)/\1.lo,g'` + VERSION_OBJECTS=`echo $VERSION_SOURCES` VERSION_DEPENDS=`echo $VERSION_SOURCES` VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[[^ ]]*/\([[^ ]]*\)\.rc,$(objects)/\1.o,g'` @@ -3488,6 +3621,19 @@ SDLTEST_DEPENDS=`echo "$SDLTEST_DEPENDS" | sed "s,\\([[^ ]]*\\)/\\([[^ ]]*\\)\\. if test "x$enable_rpath" = "xyes"; then if test $ARCH = bsdi -o $ARCH = freebsd -o $ARCH = linux -o $ARCH = netbsd; then SDL_RLD_FLAGS="-Wl,-rpath,\${libdir}" + + AC_MSG_CHECKING(for linker option --enable-new-dtags) + have_enable_new_dtags=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--enable-new-dtags" + AC_TRY_LINK([ + ],[ + ],[ + have_enable_new_dtags=yes + SDL_RLD_FLAGS="$SDL_RLD_FLAGS -Wl,--enable-new-dtags" + ]) + LDFLAGS="$save_LDFLAGS" + AC_MSG_RESULT($have_enable_new_dtags) fi if test $ARCH = solaris; then SDL_RLD_FLAGS="-R\${libdir}" @@ -3526,6 +3672,8 @@ dnl Expand the sources and objects needed to build the library AC_SUBST(ac_aux_dir) AC_SUBST(INCLUDE) AC_SUBST(OBJECTS) +AC_SUBST(GEN_HEADERS) +AC_SUBST(GEN_OBJECTS) AC_SUBST(VERSION_OBJECTS) AC_SUBST(SDLMAIN_OBJECTS) AC_SUBST(SDLTEST_OBJECTS) @@ -3534,6 +3682,7 @@ AC_SUBST(EXTRA_CFLAGS) AC_SUBST(BUILD_LDFLAGS) AC_SUBST(EXTRA_LDFLAGS) AC_SUBST(WINDRES) +AC_SUBST(WAYLAND_SCANNER) cat >Makefile.rules <<__EOF__ @@ -3546,6 +3695,7 @@ $DEPENDS $VERSION_DEPENDS $SDLMAIN_DEPENDS $SDLTEST_DEPENDS +$WAYLAND_PROTOCOLS_DEPENDS __EOF__ AC_CONFIG_FILES([ @@ -3578,11 +3728,21 @@ if test x$have_dbus_dbus_h_hdr = xyes; then else SUMMARY="${SUMMARY}Using dbus : NO\n" fi +if test x$enable_ime = xyes; then + SUMMARY="${SUMMARY}Using ime : YES\n" +else + SUMMARY="${SUMMARY}Using ime : NO\n" +fi if test x$have_ibus_ibus_h_hdr = xyes; then SUMMARY="${SUMMARY}Using ibus : YES\n" else SUMMARY="${SUMMARY}Using ibus : NO\n" fi +if test x$have_fcitx_frontend_h_hdr = xyes; then + SUMMARY="${SUMMARY}Using fcitx : YES\n" +else + SUMMARY="${SUMMARY}Using fcitx : NO\n" +fi AC_CONFIG_COMMANDS([summary], [echo -en "$SUMMARY"], [SUMMARY="$SUMMARY"]) AC_OUTPUT diff --git a/Engine/lib/sdl/debian/changelog b/Engine/lib/sdl/debian/changelog index 84d1b878b..6a88d2473 100644 --- a/Engine/lib/sdl/debian/changelog +++ b/Engine/lib/sdl/debian/changelog @@ -1,3 +1,9 @@ +libsdl2 (2.0.4) UNRELEASED; urgency=low + + * Updated SDL to version 2.0.4 + + -- Sam Lantinga Thu, 07 Jan 2016 11:02:39 -0800 + libsdl2 (2.0.3) UNRELEASED; urgency=low * Updated SDL to version 2.0.3 diff --git a/Engine/lib/sdl/debian/copyright b/Engine/lib/sdl/debian/copyright index 8ce26d1c5..99c3d4496 100644 --- a/Engine/lib/sdl/debian/copyright +++ b/Engine/lib/sdl/debian/copyright @@ -31,10 +31,6 @@ Copyright: 1995 Erik Corry 1995 Brown University License: BrownUn_UnCalifornia_ErikCorry -Files: src/stdlib/SDL_qsort.c -Copyright: 1998 Gareth McCaughan -License: Gareth_McCaughan - Files: src/test/SDL_test_md5.c Copyright: 1997-2016 Sam Lantinga 1990 RSA Data Security, Inc. @@ -270,13 +266,6 @@ License: BrownUn_UnCalifornia_ErikCorry * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -License: Gareth_McCaughan - You may use it in anything you like; you may make money - out of it; you may distribute it in object form or as - part of an executable without including source code; - you don't have to credit me. (But it would be nice if - you did.) - License: Johnson_M._Hart Permission is granted for any and all use providing that this copyright is properly acknowledged. diff --git a/Engine/lib/sdl/debian/libsdl2-dev.install b/Engine/lib/sdl/debian/libsdl2-dev.install index 7f99ff427..af2c5b19d 100644 --- a/Engine/lib/sdl/debian/libsdl2-dev.install +++ b/Engine/lib/sdl/debian/libsdl2-dev.install @@ -5,4 +5,5 @@ usr/lib/*/libSDL2.a usr/lib/*/libSDL2main.a usr/lib/*/libSDL2_test.a usr/lib/*/pkgconfig/sdl2.pc +usr/lib/*/cmake/SDL2/sdl2-config.cmake usr/share/aclocal/sdl2.m4 diff --git a/Engine/lib/sdl/debian/rules b/Engine/lib/sdl/debian/rules old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/sdl2-config.cmake.in b/Engine/lib/sdl/sdl2-config.cmake.in index e5a036adf..03efbe174 100644 --- a/Engine/lib/sdl/sdl2-config.cmake.in +++ b/Engine/lib/sdl/sdl2-config.cmake.in @@ -8,3 +8,4 @@ set(SDL2_EXEC_PREFIX "@prefix@") set(SDL2_LIBDIR "@libdir@") set(SDL2_INCLUDE_DIRS "@includedir@/SDL2") set(SDL2_LIBRARIES "-L${SDL2_LIBDIR} @SDL_RLD_FLAGS@ @SDL_LIBS@") +string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES) diff --git a/Engine/lib/sdl/sdl2.m4 b/Engine/lib/sdl/sdl2.m4 index a03b2d270..b915f99ed 100644 --- a/Engine/lib/sdl/sdl2.m4 +++ b/Engine/lib/sdl/sdl2.m4 @@ -4,6 +4,9 @@ # stolen back from Frank Belew # stolen from Manish Singh # Shamelessly stolen from Owen Taylor +# +# Changelog: +# * also look for SDL2.framework under Mac OS X # serial 1 @@ -20,6 +23,10 @@ AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL sdl_exec_prefix="$withval", sdl_exec_prefix="") AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], , enable_sdltest=yes) +AC_ARG_ENABLE(sdlframework, [ --disable-sdlframework Do not search for SDL2.framework], + , search_sdl_framework=yes) + +AC_ARG_VAR(SDL2_FRAMEWORK, [Path to SDL2.framework]) min_sdl_version=ifelse([$1], ,2.0.0,$1) @@ -53,14 +60,36 @@ AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run fi AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) PATH="$as_save_PATH" - AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) no_sdl="" - if test "$SDL2_CONFIG" = "no" ; then - no_sdl=yes - else - SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` - SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + if test "$SDL2_CONFIG" = "no" -a "x$search_sdl_framework" = "xyes"; then + AC_MSG_CHECKING(for SDL2.framework) + if test "x$SDL2_FRAMEWORK" != x; then + sdl_framework=$SDL2_FRAMEWORK + else + for d in / ~/ /System/; do + if test -d "$dLibrary/Frameworks/SDL2.framework"; then + sdl_framework="$dLibrary/Frameworks/SDL2.framework" + fi + done + fi + + if test -d $sdl_framework; then + AC_MSG_RESULT($sdl_framework) + sdl_framework_dir=`dirname $sdl_framework` + SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include" + SDL_LIBS="-F$sdl_framework_dir -Wl,-framework,SDL2" + else + no_sdl=yes + fi + fi + + if test "$SDL2_CONFIG" != "no"; then + if test "x$sdl_pc" = "xno"; then + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + fi sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` @@ -141,12 +170,15 @@ int main (int argc, char *argv[]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" + + fi + if test "x$sdl_pc" = "xno"; then + if test "x$no_sdl" = "xyes"; then + AC_MSG_RESULT(no) + else + AC_MSG_RESULT(yes) + fi fi - fi - if test "x$no_sdl" = x ; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) fi fi if test "x$no_sdl" = x ; then diff --git a/Engine/lib/sdl/src/audio/SDL_audiomem.h b/Engine/lib/sdl/src/audio/SDL_audiomem.h deleted file mode 100644 index 091d15c29..000000000 --- a/Engine/lib/sdl/src/audio/SDL_audiomem.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -#define SDL_AllocAudioMem SDL_malloc -#define SDL_FreeAudioMem SDL_free -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.c b/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.c deleted file mode 100644 index 46b617dc0..000000000 --- a/Engine/lib/sdl/src/audio/coreaudio/SDL_coreaudio.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_AUDIO_DRIVER_COREAUDIO - -#include "SDL_audio.h" -#include "../SDL_audio_c.h" -#include "../SDL_sysaudio.h" -#include "SDL_coreaudio.h" -#include "SDL_assert.h" - -#define DEBUG_COREAUDIO 0 - -static void COREAUDIO_CloseDevice(_THIS); - -#define CHECK_RESULT(msg) \ - if (result != noErr) { \ - COREAUDIO_CloseDevice(this); \ - SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \ - return 0; \ - } - -#if MACOSX_COREAUDIO -static const AudioObjectPropertyAddress devlist_address = { - kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster -}; - -typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data); - -typedef struct AudioDeviceList -{ - AudioDeviceID devid; - SDL_bool alive; - struct AudioDeviceList *next; -} AudioDeviceList; - -static AudioDeviceList *output_devs = NULL; -static AudioDeviceList *capture_devs = NULL; - -static SDL_bool -add_to_internal_dev_list(const int iscapture, AudioDeviceID devId) -{ - AudioDeviceList *item = (AudioDeviceList *) SDL_malloc(sizeof (AudioDeviceList)); - if (item == NULL) { - return SDL_FALSE; - } - item->devid = devId; - item->alive = SDL_TRUE; - item->next = iscapture ? capture_devs : output_devs; - if (iscapture) { - capture_devs = item; - } else { - output_devs = item; - } - - return SDL_TRUE; -} - -static void -addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data) -{ - if (add_to_internal_dev_list(iscapture, devId)) { - SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); - } -} - -static void -build_device_list(int iscapture, addDevFn addfn, void *addfndata) -{ - OSStatus result = noErr; - UInt32 size = 0; - AudioDeviceID *devs = NULL; - UInt32 i = 0; - UInt32 max = 0; - - result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, - &devlist_address, 0, NULL, &size); - if (result != kAudioHardwareNoError) - return; - - devs = (AudioDeviceID *) alloca(size); - if (devs == NULL) - return; - - result = AudioObjectGetPropertyData(kAudioObjectSystemObject, - &devlist_address, 0, NULL, &size, devs); - if (result != kAudioHardwareNoError) - return; - - max = size / sizeof (AudioDeviceID); - for (i = 0; i < max; i++) { - CFStringRef cfstr = NULL; - char *ptr = NULL; - AudioDeviceID dev = devs[i]; - AudioBufferList *buflist = NULL; - int usable = 0; - CFIndex len = 0; - const AudioObjectPropertyAddress addr = { - kAudioDevicePropertyStreamConfiguration, - iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster - }; - - const AudioObjectPropertyAddress nameaddr = { - kAudioObjectPropertyName, - iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster - }; - - result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size); - if (result != noErr) - continue; - - buflist = (AudioBufferList *) SDL_malloc(size); - if (buflist == NULL) - continue; - - result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, - &size, buflist); - - if (result == noErr) { - UInt32 j; - for (j = 0; j < buflist->mNumberBuffers; j++) { - if (buflist->mBuffers[j].mNumberChannels > 0) { - usable = 1; - break; - } - } - } - - SDL_free(buflist); - - if (!usable) - continue; - - - size = sizeof (CFStringRef); - result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr); - if (result != kAudioHardwareNoError) - continue; - - len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), - kCFStringEncodingUTF8); - - ptr = (char *) SDL_malloc(len + 1); - usable = ((ptr != NULL) && - (CFStringGetCString - (cfstr, ptr, len + 1, kCFStringEncodingUTF8))); - - CFRelease(cfstr); - - if (usable) { - len = strlen(ptr); - /* Some devices have whitespace at the end...trim it. */ - while ((len > 0) && (ptr[len - 1] == ' ')) { - len--; - } - usable = (len > 0); - } - - if (usable) { - ptr[len] = '\0'; - -#if DEBUG_COREAUDIO - printf("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n", - ((iscapture) ? "capture" : "output"), - (int) *devCount, ptr, (int) dev); -#endif - addfn(ptr, iscapture, dev, addfndata); - } - SDL_free(ptr); /* addfn() would have copied the string. */ - } -} - -static void -free_audio_device_list(AudioDeviceList **list) -{ - AudioDeviceList *item = *list; - while (item) { - AudioDeviceList *next = item->next; - SDL_free(item); - item = next; - } - *list = NULL; -} - -static void -COREAUDIO_DetectDevices(void) -{ - build_device_list(SDL_TRUE, addToDevList, NULL); - build_device_list(SDL_FALSE, addToDevList, NULL); -} - -static void -build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data) -{ - AudioDeviceList **list = (AudioDeviceList **) data; - AudioDeviceList *item; - for (item = *list; item != NULL; item = item->next) { - if (item->devid == devId) { - item->alive = SDL_TRUE; - return; - } - } - - add_to_internal_dev_list(iscapture, devId); /* new device, add it. */ - SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId)); -} - -static void -reprocess_device_list(const int iscapture, AudioDeviceList **list) -{ - AudioDeviceList *item; - AudioDeviceList *prev = NULL; - for (item = *list; item != NULL; item = item->next) { - item->alive = SDL_FALSE; - } - - build_device_list(iscapture, build_device_change_list, list); - - /* free items in the list that aren't still alive. */ - item = *list; - while (item != NULL) { - AudioDeviceList *next = item->next; - if (item->alive) { - prev = item; - } else { - SDL_RemoveAudioDevice(iscapture, (void *) ((size_t) item->devid)); - if (prev) { - prev->next = item->next; - } else { - *list = item->next; - } - SDL_free(item); - } - item = next; - } -} - -/* this is called when the system's list of available audio devices changes. */ -static OSStatus -device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) -{ - reprocess_device_list(SDL_TRUE, &capture_devs); - reprocess_device_list(SDL_FALSE, &output_devs); - return 0; -} -#endif - -/* The CoreAudio callback */ -static OSStatus -outputCallback(void *inRefCon, - AudioUnitRenderActionFlags * ioActionFlags, - const AudioTimeStamp * inTimeStamp, - UInt32 inBusNumber, UInt32 inNumberFrames, - AudioBufferList * ioData) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) inRefCon; - AudioBuffer *abuf; - UInt32 remaining, len; - void *ptr; - UInt32 i; - - /* Only do anything if audio is enabled and not paused */ - if (!this->enabled || this->paused) { - for (i = 0; i < ioData->mNumberBuffers; i++) { - abuf = &ioData->mBuffers[i]; - SDL_memset(abuf->mData, this->spec.silence, abuf->mDataByteSize); - } - return 0; - } - - /* No SDL conversion should be needed here, ever, since we accept - any input format in OpenAudio, and leave the conversion to CoreAudio. - */ - /* - SDL_assert(!this->convert.needed); - SDL_assert(this->spec.channels == ioData->mNumberChannels); - */ - - for (i = 0; i < ioData->mNumberBuffers; i++) { - abuf = &ioData->mBuffers[i]; - remaining = abuf->mDataByteSize; - ptr = abuf->mData; - while (remaining > 0) { - if (this->hidden->bufferOffset >= this->hidden->bufferSize) { - /* Generate the data */ - SDL_LockMutex(this->mixer_lock); - (*this->spec.callback)(this->spec.userdata, - this->hidden->buffer, this->hidden->bufferSize); - SDL_UnlockMutex(this->mixer_lock); - this->hidden->bufferOffset = 0; - } - - len = this->hidden->bufferSize - this->hidden->bufferOffset; - if (len > remaining) - len = remaining; - SDL_memcpy(ptr, (char *)this->hidden->buffer + - this->hidden->bufferOffset, len); - ptr = (char *)ptr + len; - remaining -= len; - this->hidden->bufferOffset += len; - } - } - - return 0; -} - -static OSStatus -inputCallback(void *inRefCon, - AudioUnitRenderActionFlags * ioActionFlags, - const AudioTimeStamp * inTimeStamp, - UInt32 inBusNumber, UInt32 inNumberFrames, - AudioBufferList * ioData) -{ - /* err = AudioUnitRender(afr->fAudioUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, afr->fAudioBuffer); */ - /* !!! FIXME: write me! */ - return noErr; -} - - -#if MACOSX_COREAUDIO -static const AudioObjectPropertyAddress alive_address = -{ - kAudioDevicePropertyDeviceIsAlive, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster -}; - -static OSStatus -device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) -{ - SDL_AudioDevice *this = (SDL_AudioDevice *) data; - SDL_bool dead = SDL_FALSE; - UInt32 isAlive = 1; - UInt32 size = sizeof (isAlive); - OSStatus error; - - if (!this->enabled) { - return 0; /* already known to be dead. */ - } - - error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address, - 0, NULL, &size, &isAlive); - - if (error == kAudioHardwareBadDeviceError) { - dead = SDL_TRUE; /* device was unplugged. */ - } else if ((error == kAudioHardwareNoError) && (!isAlive)) { - dead = SDL_TRUE; /* device died in some other way. */ - } - - if (dead) { - SDL_OpenedAudioDeviceDisconnected(this); - } - - return 0; -} -#endif - -static void -COREAUDIO_CloseDevice(_THIS) -{ - if (this->hidden != NULL) { - if (this->hidden->audioUnitOpened) { - #if MACOSX_COREAUDIO - /* Unregister our disconnect callback. */ - AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); - #endif - - AURenderCallbackStruct callback; - const AudioUnitElement output_bus = 0; - const AudioUnitElement input_bus = 1; - const int iscapture = this->iscapture; - const AudioUnitElement bus = - ((iscapture) ? input_bus : output_bus); - const AudioUnitScope scope = - ((iscapture) ? kAudioUnitScope_Output : - kAudioUnitScope_Input); - - /* stop processing the audio unit */ - AudioOutputUnitStop(this->hidden->audioUnit); - - /* Remove the input callback */ - SDL_memset(&callback, 0, sizeof(AURenderCallbackStruct)); - AudioUnitSetProperty(this->hidden->audioUnit, - kAudioUnitProperty_SetRenderCallback, - scope, bus, &callback, sizeof(callback)); - - #if MACOSX_COREAUDIO - CloseComponent(this->hidden->audioUnit); - #else - AudioComponentInstanceDispose(this->hidden->audioUnit); - #endif - - this->hidden->audioUnitOpened = 0; - } - SDL_free(this->hidden->buffer); - SDL_free(this->hidden); - this->hidden = NULL; - } -} - -#if MACOSX_COREAUDIO -static int -prepare_device(_THIS, void *handle, int iscapture) -{ - AudioDeviceID devid = (AudioDeviceID) ((size_t) handle); - OSStatus result = noErr; - UInt32 size = 0; - UInt32 alive = 0; - pid_t pid = 0; - - AudioObjectPropertyAddress addr = { - 0, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; - - if (handle == NULL) { - size = sizeof (AudioDeviceID); - addr.mSelector = - ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice : - kAudioHardwarePropertyDefaultOutputDevice); - result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, - 0, NULL, &size, &devid); - CHECK_RESULT("AudioHardwareGetProperty (default device)"); - } - - addr.mSelector = kAudioDevicePropertyDeviceIsAlive; - addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : - kAudioDevicePropertyScopeOutput; - - size = sizeof (alive); - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive); - CHECK_RESULT - ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)"); - - if (!alive) { - SDL_SetError("CoreAudio: requested device exists, but isn't alive."); - return 0; - } - - addr.mSelector = kAudioDevicePropertyHogMode; - size = sizeof (pid); - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid); - - /* some devices don't support this property, so errors are fine here. */ - if ((result == noErr) && (pid != -1)) { - SDL_SetError("CoreAudio: requested device is being hogged."); - return 0; - } - - this->hidden->deviceID = devid; - return 1; -} -#endif - -static int -prepare_audiounit(_THIS, void *handle, int iscapture, - const AudioStreamBasicDescription * strdesc) -{ - OSStatus result = noErr; - AURenderCallbackStruct callback; -#if MACOSX_COREAUDIO - ComponentDescription desc; - Component comp = NULL; -#else - AudioComponentDescription desc; - AudioComponent comp = NULL; -#endif - const AudioUnitElement output_bus = 0; - const AudioUnitElement input_bus = 1; - const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus); - const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output : - kAudioUnitScope_Input); - -#if MACOSX_COREAUDIO - if (!prepare_device(this, handle, iscapture)) { - return 0; - } -#endif - - SDL_zero(desc); - desc.componentType = kAudioUnitType_Output; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - -#if MACOSX_COREAUDIO - desc.componentSubType = kAudioUnitSubType_DefaultOutput; - comp = FindNextComponent(NULL, &desc); -#else - desc.componentSubType = kAudioUnitSubType_RemoteIO; - comp = AudioComponentFindNext(NULL, &desc); -#endif - - if (comp == NULL) { - SDL_SetError("Couldn't find requested CoreAudio component"); - return 0; - } - - /* Open & initialize the audio unit */ -#if MACOSX_COREAUDIO - result = OpenAComponent(comp, &this->hidden->audioUnit); - CHECK_RESULT("OpenAComponent"); -#else - /* - AudioComponentInstanceNew only available on iPhone OS 2.0 and Mac OS X 10.6 - We can't use OpenAComponent on iPhone because it is not present - */ - result = AudioComponentInstanceNew(comp, &this->hidden->audioUnit); - CHECK_RESULT("AudioComponentInstanceNew"); -#endif - - this->hidden->audioUnitOpened = 1; - -#if MACOSX_COREAUDIO - result = AudioUnitSetProperty(this->hidden->audioUnit, - kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Global, 0, - &this->hidden->deviceID, - sizeof(AudioDeviceID)); - CHECK_RESULT - ("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice)"); -#endif - - /* Set the data format of the audio unit. */ - result = AudioUnitSetProperty(this->hidden->audioUnit, - kAudioUnitProperty_StreamFormat, - scope, bus, strdesc, sizeof(*strdesc)); - CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)"); - - /* Set the audio callback */ - SDL_memset(&callback, 0, sizeof(AURenderCallbackStruct)); - callback.inputProc = ((iscapture) ? inputCallback : outputCallback); - callback.inputProcRefCon = this; - result = AudioUnitSetProperty(this->hidden->audioUnit, - kAudioUnitProperty_SetRenderCallback, - scope, bus, &callback, sizeof(callback)); - CHECK_RESULT - ("AudioUnitSetProperty (kAudioUnitProperty_SetRenderCallback)"); - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(&this->spec); - - /* Allocate a sample buffer */ - this->hidden->bufferOffset = this->hidden->bufferSize = this->spec.size; - this->hidden->buffer = SDL_malloc(this->hidden->bufferSize); - - result = AudioUnitInitialize(this->hidden->audioUnit); - CHECK_RESULT("AudioUnitInitialize"); - - /* Finally, start processing of the audio unit */ - result = AudioOutputUnitStart(this->hidden->audioUnit); - CHECK_RESULT("AudioOutputUnitStart"); - -#if MACOSX_COREAUDIO - /* Fire a callback if the device stops being "alive" (disconnected, etc). */ - AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); -#endif - - /* We're running! */ - return 1; -} - - -static int -COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) -{ - AudioStreamBasicDescription strdesc; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - int valid_datatype = 0; - - /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { - return SDL_OutOfMemory(); - } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); - - /* Setup a AudioStreamBasicDescription with the requested format */ - SDL_memset(&strdesc, '\0', sizeof(AudioStreamBasicDescription)); - strdesc.mFormatID = kAudioFormatLinearPCM; - strdesc.mFormatFlags = kLinearPCMFormatFlagIsPacked; - strdesc.mChannelsPerFrame = this->spec.channels; - strdesc.mSampleRate = this->spec.freq; - strdesc.mFramesPerPacket = 1; - - while ((!valid_datatype) && (test_format)) { - this->spec.format = test_format; - /* Just a list of valid SDL formats, so people don't pass junk here. */ - switch (test_format) { - case AUDIO_U8: - case AUDIO_S8: - case AUDIO_U16LSB: - case AUDIO_S16LSB: - case AUDIO_U16MSB: - case AUDIO_S16MSB: - case AUDIO_S32LSB: - case AUDIO_S32MSB: - case AUDIO_F32LSB: - case AUDIO_F32MSB: - valid_datatype = 1; - strdesc.mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format); - if (SDL_AUDIO_ISBIGENDIAN(this->spec.format)) - strdesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; - - if (SDL_AUDIO_ISFLOAT(this->spec.format)) - strdesc.mFormatFlags |= kLinearPCMFormatFlagIsFloat; - else if (SDL_AUDIO_ISSIGNED(this->spec.format)) - strdesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; - break; - } - } - - if (!valid_datatype) { /* shouldn't happen, but just in case... */ - COREAUDIO_CloseDevice(this); - return SDL_SetError("Unsupported audio format"); - } - - strdesc.mBytesPerFrame = - strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8; - strdesc.mBytesPerPacket = - strdesc.mBytesPerFrame * strdesc.mFramesPerPacket; - - if (!prepare_audiounit(this, handle, iscapture, &strdesc)) { - COREAUDIO_CloseDevice(this); - return -1; /* prepare_audiounit() will call SDL_SetError()... */ - } - - return 0; /* good to go. */ -} - -static void -COREAUDIO_Deinitialize(void) -{ -#if MACOSX_COREAUDIO - AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); - free_audio_device_list(&capture_devs); - free_audio_device_list(&output_devs); -#endif -} - -static int -COREAUDIO_Init(SDL_AudioDriverImpl * impl) -{ - /* Set the function pointers */ - impl->OpenDevice = COREAUDIO_OpenDevice; - impl->CloseDevice = COREAUDIO_CloseDevice; - impl->Deinitialize = COREAUDIO_Deinitialize; - -#if MACOSX_COREAUDIO - impl->DetectDevices = COREAUDIO_DetectDevices; - AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); -#else - impl->OnlyHasDefaultOutputDevice = 1; - - /* Set category to ambient sound so that other music continues playing. - You can change this at runtime in your own code if you need different - behavior. If this is common, we can add an SDL hint for this. - */ - AudioSessionInitialize(NULL, NULL, NULL, nil); - UInt32 category = kAudioSessionCategory_AmbientSound; - AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(UInt32), &category); -#endif - - impl->ProvidesOwnCallbackThread = 1; - - return 1; /* this audio target is available. */ -} - -AudioBootStrap COREAUDIO_bootstrap = { - "coreaudio", "CoreAudio", COREAUDIO_Init, 0 -}; - -#endif /* SDL_AUDIO_DRIVER_COREAUDIO */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Engine/lib/sdl/src/audio/sdlgenaudiocvt.pl b/Engine/lib/sdl/src/audio/sdlgenaudiocvt.pl old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/src/dynapi/gendynapi.pl b/Engine/lib/sdl/src/dynapi/gendynapi.pl old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/src/joystick/sort_controllers.py b/Engine/lib/sdl/src/joystick/sort_controllers.py old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/src/video/sdlgenblit.pl b/Engine/lib/sdl/src/video/sdlgenblit.pl old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/test/Makefile.in b/Engine/lib/sdl/test/Makefile.in index 9a1df774e..68f0d3dab 100644 --- a/Engine/lib/sdl/test/Makefile.in +++ b/Engine/lib/sdl/test/Makefile.in @@ -13,7 +13,10 @@ TARGETS = \ loopwavequeue$(EXE) \ testatomic$(EXE) \ testaudioinfo$(EXE) \ + testaudiocapture$(EXE) \ testautomation$(EXE) \ + testbounds$(EXE) \ + testcustomcursor$(EXE) \ testdraw2$(EXE) \ testdrawchessboard$(EXE) \ testdropfile$(EXE) \ @@ -61,6 +64,7 @@ TARGETS = \ testrendercopyex$(EXE) \ testmessage$(EXE) \ testdisplayinfo$(EXE) \ + testqsort$(EXE) \ controllermap$(EXE) \ all: Makefile $(TARGETS) @@ -110,6 +114,9 @@ testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c testaudiohotplug$(EXE): $(srcdir)/testaudiohotplug.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +testaudiocapture$(EXE): $(srcdir)/testaudiocapture.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + testatomic$(EXE): $(srcdir)/testatomic.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) @@ -270,6 +277,15 @@ testmessage$(EXE): $(srcdir)/testmessage.c testdisplayinfo$(EXE): $(srcdir)/testdisplayinfo.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) +testqsort$(EXE): $(srcdir)/testqsort.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +testbounds$(EXE): $(srcdir)/testbounds.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +testcustomcursor$(EXE): $(srcdir)/testcustomcursor.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + controllermap$(EXE): $(srcdir)/controllermap.c $(CC) -o $@ $^ $(CFLAGS) $(LIBS) diff --git a/Engine/lib/sdl/test/autogen.sh b/Engine/lib/sdl/test/autogen.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/test/configure b/Engine/lib/sdl/test/configure old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/test/controllermap.c b/Engine/lib/sdl/test/controllermap.c index 3fb30d68a..d626f9f89 100644 --- a/Engine/lib/sdl/test/controllermap.c +++ b/Engine/lib/sdl/test/controllermap.c @@ -26,12 +26,9 @@ #define SCREEN_HEIGHT 480 #else #define SCREEN_WIDTH 512 -#define SCREEN_HEIGHT 317 +#define SCREEN_HEIGHT 320 #endif -#define MAP_WIDTH 512 -#define MAP_HEIGHT 317 - #define MARKER_BUTTON 1 #define MARKER_AXIS 2 @@ -47,7 +44,7 @@ typedef struct MappingStep SDL_Texture * -LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) +LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) { SDL_Surface *temp; SDL_Texture *texture; @@ -226,7 +223,7 @@ WatchJoystick(SDL_Joystick * joystick) SDL_RenderCopy(screen, background, NULL, NULL); SDL_SetTextureAlphaMod(marker, alpha); SDL_SetTextureColorMod(marker, 10, 255, 21); - SDL_RenderCopyEx(screen, marker, NULL, &dst, step->angle, NULL, 0); + SDL_RenderCopyEx(screen, marker, NULL, &dst, step->angle, NULL, SDL_FLIP_NONE); SDL_RenderPresent(screen); if (SDL_PollEvent(&event)) { diff --git a/Engine/lib/sdl/test/gcc-fat.sh b/Engine/lib/sdl/test/gcc-fat.sh old mode 100644 new mode 100755 diff --git a/Engine/lib/sdl/test/testatomic.c b/Engine/lib/sdl/test/testatomic.c index 41cc9ab1b..d371ef31f 100644 --- a/Engine/lib/sdl/test/testatomic.c +++ b/Engine/lib/sdl/test/testatomic.c @@ -284,7 +284,7 @@ typedef struct char cache_pad4[SDL_CACHELINE_SIZE-sizeof(SDL_SpinLock)-2*sizeof(SDL_atomic_t)]; #endif - volatile SDL_bool active; + SDL_atomic_t active; /* Only needed for the mutex test */ SDL_mutex *mutex; @@ -305,7 +305,7 @@ static void InitEventQueue(SDL_EventQueue *queue) SDL_AtomicSet(&queue->rwcount, 0); SDL_AtomicSet(&queue->watcher, 0); #endif - queue->active = SDL_TRUE; + SDL_AtomicSet(&queue->active, 1); } static SDL_bool EnqueueEvent_LockFree(SDL_EventQueue *queue, const SDL_Event *event) @@ -538,7 +538,7 @@ static int FIFO_Reader(void* _data) if (DequeueEvent_LockFree(queue, &event)) { WriterData *writer = (WriterData*)event.user.data1; ++data->counters[writer->index]; - } else if (queue->active) { + } else if (SDL_AtomicGet(&queue->active)) { ++data->waits; SDL_Delay(0); } else { @@ -551,7 +551,7 @@ static int FIFO_Reader(void* _data) if (DequeueEvent_Mutex(queue, &event)) { WriterData *writer = (WriterData*)event.user.data1; ++data->counters[writer->index]; - } else if (queue->active) { + } else if (SDL_AtomicGet(&queue->active)) { ++data->waits; SDL_Delay(0); } else { @@ -571,7 +571,7 @@ static int FIFO_Watcher(void* _data) { SDL_EventQueue *queue = (SDL_EventQueue *)_data; - while (queue->active) { + while (SDL_AtomicGet(&queue->active)) { SDL_AtomicLock(&queue->lock); SDL_AtomicIncRef(&queue->watcher); while (SDL_AtomicGet(&queue->rwcount) > 0) { @@ -652,7 +652,7 @@ static void RunFIFOTest(SDL_bool lock_free) } /* Shut down the queue so readers exit */ - queue.active = SDL_FALSE; + SDL_AtomicSet(&queue.active, 0); /* Wait for the readers */ while (SDL_AtomicGet(&readersRunning) > 0) { diff --git a/Engine/lib/sdl/test/testaudiocapture.c b/Engine/lib/sdl/test/testaudiocapture.c new file mode 100644 index 000000000..26321a71c --- /dev/null +++ b/Engine/lib/sdl/test/testaudiocapture.c @@ -0,0 +1,165 @@ +/* + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +#include "SDL.h" + +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_AudioSpec spec; +static SDL_AudioDeviceID devid_in = 0; +static SDL_AudioDeviceID devid_out = 0; + +static void +loop() +{ + SDL_bool please_quit = SDL_FALSE; + SDL_Event e; + + while (SDL_PollEvent(&e)) { + if (e.type == SDL_QUIT) { + please_quit = SDL_TRUE; + } else if (e.type == SDL_KEYDOWN) { + if (e.key.keysym.sym == SDLK_ESCAPE) { + please_quit = SDL_TRUE; + } + } else if (e.type == SDL_MOUSEBUTTONDOWN) { + if (e.button.button == 1) { + SDL_PauseAudioDevice(devid_out, SDL_TRUE); + SDL_PauseAudioDevice(devid_in, SDL_FALSE); + } + } else if (e.type == SDL_MOUSEBUTTONUP) { + if (e.button.button == 1) { + SDL_PauseAudioDevice(devid_in, SDL_TRUE); + SDL_PauseAudioDevice(devid_out, SDL_FALSE); + } + } + } + + if (SDL_GetAudioDeviceStatus(devid_in) == SDL_AUDIO_PLAYING) { + SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); + } else { + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + } + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + if (please_quit) { + /* stop playing back, quit. */ + SDL_Log("Shutting down.\n"); + SDL_PauseAudioDevice(devid_in, 1); + SDL_CloseAudioDevice(devid_in); + SDL_PauseAudioDevice(devid_out, 1); + SDL_CloseAudioDevice(devid_out); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + #ifdef __EMSCRIPTEN__ + emscripten_cancel_main_loop(); + #endif + exit(0); + } + + /* Note that it would be easier to just have a one-line function that + calls SDL_QueueAudio() as a capture device callback, but we're + trying to test the API, so we use SDL_DequeueAudio() here. */ + while (SDL_TRUE) { + Uint8 buf[1024]; + const Uint32 br = SDL_DequeueAudio(devid_in, buf, sizeof (buf)); + SDL_QueueAudio(devid_out, buf, br); + if (br < sizeof (buf)) { + break; + } + } +} + +int +main(int argc, char **argv) +{ + /* (argv[1] == NULL means "open default device.") */ + const char *devname = argv[1]; + SDL_AudioSpec wanted; + int devcount; + int i; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Load the SDL library */ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return (1); + } + + window = SDL_CreateWindow("testaudiocapture", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0); + renderer = SDL_CreateRenderer(window, -1, 0); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); + + devcount = SDL_GetNumAudioDevices(SDL_TRUE); + for (i = 0; i < devcount; i++) { + SDL_Log(" Capture device #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE)); + } + + SDL_zero(wanted); + wanted.freq = 44100; + wanted.format = AUDIO_F32SYS; + wanted.channels = 1; + wanted.samples = 4096; + wanted.callback = NULL; + + SDL_zero(spec); + + /* DirectSound can fail in some instances if you open the same hardware + for both capture and output and didn't open the output end first, + according to the docs, so if you're doing something like this, always + open your capture devices second in case you land in those bizarre + circumstances. */ + + SDL_Log("Opening default playback device...\n"); + devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE); + if (!devid_out) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } + + SDL_Log("Opening capture device %s%s%s...\n", + devname ? "'" : "", + devname ? devname : "[[default]]", + devname ? "'" : ""); + + devid_in = SDL_OpenAudioDevice(argv[1], SDL_TRUE, &spec, &spec, 0); + if (!devid_in) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for capture: %s!\n", SDL_GetError()); + SDL_Quit(); + exit(1); + } + + SDL_Log("Ready! Hold down mouse or finger to record!\n"); + +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (1) { loop(); SDL_Delay(16); } +#endif + + return 0; +} + diff --git a/Engine/lib/sdl/test/testaudiohotplug.c b/Engine/lib/sdl/test/testaudiohotplug.c index e13868ec2..73d480505 100644 --- a/Engine/lib/sdl/test/testaudiohotplug.c +++ b/Engine/lib/sdl/test/testaudiohotplug.c @@ -74,6 +74,12 @@ poked(int sig) done = 1; } +static const char* +devtypestr(int iscapture) +{ + return iscapture ? "capture" : "output"; +} + static void iteration() { @@ -82,10 +88,21 @@ iteration() while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { done = 1; + } else if (e.type == SDL_KEYUP) { + if (e.key.keysym.sym == SDLK_ESCAPE) + done = 1; } else if (e.type == SDL_AUDIODEVICEADDED) { - const char *name = SDL_GetAudioDeviceName(e.adevice.which, 0); - SDL_Log("New %s audio device: %s\n", e.adevice.iscapture ? "capture" : "output", name); - if (!e.adevice.iscapture) { + int index = e.adevice.which; + int iscapture = e.adevice.iscapture; + const char *name = SDL_GetAudioDeviceName(index, iscapture); + if (name != NULL) + SDL_Log("New %s audio device at index %u: %s\n", devtypestr(iscapture), (unsigned int) index, name); + else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Got new %s device at index %u, but failed to get the name: %s\n", + devtypestr(iscapture), (unsigned int) index, SDL_GetError()); + continue; + } + if (!iscapture) { positions[posindex] = 0; spec.userdata = &positions[posindex++]; spec.callback = fillerup; @@ -99,7 +116,7 @@ iteration() } } else if (e.type == SDL_AUDIODEVICEREMOVED) { dev = (SDL_AudioDeviceID) e.adevice.which; - SDL_Log("%s device %u removed.\n", e.adevice.iscapture ? "capture" : "output", (unsigned int) dev); + SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int) dev); SDL_CloseAudioDevice(dev); } } @@ -163,6 +180,7 @@ main(int argc, char *argv[]) SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); } + SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n"); SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); #ifdef __EMSCRIPTEN__ @@ -175,6 +193,8 @@ main(int argc, char *argv[]) #endif /* Clean up on signal */ + /* Quit audio first, then free WAV. This prevents access violations in the audio threads. */ + SDL_QuitSubSystem(SDL_INIT_AUDIO); SDL_FreeWAV(sound); SDL_Quit(); return (0); diff --git a/Engine/lib/sdl/test/testaudioinfo.c b/Engine/lib/sdl/test/testaudioinfo.c index 53bf0f5e2..485fd0a38 100644 --- a/Engine/lib/sdl/test/testaudioinfo.c +++ b/Engine/lib/sdl/test/testaudioinfo.c @@ -18,7 +18,7 @@ print_devices(int iscapture) const char *typestr = ((iscapture) ? "capture" : "output"); int n = SDL_GetNumAudioDevices(iscapture); - SDL_Log("%s devices:\n", typestr); + SDL_Log("Found %d %s device%s:\n", n, typestr, n != 1 ? "s" : ""); if (n == -1) SDL_Log(" Driver can't detect specific %s devices.\n\n", typestr); @@ -27,7 +27,11 @@ print_devices(int iscapture) else { int i; for (i = 0; i < n; i++) { - SDL_Log(" %s\n", SDL_GetAudioDeviceName(i, iscapture)); + const char *name = SDL_GetAudioDeviceName(i, iscapture); + if (name != NULL) + SDL_Log(" %d: %s\n", i, name); + else + SDL_Log(" %d Error: %s\n", i, SDL_GetError()); } SDL_Log("\n"); } @@ -55,9 +59,9 @@ main(int argc, char **argv) int i; SDL_Log("Built-in audio drivers:\n"); for (i = 0; i < n; ++i) { - SDL_Log(" %s\n", SDL_GetAudioDriver(i)); + SDL_Log(" %d: %s\n", i, SDL_GetAudioDriver(i)); } - SDL_Log("\n"); + SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n"); } SDL_Log("Using audio driver: %s\n\n", SDL_GetCurrentAudioDriver()); diff --git a/Engine/lib/sdl/test/testautomation_events.c b/Engine/lib/sdl/test/testautomation_events.c index f9eb5bb9e..a0119bdbe 100644 --- a/Engine/lib/sdl/test/testautomation_events.c +++ b/Engine/lib/sdl/test/testautomation_events.c @@ -87,7 +87,7 @@ events_addDelEventWatch(void *arg) /* Create user event */ event.type = SDL_USEREVENT; - event.user.code = SDLTest_RandomSint32();; + event.user.code = SDLTest_RandomSint32(); event.user.data1 = (void *)&_userdataValue1; event.user.data2 = (void *)&_userdataValue2; @@ -137,7 +137,7 @@ events_addDelEventWatchWithUserdata(void *arg) /* Create user event */ event.type = SDL_USEREVENT; - event.user.code = SDLTest_RandomSint32();; + event.user.code = SDLTest_RandomSint32(); event.user.data1 = (void *)&_userdataValue1; event.user.data2 = (void *)&_userdataValue2; diff --git a/Engine/lib/sdl/test/testautomation_keyboard.c b/Engine/lib/sdl/test/testautomation_keyboard.c index 453832e25..b2c3b9ae1 100644 --- a/Engine/lib/sdl/test/testautomation_keyboard.c +++ b/Engine/lib/sdl/test/testautomation_keyboard.c @@ -401,8 +401,8 @@ keyboard_setTextInputRect(void *arg) SDL_Rect refRect; /* Normal visible refRect, origin inside */ - refRect.x = SDLTest_RandomIntegerInRange(1, 50);; - refRect.y = SDLTest_RandomIntegerInRange(1, 50);; + refRect.x = SDLTest_RandomIntegerInRange(1, 50); + refRect.y = SDLTest_RandomIntegerInRange(1, 50); refRect.w = SDLTest_RandomIntegerInRange(10, 50); refRect.h = SDLTest_RandomIntegerInRange(10, 50); _testSetTextInputRect(refRect); @@ -415,8 +415,8 @@ keyboard_setTextInputRect(void *arg) _testSetTextInputRect(refRect); /* 1Pixel refRect */ - refRect.x = SDLTest_RandomIntegerInRange(10, 50);; - refRect.y = SDLTest_RandomIntegerInRange(10, 50);; + refRect.x = SDLTest_RandomIntegerInRange(10, 50); + refRect.y = SDLTest_RandomIntegerInRange(10, 50); refRect.w = 1; refRect.h = 1; _testSetTextInputRect(refRect); @@ -450,15 +450,15 @@ keyboard_setTextInputRect(void *arg) _testSetTextInputRect(refRect); /* negative refRect */ - refRect.x = SDLTest_RandomIntegerInRange(-200, -100);; - refRect.y = SDLTest_RandomIntegerInRange(-200, -100);; + refRect.x = SDLTest_RandomIntegerInRange(-200, -100); + refRect.y = SDLTest_RandomIntegerInRange(-200, -100); refRect.w = 50; refRect.h = 50; _testSetTextInputRect(refRect); /* oversized refRect */ - refRect.x = SDLTest_RandomIntegerInRange(1, 50);; - refRect.y = SDLTest_RandomIntegerInRange(1, 50);; + refRect.x = SDLTest_RandomIntegerInRange(1, 50); + refRect.y = SDLTest_RandomIntegerInRange(1, 50); refRect.w = 5000; refRect.h = 5000; _testSetTextInputRect(refRect); diff --git a/Engine/lib/sdl/test/testautomation_main.c b/Engine/lib/sdl/test/testautomation_main.c index ef8f19e9e..ae060cdd1 100644 --- a/Engine/lib/sdl/test/testautomation_main.c +++ b/Engine/lib/sdl/test/testautomation_main.c @@ -137,7 +137,7 @@ static const SDLTest_TestCaseReference mainTest3 = static const SDLTest_TestCaseReference mainTest4 = { (SDLTest_TestCaseFp)main_testImpliedJoystickQuit, "main_testImpliedJoystickQuit", "Tests that quit for gamecontroller doesn't quit joystick if you inited it explicitly", TEST_ENABLED}; -/* Sequence of Platform test cases */ +/* Sequence of Main test cases */ static const SDLTest_TestCaseReference *mainTests[] = { &mainTest1, &mainTest2, @@ -146,7 +146,7 @@ static const SDLTest_TestCaseReference *mainTests[] = { NULL }; -/* Platform test suite (global) */ +/* Main test suite (global) */ SDLTest_TestSuiteReference mainTestSuite = { "Main", NULL, diff --git a/Engine/lib/sdl/test/testautomation_sdltest.c b/Engine/lib/sdl/test/testautomation_sdltest.c index ec1da8a50..54cd6e257 100644 --- a/Engine/lib/sdl/test/testautomation_sdltest.c +++ b/Engine/lib/sdl/test/testautomation_sdltest.c @@ -1093,7 +1093,7 @@ sdltest_randomIntegerInRange(void *arg) SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result); /* Range with max at integer limit */ - min = long_min - (Sint32)SDLTest_RandomSint16();; + min = long_min - (Sint32)SDLTest_RandomSint16(); max = long_max; result = SDLTest_RandomIntegerInRange(min, max); SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(...,SINT32_MAX)"); diff --git a/Engine/lib/sdl/test/testautomation_stdlib.c b/Engine/lib/sdl/test/testautomation_stdlib.c index 89245fdcb..b541995f5 100644 --- a/Engine/lib/sdl/test/testautomation_stdlib.c +++ b/Engine/lib/sdl/test/testautomation_stdlib.c @@ -253,6 +253,43 @@ stdlib_getsetenv(void *arg) return TEST_COMPLETED; } +/** + * @brief Call to SDL_sscanf + */ +#undef SDL_sscanf +int +stdlib_sscanf(void *arg) +{ + int output; + int result; + int expected_output; + int expected_result; + + expected_output = output = 123; + expected_result = -1; + result = SDL_sscanf("", "%i", &output); + SDLTest_AssertPass("Call to SDL_sscanf(\"\", \"%%i\", &output)"); + SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output); + SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result); + + expected_output = output = 123; + expected_result = 0; + result = SDL_sscanf("a", "%i", &output); + SDLTest_AssertPass("Call to SDL_sscanf(\"a\", \"%%i\", &output)"); + SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output); + SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result); + + output = 123; + expected_output = 2; + expected_result = 1; + result = SDL_sscanf("2", "%i", &output); + SDLTest_AssertPass("Call to SDL_sscanf(\"2\", \"%%i\", &output)"); + SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output); + SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result); + + return TEST_COMPLETED; +} + /* ================= Test References ================== */ /* Standard C routine test cases */ @@ -265,12 +302,15 @@ static const SDLTest_TestCaseReference stdlibTest2 = static const SDLTest_TestCaseReference stdlibTest3 = { (SDLTest_TestCaseFp)stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED }; +static const SDLTest_TestCaseReference stdlibTest4 = + { (SDLTest_TestCaseFp)stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED }; + /* Sequence of Standard C routine test cases */ static const SDLTest_TestCaseReference *stdlibTests[] = { - &stdlibTest1, &stdlibTest2, &stdlibTest3, NULL + &stdlibTest1, &stdlibTest2, &stdlibTest3, &stdlibTest4, NULL }; -/* Timer test suite (global) */ +/* Standard C routine test suite (global) */ SDLTest_TestSuiteReference stdlibTestSuite = { "Stdlib", NULL, diff --git a/Engine/lib/sdl/test/testbounds.c b/Engine/lib/sdl/test/testbounds.c new file mode 100644 index 000000000..b410be96c --- /dev/null +++ b/Engine/lib/sdl/test/testbounds.c @@ -0,0 +1,40 @@ +/* + Copyright (C) 1997-2014 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +#include "SDL.h" + +int main(int argc, char **argv) +{ + int total, i; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + SDL_Log("SDL_Init(SDL_INIT_VIDEO) failed: %s", SDL_GetError()); + return 1; + } + + total = SDL_GetNumVideoDisplays(); + for (i = 0; i < total; i++) { + SDL_Rect bounds = { -1,-1,-1,-1 }, usable = { -1,-1,-1,-1 }; + SDL_GetDisplayBounds(i, &bounds); + SDL_GetDisplayUsableBounds(i, &usable); + SDL_Log("Display #%d ('%s'): bounds={(%d,%d),%dx%d}, usable={(%d,%d),%dx%d}", + i, SDL_GetDisplayName(i), + bounds.x, bounds.y, bounds.w, bounds.h, + usable.x, usable.y, usable.w, usable.h); + } + + SDL_Quit(); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/test/testcustomcursor.c b/Engine/lib/sdl/test/testcustomcursor.c new file mode 100644 index 000000000..88b5c322d --- /dev/null +++ b/Engine/lib/sdl/test/testcustomcursor.c @@ -0,0 +1,216 @@ +/* + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +#include +#include + +#ifdef __EMSCRIPTEN__ +#include +#endif + +#include "SDL_test_common.h" + +/* Stolen from the mailing list */ +/* Creates a new mouse cursor from an XPM */ + + +/* XPM */ +static const char *arrow[] = { + /* width height num_colors chars_per_pixel */ + " 32 32 3 1", + /* colors */ + "X c #000000", + ". c #ffffff", + " c None", + /* pixels */ + "X ", + "XX ", + "X.X ", + "X..X ", + "X...X ", + "X....X ", + "X.....X ", + "X......X ", + "X.......X ", + "X........X ", + "X.....XXXXX ", + "X..X..X ", + "X.X X..X ", + "XX X..X ", + "X X..X ", + " X..X ", + " X..X ", + " X..X ", + " XX ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "0,0" +}; + +static SDL_Cursor* +init_color_cursor(const char *file) +{ + SDL_Cursor *cursor = NULL; + SDL_Surface *surface = SDL_LoadBMP(file); + if (surface) { + cursor = SDL_CreateColorCursor(surface, 0, 0); + SDL_FreeSurface(surface); + } + return cursor; +} + +static SDL_Cursor* +init_system_cursor(const char *image[]) +{ + int i, row, col; + Uint8 data[4*32]; + Uint8 mask[4*32]; + int hot_x, hot_y; + + i = -1; + for (row=0; row<32; ++row) { + for (col=0; col<32; ++col) { + if (col % 8) { + data[i] <<= 1; + mask[i] <<= 1; + } else { + ++i; + data[i] = mask[i] = 0; + } + switch (image[4+row][col]) { + case 'X': + data[i] |= 0x01; + mask[i] |= 0x01; + break; + case '.': + mask[i] |= 0x01; + break; + case ' ': + break; + } + } + } + sscanf(image[4+row], "%d,%d", &hot_x, &hot_y); + return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y); +} + +static SDLTest_CommonState *state; +int done; +SDL_Cursor *cursor = NULL; + +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ +static void +quit(int rc) +{ + SDLTest_CommonQuit(state); + exit(rc); +} + +void +loop() +{ + int i; + SDL_Event event; + /* Check for events */ + while (SDL_PollEvent(&event)) { + SDLTest_CommonEvent(state, &event, &done); + } + + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + } +#ifdef __EMSCRIPTEN__ + if (done) { + emscripten_cancel_main_loop(); + } +#endif +} + +int +main(int argc, char *argv[]) +{ + int i; + const char *color_cursor = NULL; + + /* Enable standard application logging */ + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + + /* Initialize test framework */ + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); + if (!state) { + return 1; + } + for (i = 1; i < argc;) { + int consumed; + + consumed = SDLTest_CommonArg(state, i); + if (consumed == 0) { + color_cursor = argv[i]; + break; + } + if (consumed < 0) { + SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state)); + quit(1); + } + i += consumed; + } + + if (!SDLTest_CommonInit(state)) { + quit(2); + } + + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); + SDL_RenderClear(renderer); + } + + if (color_cursor) { + cursor = init_color_cursor(color_cursor); + } else { + cursor = init_system_cursor(arrow); + } + if (!cursor) { + SDL_Log("Error, couldn't create cursor\n"); + quit(2); + } + SDL_SetCursor(cursor); + + /* Main render loop */ + done = 0; +#ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(loop, 0, 1); +#else + while (!done) { + loop(); + } +#endif + + SDL_FreeCursor(cursor); + quit(0); + + /* keep the compiler happy ... */ + return(0); +} diff --git a/Engine/lib/sdl/test/testdisplayinfo.c b/Engine/lib/sdl/test/testdisplayinfo.c index c228eb6b2..f06722e88 100644 --- a/Engine/lib/sdl/test/testdisplayinfo.c +++ b/Engine/lib/sdl/test/testdisplayinfo.c @@ -51,11 +51,18 @@ main(int argc, char *argv[]) for (dpy = 0; dpy < num_displays; dpy++) { const int num_modes = SDL_GetNumDisplayModes(dpy); SDL_Rect rect = { 0, 0, 0, 0 }; + float ddpi, hdpi, vdpi; int m; SDL_GetDisplayBounds(dpy, &rect); SDL_Log("%d: \"%s\" (%dx%d, (%d, %d)), %d modes.\n", dpy, SDL_GetDisplayName(dpy), rect.w, rect.h, rect.x, rect.y, num_modes); + if (SDL_GetDisplayDPI(dpy, &ddpi, &hdpi, &vdpi) == -1) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " DPI: failed to query (%s)\n", SDL_GetError()); + } else { + SDL_Log(" DPI: ddpi=%f; hdpi=%f; vdpi=%f\n", ddpi, hdpi, vdpi); + } + if (SDL_GetCurrentDisplayMode(dpy, &mode) == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " CURRENT: failed to query (%s)\n", SDL_GetError()); } else { diff --git a/Engine/lib/sdl/test/testdrawchessboard.c b/Engine/lib/sdl/test/testdrawchessboard.c index f2a1469d4..af929e9c3 100644 --- a/Engine/lib/sdl/test/testdrawchessboard.c +++ b/Engine/lib/sdl/test/testdrawchessboard.c @@ -100,7 +100,7 @@ main(int argc, char *argv[]) /* Create window and renderer for given surface */ - window = SDL_CreateWindow("Chess Board", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN); + window = SDL_CreateWindow("Chess Board", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0); if(!window) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Window creation fail : %s\n",SDL_GetError()); diff --git a/Engine/lib/sdl/test/testdropfile.c b/Engine/lib/sdl/test/testdropfile.c index b7f215ee8..b729b2f64 100644 --- a/Engine/lib/sdl/test/testdropfile.c +++ b/Engine/lib/sdl/test/testdropfile.c @@ -77,9 +77,14 @@ main(int argc, char *argv[]) while (SDL_PollEvent(&event)) { SDLTest_CommonEvent(state, &event, &done); - if (event.type == SDL_DROPFILE) { + if (event.type == SDL_DROPBEGIN) { + SDL_Log("Drop beginning on window %u", (unsigned int) event.drop.windowID); + } else if (event.type == SDL_DROPCOMPLETE) { + SDL_Log("Drop complete on window %u", (unsigned int) event.drop.windowID); + } else if ((event.type == SDL_DROPFILE) || (event.type == SDL_DROPTEXT)) { + const char *typestr = (event.type == SDL_DROPFILE) ? "File" : "Text"; char *dropped_filedir = event.drop.file; - SDL_Log("File dropped on window: %s", dropped_filedir); + SDL_Log("%s dropped on window %u: %s", typestr, (unsigned int) event.drop.windowID, dropped_filedir); SDL_free(dropped_filedir); } } diff --git a/Engine/lib/sdl/test/testfilesystem.c b/Engine/lib/sdl/test/testfilesystem.c index abd301c0e..61a6d5a5a 100644 --- a/Engine/lib/sdl/test/testfilesystem.c +++ b/Engine/lib/sdl/test/testfilesystem.c @@ -32,9 +32,8 @@ main(int argc, char *argv[]) if(base_path == NULL){ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find base path: %s\n", SDL_GetError()); - return 0; + return 1; } - SDL_Log("base path: '%s'\n", base_path); SDL_free(base_path); @@ -42,7 +41,7 @@ main(int argc, char *argv[]) if(pref_path == NULL){ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find pref path: %s\n", SDL_GetError()); - return 0; + return 1; } SDL_Log("pref path: '%s'\n", pref_path); SDL_free(pref_path); diff --git a/Engine/lib/sdl/test/testgamecontroller.c b/Engine/lib/sdl/test/testgamecontroller.c index ec1dfd322..38d2f7708 100644 --- a/Engine/lib/sdl/test/testgamecontroller.c +++ b/Engine/lib/sdl/test/testgamecontroller.c @@ -29,7 +29,7 @@ #define SCREEN_HEIGHT 320 #else #define SCREEN_WIDTH 512 -#define SCREEN_HEIGHT 317 +#define SCREEN_HEIGHT 320 #endif /* This is indexed by SDL_GameControllerButton. */ @@ -67,7 +67,7 @@ SDL_bool done = SDL_FALSE; SDL_Texture *background, *button, *axis; static SDL_Texture * -LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) +LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) { SDL_Surface *temp = NULL; SDL_Texture *texture = NULL; @@ -129,7 +129,7 @@ loop(void *arg) for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) { if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) { const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 }; - SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, 0); + SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, SDL_FLIP_NONE); } } @@ -139,11 +139,11 @@ loop(void *arg) if (value < -deadzone) { const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; const double angle = axis_positions[i].angle; - SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0); + SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); } else if (value > deadzone) { const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; const double angle = axis_positions[i].angle + 180.0; - SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, 0); + SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); } } @@ -181,6 +181,8 @@ WatchGameController(SDL_GameController * gamecontroller) window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, 0); + SDL_free(title); + title = NULL; if (window == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); return SDL_FALSE; diff --git a/Engine/lib/sdl/test/testgles.c b/Engine/lib/sdl/test/testgles.c index 291661a09..5be48ac56 100644 --- a/Engine/lib/sdl/test/testgles.c +++ b/Engine/lib/sdl/test/testgles.c @@ -173,7 +173,7 @@ main(int argc, char *argv[]) quit(2); } - context = SDL_calloc(state->num_windows, sizeof(context)); + context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context)); if (context == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n"); quit(2); diff --git a/Engine/lib/sdl/test/testgles2.c b/Engine/lib/sdl/test/testgles2.c index af5962ba4..45b3d79a3 100644 --- a/Engine/lib/sdl/test/testgles2.c +++ b/Engine/lib/sdl/test/testgles2.c @@ -546,7 +546,7 @@ main(int argc, char *argv[]) return 0; } - context = SDL_calloc(state->num_windows, sizeof(context)); + context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context)); if (context == NULL) { SDL_Log("Out of memory!\n"); quit(2); @@ -640,7 +640,7 @@ main(int argc, char *argv[]) } } - datas = SDL_calloc(state->num_windows, sizeof(shader_data)); + datas = (shader_data *)SDL_calloc(state->num_windows, sizeof(shader_data)); /* Set rendering settings for each context */ for (i = 0; i < state->num_windows; ++i) { diff --git a/Engine/lib/sdl/test/testime.c b/Engine/lib/sdl/test/testime.c index d6e7ea1f2..39a40f82f 100644 --- a/Engine/lib/sdl/test/testime.c +++ b/Engine/lib/sdl/test/testime.c @@ -9,7 +9,9 @@ including commercial applications, and to alter it and redistribute it freely. */ -/* A simple program to test the Input Method support in the SDL library (2.0+) */ +/* A simple program to test the Input Method support in the SDL library (2.0+) + If you build without SDL_ttf, you can use the GNU Unifont hex file instead. + Download at http://unifoundry.com/unifont.html */ #include #include @@ -22,19 +24,342 @@ #include "SDL_test_common.h" -#define DEFAULT_PTSIZE 30 -#define DEFAULT_FONT "/System/Library/Fonts/åŽæ–‡ç»†é»‘.ttf" +#define DEFAULT_PTSIZE 30 +#ifdef HAVE_SDL_TTF +#ifdef __MACOSX__ +#define DEFAULT_FONT "/System/Library/Fonts/åŽæ–‡ç»†é»‘.ttf" +#elif __WIN32__ +/* Some japanese font present on at least Windows 8.1. */ +#define DEFAULT_FONT "C:\\Windows\\Fonts\\yugothic.ttf" +#else +#define DEFAULT_FONT "NoDefaultFont.ttf" +#endif +#else +#define DEFAULT_FONT "unifont-9.0.02.hex" +#endif #define MAX_TEXT_LENGTH 256 static SDLTest_CommonState *state; static SDL_Rect textRect, markedRect; -static SDL_Color lineColor = {0,0,0,0}; -static SDL_Color backColor = {255,255,255,0}; -static SDL_Color textColor = {0,0,0,0}; +static SDL_Color lineColor = {0,0,0,255}; +static SDL_Color backColor = {255,255,255,255}; +static SDL_Color textColor = {0,0,0,255}; static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; static int cursor = 0; #ifdef HAVE_SDL_TTF static TTF_Font *font; +#else +#define UNIFONT_MAX_CODEPOINT 0x1ffff +#define UNIFONT_NUM_GLYPHS 0x20000 +/* Using 512x512 textures that are supported everywhere. */ +#define UNIFONT_TEXTURE_WIDTH 512 +#define UNIFONT_GLYPHS_IN_ROW (UNIFONT_TEXTURE_WIDTH / 16) +#define UNIFONT_GLYPHS_IN_TEXTURE (UNIFONT_GLYPHS_IN_ROW * UNIFONT_GLYPHS_IN_ROW) +#define UNIFONT_NUM_TEXTURES ((UNIFONT_NUM_GLYPHS + UNIFONT_GLYPHS_IN_TEXTURE - 1) / UNIFONT_GLYPHS_IN_TEXTURE) +#define UNIFONT_TEXTURE_SIZE (UNIFONT_TEXTURE_WIDTH * UNIFONT_TEXTURE_WIDTH * 4) +#define UNIFONT_TEXTURE_PITCH (UNIFONT_TEXTURE_WIDTH * 4) +#define UNIFONT_DRAW_SCALE 2 +struct UnifontGlyph { + Uint8 width; + Uint8 data[32]; +} *unifontGlyph; +static SDL_Texture **unifontTexture; +static Uint8 unifontTextureLoaded[UNIFONT_NUM_TEXTURES] = {0}; + +/* Unifont loading code start */ + +static Uint8 dehex(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 255; +} + +static Uint8 dehex2(char c1, char c2) +{ + return (dehex(c1) << 4) | dehex(c2); +} + +static Uint8 validate_hex(const char *cp, size_t len, Uint32 *np) +{ + Uint32 n = 0; + for (; len > 0; cp++, len--) + { + Uint8 c = dehex(*cp); + if (c == 255) + return 0; + n = (n << 4) | c; + } + if (np != NULL) + *np = n; + return 1; +} + +static void unifont_init(const char *fontname) +{ + Uint8 hexBuffer[65]; + Uint32 numGlyphs = 0; + int lineNumber = 1; + size_t bytesRead; + SDL_RWops *hexFile; + const size_t unifontGlyphSize = UNIFONT_NUM_GLYPHS * sizeof(struct UnifontGlyph); + const size_t unifontTextureSize = UNIFONT_NUM_TEXTURES * state->num_windows * sizeof(void *); + + /* Allocate memory for the glyph data so the file can be closed after initialization. */ + unifontGlyph = (struct UnifontGlyph *)SDL_malloc(unifontGlyphSize); + if (unifontGlyph == NULL) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for glyph data.\n", (int)(unifontGlyphSize + 1023) / 1024); + exit(-1); + } + SDL_memset(unifontGlyph, 0, unifontGlyphSize); + + /* Allocate memory for texture pointers for all renderers. */ + unifontTexture = (SDL_Texture **)SDL_malloc(unifontTextureSize); + if (unifontTexture == NULL) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for texture pointer data.\n", (int)(unifontTextureSize + 1023) / 1024); + exit(-1); + } + SDL_memset(unifontTexture, 0, unifontTextureSize); + + hexFile = SDL_RWFromFile(fontname, "rb"); + if (hexFile == NULL) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to open font file: %s\n", fontname); + exit(-1); + } + + /* Read all the glyph data into memory to make it accessible later when textures are created. */ + do { + int i, codepointHexSize; + size_t bytesOverread; + Uint8 glyphWidth; + Uint32 codepoint; + + bytesRead = SDL_RWread(hexFile, hexBuffer, 1, 9); + if (numGlyphs > 0 && bytesRead == 0) + break; /* EOF */ + if ((numGlyphs == 0 && bytesRead == 0) || (numGlyphs > 0 && bytesRead < 9)) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unfiont: Unexpected end of hex file.\n"); + exit(-1); + } + + /* Looking for the colon that separates the codepoint and glyph data at position 2, 4, 6 and 8. */ + if (hexBuffer[2] == ':') + codepointHexSize = 2; + else if (hexBuffer[4] == ':') + codepointHexSize = 4; + else if (hexBuffer[6] == ':') + codepointHexSize = 6; + else if (hexBuffer[8] == ':') + codepointHexSize = 8; + else + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Could not find codepoint and glyph data separator symbol in hex file on line %d.\n", lineNumber); + exit(-1); + } + + if (!validate_hex((const char *)hexBuffer, codepointHexSize, &codepoint)) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal number in hex file on line %d.\n", lineNumber); + exit(-1); + } + if (codepoint > UNIFONT_MAX_CODEPOINT) + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Codepoint on line %d exceeded limit of 0x%x.\n", lineNumber, UNIFONT_MAX_CODEPOINT); + + /* If there was glyph data read in the last file read, move it to the front of the buffer. */ + bytesOverread = 8 - codepointHexSize; + if (codepointHexSize < 8) + SDL_memmove(hexBuffer, hexBuffer + codepointHexSize + 1, bytesOverread); + bytesRead = SDL_RWread(hexFile, hexBuffer + bytesOverread, 1, 33 - bytesOverread); + if (bytesRead < (33 - bytesOverread)) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n"); + exit(-1); + } + if (hexBuffer[32] == '\n') + glyphWidth = 8; + else + { + glyphWidth = 16; + bytesRead = SDL_RWread(hexFile, hexBuffer + 33, 1, 32); + if (bytesRead < 32) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n"); + exit(-1); + } + } + + if (!validate_hex((const char *)hexBuffer, glyphWidth * 4, NULL)) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal glyph data in hex file on line %d.\n", lineNumber); + exit(-1); + } + + if (codepoint <= UNIFONT_MAX_CODEPOINT) + { + if (unifontGlyph[codepoint].width > 0) + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Ignoring duplicate codepoint 0x%08x in hex file on line %d.\n", codepoint, lineNumber); + else + { + unifontGlyph[codepoint].width = glyphWidth; + /* Pack the hex data into a more compact form. */ + for (i = 0; i < glyphWidth * 2; i++) + unifontGlyph[codepoint].data[i] = dehex2(hexBuffer[i * 2], hexBuffer[i * 2 + 1]); + numGlyphs++; + } + } + + lineNumber++; + } while (bytesRead > 0); + + SDL_RWclose(hexFile); + SDL_Log("unifont: Loaded %u glyphs.\n", numGlyphs); +} + +static void unifont_make_rgba(Uint8 *src, Uint8 *dst, Uint8 width) +{ + int i, j; + Uint8 *row = dst; + + for (i = 0; i < width * 2; i++) + { + Uint8 data = src[i]; + for (j = 0; j < 8; j++) + { + if (data & 0x80) + { + row[0] = textColor.r; + row[1] = textColor.g; + row[2] = textColor.b; + row[3] = textColor.a; + } + else + { + row[0] = 0; + row[1] = 0; + row[2] = 0; + row[3] = 0; + } + data <<= 1; + row += 4; + } + + if (width == 8 || (width == 16 && i % 2 == 1)) + { + dst += UNIFONT_TEXTURE_PITCH; + row = dst; + } + } +} + +static void unifont_load_texture(Uint32 textureID) +{ + int i; + Uint8 * textureRGBA; + + if (textureID >= UNIFONT_NUM_TEXTURES) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Tried to load out of range texture %u.\n", textureID); + exit(-1); + } + + textureRGBA = (Uint8 *)SDL_malloc(UNIFONT_TEXTURE_SIZE); + if (textureRGBA == NULL) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d MiB for a texture.\n", UNIFONT_TEXTURE_SIZE / 1024 / 1024); + exit(-1); + } + SDL_memset(textureRGBA, 0, UNIFONT_TEXTURE_SIZE); + + /* Copy the glyphs into memory in RGBA format. */ + for (i = 0; i < UNIFONT_GLYPHS_IN_TEXTURE; i++) + { + Uint32 codepoint = UNIFONT_GLYPHS_IN_TEXTURE * textureID + i; + if (unifontGlyph[codepoint].width > 0) + { + const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE; + const size_t offset = (cInTex / UNIFONT_GLYPHS_IN_ROW) * UNIFONT_TEXTURE_PITCH * 16 + (cInTex % UNIFONT_GLYPHS_IN_ROW) * 16 * 4; + unifont_make_rgba(unifontGlyph[codepoint].data, textureRGBA + offset, unifontGlyph[codepoint].width); + } + } + + /* Create textures and upload the RGBA data from above. */ + for (i = 0; i < state->num_windows; ++i) + { + SDL_Renderer *renderer = state->renderers[i]; + SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID]; + if (state->windows[i] == NULL || renderer == NULL || tex != NULL) + continue; + tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, UNIFONT_TEXTURE_WIDTH, UNIFONT_TEXTURE_WIDTH); + if (tex == NULL) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to create texture %u for renderer %d.\n", textureID, i); + exit(-1); + } + unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID] = tex; + SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND); + if (SDL_UpdateTexture(tex, NULL, textureRGBA, UNIFONT_TEXTURE_PITCH) != 0) + { + SDL_Log("unifont error: Failed to update texture %u data for renderer %d.\n", textureID, i); + } + } + + SDL_free(textureRGBA); + unifontTextureLoaded[textureID] = 1; +} + +static Sint32 unifont_draw_glyph(Uint32 codepoint, int rendererID, SDL_Rect *dstrect) +{ + SDL_Texture *texture; + const Uint32 textureID = codepoint / UNIFONT_GLYPHS_IN_TEXTURE; + SDL_Rect srcrect; + srcrect.w = srcrect.h = 16; + if (codepoint > UNIFONT_MAX_CODEPOINT) + return 0; + if (!unifontTextureLoaded[textureID]) + unifont_load_texture(textureID); + texture = unifontTexture[UNIFONT_NUM_TEXTURES * rendererID + textureID]; + if (texture != NULL) + { + const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE; + srcrect.x = cInTex % UNIFONT_GLYPHS_IN_ROW * 16; + srcrect.y = cInTex / UNIFONT_GLYPHS_IN_ROW * 16; + SDL_RenderCopy(state->renderers[rendererID], texture, &srcrect, dstrect); + } + return unifontGlyph[codepoint].width; +} + +static void unifont_cleanup() +{ + int i, j; + for (i = 0; i < state->num_windows; ++i) + { + SDL_Renderer *renderer = state->renderers[i]; + if (state->windows[i] == NULL || renderer == NULL) + continue; + for (j = 0; j < UNIFONT_NUM_TEXTURES; j++) + { + SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + j]; + if (tex != NULL) + SDL_DestroyTexture(tex); + } + } + + for (j = 0; j < UNIFONT_NUM_TEXTURES; j++) + unifontTextureLoaded[j] = 0; + + SDL_free(unifontTexture); + SDL_free(unifontGlyph); +} + +/* Unifont code end */ #endif size_t utf8_length(unsigned char c) @@ -78,6 +403,30 @@ char *utf8_advance(char *p, size_t distance) return p; } +Uint32 utf8_decode(char *p, size_t len) +{ + Uint32 codepoint = 0; + size_t i = 0; + if (!len) + return 0; + + for (; i < len; ++i) + { + if (i == 0) + codepoint = (0xff >> len) & *p; + else + { + codepoint <<= 6; + codepoint |= 0x3f & *p; + } + if (!*p) + return 0; + p++; + } + + return codepoint; +} + void usage() { SDL_Log("usage: testime [--font fontfile]\n"); @@ -105,34 +454,61 @@ void CleanupVideo() #ifdef HAVE_SDL_TTF TTF_CloseFont(font); TTF_Quit(); +#else + unifont_cleanup(); #endif } +void _Redraw(int rendererID) { + SDL_Renderer * renderer = state->renderers[rendererID]; + SDL_Rect drawnTextRect, cursorRect, underlineRect; + drawnTextRect = textRect; + drawnTextRect.w = 0; -void _Redraw(SDL_Renderer * renderer) { - int w = 0, h = textRect.h; - SDL_Rect cursorRect, underlineRect; - - SDL_SetRenderDrawColor(renderer, 255,255,255,255); + SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a); SDL_RenderFillRect(renderer,&textRect); -#ifdef HAVE_SDL_TTF if (*text) { +#ifdef HAVE_SDL_TTF SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, textColor); - SDL_Rect dest = {textRect.x, textRect.y, textSur->w, textSur->h }; + SDL_Texture *texture; - SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur); + /* Vertically center text */ + drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2; + drawnTextRect.w = textSur->w; + drawnTextRect.h = textSur->h; + + texture = SDL_CreateTextureFromSurface(renderer,textSur); SDL_FreeSurface(textSur); - SDL_RenderCopy(renderer,texture,NULL,&dest); + SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect); SDL_DestroyTexture(texture); - TTF_SizeUTF8(font, text, &w, &h); - } -#endif +#else + char *utext = text; + Uint32 codepoint; + size_t len; + SDL_Rect dstrect; - markedRect.x = textRect.x + w; - markedRect.w = textRect.w - w; + dstrect.x = textRect.x; + dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2; + dstrect.w = 16 * UNIFONT_DRAW_SCALE; + dstrect.h = 16 * UNIFONT_DRAW_SCALE; + drawnTextRect.y = dstrect.y; + drawnTextRect.h = dstrect.h; + + while ((codepoint = utf8_decode(utext, len = utf8_length(*utext)))) + { + Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE; + dstrect.x += advance; + drawnTextRect.w += advance; + utext += len; + } +#endif + } + + markedRect.x = textRect.x + drawnTextRect.w; + markedRect.w = textRect.w - drawnTextRect.w; if (markedRect.w < 0) { /* Stop text input because we cannot hold any more characters */ @@ -144,49 +520,88 @@ void _Redraw(SDL_Renderer * renderer) { SDL_StartTextInput(); } - cursorRect = markedRect; + cursorRect = drawnTextRect; + cursorRect.x += cursorRect.w; cursorRect.w = 2; - cursorRect.h = h; + cursorRect.h = drawnTextRect.h; - SDL_SetRenderDrawColor(renderer, 255,255,255,255); + drawnTextRect.x += drawnTextRect.w; + drawnTextRect.w = 0; + + SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a); SDL_RenderFillRect(renderer,&markedRect); if (markedText[0]) { #ifdef HAVE_SDL_TTF + SDL_Surface *textSur; + SDL_Texture *texture; if (cursor) { char *p = utf8_advance(markedText, cursor); char c = 0; if (!p) - p = &markedText[strlen(markedText)]; + p = &markedText[SDL_strlen(markedText)]; c = *p; *p = 0; - TTF_SizeUTF8(font, markedText, &w, 0); - cursorRect.x += w; + TTF_SizeUTF8(font, markedText, &drawnTextRect.w, NULL); + cursorRect.x += drawnTextRect.w; *p = c; } - SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, markedText, textColor); - SDL_Rect dest = {markedRect.x, markedRect.y, textSur->w, textSur->h }; - TTF_SizeUTF8(font, markedText, &w, &h); - SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer,textSur); + textSur = TTF_RenderUTF8_Blended(font, markedText, textColor); + /* Vertically center text */ + drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2; + drawnTextRect.w = textSur->w; + drawnTextRect.h = textSur->h; + + texture = SDL_CreateTextureFromSurface(renderer,textSur); SDL_FreeSurface(textSur); - SDL_RenderCopy(renderer,texture,NULL,&dest); + SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect); SDL_DestroyTexture(texture); +#else + int i = 0; + char *utext = markedText; + Uint32 codepoint; + size_t len; + SDL_Rect dstrect; + + dstrect.x = drawnTextRect.x; + dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2; + dstrect.w = 16 * UNIFONT_DRAW_SCALE; + dstrect.h = 16 * UNIFONT_DRAW_SCALE; + drawnTextRect.y = dstrect.y; + drawnTextRect.h = dstrect.h; + + while ((codepoint = utf8_decode(utext, len = utf8_length(*utext)))) + { + Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE; + dstrect.x += advance; + drawnTextRect.w += advance; + if (i < cursor) + cursorRect.x += advance; + i++; + utext += len; + } #endif - underlineRect = markedRect; - underlineRect.y += (h - 2); - underlineRect.h = 2; - underlineRect.w = w; + if (cursor > 0) + { + cursorRect.y = drawnTextRect.y; + cursorRect.h = drawnTextRect.h; + } - SDL_SetRenderDrawColor(renderer, 0,0,0,0); - SDL_RenderFillRect(renderer,&markedRect); + underlineRect = markedRect; + underlineRect.y = drawnTextRect.y + drawnTextRect.h - 2; + underlineRect.h = 2; + underlineRect.w = drawnTextRect.w; + + SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a); + SDL_RenderFillRect(renderer, &underlineRect); } - SDL_SetRenderDrawColor(renderer, 0,0,0,0); + SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a); SDL_RenderFillRect(renderer,&cursorRect); SDL_SetTextInputRect(&markedRect); @@ -201,7 +616,8 @@ void Redraw() { SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); - _Redraw(renderer); + /* Sending in the window id to let the font renderers know which one we're working with. */ + _Redraw(i); SDL_RenderPresent(renderer); } @@ -259,6 +675,8 @@ int main(int argc, char *argv[]) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to find font: %s\n", TTF_GetError()); exit(-1); } +#else + unifont_init(fontname); #endif SDL_Log("Using font: %s\n", fontname); @@ -288,6 +706,8 @@ int main(int argc, char *argv[]) { Redraw(); break; case SDLK_BACKSPACE: + /* Only delete text if not in editing mode. */ + if (!markedText[0]) { size_t textlen = SDL_strlen(text); @@ -354,7 +774,7 @@ int main(int argc, char *argv[]) { SDL_Log("text editing \"%s\", selected range (%d, %d)\n", event.edit.text, event.edit.start, event.edit.length); - strcpy(markedText, event.edit.text); + SDL_strlcpy(markedText, event.edit.text, SDL_TEXTEDITINGEVENT_TEXT_SIZE); cursor = event.edit.start; Redraw(); break; diff --git a/Engine/lib/sdl/test/testlock.c b/Engine/lib/sdl/test/testlock.c index 1106ec3bf..113ba0d4c 100644 --- a/Engine/lib/sdl/test/testlock.c +++ b/Engine/lib/sdl/test/testlock.c @@ -23,7 +23,7 @@ static SDL_mutex *mutex = NULL; static SDL_threadID mainthread; static SDL_Thread *threads[6]; -static volatile int doterminate = 0; +static SDL_atomic_t doterminate; /* * SDL_Quit() shouldn't be used with atexit() directly because @@ -45,7 +45,7 @@ void terminate(int sig) { signal(SIGINT, terminate); - doterminate = 1; + SDL_AtomicSet(&doterminate, 1); } void @@ -54,7 +54,7 @@ closemutex(int sig) SDL_threadID id = SDL_ThreadID(); int i; SDL_Log("Process %lu: Cleaning up...\n", id == mainthread ? 0 : id); - doterminate = 1; + SDL_AtomicSet(&doterminate, 1); for (i = 0; i < 6; ++i) SDL_WaitThread(threads[i], NULL); SDL_DestroyMutex(mutex); @@ -66,7 +66,7 @@ Run(void *data) { if (SDL_ThreadID() == mainthread) signal(SIGTERM, closemutex); - while (!doterminate) { + while (!SDL_AtomicGet(&doterminate)) { SDL_Log("Process %lu ready to work\n", SDL_ThreadID()); if (SDL_LockMutex(mutex) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError()); @@ -82,7 +82,7 @@ Run(void *data) /* If this sleep isn't done, then threads may starve */ SDL_Delay(10); } - if (SDL_ThreadID() == mainthread && doterminate) { + if (SDL_ThreadID() == mainthread && SDL_AtomicGet(&doterminate)) { SDL_Log("Process %lu: raising SIGTERM\n", SDL_ThreadID()); raise(SIGTERM); } @@ -105,6 +105,8 @@ main(int argc, char *argv[]) } atexit(SDL_Quit_Wrapper); + SDL_AtomicSet(&doterminate, 0); + if ((mutex = SDL_CreateMutex()) == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create mutex: %s\n", SDL_GetError()); exit(1); diff --git a/Engine/lib/sdl/test/testmultiaudio.c b/Engine/lib/sdl/test/testmultiaudio.c index 117ef2696..1b07ba9fc 100644 --- a/Engine/lib/sdl/test/testmultiaudio.c +++ b/Engine/lib/sdl/test/testmultiaudio.c @@ -25,7 +25,7 @@ typedef struct { SDL_AudioDeviceID dev; int soundpos; - volatile int done; + SDL_atomic_t done; } callback_data; callback_data cbd[64]; @@ -46,14 +46,14 @@ play_through_once(void *arg, Uint8 * stream, int len) if (len > 0) { stream += cpy; SDL_memset(stream, spec.silence, len); - cbd->done++; + SDL_AtomicSet(&cbd->done, 1); } } void loop() { - if(cbd[0].done) { + if (SDL_AtomicGet(&cbd[0].done)) { #ifdef __EMSCRIPTEN__ emscripten_cancel_main_loop(); #endif @@ -100,8 +100,7 @@ test_multi_audio(int devcount) #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(loop, 0, 1); #else - while (!cbd[0].done) - { + while (!SDL_AtomicGet(&cbd[0].done)) { #ifdef __ANDROID__ /* Empty queue, some application events would prevent pause. */ while (SDL_PollEvent(&event)){} @@ -136,7 +135,7 @@ test_multi_audio(int devcount) while (keep_going) { keep_going = 0; for (i = 0; i < devcount; i++) { - if ((cbd[i].dev) && (!cbd[i].done)) { + if ((cbd[i].dev) && (!SDL_AtomicGet(&cbd[i].done))) { keep_going = 1; } } diff --git a/Engine/lib/sdl/test/testqsort.c b/Engine/lib/sdl/test/testqsort.c new file mode 100644 index 000000000..48659f307 --- /dev/null +++ b/Engine/lib/sdl/test/testqsort.c @@ -0,0 +1,108 @@ +/* + Copyright (C) 1997-2016 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ + +#include "SDL_test.h" + +static int +num_compare(const void *_a, const void *_b) +{ + const int a = *((const int *) _a); + const int b = *((const int *) _b); + return (a < b) ? -1 : ((a > b) ? 1 : 0); +} + +static void +test_sort(const char *desc, int *nums, const int arraylen) +{ + int i; + int prev; + + SDL_Log("test: %s arraylen=%d", desc, arraylen); + + SDL_qsort(nums, arraylen, sizeof (nums[0]), num_compare); + + prev = nums[0]; + for (i = 1; i < arraylen; i++) { + const int val = nums[i]; + if (val < prev) { + SDL_Log("sort is broken!"); + return; + } + prev = val; + } +} + +int +main(int argc, char *argv[]) +{ + static int nums[1024 * 100]; + static const int itervals[] = { SDL_arraysize(nums), 12 }; + int iteration; + SDLTest_RandomContext rndctx; + + if (argc > 1) + { + int success; + Uint64 seed = 0; + if (argv[1][0] == '0' && argv[1][1] == 'x') + success = SDL_sscanf(argv[1] + 2, "%llx", &seed); + else + success = SDL_sscanf(argv[1], "%llu", &seed); + if (!success) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid seed. Use a decimal or hexadecimal number.\n"); + return 1; + } + if (seed <= 0xffffffff) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Seed must be equal or greater than 0x100000000.\n"); + return 1; + } + SDLTest_RandomInit(&rndctx, (unsigned int)(seed >> 32), (unsigned int)(seed & 0xffffffff)); + } + else + { + SDLTest_RandomInitTime(&rndctx); + } + SDL_Log("Using random seed 0x%08x%08x\n", rndctx.x, rndctx.c); + + for (iteration = 0; iteration < SDL_arraysize(itervals); iteration++) { + const int arraylen = itervals[iteration]; + int i; + + for (i = 0; i < arraylen; i++) { + nums[i] = i; + } + test_sort("already sorted", nums, arraylen); + + for (i = 0; i < arraylen; i++) { + nums[i] = i; + } + nums[arraylen-1] = -1; + test_sort("already sorted except last element", nums, arraylen); + + for (i = 0; i < arraylen; i++) { + nums[i] = (arraylen-1) - i; + } + test_sort("reverse sorted", nums, arraylen); + + for (i = 0; i < arraylen; i++) { + nums[i] = SDLTest_RandomInt(&rndctx); + } + test_sort("random sorted", nums, arraylen); + } + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/Engine/lib/sdl/test/testrendercopyex.c b/Engine/lib/sdl/test/testrendercopyex.c index 856abf7d0..e34890245 100644 --- a/Engine/lib/sdl/test/testrendercopyex.c +++ b/Engine/lib/sdl/test/testrendercopyex.c @@ -45,7 +45,7 @@ quit(int rc) } SDL_Texture * -LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) +LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) { SDL_Surface *temp; SDL_Texture *texture; @@ -126,7 +126,7 @@ Draw(DrawState *s) s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2; s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2; - SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, s->scale_direction); + SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, (SDL_RendererFlip)s->scale_direction); SDL_SetRenderTarget(s->renderer, NULL); SDL_RenderCopy(s->renderer, target, NULL, NULL); diff --git a/Engine/lib/sdl/test/testshape.c b/Engine/lib/sdl/test/testshape.c index 00750a970..476fac21e 100644 --- a/Engine/lib/sdl/test/testshape.c +++ b/Engine/lib/sdl/test/testshape.c @@ -71,6 +71,10 @@ int main(int argc,char** argv) num_pictures = argc - 1; pictures = (LoadedPicture *)SDL_malloc(sizeof(LoadedPicture)*num_pictures); + if (!pictures) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not allocate memory."); + exit(1); + } for(i=0;inum_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + } #ifdef __EMSCRIPTEN__ if (done) { emscripten_cancel_main_loop(); @@ -122,7 +129,6 @@ main(int argc, char *argv[]) if (!state) { return 1; } - state->skip_renderer = SDL_TRUE; for (i = 1; i < argc;) { int consumed; @@ -140,6 +146,12 @@ main(int argc, char *argv[]) quit(2); } + for (i = 0; i < state->num_windows; ++i) { + SDL_Renderer *renderer = state->renderers[i]; + SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); + SDL_RenderClear(renderer); + } + /* Main render loop */ done = 0; #ifdef __EMSCRIPTEN__ diff --git a/Engine/lib/sdl/test/torturethread.c b/Engine/lib/sdl/test/torturethread.c index 5719a7195..6b98a0a9f 100644 --- a/Engine/lib/sdl/test/torturethread.c +++ b/Engine/lib/sdl/test/torturethread.c @@ -21,7 +21,7 @@ #define NUMTHREADS 10 -static char volatile time_for_threads_to_die[NUMTHREADS]; +static SDL_atomic_t time_for_threads_to_die[NUMTHREADS]; /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void @@ -58,7 +58,7 @@ ThreadFunc(void *data) } SDL_Log("Thread '%d' waiting for signal\n", tid); - while (time_for_threads_to_die[tid] != 1) { + while (SDL_AtomicGet(&time_for_threads_to_die[tid]) != 1) { ; /* do nothing */ } @@ -92,7 +92,7 @@ main(int argc, char *argv[]) for (i = 0; i < NUMTHREADS; i++) { char name[64]; SDL_snprintf(name, sizeof (name), "Parent%d", i); - time_for_threads_to_die[i] = 0; + SDL_AtomicSet(&time_for_threads_to_die[i], 0); threads[i] = SDL_CreateThread(ThreadFunc, name, (void*) (uintptr_t) i); if (threads[i] == NULL) { @@ -102,7 +102,7 @@ main(int argc, char *argv[]) } for (i = 0; i < NUMTHREADS; i++) { - time_for_threads_to_die[i] = 1; + SDL_AtomicSet(&time_for_threads_to_die[i], 1); } for (i = 0; i < NUMTHREADS; i++) { diff --git a/Engine/source/.gitattributes b/Engine/source/.gitattributes new file mode 100644 index 000000000..abf67ea1d --- /dev/null +++ b/Engine/source/.gitattributes @@ -0,0 +1,5 @@ +*.cpp filter=tabspace +*.h filter=tabspace +*.l filter=tabspace +*.y filter=tabspace +*.mm filter=tabspace diff --git a/Tools/CMake/torque3d.cmake b/Tools/CMake/torque3d.cmake index 44591dd94..30027e4cd 100644 --- a/Tools/CMake/torque3d.cmake +++ b/Tools/CMake/torque3d.cmake @@ -640,6 +640,7 @@ if (APPLE) addFramework("CoreVideo") #grrr damn you sdl! addFramework("Carbon") + addFramework("AudioToolbox") addLib("iconv") #set a few arch defaults set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "OSX Architecture" FORCE) From cf56764347fdb481070e594a7e6d839311c7ae7a Mon Sep 17 00:00:00 2001 From: "Thomas \"elfprince13\" Dickerson" Date: Fri, 13 Jan 2017 10:45:52 -0500 Subject: [PATCH 36/50] didn't mean to include this for everyone --- Engine/source/.gitattributes | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 Engine/source/.gitattributes diff --git a/Engine/source/.gitattributes b/Engine/source/.gitattributes deleted file mode 100644 index abf67ea1d..000000000 --- a/Engine/source/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -*.cpp filter=tabspace -*.h filter=tabspace -*.l filter=tabspace -*.y filter=tabspace -*.mm filter=tabspace From 512514df20f6f207ce8bd6998195460d7915cda4 Mon Sep 17 00:00:00 2001 From: Thomas Dickerson Date: Fri, 13 Jan 2017 14:40:10 -0500 Subject: [PATCH 37/50] Call the correct system rename Addressing #1913 --- Engine/source/platformPOSIX/posixVolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Engine/source/platformPOSIX/posixVolume.cpp b/Engine/source/platformPOSIX/posixVolume.cpp index a5d0871d0..0f39bea3c 100644 --- a/Engine/source/platformPOSIX/posixVolume.cpp +++ b/Engine/source/platformPOSIX/posixVolume.cpp @@ -206,7 +206,7 @@ bool PosixFileSystem::rename(const Path& from,const Path& to) String fa = buildFileName(_volume,from); String fb = buildFileName(_volume,to); - if (!rename(fa.c_str(),fb.c_str())) + if (!::rename(fa.c_str(),fb.c_str())) return true; return false; From 2029e3eb2234e7175c4dae718617658bc12e86dd Mon Sep 17 00:00:00 2001 From: LukasPJ Date: Sun, 15 Jan 2017 23:22:46 +0100 Subject: [PATCH 38/50] Make RenderPassManager call Parent::InitPersistFields --- Engine/source/renderInstance/renderPassManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Engine/source/renderInstance/renderPassManager.cpp b/Engine/source/renderInstance/renderPassManager.cpp index f620a627b..3ed2671dc 100644 --- a/Engine/source/renderInstance/renderPassManager.cpp +++ b/Engine/source/renderInstance/renderPassManager.cpp @@ -124,6 +124,7 @@ RenderPassManager::RenderBinEventSignal& RenderPassManager::getRenderBinSignal() void RenderPassManager::initPersistFields() { + Parent::initPersistFields(); } RenderPassManager::RenderPassManager() From f50d46dffc7ccf382bb936c9ea90b4cced3c5723 Mon Sep 17 00:00:00 2001 From: LukasPJ Date: Sun, 15 Jan 2017 23:23:55 +0100 Subject: [PATCH 39/50] Cleanup when deactivating light manager instead of reinitializing --- .../renderInstance/renderParticleMgr.cpp | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/Engine/source/renderInstance/renderParticleMgr.cpp b/Engine/source/renderInstance/renderParticleMgr.cpp index dcae9756c..ad0811f91 100644 --- a/Engine/source/renderInstance/renderParticleMgr.cpp +++ b/Engine/source/renderInstance/renderParticleMgr.cpp @@ -589,43 +589,51 @@ bool RenderParticleMgr::_initShader() void RenderParticleMgr::_onLMActivate( const char*, bool activate ) { - RenderPassManager *rpm = getRenderPass(); - if ( !rpm ) - return; - - // Hunt for the pre-pass manager/target - RenderPrePassMgr *prePassBin = NULL; - for( U32 i = 0; i < rpm->getManagerCount(); i++ ) + if ( activate ) { - RenderBinManager *bin = rpm->getManager(i); - if( bin->getRenderInstType() == RenderPrePassMgr::RIT_PrePass ) + RenderPassManager *rpm = getRenderPass(); + if ( !rpm ) + return; + + // Hunt for the pre-pass manager/target + RenderPrePassMgr *prePassBin = NULL; + for( U32 i = 0; i < rpm->getManagerCount(); i++ ) { - prePassBin = (RenderPrePassMgr*)bin; - break; + RenderBinManager *bin = rpm->getManager(i); + if( bin->getRenderInstType() == RenderPrePassMgr::RIT_PrePass ) + { + prePassBin = (RenderPrePassMgr*)bin; + break; + } } - } - // If we found the prepass bin, set this bin to render very shortly afterwards - // and re-add this render-manager. If there is no pre-pass bin, or it doesn't - // have a depth-texture, we can't render offscreen. - mOffscreenRenderEnabled = prePassBin && (prePassBin->getTargetChainLength() > 0); - if(mOffscreenRenderEnabled) - { - rpm->removeManager(this); - setRenderOrder( prePassBin->getRenderOrder() + 0.011f ); - rpm->addManager(this); - } + // If we found the prepass bin, set this bin to render very shortly afterwards + // and re-add this render-manager. If there is no pre-pass bin, or it doesn't + // have a depth-texture, we can't render offscreen. + mOffscreenRenderEnabled = prePassBin && (prePassBin->getTargetChainLength() > 0); + if(mOffscreenRenderEnabled) + { + rpm->removeManager(this); + setRenderOrder( prePassBin->getRenderOrder() + 0.011f ); + rpm->addManager(this); + } - // Find the targets we use - mPrepassTarget = NamedTexTarget::find( "prepass" ); - mEdgeTarget = NamedTexTarget::find( "edge" ); + // Find the targets we use + mPrepassTarget = NamedTexTarget::find( "prepass" ); + mEdgeTarget = NamedTexTarget::find( "edge" ); - // Setup the shader - if ( activate ) + // Setup the shader _initShader(); - if ( mScreenQuadVertBuff.isNull() ) - _initGFXResources(); + if ( mScreenQuadVertBuff.isNull() ) + _initGFXResources(); + } + else + { + mStencilClearSB = NULL; + mScreenQuadPrimBuff = NULL; + mScreenQuadVertBuff = NULL; + } } GFXStateBlockRef RenderParticleMgr::_getOffscreenStateBlock(ParticleRenderInst *ri) From 11532e10cc406b42a898534fdca0de12d4f4e36e Mon Sep 17 00:00:00 2001 From: rextimmy Date: Mon, 16 Jan 2017 15:35:25 +1000 Subject: [PATCH 40/50] Add log2 function to mMathFn.h --- Engine/source/math/mMathFn.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Engine/source/math/mMathFn.h b/Engine/source/math/mMathFn.h index 1855656e7..93596f63f 100644 --- a/Engine/source/math/mMathFn.h +++ b/Engine/source/math/mMathFn.h @@ -320,6 +320,11 @@ inline F32 mLog(const F32 val) return (F32) log(val); } +inline F32 mLog2(const F32 val) +{ + return (F32) log2(val); +} + inline F32 mExp(const F32 val) { return (F32) exp(val); @@ -380,6 +385,10 @@ inline F64 mLog(const F64 val) return (F64) log(val); } +inline F64 mLog2(const F64 val) +{ + return (F64) log2(val); +} inline F32 mCatmullrom(F32 t, F32 p0, F32 p1, F32 p2, F32 p3) { From f6d624be8f22c1d67bf6fd498fd4ee32d9b7e487 Mon Sep 17 00:00:00 2001 From: rextimmy Date: Mon, 16 Jan 2017 15:36:52 +1000 Subject: [PATCH 41/50] Fix mipmap count and potential crash for non square textures that are allocated with GBitmap class --- Engine/source/gfx/bitmap/gBitmap.cpp | 5 ++++- Engine/source/gfx/gfxTextureManager.cpp | 16 +--------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/Engine/source/gfx/bitmap/gBitmap.cpp b/Engine/source/gfx/bitmap/gBitmap.cpp index e5ef6b407..9e20d6951 100644 --- a/Engine/source/gfx/bitmap/gBitmap.cpp +++ b/Engine/source/gfx/bitmap/gBitmap.cpp @@ -327,7 +327,10 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool mNumMipLevels++; allocPixels += currWidth * currHeight * mBytesPerPixel; - } while (currWidth != 1 && currHeight != 1); + } while (currWidth != 1 || currHeight != 1); + + U32 expectedMips = mFloor(mLog2(mMax(in_width, in_height))) + 1; + AssertFatal(mNumMipLevels == expectedMips, "GBitmap::allocateBitmap: mipmap count wrong"); } AssertFatal(mNumMipLevels <= c_maxMipLevels, "GBitmap::allocateBitmap: too many miplevels"); diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index b656fcffd..781e0daa2 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1085,21 +1085,7 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, // NOTE: Does this belong here? if( inOutNumMips == 0 && !autoGenSupp ) { - U32 currWidth = width; - U32 currHeight = height; - - inOutNumMips = 1; - do - { - currWidth >>= 1; - currHeight >>= 1; - if( currWidth == 0 ) - currWidth = 1; - if( currHeight == 0 ) - currHeight = 1; - - inOutNumMips++; - } while ( currWidth != 1 && currHeight != 1 ); + inOutNumMips = mFloor(mLog2(mMax(width, height))) + 1; } } } From f02d0d6c4ee4b131ebf8ac65a7ee9ff666eb5b8b Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 16 Jan 2017 00:09:55 -0600 Subject: [PATCH 42/50] Hooks the splash window code up to the same image loading code as the icon code, and also adds a check if it tries to load a BMP for either(this is a bad format and really shouldn't be used for pretty much anything). Also includes a icon for the templates. --- .../windowManager/sdl/sdlSplashScreen.cpp | 49 ++++++++++- .../source/windowManager/sdl/sdlWindowMgr.cpp | 82 ++++++++++-------- Templates/Empty/game/core/torque.png | Bin 0 -> 1331 bytes Templates/Full/game/core/torque.png | Bin 0 -> 1331 bytes 4 files changed, 92 insertions(+), 39 deletions(-) create mode 100644 Templates/Empty/game/core/torque.png create mode 100644 Templates/Full/game/core/torque.png diff --git a/Engine/source/windowManager/sdl/sdlSplashScreen.cpp b/Engine/source/windowManager/sdl/sdlSplashScreen.cpp index bf0931a9c..1cf2440af 100644 --- a/Engine/source/windowManager/sdl/sdlSplashScreen.cpp +++ b/Engine/source/windowManager/sdl/sdlSplashScreen.cpp @@ -22,7 +22,7 @@ #include "platform/platform.h" #include "console/console.h" - +#include "gfx/bitmap/gBitmap.h" #include "SDL.h" #include "windowManager/sdl/sdlWindow.h" @@ -36,7 +36,52 @@ bool Platform::displaySplashWindow( String path ) if(path.isEmpty()) return false; - gSplashImage = SDL_LoadBMP(path); + Torque::Path iconPath = Torque::Path(path); + + if (iconPath.getExtension() == String("bmp")) + { + Con::errorf("Unable to use bmp format images for the splash screen. Please use a different format."); + return false; + } + + Resource img = GBitmap::load(iconPath); + if (img != NULL) + { + U32 pitch; + U32 width = img->getWidth(); + bool hasAlpha = img->getHasTransparency(); + U32 depth; + + if (hasAlpha) + { + pitch = 4 * width; + depth = 32; + } + else + { + pitch = 3 * width; + depth = 24; + } + + Uint32 rmask, gmask, bmask, amask; + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) + { + S32 shift = hasAlpha ? 8 : 0; + rmask = 0xff000000 >> shift; + gmask = 0x00ff0000 >> shift; + bmask = 0x0000ff00 >> shift; + amask = 0x000000ff >> shift; + } + else + { + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = hasAlpha ? 0xff000000 : 0; + } + + gSplashImage = SDL_CreateRGBSurfaceFrom(img->getAddress(0, 0), img->getWidth(), img->getHeight(), depth, pitch, rmask, gmask, bmask, amask); + } //now the pop-up window if (gSplashImage) diff --git a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp index 6157374dd..489377082 100644 --- a/Engine/source/windowManager/sdl/sdlWindowMgr.cpp +++ b/Engine/source/windowManager/sdl/sdlWindowMgr.cpp @@ -168,47 +168,55 @@ PlatformWindow *PlatformWindowManagerSDL::createWindow(GFXDevice *device, const //Now, fetch our window icon, if any Torque::Path iconPath = Torque::Path(Con::getVariable( "$Core::windowIcon" )); - Resource bmp = GBitmap::load(iconPath); - if (bmp != NULL) + + if (iconPath.getExtension() == String("bmp")) { - U32 pitch; - U32 width = bmp->getWidth(); - bool hasAlpha = bmp->getHasTransparency(); - U32 depth; - - if (hasAlpha) + Con::errorf("Unable to use bmp format images for the window icon. Please use a different format."); + } + else + { + Resource img = GBitmap::load(iconPath); + if (img != NULL) { - pitch = 4 * width; - depth = 32; - } - else - { - pitch = 3 * width; - depth = 24; - } + U32 pitch; + U32 width = img->getWidth(); + bool hasAlpha = img->getHasTransparency(); + U32 depth; - Uint32 rmask, gmask, bmask, amask; - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) - { - S32 shift = hasAlpha ? 8 : 0; - rmask = 0xff000000 >> shift; - gmask = 0x00ff0000 >> shift; - bmask = 0x0000ff00 >> shift; - amask = 0x000000ff >> shift; + if (hasAlpha) + { + pitch = 4 * width; + depth = 32; + } + else + { + pitch = 3 * width; + depth = 24; + } + + Uint32 rmask, gmask, bmask, amask; + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) + { + S32 shift = hasAlpha ? 8 : 0; + rmask = 0xff000000 >> shift; + gmask = 0x00ff0000 >> shift; + bmask = 0x0000ff00 >> shift; + amask = 0x000000ff >> shift; + } + else + { + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = hasAlpha ? 0xff000000 : 0; + } + + SDL_Surface* iconSurface = SDL_CreateRGBSurfaceFrom(img->getAddress(0, 0), img->getWidth(), img->getHeight(), depth, pitch, rmask, gmask, bmask, amask); + + SDL_SetWindowIcon(window->mWindowHandle, iconSurface); + + SDL_FreeSurface(iconSurface); } - else - { - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = hasAlpha ? 0xff000000 : 0; - } - - SDL_Surface* iconSurface = SDL_CreateRGBSurfaceFrom(bmp->getAddress(0, 0), bmp->getWidth(), bmp->getHeight(), depth, pitch, rmask, gmask, bmask, amask); - - SDL_SetWindowIcon(window->mWindowHandle, iconSurface); - - SDL_FreeSurface(iconSurface); } if(device) diff --git a/Templates/Empty/game/core/torque.png b/Templates/Empty/game/core/torque.png new file mode 100644 index 0000000000000000000000000000000000000000..1023f2bb6655b4e5740ee9dbd56a2e4c2ac27594 GIT binary patch literal 1331 zcmV-31ue_)p4!cG4G5pgl# zAhXdy5XFU{3qgyx>Ozo$8!ePkTLhV=SS?N4Nt>6Ky!+m9(I!or`(9uAUPwI4ymxQT zcfNDJbMAdWkL;b%3Bv!?KFt^C@ufMsl1lX)gckOOKTSPN1#!IXs3v+IEFRWI4{}qq zR+w!%4*>I;j=3JQ5DEj|OGECN;xQuH8j|N4BzTMwrlDY$+F&27b3nZhz)hu)iVj|>P2n1l;sIZ#d z-I`d)ECd4ZFgHyf50Bz*EY;Pz5zg@-H${Cb;`c`<>5X`z*@drbF>FLEtXQV6^%=o& zO^=4s+`3wPZ)}oY)nm#I3;-XQWvt4Yuf48EVpz88Om zGXEL5VwsrW!3+9a^xschrt=(MwyGWTk6-)ClGq5)+*}#>B441J(YWiv64_X)8(5XK z3pw7ZN~AU0b>dPoNuj3D2p3qY8(5JhZtDpYc>8Nx3Qz~OgRCFFN(VXkU!(Uo7_yebuAS1RCaEio_HWY9nkb2+g&S7qfZt8vHy*iKjG8*#lGs z90&l{5aY+O{48G}0U##?p3_d5*&CgpcXzj0R{)fEJ_-gjA1Qpl^e=lmIjoH2tw)GWTpPX=&2BuOE&Hz0D;5Kx59b&39ASvW^>S;6;m5Dwx(3G4_TjB@P=$QUA pF#IVk{A1f~bTu@*AIj5e{{eIA^)eNAYt;Y%002ovPDHLkV1ikdVpISC literal 0 HcmV?d00001 diff --git a/Templates/Full/game/core/torque.png b/Templates/Full/game/core/torque.png new file mode 100644 index 0000000000000000000000000000000000000000..1023f2bb6655b4e5740ee9dbd56a2e4c2ac27594 GIT binary patch literal 1331 zcmV-31ue_)p4!cG4G5pgl# zAhXdy5XFU{3qgyx>Ozo$8!ePkTLhV=SS?N4Nt>6Ky!+m9(I!or`(9uAUPwI4ymxQT zcfNDJbMAdWkL;b%3Bv!?KFt^C@ufMsl1lX)gckOOKTSPN1#!IXs3v+IEFRWI4{}qq zR+w!%4*>I;j=3JQ5DEj|OGECN;xQuH8j|N4BzTMwrlDY$+F&27b3nZhz)hu)iVj|>P2n1l;sIZ#d z-I`d)ECd4ZFgHyf50Bz*EY;Pz5zg@-H${Cb;`c`<>5X`z*@drbF>FLEtXQV6^%=o& zO^=4s+`3wPZ)}oY)nm#I3;-XQWvt4Yuf48EVpz88Om zGXEL5VwsrW!3+9a^xschrt=(MwyGWTk6-)ClGq5)+*}#>B441J(YWiv64_X)8(5XK z3pw7ZN~AU0b>dPoNuj3D2p3qY8(5JhZtDpYc>8Nx3Qz~OgRCFFN(VXkU!(Uo7_yebuAS1RCaEio_HWY9nkb2+g&S7qfZt8vHy*iKjG8*#lGs z90&l{5aY+O{48G}0U##?p3_d5*&CgpcXzj0R{)fEJ_-gjA1Qpl^e=lmIjoH2tw)GWTpPX=&2BuOE&Hz0D;5Kx59b&39ASvW^>S;6;m5Dwx(3G4_TjB@P=$QUA pF#IVk{A1f~bTu@*AIj5e{{eIA^)eNAYt;Y%002ovPDHLkV1ikdVpISC literal 0 HcmV?d00001 From 6a204f3528974f3efacd32b42a6328b012b9b521 Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 16 Jan 2017 00:16:17 -0600 Subject: [PATCH 43/50] Missed removing the old BMP splash for the new PNG one. --- Templates/Empty/game/art/gui/splash.bmp | Bin 338576 -> 0 bytes Templates/Empty/game/art/gui/splash.png | Bin 0 -> 11864 bytes Templates/Empty/game/main.cs | 2 +- Templates/Full/game/art/gui/splash.bmp | Bin 338576 -> 0 bytes Templates/Full/game/art/gui/splash.png | Bin 0 -> 11864 bytes Templates/Full/game/main.cs | 2 +- 6 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 Templates/Empty/game/art/gui/splash.bmp create mode 100644 Templates/Empty/game/art/gui/splash.png delete mode 100644 Templates/Full/game/art/gui/splash.bmp create mode 100644 Templates/Full/game/art/gui/splash.png diff --git a/Templates/Empty/game/art/gui/splash.bmp b/Templates/Empty/game/art/gui/splash.bmp deleted file mode 100644 index 47cb47f97e390125d04ee2fc9c4a53edee71a7ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338576 zcmeI5d9)S9oyW-^ITM!mcn^52BC>fVITIt8GoF(upvgH&R9xmv50^X-U?D3Q&Qj0_0j#3I0n3s6Z$RkZYl|BQZ z|D^&{AQT12wNP4;^`HV&ps4`4)>MN3QUNLuiUQ=Ce=WIY&6?XIpNlTKaNa2=%kPXM zKR;#vkIQe*kij4Lhxg-)fIN8cL7$QF&pPW&nc0dJcl##?Ev5o71<19SBsDt#PVN1X zy#$-Y-+e#Ow_m@Z_;&RFU{}X}T^-W~bxjxFp@ZfQA3T3V&w1iIYUo9Kj9fN$)O~{n zAJNr4b>P5##kaF_ua1sA#kYU|-9>KryYB}&WI<^h1O#iQ5Y3?issiMisz}{_gKLAk zjs%OY0%vQd5e=dOyDC7g?W#xpeqlBZW5bD~pOcWX2<$%c$7!fCI*ws1Ch6)Y z5-p+vyC^`e?IK4#e_(!X^za)ka3+(C+wCDEex*ew*XntN&?-fN2G_RnQ)2~=J@yzZ z2uMiT1=3JubbMgf$H$M`qsCIvG%C=m0J-MDb#UFa*AD1E(GF)aRnL&G7$GbzG6uyS zNJbOeTLE&-gZAI>)Kj3z_}w0pkg^Dj7P#UgKIDG z8K0kEONv1f9#y1^x#^dkY zBD$YXs?pZ=Q-ECasm(9B_~On1lcSt64Hw@{MXvdD#k8xf+^P zTx#T0r4Iz{Ed9XH~JndfxpDed5{WdDnPDj3RR|Jn`S(4c{bn%?0d;}_pe z1#;m|I()H+(F?M^-FOKpK!&AKQ;@~ugNAVQ{A(3jTqgw@Tzi=xe-!xlJMJj*%%agF zu8-5i=m-$jzu!o_a}U0iQ9_-_!e0a0rcBun-$sd zH42bx)#zTZRCIgmXBIixO{GJqB5~wfnL$r69|w|($vAk3;tOw4uup&we+%&4bI&~m zQAFE4HvMw4qUR4hG@bIv}i zt7Dp+GBXVf88WjpJmF4Ye6h~~>lI~|iwe@|EB(T(OM&ECU0TA(4h*%5JhQ0ylBhlw z6Pb&#Fus`S1M;wr0ei|cDQdjp^kD&nPM^`GSkK7hT0Pq(->UKB##%qK$jNT1C>=7w ziCoJ#h&zV`^`eem@$LE<7G|HqBClYdoaqzb!{2hIZ_b=!^BasYN>qScD^YBxMPZ@P z`k6&ec2i~JK%UJ&n8hi9JUk#X>gYLnZ-X@0Gyv*h1;c6EGP9xzkZVO1tSUY3d$4|H z(YW0nGVQ(A@h#wGmjsVFi8^|C4>ZQMFvxb zGnI7o#5#s>^o;buT-)_O{Go?eP_QPGYaTc4adVEfer6GRuc_x{7r#tGwW2KH=wU`u ztYZjAPq|?QcMhL+>O7CHq~J^^*F0`g_y_~~PqgdI#dlL_V$RMyFH%WIud8z^{*Uqa zN(#<&a?S51#T1*}Gm9|UqzR^i(Yzp3K_jtUm*db{btH1FR?T5-%+x9SjqLfJMYn{n zQ4m;~$t`U2E6MJ|Z^ec!t`0ZS`EwwoL`W#uohFCxR0O#HwM`pa1+G>t_}jE%{}`E90yMDf~(T{m}|Fyf)g|By!FB*0+9U5f=C| zc;xC7Ci48^l##W&4Z9K>+PuGpf~!D-Yp?R-tpd{zIe7SxMMk|*M8-|3uHcoCPuN_; zB*1aU&GGiy3D$6O&HJW3_nfoso>^4RZmNK}hP4+wRps7$fA0M?6kG+!HSe4B(MKM! zer8dIpXKUQz+A)IbH-_~3Vg<;x5Ly+z3wIk>3`I-W79KFyFbIXS9Kr<@Tph@@ z5Sn!6%o#%m&9&fK3A?F6<=TYN8{sCySq|X>3a$?1S_n;g>Gvrv(F-M`e~<5ow7eL2iSFW z?1u@#(ZjAAH|pV90ZY>u02;RqdVa}-Y(BXbNbBBk!}WI0EONV>3a_@q3ycA;bI&~| zP1#2ueH7LT%)#p!&~I#a=Rv~;&l@xR4o$379u2dZmtOk)vuHuwYu-#d%*~#f;Wfco&EP3+;wD~83!K|b{f@DUk%1| zq5!$(M8;ZV0xnp*1m4MRs?N^6FuH^R@Wl#hfe|YPu)_z>uiPn1GXSpv;~=zPE4Mm1 zxz=ih%gY}lJBw!)6-nr*mJhRApH&yGn zR**zUE=Y~RGK|C*lVX^B#Jb9u5lc+{Ss7ov%AopYrUiKlkZXAgd3FBRzy3AWB~77# zmt$J{YtKFRoO6YMA&C;ZfLsje95{LE)cs-PlAr$c^wUp+KZ_*}BfOH+Vc zD^2Q>3c?@@y%9r8BO=)Crot!>ZjRfEVd-S5Rg2Q&}`9Pj{A78wDC%d!3(v6gYnF zai-5Kk}NQy8@PtD+$uN!^waE~X)f6pT{J*$Zp~wEUMN7WdC^Q}MlM;h#NwGnMnn^l zaTmq3sr#E5mlu21Q8O)WEtXJ2V3$RM8*j)fkmmzbfLsf$QJ;VQc{nMUV#Dh}qrE*h zEa%$w0f$ZR&bfvRNA#SRYi&jZSrLfv*kg}{*1)Wfh63c8hDe@75k$jGIhH9w988&I zbpH4$izU$(ajnS1JmjJQwy#18PnwQqI#z&Ob1Z08+5O-Lmr9}uhYQ28IJ`2B$Z08k ze@*OCa$99AdKB68E+-1{NVr3%AL7TuF*vUte<$?x-`9j0u8Rc!H-u8{PLH- zm^O7v2GInV;JoN_4Kej`CSzhR=g)q&#EEzqHsYNxGG`gU#2@AgHJ3r6iv};e@PZS= zn2C1^kZayGS+BuA`q7Pmn(X;$0X#6$h-(&02N?f4;Tmr503tDAmsS@X2eYs*0^{Yh zN<|k9FgEwHX=$_z1;{lQDprvPRtfO%35?XFhmuGHqj4ODeu-wz$=;I{Z-K{EVC90kZZMQ1`8wL;NZnb!gGNOljdq= zcsFsc$6_}XJS@!afo_;+gGq2CP3r=84^YEx849^Hf5In)6DMX8<)Q&5>E_Qr-P97s z4@LoU&DW*`L6l7en1PBrTS z0M85eSYY}OGhA?*9)JAtv?^ifia4NQMs9Ye;5?=k%H!>zK!a=B`SDPJS+m|7ipFUr zr{0uFsCdli5eY;)phQz)_bA4L7-LSJwD;wgUAAe{rl`jFiR0p~j%cdlVeEoH&e5_M zZZ`$UHIG~TrXT%C8Hz>;CBhh5YTh9s;-}5iS>r}bz~KfC_)v!)dI$g~6bFWbSdh()7X#kZXk{tTcnfp=g|L`bXr{dj>e{P62Ro0uKIE?p+;rr63i2z;A!+ zyh@veg;%TqxmIxl6f8b_D5{S$855&dYoKT*+_}QAr}YA8ZYh}ByYtSU6%>}qy;gu+ z^Sb%A>kLIDvvdM>yQy+nQ(6Rgg&6Sq-Key_uma>-VF|0w!1++LGzPVzATAnIeLdEq zd~&T8%}~S$=R;B4>Dmh7l#^%gqsfn-TSQN$4M2eg*WTpETLo^qDSuT|X9Oza#Bc5` z2T4v!!NTk1mtW>>W72Rp3Xp4VbgVWPw?om^Er~iIS9T^?GSmZmR`96{vyPH`MWx$i9S}Pf(A* zox9FpgbUdjN;$V9g)`i1rM%Kns0dmb!I4_c2amD2m#*gdj*ssVN zIn(f0w`Eg27U_U#Q@m&w8rfOYS~mg2ora%VRCKVy0xv>k|lVc0J-KtBe^mW z-5v|3=>M%)FcrRA$*T&uc^EHnz~mjC?8ZT;tLr3ye8{x`8qur@pc@b%ZU?~}S=#iO z#qkoJ-KMNRVEIBk;1}DcuvB6u1Y?J*K!a;<@zZ7sEL*npfN4`5-VRd!gWE6y1()$R zUS~C7!nihTKvp+P0dg%%o#4+c#)9dDad=6>=;1e7IA}5npyu#}FN#x^_7fve+;M`l zxE&W23BIvdL45_tHGQpujR`1-1=BGjmPl0T2jDbS^2jzo4T}|co;Zx(vSmxK&BKbB zD?qN9YZhV(aACoMuLBU>ou4#XFs%w|SfBuTF~8P(d&h#Whu9{plf44un!R@6r3Bq( z&z^4OEr2yp!Q9S{y#eAdn}M||pa8j6K)j%niUreteTNMnvMAAUEB~$z!Oh;+ z^bPp%sG*l(2#kC2U}wf4S^)9d92+PAlKUc3ec(l;>A~hBOU!eDE7}+a#u&wS?k>|wQAKWn0?DF zw*b33_A^eqDL}5ZTZ>!Pck9-z3wJJrXqJuGKFP?n_G#;) zH3i!6OgG$DQ5wbK1!2DweYBzt*#_y!wKiyEM^!v}_N;z=yW^}W?FjZuVL0rlHq0hu z1<19KTi0RTPCW5=Kn;%rDve_Cf?xn<`W#k@S%s=VgKO{bLj}?mxN`Ag%+_PaQk*rV z9l<;F;H;(F$TL*nJq5_M_q1RrQGvUbFULLo)j|#Q#OC&e3l}6>$b(csQGi@i1mVwJ z6j;4_)zF?HnAj@KFH0YV7vuPY3Zy7NuB8aW!|%KUj`ZHP*0EP8RrbbL-kP750K(6I$)P^yDk`X=UiB~;U2sIRqjZ?SXc553p z0jpd@0dlQ~dcmf}I27*~#e<1PkGQ`47qUo_ij7mjs?3VDOaXGOWzzbb@s(FD?&{c2 zJa7$s?xbh%Lyj;CZs9}N+w*=Q* zD4JJK1<18}woCO^fho$1so=Qb{ZFN#t$)9fixw`ZUI<#?p#lxA{f-|hu&V+G9x!e6 zu=6s^wO?I@fQ`)Qh;33lBo?NEn2j2=%BfAu8AY9UQfV2 zhc6sGyA5S$m7OR+t~rr0z)XI8+ih~`Adzl(gJ+A@6Y!Kb+(5Ts!-fE5WtB=%fLtp@ zW)BMiR&b+#BGIA;$BbO+d_4ghrw%{-P!Bbu$#qeHT&qh<)X)yhaE%@Lizvks!&pyn z_=03OYvAeKci&Y*L1>aM3Xp5Qv{VIlV(DO1&n1a0iyw5gp0IP{)U*m}%OV3(fLsfx zFFLb zPv{&t8Bel|8Nvfpz)S&h%}lShioJ2;MyyLF!YlWn-FgBxPF;P~Rc$3QE87YM$hB6e z8cv?@p2mz=l1s6~2&U@^*f=!|_u{_%ayas_CKV|_u2m$wC&eCd_+cY@zLkhA&4c>u z3Ah*cj71AQ5r$^gS^;vc*3DD7aRAMbu34H0%ZQe{o*-UgKxeJ;77xP!axIK@Y*j5* zthjqXzp=^&_zZq!oXTEL=-oK=h1spD2J>w*1sYuY13y$CMS(NUScGR5>EFnffi|2< zyn|QVi~ID`8&gc+VJcvz0J&zSS9``@xnjk{3FEsv51KG~V>Y&O&n7ZssZNt$}6t`Js6XY8Gc7DyfPvrat#}&fX)C_W0fjWfLyCcct4B1`s%B2 zD~5RWK?b}sPQ|&_yK(BkX@2TKt81zNxmMGLsjXR<1^ehelREqFWw)3R=NdLn0hhI{ zFAeii0dmd9R;%7->%|0xYdbeijjz5wv>+@6$hENAv&7nn#e~6KM;a|AD37AV#;FU= z|6Yk!v#7REpux32@*JWMLnh`WGX)jM zQh;2`Qitbs6u9P^tMwNXqFlqhxZgNqkxmheLj{Z!AlHoKV&r56o_Xf!kM1)W??cF4 zOpsg?8>f&kIY%C)0tFNx*9wToq`N8r=Lc>T;I#JDh&6Aq z0u8SHi61K9RDo+#783;5a4+sX_pEeUATy%^?>%V*8{#T;k7oLC1Bm2EDm0a_pnLIY~YhODlx|jg2!C8Yh=W&&+OuzN! zO~-uc;Yt5=_k=M^6Te6P>*}i(KkI~X$Rx^5)38XnFGt5?@6Dsep|FQ9J<8C^FsxwfFlJY)Ig;NA9&Rw*Einy zeKeD`PrPB2$%W1NHKSCykx`d}KXt#P8%SqrSZ)!nB9LpYlw>|spjQFO6hN(Dw~wN2 z(+h9w>nm;0Pof|5>c!8=!6^dEmu}NfTUtzVtu(1wQ1}YKqmk}RL8u9_B--F8>C4wr zuE7jcE$X=4cFT+Uwv`i;Tq{RsmeLjq$Vn(THLfa*B~-ym&`LAUR&xzzV5BS!gL!pB z8@Z-=sW2K9$WZ`&TL1_vhB;A9PJ70^*Y z(#LMCAfpJ(VF_Y_BN@@;snWQH5~FAXf~5`B2FSH)^=IjUC?L^eG!dp>dH8?=Z942I zlWVAg9FV$oRQ1J)$82!zFZ@seDo{XydH?pf;0{Kk1+qy^DhIhb`CoYcMqx~9c1}-h z-~I==jBxdp&pFN8GBa|`QaC1~0#OB~eC%F z+l6`fyLAfWR$N9P*Q68-PytH?;IIg&fo_&rXe0yCPzu128@GI}!6fNX9{JhTxfZrM z0=d>|g_(c&3aonIHNiCl#(paQlEta|V_7oEQmUj%IP$WMpN8>76uQecUQnV+fa7;nD$N3nn~ z=WUQ5xn>|1qf&ti6}W48W3-z~&kDH)edH}Kn_qmVD!ItDs+9My-1Y0;ocX!c(eIou zKkQ#MytP=;s^(k+&V;vk);HEyB{sQMmGYjIi}A(uPyceyJ?@NtK|0T>;j_8Y56Z2C zBw%jL7DYH@=VRJ%*Gr4?&&`%x%aw=`dKG}179|?Ox8J&%(v+!yxb;^D7L{}Dnya1{ zF59|_{^ujtvaZZ0o_OM>n{N8{x4(VD2`3!Z{LG#`8%OZD|Ni^468ms&`}Xaqg{V%m zeuts5;)tx^sV6_CK<(^r+6*y7ahG3yIr5K6DvDmPU;&QftSr|D2}`mOfDojB*Opsk zj{^=kAftY$zQ_uGnF2NVZt*-bj_4E@w*+;8k($CPl1Ak%5-!p- z8G=}xl7mpJ9^@vkoNKU9tco7{rAKnDZAAp{xdsMBy96%cA~GR2Q zN)bie6D2F)IJ^3=5O(SyTUdn|GzDsyWy4%sb}7-bn#HB*3{ye3XoiVlMTfN9Oph07 znnXM84$7H$z(Oa7I&cm5dBDNc88z$F$TUuaYk%|hg9=11R$Sk9ReAHxH!;ABW@QoH zXPjy8fBgl*}7>I^9uev_REimLFh#nJgt)zqKWuAky{j} zS{u-C@7AR8?DU24(d*KVYirl8)$H)mveLo=3K`W=I-#BZFTVJq;&$D9^UWEBe&;*i zNi$eEE+7J^#TP(Fjo2TNF@Vhms4xR#LnUYBCp3o?;*+aC?9ZqjGEp*j^3$$qGVHWC zb^C2w1f<~m?0EA}IyqF!6k(xUI#|8xH##=Eje~}Jw+@YGT`L$Ly@GLln`Q;5DS(g} z!h-`W5JAZkOj){gDf(?%Z_M^Dlul@;zmiFI#nb#I*biPL8gSalk4HTE zXToxFO|#W@iB^znaj!>oLiBbWmjtE&eDO|*OftMD^f%en5lFi{rsaU+%8X}5<0_J7ZdqRweFUty{NFGi^pRrGtT$@yJRXR3RQG@yL!HI~4!x#1l_U zj42K(k#og4?kkTdBhVFhy{zP~2oCY#vSr7~Emuh%{i$dbJrxaWMvEq?NqEba->q5w z`o$MKeaNTp7gK5C@2MZV7su_4L~bGzyW~z%!FXYVbuEgR(Y{<$dO|iJ^d*jW`^}p- zE6J6j^|`ii;le1y;md$@O6Kw>FddDIaNH6ZSp;wiM!)dXlnCOdV*k-cAFV`FL_mBc zg8omXth9uh(bAHac3cuCiZCS%qG58ah)J@PBAFCSD{Xjk{aXdIvPj;(TvPhI6K72{ zfHDb%!JyJGN+;ChTAWjGIhCBFKb1jooIcUWMqy<&7I;;XlWU3~@~7Kl9mdC>!>B#WOLr2+ zY?@-8QVOh6A{6JP)mY!_<!qk##xwhi& zSA^vlQ=3}uDt?=CZOfJ|%H{snTW`72R9T4p?svbd!#GkMh^i&ol6*?<7 zyE*hpU~O3XIp8st_y4q(Db8^rs3 z99zY?CQMcE0aBxMSqnI5QFa4@uGkG^L~~Yn3Ii0wP+w`4X+Y5`ExBg2wB+?XzIE&G z1t0)8BMU3!nzhYF70iv?zFbq>8CTt2nNUZz@itI8VH|w%Bxy&KF=;d_P)u>?z@xN$ z^pD50jsKTGuIcNU9TQVjK%41Mv_h^)XAOYMu3AgawlCM>j#crIn$n-))PSDx_H)QJ zh0al~pw%;hOr#n}y$il8m7 zSmJ*M#RY~w&ohTy+Wci4=dx!6Q?kl70)Vd+~l0JqAQD1>L@XjXPNgNRoNGp6rbSMxUG8xZ zO~9yl5C6&S+v?A?ZQK6v-d)5d{LNL;Is&=YD_t7e1nJPRK_YqeV@gW_lZYn&&W0L_ z%T6xyF$w@uTeogayAIOOCW=5>m?ZHE*x_fQgCg^1{!fZz@4zlPGIIU1g$us`5&AEo&E(VXLJW`az_)g?w z%ExlJ7KIvIHvClVuka_irizcz9Q+!i&X19)CecJ;PPhgOF>=gx)70wi{Ebw~4I)u^ z#lt8IM9UcGDy6hJ*PzCnuRJP{1m8^&NB^h9(}t(=|1XJVD-%W!x(&l5c~?i>poW@~ zYpKl*CkUNc%%&+rR5{}YK1ZD1r|>h@El zI>pxq0S-Y%i}78nxpv((n}lunyM|Ch!;x!6u3o040;vkfRngNZqfEA)dEYq2WO(@Y1$F%DW%#xP6;` z-G2MdU*!s;Q9@b7B^Ny_{3&^)cmUNo?Uc3BO+x^s6wkIrIgo2D5|-IgfxmCu@Qwrl zpa5Xyih?8(YUiA_Avb0yO2R~tFV$n4@SVykG=hFWqP7LWM$Lvx~ zT7qT-slYueUXxzi)Q{hr;eWv)k~{)Ftf2-OWj+X4d{Okw&po8DOb{)*3iWBhI&v*K zu55J}1guYE(2^h(fNKLBNXHGBgYO310D16+KstoMk!S>*Dk23kl({(xz<$^aYl~P_ zW?FKMTr2Z>YtynY0tIWN{}PYs;Ktt!X|goPuSU0e;%l56Bz4KK?u zO#Bq>r~nn90--2Cu7%Q)tOpgK0!;&{Uwowg2UZ3Qz$m5Q+liS|}~adQbr>&{Tk2 zYbwEisQ?uSMFDaxl$K;Yr~nmcDnPC^mEgZrfC_}70J#=QOR^qRfC@AfAlI5o@LwuG z1wv7PTnnWoSq~~e1)2(wYfUBiFBPByp(sGEh0>C&2Nj?KO$ErcrV{*@3Q&Pi6liem z|M;N-RDcSEq5!!TN=vdHRDcRJ6(HA|O7LGQKm|fkfLsfuC0P$DKn0o#kZVmP_%9Wp Y0--3-;2QqnhYC;uDiDkU@Am2Q|HxtSh5!Hn diff --git a/Templates/Empty/game/art/gui/splash.png b/Templates/Empty/game/art/gui/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..333df9eb3950726e7eb4ebde5dfe034e8a0b1a6f GIT binary patch literal 11864 zcmZX41yoewx9=b*ARr?h(v5_44c#CENH>BsNDST5jfmvX-AK0xNOukmlG5Gvj{kM< zdhgvk#p1+wcJFWh_6}Ep%3{4Fc?kl6u;k^WK7c?->A?3j+B4t?`{;ot@aKhzqO26? z>EAo6tuP)qg6<%v0|S9DaQ=OfCYF5ffrF^d@=DUEe~`d0UQsSh+v$TqlpuL2adr3k zgLDsXHM7T~%(S#TC97Ag@Omr12%37UZpZJuSb|#OSp$oXQuDh}q?BCD&#H?9DHX{G zv*4?oEYbuC5*S7L!S$4aTB-S%>l&$e&N3;q(%;J&>R9a(?|PZ2GU}}o;E~MwGtr03<0O=tXI^$VzxtbCf zI=d| z^!H-5?}`MdMW0v7eAeN0_P1>Ux$l$SVGj2Zn+fKsa}GG`L_7l+YJ6s6d%vw#voJ)E zWXyJ4SOPS8)Mg3B?jQTDANZk-5| zskB110_aUQpSr=5J(u2)*QIaG1%6NqpKrn$}rfB zQZa1H0l!LhJ36?*p~e~i(-msp{&30Y^O>6@+ABl6TvJO^bIs-1Ym;K1lRGx_ z(a}c24avB8?fJu-q0q+}qE))I$(_-?bAXj5?iiT5z3u~Z?)%u;xTm#9c9m@;|Kr*e z*5*+1O_7z_-2}L1+nUl;lxjig@WRaw$>C06CA_<-y%$%-w$0;QRIS zTR^^2%@ibUE=^0LZ+LnrajyMF+kZ7>M%)!L9=4C(^?pn2wPpQTW|E9vKA&1O)uD zIsfqC!<4nl=YOw?$^}g=EkGr}uU8`E%5-ykn-C8#FE7u%#xGh%O+{su4cy{-aC*e) zVQR*i;(0$mknr|7yVw4K_VV$=%)w%)D$L^MYJ_Xxd~X}_aL~*L=&h`ZBPT!y0rheY zW4@bJgUz!L%*+y{OoUv|CnR}n4kTFDc}^B6kxP}!rZ6%xf~Cs6Csqaq22!{zmVK_4 z4hu9hBXTuMEk@FI#HTzVnpRfDy5($4Os^MNcKsYKEYn|y{x+Oj zTg%PIM~Fq0adWaNekkeBW62q862=T~oQ{*m!;#5&IMht4C4=*z`dWTc)zN7(?g&`+ z-HRx26m@#tu)KVr1n0HlPBmz84d(pYQ@tPX9HXSP)awjaCy|wr@$YaMOnS0$xLngl zQZlgr)2=GgusIB%Kwe&+alt)z=$J3#??fH?I`ZQ5*Zs0HK_7VcM87W0yO3^q(xf&1 z%1OVPOQk2~tt^{tT%J1J^vujmID7#vVZ}|trqB%==0_gzvKky6z2f}5$;Q^YUd^Hh z==H;gwYDM-Oh9j6ladg6y8dQ!ySuxmr>BPtPBa8n6TE(p_dj-ZwThGUi!mLv9GUtT zQA@}9X{l`<=%Vfu8xW36G4_Zy0rdoYs%?QRm-6Q3=9VHeb8|MMpRJ=1f8BD;(rK2# z3hk-@EzHHSv3Ibo_w0e2H#axFdCSeE8fIo@vCT8NMZ=k*ep^E+83{=rlkfk%yrX4m zj60rX+|&cVAs_Gibb~=Yw)RMzPni$#GwwSB{A*MEi9TA-Xl1N#VXN<`%n9_&(O!d3k;;3$tJh&ow$`JO%K|>??EB)+p#zHcm@)DYfb=-L=npaRj zZ2*P{>g=^=WOSYF=LDD1FVd+o&a)&Iv{8iUAZ~}#%!D<$F03k<@FG^D#jezF?zI8R zq@|@ZVmmc9&@HQ7+J`{)3ib=0ud%n%-;Akd9=(VFsD^ zM1IzLt~0Z<*1VymwM0Hgs+e8x&bEg43S^s9;a7K_hVona|{j)=!<$5C88k_6BGNC;0#u`y6ZrpP(#Cvt2t23+`bK=HC|~~ zvD&yxryapyEUKt*-GzacN05F>M%w|IpkNX%*|#NpaI1=+x}%@_H}d3BNn^bbt=T_@ zUgI=?dAlhQtbOr1Yzk$t%YZcoqGG!~Rb^*)z;oTvkKVtCF?rGF;Uhd6RK=TNS)*O{ zxikkX;mhMifJnq^!|WdstgN)~^Dr2zTkZ7f8aA)#Fa|Swsi>)~Kjw0-%9HU&L`EJp zZIio^)>Kzd1lBSoC|uQ+K?`y7e51jgaD||cM1NBonhQ#wu1GUpwtRXiJ##s%I(~Ra z+{F3N`g55?#DFyGgeRlcZn;(G>ymYyZU!sOR1_f~3&=-i7MAm`wwq)PKnzo^IR`F( zXkUJuJ?&x6VTR@D#2yHssT0o z^a;&!@Sl?lvF4o+x67JTp7{)sH7q zBc|_#g-!OS7i)w%rn!3D*N$4iw9o><||&6j{}-^v#FwHzw7FQZw|MoAKleq5cm!R$IV^a|`aUJb;) zZDW(y&`9u#N$}eC(9EVh zdBcdLuV!=7kpwOX!VEh)yun0PSOfR4IhV5XQeDfP0E=#IQNt0g#Kw+QyT>|VdmV4a zHDcdGIA$nMKHk%2bPcO4l*ZG)A;JG<5lyQBzT*DSqxIDDFk5>iDM#u&%*Sgx`|C^w z>qXZ_e>~tlt+jY1B_;IA8H-D3%*@O$C%k42%7MLz=OFsV#>VljOw*Ba2BfK>q>XCM zbb?TH?~#4`Lbl=lk8eg1U>xq?&&zd)si|vbJ2;>HmRaI+TgPbcZ-w{bZ4KYfDiC3uN z6hJ@ZJIZJ>M_>{!>)W@bB_+Ej4z0#%9mcb*9$fau#33h!2y*XZ@$C1eAH70-Br4vI z&Nu6D(Pe_2toJT|mvPWMGhBVy%&W3$INpB0$-abNQcw_L!Rda(c}(rrkyTV=dAiZh zCNN`Nmu7u_xe27)Ljtu}5nDq;LseDP+cgWo3hPdS_Erkz&9>PDpn|qO5hPcrxh=IP zueNpPV$Zo@>TcQRA~h`P$nvwfUQTAW(Up(UXOhaT&DL_Rnzhc9K~+vzzJKwp?l$6; zpSi*K_t;T#ddMQTjXl{c01+EXO9%5!sAy=^d7PQ+vW+fl9%e{V20`ee;YP>57&5)r zl+I?V%?2T)<>oayUc{q0iNH>12~N)cipip&PA3&=w?NKXXxE~@{AaiLWncx?&_$6u z9o`j(#GSFBem)b--=6hS&~Jg`7nw7t8EWsBkz-L9-EnK?mUUtRLa*_ zem*fmnQD3~7moO)KO7DHzJsaNXhRioa~7~&jKb4VAn_!Gx8v4zEpA5@#lFSTjG#(5b;6a@7Dk^BYR$$So(x6t|f=gkNG07!}uM1m>{xylaT|ntIpdq#!vS7 zA~%&jw?g4$6GT5);*al_-Xs>A`MbEg5Wq@R=8ZBhjvVwgQt!St*UGacabd>C#c_x! z2zq}F?~yt9{%nMG*n5+1)adbw)c$FExB;CCH`*xp%65`K^hz{V5LZ0Dt%k(dbCTsD65%2_regH4ULK_`_>N)k35JQ%BB za+&Oqj(qwe%l@;W)__fw;LlGfUiEk=@Zb9^5_0f-rc>pFnnNHYy}QjG;~C?t)%RV0 z8!TDf+xT>K#P<{vhfZA8-=9>T9mYF1&!RNbBO}pw{G$iyPv|ptgKX}j$>(C%Ct3y4 z-5yTa!V+@Y)HVQo5cDVDX9kAItA6r$qFN``aL7w$Cp*nOAop&znx{|;3^mW#&*VO% zJWoR)o(c!){5YxJYR5S>l+=nC&Ax@91iLdr?UqI~HVpap`j1OquGxT4cC$lQ87t@v zs1tb=aSM;a=S(}3(Ss|HD1!!Rj+j?~D2TbNIuCE=%zjO3$;ILkcjvHFR@mvw3DEPb z2Em4*q-Y9;w+W2rZ8`~3BijMG-WZsn?$8dbKms?m(Qlh<*d-RMPA55Tl7)Y?ra4lC zDW`ecVe#P+v$x}+7or#-Q>y4Y;pVMzRtS6tb9&#W$GINxmQEi_AU>TSgdaY+PiAR7 z&Vn~2kXY-%(Nhu6=0ByF0}9ekv6GyE{tei)a*C(Y(5WNH`o|vA6cQWYC&N z%lm9(qrJujU>uZz~*zB z1Q=czAd7)2;1{%4e}u#r25mL>`Za9aL&M&vu4BsUvbCEH7KBac15nYkug)uNY5lI* zk407sUeBy$Tk^xfoK7?GRdKJI*QPE@o6ZcDPXN#4<(Bpaq$Q!$GZ?%W8eckt#yJ;0 zI2d18XmI76M`Sb8gWFp$yaA1B*)W*=PptT^ zuR~tWT`fg zl3s3BnIdn@+i8|s-FX!p9G#VskDhV>Y(3+c{OPrKw9-~5avZ-+%R;p`b6r~-7M*+1 zH=Zk-Z9^HxqSJidc0sCzMJ~u8BZJ2Dx#c=$TDR8qAoKBh)t@AElET~h^4Nm#T-FP> z5lE0-Ju3p<_l>{QP!19c>gk^rj&i%H11r9~JH9wsudx^n7rHrEK<^?_)tYZ>JXo_x zn%`07^M0KB^F@G#w=_ZPiAoU~lNPY>*Z~mm+6cMx>@g;SPBBTuoB@U_d;GwntB)8v z?vA5rSaDqdy&=|RJ3@V-iWkKto{kER+1lEggKhh27~FmCd}mfx+j~SS|5u|Fv3S{` zjY)`xQ#ANI0FY0dP;Yb+*<-J)WTocB#PZKXg-90{mnWW-cP0QfN}USa0fCt9n%LYi zn-{&!nyHDU#GxBsn=VBdj{%^m6eDoy;TyikGX&y*)RQOaYCm2by)8HA89k|g#TU6x zveMn@>pih|%jbq`Xu-1!-0Ed=-=!km_KSXj0Fwx#OohWKJoc*)TdeL$iNj)9haqF>i|DTyCFd=FTXv+U8;0!(=H7eCtdR)>S{-bJzMA9s^EL zejvn>b=u5_X|9yhmlo$OBK+-hRoflZ)o9N{ut?u!0Nix;`zaL&^{&)aIv@PZ)>>gF z#amqtiR>0l9Ts8+n<00}Dtf!C+^( zu}XS8et-1T%P5$hVbhMA7^H9Y#R+0^0{o6SZpbY)p18UA-p>7#sJto4if9s1H$O69 z{jV$VIskq9D7-$GE1et;;ocN1NuUe^9N$z}| zg~IVS#gcmX09v2Tk@8-&W=7SSLYmxn0~I0}DOHT)*(HPL?f;9M78B`jhqlo2szBpb zwjZU~2dk6E2h{iUYSz}wpHckVUPx>NUCxPuv-%UIA`y7_>uf-i0Q{|4P$~8@Rpkb0 zH0ry;CB^K@;?SB5=;=Xa%ESM&@81(ltJb^rTETREVp+5p^0zqhdcJ^>cGW}@tQi7r z1u-x~ZHJYeqrID`)sc7cfrO=0G>wLYz0@Uu{`>p)q@FrCluz$?m!`8?xBQiT5~Bn} zxw}p9{`IRY8!;jh63oTc#!$fpLrY=8ynC@seWgk1Zn{P?K%+q?lDJGIjRz(_&X6f&(@_M`RJaI)OP*i>Y zyRyw5rNRh+=8m%d7QXic>_Aj-{t_=*6-->>qb9R(xI(+U=@iHjBKH+Tzy3Hmk zLQ|t~eAV!uxE%Fzva-b%GPEr zY6+KOZTW9PP)Y$5z_qOl9=c z++WS9kNoJaEu90zLfe~{@pInuwj(3`#CpNBOn;>j@38s*R#?)}5hi)gIsA0vK;&=oo`8>W^x^B$#57Tq-<7&YQ4Dk+}uIIM5xEsjcq(Y!1 zDlaG#atH@-B)ri{^je}+fagtf8+?c`F*wFh+2;81E@k+Pki~Xvw*c$glaJ*$6<1AW z>Cnd0Ks`T^gd9C9i}bkps_P^ z^J@jU8~;BTZBb`C_>Z1W(6_sIr2KAsk6xpZWU+Q zm^@!s>hvezrg0tAJd-)6p`-KRL+btdTmveWCf&<7i0w{2m-lDlTIUiwE+HZP{2^g#aLV zp7I7RS$VlQzw?&iARSd`;b*Nu#K!BdYB?{Eow39aw-|3V2>|voNky+~{`7Y;>uTeq zKgLlKkYdU}FadTb_*D#ij0ZJ4Ce!~YIp2y?OY;zcO_0axe8rWN4vtLMgK+BP6rDYl zA#}H)FPK!t&~CAAL)%>K_bIb4U5je$jCw~^8LWfAy0j7a;Xv4Qrv*8)?n>Lq+3Ydu zQct~VVj|7O6VO*(J(X15e%+>ym|DceWmtWs~fqpf9f}lcaKL~Vo^LBjR2+#=KjqBTy~Ifq8gXg38jn9?HAg)GK+{@xy73gC1<3J_qLK? zcG)iec>IF;Bxhu;oYRf;N-j-~7FSgtE(MXcs?~LYzRJJ_c7^oT*475lqEIHjiQgjM z{jdK7&8LlI?#EEr)?>KJ`Wi07;_0`bsT&VlDa6F2d}V%rWBtCV<+u-Is@OA2uTUo5 zhr~3Av&fPw`NLF+5Ov zZwc?FrD@n`iazbb=BksmD-pfTDKSkci3QvAqpVdQny+xl6~gTa6eoXwgYRS@^0#LeY4nRx zOJG1j(JUt~e-o{sQ8*d>T>&Ch;OX_`)fL-MBlJ9CgpjcOqt4}Qwq&kp{*u8Cd?%Uo z_c!&DSPLE~Er~+-sKEXSo*6G(C-Gu52<1Tv@f8xm#`%39g6v33QzN16=cQ0&KA#JQ zt3xz+V$ETrNId`|Dh)7p+$-vsK;cOJy3mX-($t$%K#eK2Mi94KT~bo=m4q!a{?w+- z+ZzuL*~cT%$9m5Mm+LUUI-_Pwx8tZJQt$D)AIgnDk8FhOD6@W!A|@^gi-ea|MkF!j z!bRFMNr_Ndm8AR?HabujR5i1D9Msw8a~$q&srC4SO->CEDE2`nMD#Q?G(AkGUf687 zJQ+DrGI_uTi1K#&plS}Lzq=KWt8l-YW$noS-0hqw1U+xNBSG-1+F#$$iZ6ddKPKOt zW&D{s(7wwj^`5G$fyxHy%jtnEI`d!gdqtb+)XYVpA~(Od4QwuksUs$wGv_49eSaea z!;g0groQ8q(qt_alLt8(a_ebx+&+wT0)nCkVE3(Jh3rk%t34u&k9|)ny&Vjdnqu zh2D!s_{i2opA+}tDpid>zq$Q4wt45U5xKS487F^O_*neebK zQQV!JrHpL6YvIwpzM@w{AZHh{-~WPe>71>r()W#NmE>XF@)%ssa!tawI7`gostS2) zBQYhyUWwueKzQet7lH}gGl+8NHNFu|5K68p({U54fdQ(M!l!pc!h5N6w!B19FLK38 zCy6n8G)pfu<%cZ8YyA^jxmi5&8uy+Tw@qC-DIEahokWQv#QI#6O7GyY%>-5$R5eJI zRbLgxjlL-ceMPC#E=4G%a#z7iKTqw}zQ|QAovvaL(xq;br+!$eJ=c+6tdylaZyXKh zsHRgg59|PG;Q=*M#GLJ8he?x}dxWyyO&j?1c?-}>W7?Cv}Arcw!Tja=7NeUi_zF zu#gr#OHPrWr3>HEJ>14hS6;DK!IZo(zrpZA^zq;_W45tLqvcP81VYR*U8Oz1=5-@M z_1wp^I-|~X{y0V@mbmaD^$1^T^JB|!Zg7ILV+(hpfY;B0g2e6F0JLeIsmcpngUQ{D zW1o~yPv)nqt=(H&<{e7)QJ9;-liTvf800M9=}=6Aj$)!qi^~D9^ci_Q8tTJ~2b91L zxrW;N)Ju;!!KeK??KsA8f~U(Ep+Q5VxBJ2GPW#d^ovin>Qs;Fcwm>kUwzjr;aF9^G z)%znJDK$W}b3v9gu;RYn;I>#ijV>^!gVNmdCfBn6>x?GQn7|4`ONSPoR{2DLop^sx z$D(i~utvr`ov+hi3*YyO3gcbh6YHkO)K!blAG{VCx%&P4V7U!-R4*v7Ra_LX0(@+( z>*jdu1b~Xy}}ASeF~@^rjD&Mu*b5OmELKVl8=L zE}sO`p{0}gVODgkfZf7qtB!8qOCcGOhXak59q;w;8{RtHtZ; zP_u2~Dr}0*!aNzKuA0KpsDP?;hH~*1g@cEeZRY%-Ar^A(kfuLUy?;@=0eHX?PQO!s zmMRTS4lq2>^SivL97`q|1E>$1S21(YX+HSO@W_IlHw%(W#5F?|dOY_3R1dn(G-eVKrypIXD5%wXe00>8uw>uDjVuq}SzU=;;+{mg|Z}JAHSKm2%KG^y0 z=$1~-MXUyjRahQ$1pbFSD8jkfk%Lo|m%B?FH*6ul%2`p-jx`U!Hc^};9^h~^Xb~mg zxWL{K`0U^mLo0jzrSSfG#hNfowKs)l*@$4N!zbrnJj4dA z7N{wm-ofnXt`|yInEkhF;P>=-IC#{okgmiXD1X_PVo(kZZFwT9Py_O!*wnxJ-C5AU zF)FizM-63fzG<+6+QK#EO+9ZR4Y#>gY%TvAUIwZlZ88H3hm%thf5Lr(Xv;~BId@86 z51rLLc3B|;Ru?&qNNH3f2*$tmqJ zcQ?6n0VIK{s&Qj(U6w>C4t!IVa_F1r_Fbx6U` z$}6wW)YM}VeVUMj#DN^PSn2w%aWmX z`KT#8Obml+Aq^Vb`8H5BTZIuXA{>`~wdV^s(1R{_$Pf+|+e}5D#04tnFh&-F$Z<=| zK0^$CtFbi)cdIfapmH}PvJq@sf#Eu$EL$1FzTy2P`KMy%azj5aP=XE0q#pn)hKYF{ zjDVOCC_7o!FhSKrY-(T_RSH$cbUg*M^-t3HIeocHJMWd1yO5Cqr>BbIY4g?hhZd1R z8UG=)5=NEntn`!yxOssCFBE|q&fmD1;Foo_!DTAA8K`wWS(wh-0JKQ(XFCs$=30iY zc=2!7Hgp08!2?$9nFqpx*yS(QkZ1qU;FyZ((makY`{G4b5Vl#e0q66gf5<0hV%_e! zr-pIAia3x&jfn(4zXTpFmOdu7MZYE%hx(6>i8{}RpkDztQjMP&Qc}ssBd|ZtP zBjN@p?e|O6)cQ7ec6JsmG+YS|(Zal?La`}+Zl&711CIxEn^bADR8aiug-&eTRuvcb z?_Vy+!1YJg0OqAZ^3qVL3JK$Y{{!qCM1lYS literal 0 HcmV?d00001 diff --git a/Templates/Empty/game/main.cs b/Templates/Empty/game/main.cs index 87daf9770..44b333b87 100644 --- a/Templates/Empty/game/main.cs +++ b/Templates/Empty/game/main.cs @@ -29,7 +29,7 @@ $defaultGame = "scripts"; // Set profile directory $Pref::Video::ProfilePath = "core/profile"; $Core::windowIcon = "core/torque.png"; -$Core::splashWindowImage = "art/gui/splash.bmp"; +$Core::splashWindowImage = "art/gui/splash.png"; function createCanvas(%windowTitle) { diff --git a/Templates/Full/game/art/gui/splash.bmp b/Templates/Full/game/art/gui/splash.bmp deleted file mode 100644 index 47cb47f97e390125d04ee2fc9c4a53edee71a7ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 338576 zcmeI5d9)S9oyW-^ITM!mcn^52BC>fVITIt8GoF(upvgH&R9xmv50^X-U?D3Q&Qj0_0j#3I0n3s6Z$RkZYl|BQZ z|D^&{AQT12wNP4;^`HV&ps4`4)>MN3QUNLuiUQ=Ce=WIY&6?XIpNlTKaNa2=%kPXM zKR;#vkIQe*kij4Lhxg-)fIN8cL7$QF&pPW&nc0dJcl##?Ev5o71<19SBsDt#PVN1X zy#$-Y-+e#Ow_m@Z_;&RFU{}X}T^-W~bxjxFp@ZfQA3T3V&w1iIYUo9Kj9fN$)O~{n zAJNr4b>P5##kaF_ua1sA#kYU|-9>KryYB}&WI<^h1O#iQ5Y3?issiMisz}{_gKLAk zjs%OY0%vQd5e=dOyDC7g?W#xpeqlBZW5bD~pOcWX2<$%c$7!fCI*ws1Ch6)Y z5-p+vyC^`e?IK4#e_(!X^za)ka3+(C+wCDEex*ew*XntN&?-fN2G_RnQ)2~=J@yzZ z2uMiT1=3JubbMgf$H$M`qsCIvG%C=m0J-MDb#UFa*AD1E(GF)aRnL&G7$GbzG6uyS zNJbOeTLE&-gZAI>)Kj3z_}w0pkg^Dj7P#UgKIDG z8K0kEONv1f9#y1^x#^dkY zBD$YXs?pZ=Q-ECasm(9B_~On1lcSt64Hw@{MXvdD#k8xf+^P zTx#T0r4Iz{Ed9XH~JndfxpDed5{WdDnPDj3RR|Jn`S(4c{bn%?0d;}_pe z1#;m|I()H+(F?M^-FOKpK!&AKQ;@~ugNAVQ{A(3jTqgw@Tzi=xe-!xlJMJj*%%agF zu8-5i=m-$jzu!o_a}U0iQ9_-_!e0a0rcBun-$sd zH42bx)#zTZRCIgmXBIixO{GJqB5~wfnL$r69|w|($vAk3;tOw4uup&we+%&4bI&~m zQAFE4HvMw4qUR4hG@bIv}i zt7Dp+GBXVf88WjpJmF4Ye6h~~>lI~|iwe@|EB(T(OM&ECU0TA(4h*%5JhQ0ylBhlw z6Pb&#Fus`S1M;wr0ei|cDQdjp^kD&nPM^`GSkK7hT0Pq(->UKB##%qK$jNT1C>=7w ziCoJ#h&zV`^`eem@$LE<7G|HqBClYdoaqzb!{2hIZ_b=!^BasYN>qScD^YBxMPZ@P z`k6&ec2i~JK%UJ&n8hi9JUk#X>gYLnZ-X@0Gyv*h1;c6EGP9xzkZVO1tSUY3d$4|H z(YW0nGVQ(A@h#wGmjsVFi8^|C4>ZQMFvxb zGnI7o#5#s>^o;buT-)_O{Go?eP_QPGYaTc4adVEfer6GRuc_x{7r#tGwW2KH=wU`u ztYZjAPq|?QcMhL+>O7CHq~J^^*F0`g_y_~~PqgdI#dlL_V$RMyFH%WIud8z^{*Uqa zN(#<&a?S51#T1*}Gm9|UqzR^i(Yzp3K_jtUm*db{btH1FR?T5-%+x9SjqLfJMYn{n zQ4m;~$t`U2E6MJ|Z^ec!t`0ZS`EwwoL`W#uohFCxR0O#HwM`pa1+G>t_}jE%{}`E90yMDf~(T{m}|Fyf)g|By!FB*0+9U5f=C| zc;xC7Ci48^l##W&4Z9K>+PuGpf~!D-Yp?R-tpd{zIe7SxMMk|*M8-|3uHcoCPuN_; zB*1aU&GGiy3D$6O&HJW3_nfoso>^4RZmNK}hP4+wRps7$fA0M?6kG+!HSe4B(MKM! zer8dIpXKUQz+A)IbH-_~3Vg<;x5Ly+z3wIk>3`I-W79KFyFbIXS9Kr<@Tph@@ z5Sn!6%o#%m&9&fK3A?F6<=TYN8{sCySq|X>3a$?1S_n;g>Gvrv(F-M`e~<5ow7eL2iSFW z?1u@#(ZjAAH|pV90ZY>u02;RqdVa}-Y(BXbNbBBk!}WI0EONV>3a_@q3ycA;bI&~| zP1#2ueH7LT%)#p!&~I#a=Rv~;&l@xR4o$379u2dZmtOk)vuHuwYu-#d%*~#f;Wfco&EP3+;wD~83!K|b{f@DUk%1| zq5!$(M8;ZV0xnp*1m4MRs?N^6FuH^R@Wl#hfe|YPu)_z>uiPn1GXSpv;~=zPE4Mm1 zxz=ih%gY}lJBw!)6-nr*mJhRApH&yGn zR**zUE=Y~RGK|C*lVX^B#Jb9u5lc+{Ss7ov%AopYrUiKlkZXAgd3FBRzy3AWB~77# zmt$J{YtKFRoO6YMA&C;ZfLsje95{LE)cs-PlAr$c^wUp+KZ_*}BfOH+Vc zD^2Q>3c?@@y%9r8BO=)Crot!>ZjRfEVd-S5Rg2Q&}`9Pj{A78wDC%d!3(v6gYnF zai-5Kk}NQy8@PtD+$uN!^waE~X)f6pT{J*$Zp~wEUMN7WdC^Q}MlM;h#NwGnMnn^l zaTmq3sr#E5mlu21Q8O)WEtXJ2V3$RM8*j)fkmmzbfLsf$QJ;VQc{nMUV#Dh}qrE*h zEa%$w0f$ZR&bfvRNA#SRYi&jZSrLfv*kg}{*1)Wfh63c8hDe@75k$jGIhH9w988&I zbpH4$izU$(ajnS1JmjJQwy#18PnwQqI#z&Ob1Z08+5O-Lmr9}uhYQ28IJ`2B$Z08k ze@*OCa$99AdKB68E+-1{NVr3%AL7TuF*vUte<$?x-`9j0u8Rc!H-u8{PLH- zm^O7v2GInV;JoN_4Kej`CSzhR=g)q&#EEzqHsYNxGG`gU#2@AgHJ3r6iv};e@PZS= zn2C1^kZayGS+BuA`q7Pmn(X;$0X#6$h-(&02N?f4;Tmr503tDAmsS@X2eYs*0^{Yh zN<|k9FgEwHX=$_z1;{lQDprvPRtfO%35?XFhmuGHqj4ODeu-wz$=;I{Z-K{EVC90kZZMQ1`8wL;NZnb!gGNOljdq= zcsFsc$6_}XJS@!afo_;+gGq2CP3r=84^YEx849^Hf5In)6DMX8<)Q&5>E_Qr-P97s z4@LoU&DW*`L6l7en1PBrTS z0M85eSYY}OGhA?*9)JAtv?^ifia4NQMs9Ye;5?=k%H!>zK!a=B`SDPJS+m|7ipFUr zr{0uFsCdli5eY;)phQz)_bA4L7-LSJwD;wgUAAe{rl`jFiR0p~j%cdlVeEoH&e5_M zZZ`$UHIG~TrXT%C8Hz>;CBhh5YTh9s;-}5iS>r}bz~KfC_)v!)dI$g~6bFWbSdh()7X#kZXk{tTcnfp=g|L`bXr{dj>e{P62Ro0uKIE?p+;rr63i2z;A!+ zyh@veg;%TqxmIxl6f8b_D5{S$855&dYoKT*+_}QAr}YA8ZYh}ByYtSU6%>}qy;gu+ z^Sb%A>kLIDvvdM>yQy+nQ(6Rgg&6Sq-Key_uma>-VF|0w!1++LGzPVzATAnIeLdEq zd~&T8%}~S$=R;B4>Dmh7l#^%gqsfn-TSQN$4M2eg*WTpETLo^qDSuT|X9Oza#Bc5` z2T4v!!NTk1mtW>>W72Rp3Xp4VbgVWPw?om^Er~iIS9T^?GSmZmR`96{vyPH`MWx$i9S}Pf(A* zox9FpgbUdjN;$V9g)`i1rM%Kns0dmb!I4_c2amD2m#*gdj*ssVN zIn(f0w`Eg27U_U#Q@m&w8rfOYS~mg2ora%VRCKVy0xv>k|lVc0J-KtBe^mW z-5v|3=>M%)FcrRA$*T&uc^EHnz~mjC?8ZT;tLr3ye8{x`8qur@pc@b%ZU?~}S=#iO z#qkoJ-KMNRVEIBk;1}DcuvB6u1Y?J*K!a;<@zZ7sEL*npfN4`5-VRd!gWE6y1()$R zUS~C7!nihTKvp+P0dg%%o#4+c#)9dDad=6>=;1e7IA}5npyu#}FN#x^_7fve+;M`l zxE&W23BIvdL45_tHGQpujR`1-1=BGjmPl0T2jDbS^2jzo4T}|co;Zx(vSmxK&BKbB zD?qN9YZhV(aACoMuLBU>ou4#XFs%w|SfBuTF~8P(d&h#Whu9{plf44un!R@6r3Bq( z&z^4OEr2yp!Q9S{y#eAdn}M||pa8j6K)j%niUreteTNMnvMAAUEB~$z!Oh;+ z^bPp%sG*l(2#kC2U}wf4S^)9d92+PAlKUc3ec(l;>A~hBOU!eDE7}+a#u&wS?k>|wQAKWn0?DF zw*b33_A^eqDL}5ZTZ>!Pck9-z3wJJrXqJuGKFP?n_G#;) zH3i!6OgG$DQ5wbK1!2DweYBzt*#_y!wKiyEM^!v}_N;z=yW^}W?FjZuVL0rlHq0hu z1<19KTi0RTPCW5=Kn;%rDve_Cf?xn<`W#k@S%s=VgKO{bLj}?mxN`Ag%+_PaQk*rV z9l<;F;H;(F$TL*nJq5_M_q1RrQGvUbFULLo)j|#Q#OC&e3l}6>$b(csQGi@i1mVwJ z6j;4_)zF?HnAj@KFH0YV7vuPY3Zy7NuB8aW!|%KUj`ZHP*0EP8RrbbL-kP750K(6I$)P^yDk`X=UiB~;U2sIRqjZ?SXc553p z0jpd@0dlQ~dcmf}I27*~#e<1PkGQ`47qUo_ij7mjs?3VDOaXGOWzzbb@s(FD?&{c2 zJa7$s?xbh%Lyj;CZs9}N+w*=Q* zD4JJK1<18}woCO^fho$1so=Qb{ZFN#t$)9fixw`ZUI<#?p#lxA{f-|hu&V+G9x!e6 zu=6s^wO?I@fQ`)Qh;33lBo?NEn2j2=%BfAu8AY9UQfV2 zhc6sGyA5S$m7OR+t~rr0z)XI8+ih~`Adzl(gJ+A@6Y!Kb+(5Ts!-fE5WtB=%fLtp@ zW)BMiR&b+#BGIA;$BbO+d_4ghrw%{-P!Bbu$#qeHT&qh<)X)yhaE%@Lizvks!&pyn z_=03OYvAeKci&Y*L1>aM3Xp5Qv{VIlV(DO1&n1a0iyw5gp0IP{)U*m}%OV3(fLsfx zFFLb zPv{&t8Bel|8Nvfpz)S&h%}lShioJ2;MyyLF!YlWn-FgBxPF;P~Rc$3QE87YM$hB6e z8cv?@p2mz=l1s6~2&U@^*f=!|_u{_%ayas_CKV|_u2m$wC&eCd_+cY@zLkhA&4c>u z3Ah*cj71AQ5r$^gS^;vc*3DD7aRAMbu34H0%ZQe{o*-UgKxeJ;77xP!axIK@Y*j5* zthjqXzp=^&_zZq!oXTEL=-oK=h1spD2J>w*1sYuY13y$CMS(NUScGR5>EFnffi|2< zyn|QVi~ID`8&gc+VJcvz0J&zSS9``@xnjk{3FEsv51KG~V>Y&O&n7ZssZNt$}6t`Js6XY8Gc7DyfPvrat#}&fX)C_W0fjWfLyCcct4B1`s%B2 zD~5RWK?b}sPQ|&_yK(BkX@2TKt81zNxmMGLsjXR<1^ehelREqFWw)3R=NdLn0hhI{ zFAeii0dmd9R;%7->%|0xYdbeijjz5wv>+@6$hENAv&7nn#e~6KM;a|AD37AV#;FU= z|6Yk!v#7REpux32@*JWMLnh`WGX)jM zQh;2`Qitbs6u9P^tMwNXqFlqhxZgNqkxmheLj{Z!AlHoKV&r56o_Xf!kM1)W??cF4 zOpsg?8>f&kIY%C)0tFNx*9wToq`N8r=Lc>T;I#JDh&6Aq z0u8SHi61K9RDo+#783;5a4+sX_pEeUATy%^?>%V*8{#T;k7oLC1Bm2EDm0a_pnLIY~YhODlx|jg2!C8Yh=W&&+OuzN! zO~-uc;Yt5=_k=M^6Te6P>*}i(KkI~X$Rx^5)38XnFGt5?@6Dsep|FQ9J<8C^FsxwfFlJY)Ig;NA9&Rw*Einy zeKeD`PrPB2$%W1NHKSCykx`d}KXt#P8%SqrSZ)!nB9LpYlw>|spjQFO6hN(Dw~wN2 z(+h9w>nm;0Pof|5>c!8=!6^dEmu}NfTUtzVtu(1wQ1}YKqmk}RL8u9_B--F8>C4wr zuE7jcE$X=4cFT+Uwv`i;Tq{RsmeLjq$Vn(THLfa*B~-ym&`LAUR&xzzV5BS!gL!pB z8@Z-=sW2K9$WZ`&TL1_vhB;A9PJ70^*Y z(#LMCAfpJ(VF_Y_BN@@;snWQH5~FAXf~5`B2FSH)^=IjUC?L^eG!dp>dH8?=Z942I zlWVAg9FV$oRQ1J)$82!zFZ@seDo{XydH?pf;0{Kk1+qy^DhIhb`CoYcMqx~9c1}-h z-~I==jBxdp&pFN8GBa|`QaC1~0#OB~eC%F z+l6`fyLAfWR$N9P*Q68-PytH?;IIg&fo_&rXe0yCPzu128@GI}!6fNX9{JhTxfZrM z0=d>|g_(c&3aonIHNiCl#(paQlEta|V_7oEQmUj%IP$WMpN8>76uQecUQnV+fa7;nD$N3nn~ z=WUQ5xn>|1qf&ti6}W48W3-z~&kDH)edH}Kn_qmVD!ItDs+9My-1Y0;ocX!c(eIou zKkQ#MytP=;s^(k+&V;vk);HEyB{sQMmGYjIi}A(uPyceyJ?@NtK|0T>;j_8Y56Z2C zBw%jL7DYH@=VRJ%*Gr4?&&`%x%aw=`dKG}179|?Ox8J&%(v+!yxb;^D7L{}Dnya1{ zF59|_{^ujtvaZZ0o_OM>n{N8{x4(VD2`3!Z{LG#`8%OZD|Ni^468ms&`}Xaqg{V%m zeuts5;)tx^sV6_CK<(^r+6*y7ahG3yIr5K6DvDmPU;&QftSr|D2}`mOfDojB*Opsk zj{^=kAftY$zQ_uGnF2NVZt*-bj_4E@w*+;8k($CPl1Ak%5-!p- z8G=}xl7mpJ9^@vkoNKU9tco7{rAKnDZAAp{xdsMBy96%cA~GR2Q zN)bie6D2F)IJ^3=5O(SyTUdn|GzDsyWy4%sb}7-bn#HB*3{ye3XoiVlMTfN9Oph07 znnXM84$7H$z(Oa7I&cm5dBDNc88z$F$TUuaYk%|hg9=11R$Sk9ReAHxH!;ABW@QoH zXPjy8fBgl*}7>I^9uev_REimLFh#nJgt)zqKWuAky{j} zS{u-C@7AR8?DU24(d*KVYirl8)$H)mveLo=3K`W=I-#BZFTVJq;&$D9^UWEBe&;*i zNi$eEE+7J^#TP(Fjo2TNF@Vhms4xR#LnUYBCp3o?;*+aC?9ZqjGEp*j^3$$qGVHWC zb^C2w1f<~m?0EA}IyqF!6k(xUI#|8xH##=Eje~}Jw+@YGT`L$Ly@GLln`Q;5DS(g} z!h-`W5JAZkOj){gDf(?%Z_M^Dlul@;zmiFI#nb#I*biPL8gSalk4HTE zXToxFO|#W@iB^znaj!>oLiBbWmjtE&eDO|*OftMD^f%en5lFi{rsaU+%8X}5<0_J7ZdqRweFUty{NFGi^pRrGtT$@yJRXR3RQG@yL!HI~4!x#1l_U zj42K(k#og4?kkTdBhVFhy{zP~2oCY#vSr7~Emuh%{i$dbJrxaWMvEq?NqEba->q5w z`o$MKeaNTp7gK5C@2MZV7su_4L~bGzyW~z%!FXYVbuEgR(Y{<$dO|iJ^d*jW`^}p- zE6J6j^|`ii;le1y;md$@O6Kw>FddDIaNH6ZSp;wiM!)dXlnCOdV*k-cAFV`FL_mBc zg8omXth9uh(bAHac3cuCiZCS%qG58ah)J@PBAFCSD{Xjk{aXdIvPj;(TvPhI6K72{ zfHDb%!JyJGN+;ChTAWjGIhCBFKb1jooIcUWMqy<&7I;;XlWU3~@~7Kl9mdC>!>B#WOLr2+ zY?@-8QVOh6A{6JP)mY!_<!qk##xwhi& zSA^vlQ=3}uDt?=CZOfJ|%H{snTW`72R9T4p?svbd!#GkMh^i&ol6*?<7 zyE*hpU~O3XIp8st_y4q(Db8^rs3 z99zY?CQMcE0aBxMSqnI5QFa4@uGkG^L~~Yn3Ii0wP+w`4X+Y5`ExBg2wB+?XzIE&G z1t0)8BMU3!nzhYF70iv?zFbq>8CTt2nNUZz@itI8VH|w%Bxy&KF=;d_P)u>?z@xN$ z^pD50jsKTGuIcNU9TQVjK%41Mv_h^)XAOYMu3AgawlCM>j#crIn$n-))PSDx_H)QJ zh0al~pw%;hOr#n}y$il8m7 zSmJ*M#RY~w&ohTy+Wci4=dx!6Q?kl70)Vd+~l0JqAQD1>L@XjXPNgNRoNGp6rbSMxUG8xZ zO~9yl5C6&S+v?A?ZQK6v-d)5d{LNL;Is&=YD_t7e1nJPRK_YqeV@gW_lZYn&&W0L_ z%T6xyF$w@uTeogayAIOOCW=5>m?ZHE*x_fQgCg^1{!fZz@4zlPGIIU1g$us`5&AEo&E(VXLJW`az_)g?w z%ExlJ7KIvIHvClVuka_irizcz9Q+!i&X19)CecJ;PPhgOF>=gx)70wi{Ebw~4I)u^ z#lt8IM9UcGDy6hJ*PzCnuRJP{1m8^&NB^h9(}t(=|1XJVD-%W!x(&l5c~?i>poW@~ zYpKl*CkUNc%%&+rR5{}YK1ZD1r|>h@El zI>pxq0S-Y%i}78nxpv((n}lunyM|Ch!;x!6u3o040;vkfRngNZqfEA)dEYq2WO(@Y1$F%DW%#xP6;` z-G2MdU*!s;Q9@b7B^Ny_{3&^)cmUNo?Uc3BO+x^s6wkIrIgo2D5|-IgfxmCu@Qwrl zpa5Xyih?8(YUiA_Avb0yO2R~tFV$n4@SVykG=hFWqP7LWM$Lvx~ zT7qT-slYueUXxzi)Q{hr;eWv)k~{)Ftf2-OWj+X4d{Okw&po8DOb{)*3iWBhI&v*K zu55J}1guYE(2^h(fNKLBNXHGBgYO310D16+KstoMk!S>*Dk23kl({(xz<$^aYl~P_ zW?FKMTr2Z>YtynY0tIWN{}PYs;Ktt!X|goPuSU0e;%l56Bz4KK?u zO#Bq>r~nn90--2Cu7%Q)tOpgK0!;&{Uwowg2UZ3Qz$m5Q+liS|}~adQbr>&{Tk2 zYbwEisQ?uSMFDaxl$K;Yr~nmcDnPC^mEgZrfC_}70J#=QOR^qRfC@AfAlI5o@LwuG z1wv7PTnnWoSq~~e1)2(wYfUBiFBPByp(sGEh0>C&2Nj?KO$ErcrV{*@3Q&Pi6liem z|M;N-RDcSEq5!!TN=vdHRDcRJ6(HA|O7LGQKm|fkfLsfuC0P$DKn0o#kZVmP_%9Wp Y0--3-;2QqnhYC;uDiDkU@Am2Q|HxtSh5!Hn diff --git a/Templates/Full/game/art/gui/splash.png b/Templates/Full/game/art/gui/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..333df9eb3950726e7eb4ebde5dfe034e8a0b1a6f GIT binary patch literal 11864 zcmZX41yoewx9=b*ARr?h(v5_44c#CENH>BsNDST5jfmvX-AK0xNOukmlG5Gvj{kM< zdhgvk#p1+wcJFWh_6}Ep%3{4Fc?kl6u;k^WK7c?->A?3j+B4t?`{;ot@aKhzqO26? z>EAo6tuP)qg6<%v0|S9DaQ=OfCYF5ffrF^d@=DUEe~`d0UQsSh+v$TqlpuL2adr3k zgLDsXHM7T~%(S#TC97Ag@Omr12%37UZpZJuSb|#OSp$oXQuDh}q?BCD&#H?9DHX{G zv*4?oEYbuC5*S7L!S$4aTB-S%>l&$e&N3;q(%;J&>R9a(?|PZ2GU}}o;E~MwGtr03<0O=tXI^$VzxtbCf zI=d| z^!H-5?}`MdMW0v7eAeN0_P1>Ux$l$SVGj2Zn+fKsa}GG`L_7l+YJ6s6d%vw#voJ)E zWXyJ4SOPS8)Mg3B?jQTDANZk-5| zskB110_aUQpSr=5J(u2)*QIaG1%6NqpKrn$}rfB zQZa1H0l!LhJ36?*p~e~i(-msp{&30Y^O>6@+ABl6TvJO^bIs-1Ym;K1lRGx_ z(a}c24avB8?fJu-q0q+}qE))I$(_-?bAXj5?iiT5z3u~Z?)%u;xTm#9c9m@;|Kr*e z*5*+1O_7z_-2}L1+nUl;lxjig@WRaw$>C06CA_<-y%$%-w$0;QRIS zTR^^2%@ibUE=^0LZ+LnrajyMF+kZ7>M%)!L9=4C(^?pn2wPpQTW|E9vKA&1O)uD zIsfqC!<4nl=YOw?$^}g=EkGr}uU8`E%5-ykn-C8#FE7u%#xGh%O+{su4cy{-aC*e) zVQR*i;(0$mknr|7yVw4K_VV$=%)w%)D$L^MYJ_Xxd~X}_aL~*L=&h`ZBPT!y0rheY zW4@bJgUz!L%*+y{OoUv|CnR}n4kTFDc}^B6kxP}!rZ6%xf~Cs6Csqaq22!{zmVK_4 z4hu9hBXTuMEk@FI#HTzVnpRfDy5($4Os^MNcKsYKEYn|y{x+Oj zTg%PIM~Fq0adWaNekkeBW62q862=T~oQ{*m!;#5&IMht4C4=*z`dWTc)zN7(?g&`+ z-HRx26m@#tu)KVr1n0HlPBmz84d(pYQ@tPX9HXSP)awjaCy|wr@$YaMOnS0$xLngl zQZlgr)2=GgusIB%Kwe&+alt)z=$J3#??fH?I`ZQ5*Zs0HK_7VcM87W0yO3^q(xf&1 z%1OVPOQk2~tt^{tT%J1J^vujmID7#vVZ}|trqB%==0_gzvKky6z2f}5$;Q^YUd^Hh z==H;gwYDM-Oh9j6ladg6y8dQ!ySuxmr>BPtPBa8n6TE(p_dj-ZwThGUi!mLv9GUtT zQA@}9X{l`<=%Vfu8xW36G4_Zy0rdoYs%?QRm-6Q3=9VHeb8|MMpRJ=1f8BD;(rK2# z3hk-@EzHHSv3Ibo_w0e2H#axFdCSeE8fIo@vCT8NMZ=k*ep^E+83{=rlkfk%yrX4m zj60rX+|&cVAs_Gibb~=Yw)RMzPni$#GwwSB{A*MEi9TA-Xl1N#VXN<`%n9_&(O!d3k;;3$tJh&ow$`JO%K|>??EB)+p#zHcm@)DYfb=-L=npaRj zZ2*P{>g=^=WOSYF=LDD1FVd+o&a)&Iv{8iUAZ~}#%!D<$F03k<@FG^D#jezF?zI8R zq@|@ZVmmc9&@HQ7+J`{)3ib=0ud%n%-;Akd9=(VFsD^ zM1IzLt~0Z<*1VymwM0Hgs+e8x&bEg43S^s9;a7K_hVona|{j)=!<$5C88k_6BGNC;0#u`y6ZrpP(#Cvt2t23+`bK=HC|~~ zvD&yxryapyEUKt*-GzacN05F>M%w|IpkNX%*|#NpaI1=+x}%@_H}d3BNn^bbt=T_@ zUgI=?dAlhQtbOr1Yzk$t%YZcoqGG!~Rb^*)z;oTvkKVtCF?rGF;Uhd6RK=TNS)*O{ zxikkX;mhMifJnq^!|WdstgN)~^Dr2zTkZ7f8aA)#Fa|Swsi>)~Kjw0-%9HU&L`EJp zZIio^)>Kzd1lBSoC|uQ+K?`y7e51jgaD||cM1NBonhQ#wu1GUpwtRXiJ##s%I(~Ra z+{F3N`g55?#DFyGgeRlcZn;(G>ymYyZU!sOR1_f~3&=-i7MAm`wwq)PKnzo^IR`F( zXkUJuJ?&x6VTR@D#2yHssT0o z^a;&!@Sl?lvF4o+x67JTp7{)sH7q zBc|_#g-!OS7i)w%rn!3D*N$4iw9o><||&6j{}-^v#FwHzw7FQZw|MoAKleq5cm!R$IV^a|`aUJb;) zZDW(y&`9u#N$}eC(9EVh zdBcdLuV!=7kpwOX!VEh)yun0PSOfR4IhV5XQeDfP0E=#IQNt0g#Kw+QyT>|VdmV4a zHDcdGIA$nMKHk%2bPcO4l*ZG)A;JG<5lyQBzT*DSqxIDDFk5>iDM#u&%*Sgx`|C^w z>qXZ_e>~tlt+jY1B_;IA8H-D3%*@O$C%k42%7MLz=OFsV#>VljOw*Ba2BfK>q>XCM zbb?TH?~#4`Lbl=lk8eg1U>xq?&&zd)si|vbJ2;>HmRaI+TgPbcZ-w{bZ4KYfDiC3uN z6hJ@ZJIZJ>M_>{!>)W@bB_+Ej4z0#%9mcb*9$fau#33h!2y*XZ@$C1eAH70-Br4vI z&Nu6D(Pe_2toJT|mvPWMGhBVy%&W3$INpB0$-abNQcw_L!Rda(c}(rrkyTV=dAiZh zCNN`Nmu7u_xe27)Ljtu}5nDq;LseDP+cgWo3hPdS_Erkz&9>PDpn|qO5hPcrxh=IP zueNpPV$Zo@>TcQRA~h`P$nvwfUQTAW(Up(UXOhaT&DL_Rnzhc9K~+vzzJKwp?l$6; zpSi*K_t;T#ddMQTjXl{c01+EXO9%5!sAy=^d7PQ+vW+fl9%e{V20`ee;YP>57&5)r zl+I?V%?2T)<>oayUc{q0iNH>12~N)cipip&PA3&=w?NKXXxE~@{AaiLWncx?&_$6u z9o`j(#GSFBem)b--=6hS&~Jg`7nw7t8EWsBkz-L9-EnK?mUUtRLa*_ zem*fmnQD3~7moO)KO7DHzJsaNXhRioa~7~&jKb4VAn_!Gx8v4zEpA5@#lFSTjG#(5b;6a@7Dk^BYR$$So(x6t|f=gkNG07!}uM1m>{xylaT|ntIpdq#!vS7 zA~%&jw?g4$6GT5);*al_-Xs>A`MbEg5Wq@R=8ZBhjvVwgQt!St*UGacabd>C#c_x! z2zq}F?~yt9{%nMG*n5+1)adbw)c$FExB;CCH`*xp%65`K^hz{V5LZ0Dt%k(dbCTsD65%2_regH4ULK_`_>N)k35JQ%BB za+&Oqj(qwe%l@;W)__fw;LlGfUiEk=@Zb9^5_0f-rc>pFnnNHYy}QjG;~C?t)%RV0 z8!TDf+xT>K#P<{vhfZA8-=9>T9mYF1&!RNbBO}pw{G$iyPv|ptgKX}j$>(C%Ct3y4 z-5yTa!V+@Y)HVQo5cDVDX9kAItA6r$qFN``aL7w$Cp*nOAop&znx{|;3^mW#&*VO% zJWoR)o(c!){5YxJYR5S>l+=nC&Ax@91iLdr?UqI~HVpap`j1OquGxT4cC$lQ87t@v zs1tb=aSM;a=S(}3(Ss|HD1!!Rj+j?~D2TbNIuCE=%zjO3$;ILkcjvHFR@mvw3DEPb z2Em4*q-Y9;w+W2rZ8`~3BijMG-WZsn?$8dbKms?m(Qlh<*d-RMPA55Tl7)Y?ra4lC zDW`ecVe#P+v$x}+7or#-Q>y4Y;pVMzRtS6tb9&#W$GINxmQEi_AU>TSgdaY+PiAR7 z&Vn~2kXY-%(Nhu6=0ByF0}9ekv6GyE{tei)a*C(Y(5WNH`o|vA6cQWYC&N z%lm9(qrJujU>uZz~*zB z1Q=czAd7)2;1{%4e}u#r25mL>`Za9aL&M&vu4BsUvbCEH7KBac15nYkug)uNY5lI* zk407sUeBy$Tk^xfoK7?GRdKJI*QPE@o6ZcDPXN#4<(Bpaq$Q!$GZ?%W8eckt#yJ;0 zI2d18XmI76M`Sb8gWFp$yaA1B*)W*=PptT^ zuR~tWT`fg zl3s3BnIdn@+i8|s-FX!p9G#VskDhV>Y(3+c{OPrKw9-~5avZ-+%R;p`b6r~-7M*+1 zH=Zk-Z9^HxqSJidc0sCzMJ~u8BZJ2Dx#c=$TDR8qAoKBh)t@AElET~h^4Nm#T-FP> z5lE0-Ju3p<_l>{QP!19c>gk^rj&i%H11r9~JH9wsudx^n7rHrEK<^?_)tYZ>JXo_x zn%`07^M0KB^F@G#w=_ZPiAoU~lNPY>*Z~mm+6cMx>@g;SPBBTuoB@U_d;GwntB)8v z?vA5rSaDqdy&=|RJ3@V-iWkKto{kER+1lEggKhh27~FmCd}mfx+j~SS|5u|Fv3S{` zjY)`xQ#ANI0FY0dP;Yb+*<-J)WTocB#PZKXg-90{mnWW-cP0QfN}USa0fCt9n%LYi zn-{&!nyHDU#GxBsn=VBdj{%^m6eDoy;TyikGX&y*)RQOaYCm2by)8HA89k|g#TU6x zveMn@>pih|%jbq`Xu-1!-0Ed=-=!km_KSXj0Fwx#OohWKJoc*)TdeL$iNj)9haqF>i|DTyCFd=FTXv+U8;0!(=H7eCtdR)>S{-bJzMA9s^EL zejvn>b=u5_X|9yhmlo$OBK+-hRoflZ)o9N{ut?u!0Nix;`zaL&^{&)aIv@PZ)>>gF z#amqtiR>0l9Ts8+n<00}Dtf!C+^( zu}XS8et-1T%P5$hVbhMA7^H9Y#R+0^0{o6SZpbY)p18UA-p>7#sJto4if9s1H$O69 z{jV$VIskq9D7-$GE1et;;ocN1NuUe^9N$z}| zg~IVS#gcmX09v2Tk@8-&W=7SSLYmxn0~I0}DOHT)*(HPL?f;9M78B`jhqlo2szBpb zwjZU~2dk6E2h{iUYSz}wpHckVUPx>NUCxPuv-%UIA`y7_>uf-i0Q{|4P$~8@Rpkb0 zH0ry;CB^K@;?SB5=;=Xa%ESM&@81(ltJb^rTETREVp+5p^0zqhdcJ^>cGW}@tQi7r z1u-x~ZHJYeqrID`)sc7cfrO=0G>wLYz0@Uu{`>p)q@FrCluz$?m!`8?xBQiT5~Bn} zxw}p9{`IRY8!;jh63oTc#!$fpLrY=8ynC@seWgk1Zn{P?K%+q?lDJGIjRz(_&X6f&(@_M`RJaI)OP*i>Y zyRyw5rNRh+=8m%d7QXic>_Aj-{t_=*6-->>qb9R(xI(+U=@iHjBKH+Tzy3Hmk zLQ|t~eAV!uxE%Fzva-b%GPEr zY6+KOZTW9PP)Y$5z_qOl9=c z++WS9kNoJaEu90zLfe~{@pInuwj(3`#CpNBOn;>j@38s*R#?)}5hi)gIsA0vK;&=oo`8>W^x^B$#57Tq-<7&YQ4Dk+}uIIM5xEsjcq(Y!1 zDlaG#atH@-B)ri{^je}+fagtf8+?c`F*wFh+2;81E@k+Pki~Xvw*c$glaJ*$6<1AW z>Cnd0Ks`T^gd9C9i}bkps_P^ z^J@jU8~;BTZBb`C_>Z1W(6_sIr2KAsk6xpZWU+Q zm^@!s>hvezrg0tAJd-)6p`-KRL+btdTmveWCf&<7i0w{2m-lDlTIUiwE+HZP{2^g#aLV zp7I7RS$VlQzw?&iARSd`;b*Nu#K!BdYB?{Eow39aw-|3V2>|voNky+~{`7Y;>uTeq zKgLlKkYdU}FadTb_*D#ij0ZJ4Ce!~YIp2y?OY;zcO_0axe8rWN4vtLMgK+BP6rDYl zA#}H)FPK!t&~CAAL)%>K_bIb4U5je$jCw~^8LWfAy0j7a;Xv4Qrv*8)?n>Lq+3Ydu zQct~VVj|7O6VO*(J(X15e%+>ym|DceWmtWs~fqpf9f}lcaKL~Vo^LBjR2+#=KjqBTy~Ifq8gXg38jn9?HAg)GK+{@xy73gC1<3J_qLK? zcG)iec>IF;Bxhu;oYRf;N-j-~7FSgtE(MXcs?~LYzRJJ_c7^oT*475lqEIHjiQgjM z{jdK7&8LlI?#EEr)?>KJ`Wi07;_0`bsT&VlDa6F2d}V%rWBtCV<+u-Is@OA2uTUo5 zhr~3Av&fPw`NLF+5Ov zZwc?FrD@n`iazbb=BksmD-pfTDKSkci3QvAqpVdQny+xl6~gTa6eoXwgYRS@^0#LeY4nRx zOJG1j(JUt~e-o{sQ8*d>T>&Ch;OX_`)fL-MBlJ9CgpjcOqt4}Qwq&kp{*u8Cd?%Uo z_c!&DSPLE~Er~+-sKEXSo*6G(C-Gu52<1Tv@f8xm#`%39g6v33QzN16=cQ0&KA#JQ zt3xz+V$ETrNId`|Dh)7p+$-vsK;cOJy3mX-($t$%K#eK2Mi94KT~bo=m4q!a{?w+- z+ZzuL*~cT%$9m5Mm+LUUI-_Pwx8tZJQt$D)AIgnDk8FhOD6@W!A|@^gi-ea|MkF!j z!bRFMNr_Ndm8AR?HabujR5i1D9Msw8a~$q&srC4SO->CEDE2`nMD#Q?G(AkGUf687 zJQ+DrGI_uTi1K#&plS}Lzq=KWt8l-YW$noS-0hqw1U+xNBSG-1+F#$$iZ6ddKPKOt zW&D{s(7wwj^`5G$fyxHy%jtnEI`d!gdqtb+)XYVpA~(Od4QwuksUs$wGv_49eSaea z!;g0groQ8q(qt_alLt8(a_ebx+&+wT0)nCkVE3(Jh3rk%t34u&k9|)ny&Vjdnqu zh2D!s_{i2opA+}tDpid>zq$Q4wt45U5xKS487F^O_*neebK zQQV!JrHpL6YvIwpzM@w{AZHh{-~WPe>71>r()W#NmE>XF@)%ssa!tawI7`gostS2) zBQYhyUWwueKzQet7lH}gGl+8NHNFu|5K68p({U54fdQ(M!l!pc!h5N6w!B19FLK38 zCy6n8G)pfu<%cZ8YyA^jxmi5&8uy+Tw@qC-DIEahokWQv#QI#6O7GyY%>-5$R5eJI zRbLgxjlL-ceMPC#E=4G%a#z7iKTqw}zQ|QAovvaL(xq;br+!$eJ=c+6tdylaZyXKh zsHRgg59|PG;Q=*M#GLJ8he?x}dxWyyO&j?1c?-}>W7?Cv}Arcw!Tja=7NeUi_zF zu#gr#OHPrWr3>HEJ>14hS6;DK!IZo(zrpZA^zq;_W45tLqvcP81VYR*U8Oz1=5-@M z_1wp^I-|~X{y0V@mbmaD^$1^T^JB|!Zg7ILV+(hpfY;B0g2e6F0JLeIsmcpngUQ{D zW1o~yPv)nqt=(H&<{e7)QJ9;-liTvf800M9=}=6Aj$)!qi^~D9^ci_Q8tTJ~2b91L zxrW;N)Ju;!!KeK??KsA8f~U(Ep+Q5VxBJ2GPW#d^ovin>Qs;Fcwm>kUwzjr;aF9^G z)%znJDK$W}b3v9gu;RYn;I>#ijV>^!gVNmdCfBn6>x?GQn7|4`ONSPoR{2DLop^sx z$D(i~utvr`ov+hi3*YyO3gcbh6YHkO)K!blAG{VCx%&P4V7U!-R4*v7Ra_LX0(@+( z>*jdu1b~Xy}}ASeF~@^rjD&Mu*b5OmELKVl8=L zE}sO`p{0}gVODgkfZf7qtB!8qOCcGOhXak59q;w;8{RtHtZ; zP_u2~Dr}0*!aNzKuA0KpsDP?;hH~*1g@cEeZRY%-Ar^A(kfuLUy?;@=0eHX?PQO!s zmMRTS4lq2>^SivL97`q|1E>$1S21(YX+HSO@W_IlHw%(W#5F?|dOY_3R1dn(G-eVKrypIXD5%wXe00>8uw>uDjVuq}SzU=;;+{mg|Z}JAHSKm2%KG^y0 z=$1~-MXUyjRahQ$1pbFSD8jkfk%Lo|m%B?FH*6ul%2`p-jx`U!Hc^};9^h~^Xb~mg zxWL{K`0U^mLo0jzrSSfG#hNfowKs)l*@$4N!zbrnJj4dA z7N{wm-ofnXt`|yInEkhF;P>=-IC#{okgmiXD1X_PVo(kZZFwT9Py_O!*wnxJ-C5AU zF)FizM-63fzG<+6+QK#EO+9ZR4Y#>gY%TvAUIwZlZ88H3hm%thf5Lr(Xv;~BId@86 z51rLLc3B|;Ru?&qNNH3f2*$tmqJ zcQ?6n0VIK{s&Qj(U6w>C4t!IVa_F1r_Fbx6U` z$}6wW)YM}VeVUMj#DN^PSn2w%aWmX z`KT#8Obml+Aq^Vb`8H5BTZIuXA{>`~wdV^s(1R{_$Pf+|+e}5D#04tnFh&-F$Z<=| zK0^$CtFbi)cdIfapmH}PvJq@sf#Eu$EL$1FzTy2P`KMy%azj5aP=XE0q#pn)hKYF{ zjDVOCC_7o!FhSKrY-(T_RSH$cbUg*M^-t3HIeocHJMWd1yO5Cqr>BbIY4g?hhZd1R z8UG=)5=NEntn`!yxOssCFBE|q&fmD1;Foo_!DTAA8K`wWS(wh-0JKQ(XFCs$=30iY zc=2!7Hgp08!2?$9nFqpx*yS(QkZ1qU;FyZ((makY`{G4b5Vl#e0q66gf5<0hV%_e! zr-pIAia3x&jfn(4zXTpFmOdu7MZYE%hx(6>i8{}RpkDztQjMP&Qc}ssBd|ZtP zBjN@p?e|O6)cQ7ec6JsmG+YS|(Zal?La`}+Zl&711CIxEn^bADR8aiug-&eTRuvcb z?_Vy+!1YJg0OqAZ^3qVL3JK$Y{{!qCM1lYS literal 0 HcmV?d00001 diff --git a/Templates/Full/game/main.cs b/Templates/Full/game/main.cs index d4a6656e0..65aae6d7f 100644 --- a/Templates/Full/game/main.cs +++ b/Templates/Full/game/main.cs @@ -29,7 +29,7 @@ $defaultGame = "scripts"; // Set profile directory $Pref::Video::ProfilePath = "core/profile"; $Core::windowIcon = "core/torque.png"; -$Core::splashWindowImage = "art/gui/splash.bmp"; +$Core::splashWindowImage = "art/gui/splash.png"; function createCanvas(%windowTitle) { From c7b041f54500a5c579935a032d26ea4b27e65264 Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 16 Jan 2017 22:11:32 -0600 Subject: [PATCH 44/50] Fixes the debug netevent packing error by keeping the mStart value as it's proper 0-1 range until it gets to the client, using a temporary world-space var for finding strike target objects in the radius. Also add a checker for if there is a texture or not set for the lighting bolt. If it use, set the stateblock description to support it and set the texture, if not, only utilize the color blend. --- Engine/source/T3D/fx/lightning.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Engine/source/T3D/fx/lightning.cpp b/Engine/source/T3D/fx/lightning.cpp index 125c5891d..c7981df47 100644 --- a/Engine/source/T3D/fx/lightning.cpp +++ b/Engine/source/T3D/fx/lightning.cpp @@ -478,11 +478,15 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendOne); desc.setCullMode(GFXCullNone); desc.zWriteEnable = false; - desc.samplersDefined = true; - desc.samplers[0].magFilter = GFXTextureFilterLinear; - desc.samplers[0].minFilter = GFXTextureFilterLinear; - desc.samplers[0].addressModeU = GFXAddressWrap; - desc.samplers[0].addressModeV = GFXAddressWrap; + + if (mDataBlock->strikeTextures[0].isValid()) + { + desc.samplersDefined = true; + desc.samplers[0].magFilter = GFXTextureFilterLinear; + desc.samplers[0].minFilter = GFXTextureFilterLinear; + desc.samplers[0].addressModeU = GFXAddressWrap; + desc.samplers[0].addressModeV = GFXAddressWrap; + } mLightningSB = GFX->createStateBlock(desc); @@ -494,7 +498,8 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base Strike* walk = mStrikeListHead; while (walk != NULL) { - GFX->setTexture(0, mDataBlock->strikeTextures[0]); + if (mDataBlock->strikeTextures[0].isValid()) + GFX->setTexture(0, mDataBlock->strikeTextures[0]); for( U32 i=0; i<3; i++ ) { @@ -731,18 +736,19 @@ void Lightning::strikeRandomPoint() Point3F strikePoint( gRandGen.randF( 0.0f, 1.0f ), gRandGen.randF( 0.0f, 1.0f ), 0.0f ); // check if an object is within target range + Point3F worldPosStrikePoint = strikePoint; - strikePoint *= mObjScale; - strikePoint += getPosition(); - strikePoint += Point3F( -mObjScale.x * 0.5f, -mObjScale.y * 0.5f, 0.0f ); + worldPosStrikePoint *= mObjScale; + worldPosStrikePoint += getPosition(); + worldPosStrikePoint += Point3F( -mObjScale.x * 0.5f, -mObjScale.y * 0.5f, 0.0f ); Box3F queryBox; F32 boxWidth = strikeRadius * 2.0f; queryBox.minExtents.set( -boxWidth * 0.5f, -boxWidth * 0.5f, -mObjScale.z * 0.5f ); queryBox.maxExtents.set( boxWidth * 0.5f, boxWidth * 0.5f, mObjScale.z * 0.5f ); - queryBox.minExtents += strikePoint; - queryBox.maxExtents += strikePoint; + queryBox.minExtents += worldPosStrikePoint; + queryBox.maxExtents += worldPosStrikePoint; SimpleQueryList sql; getContainer()->findObjects(queryBox, DAMAGEABLE_TYPEMASK, From ec8b657b715709376f71cc8311d6e276faf13265 Mon Sep 17 00:00:00 2001 From: Areloch Date: Thu, 19 Jan 2017 19:15:50 -0600 Subject: [PATCH 45/50] Adds support for multiple textures used in the strike rendering per @RichardsGameStudio's help. --- Engine/source/T3D/fx/lightning.cpp | 21 ++++++++++++++++-- Engine/source/T3D/fx/lightning.h | 1 + .../Full/game/art/datablocks/environment.cs | 2 ++ .../Full/game/art/environment/lightning.png | Bin 0 -> 2876 bytes 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 Templates/Full/game/art/environment/lightning.png diff --git a/Engine/source/T3D/fx/lightning.cpp b/Engine/source/T3D/fx/lightning.cpp index c7981df47..ed941a82b 100644 --- a/Engine/source/T3D/fx/lightning.cpp +++ b/Engine/source/T3D/fx/lightning.cpp @@ -243,6 +243,7 @@ LightningData::LightningData() dMemset( strikeTextureNames, 0, sizeof( strikeTextureNames ) ); dMemset( strikeTextures, 0, sizeof( strikeTextures ) ); dMemset( thunderSounds, 0, sizeof( thunderSounds ) ); + mNumStrikeTextures = 0; } LightningData::~LightningData() @@ -297,10 +298,14 @@ bool LightningData::preload(bool server, String &errorStr) if( !sfxResolve( &strikeSound, sfxErrorStr ) ) Con::errorf(ConsoleLogEntry::General, "LightningData::preload: Invalid packet: %s", sfxErrorStr.c_str()); + mNumStrikeTextures = 0; for (U32 i = 0; i < MaxTextures; i++) { if (strikeTextureNames[i][0]) + { strikeTextures[i] = GFXTexHandle(strikeTextureNames[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - strikeTextures[%d] (line %d)", __FUNCTION__, i, __LINE__)); + mNumStrikeTextures++; + } } } @@ -317,6 +322,9 @@ void LightningData::packData(BitStream* stream) U32 i; for (i = 0; i < MaxThunders; i++) sfxWrite( stream, thunderSounds[ i ] ); + + stream->writeInt(mNumStrikeTextures, 4); + for (i = 0; i < MaxTextures; i++) { stream->writeString(strikeTextureNames[i]); } @@ -331,6 +339,9 @@ void LightningData::unpackData(BitStream* stream) U32 i; for (i = 0; i < MaxThunders; i++) sfxRead( stream, &thunderSounds[ i ] ); + + mNumStrikeTextures = stream->readInt(4); + for (i = 0; i < MaxTextures; i++) { strikeTextureNames[i] = stream->readSTString(); } @@ -479,7 +490,7 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base desc.setCullMode(GFXCullNone); desc.zWriteEnable = false; - if (mDataBlock->strikeTextures[0].isValid()) + if (mDataBlock->mNumStrikeTextures != 0) { desc.samplersDefined = true; desc.samplers[0].magFilter = GFXTextureFilterLinear; @@ -498,8 +509,14 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base Strike* walk = mStrikeListHead; while (walk != NULL) { - if (mDataBlock->strikeTextures[0].isValid()) + if (mDataBlock->mNumStrikeTextures > 1) + { + GFX->setTexture(0, mDataBlock->strikeTextures[sgLightningRand.randI(0, mDataBlock->mNumStrikeTextures - 1)]); + } + else if (mDataBlock->mNumStrikeTextures > 0) + { GFX->setTexture(0, mDataBlock->strikeTextures[0]); + } for( U32 i=0; i<3; i++ ) { diff --git a/Engine/source/T3D/fx/lightning.h b/Engine/source/T3D/fx/lightning.h index 20620fca5..71ff493d1 100644 --- a/Engine/source/T3D/fx/lightning.h +++ b/Engine/source/T3D/fx/lightning.h @@ -70,6 +70,7 @@ class LightningData : public GameBaseData GFXTexHandle strikeTextures[MaxTextures]; U32 numThunders; + U32 mNumStrikeTextures; protected: bool onAdd(); diff --git a/Templates/Full/game/art/datablocks/environment.cs b/Templates/Full/game/art/datablocks/environment.cs index c9d2b0a51..ab9af14d3 100644 --- a/Templates/Full/game/art/datablocks/environment.cs +++ b/Templates/Full/game/art/datablocks/environment.cs @@ -83,6 +83,8 @@ datablock LightningData(DefaultStorm) thunderSounds[1] = ThunderCrash2Sound; thunderSounds[2] = ThunderCrash3Sound; thunderSounds[3] = ThunderCrash4Sound; + + strikeTextures[0] = "art/environment/lightning"; }; datablock ReflectorDesc( DefaultCubeDesc ) diff --git a/Templates/Full/game/art/environment/lightning.png b/Templates/Full/game/art/environment/lightning.png new file mode 100644 index 0000000000000000000000000000000000000000..fc19efad9592e68a518f65044a32c509fed28aaf GIT binary patch literal 2876 zcmV-C3&Zq@P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0001INklo3Cq0j;w{ago literal 0 HcmV?d00001 From f8b650f7a1225e5ebc7dd32d08e040b6fb320871 Mon Sep 17 00:00:00 2001 From: Areloch Date: Sat, 21 Jan 2017 17:11:54 -0600 Subject: [PATCH 46/50] Reworks the open/close functions of the gui and world editors so they will properly toggle between and clean up when closed. --- Templates/Empty/game/art/gui/mainMenuGui.gui | 2 +- .../game/tools/base/utils/inspector.ed.cs | 2 +- .../game/tools/guiEditor/gui/guiEditor.ed.gui | 2 +- .../tools/guiEditor/scripts/guiEditor.ed.cs | 43 ++++++++- .../tools/worldEditor/gui/EditorGui.ed.gui | 2 +- .../tools/worldEditor/scripts/EditorGui.ed.cs | 19 +++- .../tools/worldEditor/scripts/editor.ed.cs | 32 ++----- .../tools/worldEditor/scripts/menus.ed.cs | 88 +++++++++++-------- Templates/Full/game/art/gui/mainMenuGui.gui | 2 +- .../game/tools/base/utils/inspector.ed.cs | 2 +- .../game/tools/guiEditor/gui/guiEditor.ed.gui | 2 +- .../tools/guiEditor/scripts/guiEditor.ed.cs | 43 ++++++++- .../tools/worldEditor/gui/EditorGui.ed.gui | 2 +- .../tools/worldEditor/scripts/EditorGui.ed.cs | 19 +++- .../tools/worldEditor/scripts/editor.ed.cs | 32 ++----- .../tools/worldEditor/scripts/menus.ed.cs | 88 +++++++++++-------- 16 files changed, 238 insertions(+), 142 deletions(-) diff --git a/Templates/Empty/game/art/gui/mainMenuGui.gui b/Templates/Empty/game/art/gui/mainMenuGui.gui index e9d575093..212944c56 100644 --- a/Templates/Empty/game/art/gui/mainMenuGui.gui +++ b/Templates/Empty/game/art/gui/mainMenuGui.gui @@ -106,7 +106,7 @@ profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "GuiEdit();"; + command = "toggleGuiEditor(1);"; tooltipProfile = "GuiToolTipProfile"; tooltip = "The GUI Editor is accessible in-game by pressing F10"; hovertime = "1000"; diff --git a/Templates/Empty/game/tools/base/utils/inspector.ed.cs b/Templates/Empty/game/tools/base/utils/inspector.ed.cs index 9df8c7e98..f7c27ecf0 100644 --- a/Templates/Empty/game/tools/base/utils/inspector.ed.cs +++ b/Templates/Empty/game/tools/base/utils/inspector.ed.cs @@ -105,7 +105,7 @@ function EditorInspectorBase::onAdd( %this ) superClass = "MenuBuilder"; isPopup = true; - item[ 0 ] = "Edit Profile" TAB "" TAB "if( !$InGuiEditor ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );"; + item[ 0 ] = "Edit Profile" TAB "" TAB "if( !GuiEditorIsActive() ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );"; item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; item[ 3 ] = "-"; diff --git a/Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui b/Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui index e387f1bc0..cc03cbd07 100644 --- a/Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui +++ b/Templates/Empty/game/tools/guiEditor/gui/guiEditor.ed.gui @@ -86,7 +86,7 @@ minExtent = "8 8"; canSave = "1"; visible = "1"; - command = "GuiEditor.switchToWorldEditor();"; + command = "toggleEditor(1);"; tooltipProfile = "ToolsGuiToolTipProfile"; ToolTip = "World Editor"; hovertime = "1000"; diff --git a/Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs b/Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs index eace7d43b..61dc8c5e7 100644 --- a/Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs +++ b/Templates/Empty/game/tools/guiEditor/scripts/guiEditor.ed.cs @@ -75,11 +75,26 @@ function toggleGuiEditor( %make ) if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui ) toggleEditor( true ); - GuiEdit(); + if( !isObject( GuiEditCanvas ) ) + new GuiControl( GuiEditCanvas, EditorGuiGroup ); - // Cancel the scheduled event to prevent - // the level from cycling after it's duration - // has elapsed. + if( GuiEditorIsActive() ) + { + GuiEditor.close(); + } + else + { + GuiEditor.open(); + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + } + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. cancel($Game::Schedule); } } @@ -98,6 +113,26 @@ package GuiEditor_BlockDialogs //--------------------------------------------------------------------------------------------- +function GuiEditor::open(%this) +{ + GuiEditCanvas.onCreateMenu(); + + GuiEditContent(Canvas.getContent()); +} + +function GuiEditor::close(%this) +{ + // prevent the mission editor from opening while the GuiEditor is open. + if(Canvas.getContent() != GuiEditorGui.getId()) + return; + + GuiGroup.add(GuiEditorGui); + + Canvas.setContent(GuiEditor.lastContent); + + GuiEditCanvas.onDestroyMenu(); +} + function GuiEditor::openForEditing( %this, %content ) { Canvas.setContent( GuiEditorGui ); diff --git a/Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui index 445bacf63..3eb8558e4 100644 --- a/Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui +++ b/Templates/Empty/game/tools/worldEditor/gui/EditorGui.ed.gui @@ -67,7 +67,7 @@ MinExtent = "8 8"; canSave = "1"; Visible = "1"; - Command = "toggleEditor( true ); GuiEdit(); $GuiEditorBtnPressed = true;"; + Command = "toggleGuiEditor(true); $GuiEditorBtnPressed = true;"; tooltipprofile = "ToolsGuiToolTipProfile"; ToolTip = "Open the GuiEditor"; hovertime = "1000"; diff --git a/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs index 38a180e64..31f794d17 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -35,8 +35,6 @@ function EditorGui::init(%this) $NextOperationId = 1; $HeightfieldDirtyRow = -1; - %this.buildMenus(); - if( !isObject( %this-->ToolsPaletteWindow ) ) { // Load Creator/Inspector GUI @@ -1914,6 +1912,8 @@ function Editor::open(%this) if(Canvas.getContent() == GuiEditorGui.getId()) return; + EditorGui.buildMenus(); + if( !EditorGui.isInitialized ) EditorGui.init(); @@ -1929,6 +1929,21 @@ function Editor::close(%this, %gui) if(isObject(MessageHud)) MessageHud.close(); EditorGui.writeCameraSettings(); + + EditorGui.onDestroyMenu(); +} + +function EditorGui::onDestroyMenu(%this) +{ + if( !isObject( %this.menuBar ) ) + return; + + // Destroy menus + while( %this.menuBar.getCount() != 0 ) + %this.menuBar.getObject( 0 ).delete(); + + %this.menuBar.removeFromCanvas(); + %this.menuBar.delete(); } $RelightCallback = ""; diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs index 74b34e0a9..8545c9d67 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/editor.ed.cs @@ -99,18 +99,12 @@ function Editor::checkActiveLoadDone() //------------------------------------------------------------------------------ function toggleEditor(%make) { - if (Canvas.isFullscreen()) - { - MessageBoxOK("Windowed Mode Required", "Please switch to windowed mode to access the Mission Editor."); - return; - } - if (%make) - { + { %timerId = startPrecisionTimer(); - if( $InGuiEditor ) - GuiEdit(); + if( GuiEditorIsActive() ) + toggleGuiEditor(1); if( !$missionRunning ) { @@ -141,29 +135,21 @@ function toggleEditor(%make) Editor.close("PlayGui"); } } - else + else { - if ( !$GuiEditorBtnPressed ) - { - canvas.pushDialog( EditorLoadingGui ); - canvas.repaint(); - } - else - { - $GuiEditorBtnPressed = false; - } + canvas.pushDialog( EditorLoadingGui ); + canvas.repaint(); Editor.open(); - // Cancel the scheduled event to prevent - // the level from cycling after it's duration - // has elapsed. + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. cancel($Game::Schedule); if (theLevelInfo.type $= "DemoScene") commandToServer('dropCameraAtPlayer', true); - canvas.popDialog(EditorLoadingGui); } diff --git a/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs index b6c4200d4..be068b9ed 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs @@ -42,47 +42,59 @@ function EditorGui::buildMenus(%this) } // Sub menus (temporary, until MenuBuilder gets updated) - // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState. - // The new min/max for the editor camera speed range can be set in each level's levelInfo object. - %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions) + // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState. + // The new min/max for the editor camera speed range can be set in each level's levelInfo object. + if(!isObject(EditorCameraSpeedOptions)) { - superClass = "MenuBuilder"; - class = "EditorCameraSpeedMenu"; - - item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5"; - item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35"; - item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70"; - item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100"; - item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130"; - item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165"; - item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200"; - }; - %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions) + %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions) + { + superClass = "MenuBuilder"; + class = "EditorCameraSpeedMenu"; + + item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5"; + item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35"; + item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70"; + item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100"; + item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130"; + item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165"; + item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200"; + }; + } + if(!isObject(EditorFreeCameraTypeOptions)) { - superClass = "MenuBuilder"; - class = "EditorFreeCameraTypeMenu"; - - item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; - item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; - Item[2] = "-"; - item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; - item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; - }; - %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions) + %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorFreeCameraTypeMenu"; + + item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; + Item[2] = "-"; + item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; + item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; + }; + } + if(!isObject(EditorPlayerCameraTypeOptions)) { - superClass = "MenuBuilder"; - class = "EditorPlayerCameraTypeMenu"; - - Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; - Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; - }; - %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks) + %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorPlayerCameraTypeMenu"; + + Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; + Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; + }; + } + if(!isObject(EditorCameraBookmarks)) { - superClass = "MenuBuilder"; - class = "EditorCameraBookmarksMenu"; - - //item[0] = "None"; - }; + %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks) + { + superClass = "MenuBuilder"; + class = "EditorCameraBookmarksMenu"; + + //item[0] = "None"; + }; + } %this.viewTypeMenu = new PopupMenu() { superClass = "MenuBuilder"; @@ -98,7 +110,7 @@ function EditorGui::buildMenus(%this) }; // Menu bar - %this.menuBar = new MenuBar() + %this.menuBar = new MenuBar(WorldEditorMenubar) { dynamicItemInsertPos = 3; }; diff --git a/Templates/Full/game/art/gui/mainMenuGui.gui b/Templates/Full/game/art/gui/mainMenuGui.gui index bde78491f..895f48200 100644 --- a/Templates/Full/game/art/gui/mainMenuGui.gui +++ b/Templates/Full/game/art/gui/mainMenuGui.gui @@ -126,7 +126,7 @@ profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; - command = "GuiEdit();"; + command = "toggleGuiEditor(1);"; tooltipProfile = "GuiToolTipProfile"; tooltip = "The GUI Editor is accessible in-game by pressing F10"; hovertime = "1000"; diff --git a/Templates/Full/game/tools/base/utils/inspector.ed.cs b/Templates/Full/game/tools/base/utils/inspector.ed.cs index 9df8c7e98..f7c27ecf0 100644 --- a/Templates/Full/game/tools/base/utils/inspector.ed.cs +++ b/Templates/Full/game/tools/base/utils/inspector.ed.cs @@ -105,7 +105,7 @@ function EditorInspectorBase::onAdd( %this ) superClass = "MenuBuilder"; isPopup = true; - item[ 0 ] = "Edit Profile" TAB "" TAB "if( !$InGuiEditor ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );"; + item[ 0 ] = "Edit Profile" TAB "" TAB "if( !GuiEditorIsActive() ) toggleGuiEditor( true ); GuiEditor.editProfile( %this.inspectorField.getData() );"; item[ 1 ] = "Jump to Definition in Torsion" TAB "" TAB "EditorOpenDeclarationInTorsion( %this.inspectorField.getData() );"; item[ 2 ] = "Inspect Object" TAB "" TAB "inspectObject( %this.inspectorField.getData() );"; item[ 3 ] = "-"; diff --git a/Templates/Full/game/tools/guiEditor/gui/guiEditor.ed.gui b/Templates/Full/game/tools/guiEditor/gui/guiEditor.ed.gui index e387f1bc0..cc03cbd07 100644 --- a/Templates/Full/game/tools/guiEditor/gui/guiEditor.ed.gui +++ b/Templates/Full/game/tools/guiEditor/gui/guiEditor.ed.gui @@ -86,7 +86,7 @@ minExtent = "8 8"; canSave = "1"; visible = "1"; - command = "GuiEditor.switchToWorldEditor();"; + command = "toggleEditor(1);"; tooltipProfile = "ToolsGuiToolTipProfile"; ToolTip = "World Editor"; hovertime = "1000"; diff --git a/Templates/Full/game/tools/guiEditor/scripts/guiEditor.ed.cs b/Templates/Full/game/tools/guiEditor/scripts/guiEditor.ed.cs index eace7d43b..61dc8c5e7 100644 --- a/Templates/Full/game/tools/guiEditor/scripts/guiEditor.ed.cs +++ b/Templates/Full/game/tools/guiEditor/scripts/guiEditor.ed.cs @@ -75,11 +75,26 @@ function toggleGuiEditor( %make ) if( EditorIsActive() && !GuiEditor.toggleIntoEditorGui ) toggleEditor( true ); - GuiEdit(); + if( !isObject( GuiEditCanvas ) ) + new GuiControl( GuiEditCanvas, EditorGuiGroup ); - // Cancel the scheduled event to prevent - // the level from cycling after it's duration - // has elapsed. + if( GuiEditorIsActive() ) + { + GuiEditor.close(); + } + else + { + GuiEditor.open(); + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. + cancel($Game::Schedule); + } + + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. cancel($Game::Schedule); } } @@ -98,6 +113,26 @@ package GuiEditor_BlockDialogs //--------------------------------------------------------------------------------------------- +function GuiEditor::open(%this) +{ + GuiEditCanvas.onCreateMenu(); + + GuiEditContent(Canvas.getContent()); +} + +function GuiEditor::close(%this) +{ + // prevent the mission editor from opening while the GuiEditor is open. + if(Canvas.getContent() != GuiEditorGui.getId()) + return; + + GuiGroup.add(GuiEditorGui); + + Canvas.setContent(GuiEditor.lastContent); + + GuiEditCanvas.onDestroyMenu(); +} + function GuiEditor::openForEditing( %this, %content ) { Canvas.setContent( GuiEditorGui ); diff --git a/Templates/Full/game/tools/worldEditor/gui/EditorGui.ed.gui b/Templates/Full/game/tools/worldEditor/gui/EditorGui.ed.gui index 445bacf63..3eb8558e4 100644 --- a/Templates/Full/game/tools/worldEditor/gui/EditorGui.ed.gui +++ b/Templates/Full/game/tools/worldEditor/gui/EditorGui.ed.gui @@ -67,7 +67,7 @@ MinExtent = "8 8"; canSave = "1"; Visible = "1"; - Command = "toggleEditor( true ); GuiEdit(); $GuiEditorBtnPressed = true;"; + Command = "toggleGuiEditor(true); $GuiEditorBtnPressed = true;"; tooltipprofile = "ToolsGuiToolTipProfile"; ToolTip = "Open the GuiEditor"; hovertime = "1000"; diff --git a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs index 38a180e64..31f794d17 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -35,8 +35,6 @@ function EditorGui::init(%this) $NextOperationId = 1; $HeightfieldDirtyRow = -1; - %this.buildMenus(); - if( !isObject( %this-->ToolsPaletteWindow ) ) { // Load Creator/Inspector GUI @@ -1914,6 +1912,8 @@ function Editor::open(%this) if(Canvas.getContent() == GuiEditorGui.getId()) return; + EditorGui.buildMenus(); + if( !EditorGui.isInitialized ) EditorGui.init(); @@ -1929,6 +1929,21 @@ function Editor::close(%this, %gui) if(isObject(MessageHud)) MessageHud.close(); EditorGui.writeCameraSettings(); + + EditorGui.onDestroyMenu(); +} + +function EditorGui::onDestroyMenu(%this) +{ + if( !isObject( %this.menuBar ) ) + return; + + // Destroy menus + while( %this.menuBar.getCount() != 0 ) + %this.menuBar.getObject( 0 ).delete(); + + %this.menuBar.removeFromCanvas(); + %this.menuBar.delete(); } $RelightCallback = ""; diff --git a/Templates/Full/game/tools/worldEditor/scripts/editor.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/editor.ed.cs index 74b34e0a9..8545c9d67 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/editor.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/editor.ed.cs @@ -99,18 +99,12 @@ function Editor::checkActiveLoadDone() //------------------------------------------------------------------------------ function toggleEditor(%make) { - if (Canvas.isFullscreen()) - { - MessageBoxOK("Windowed Mode Required", "Please switch to windowed mode to access the Mission Editor."); - return; - } - if (%make) - { + { %timerId = startPrecisionTimer(); - if( $InGuiEditor ) - GuiEdit(); + if( GuiEditorIsActive() ) + toggleGuiEditor(1); if( !$missionRunning ) { @@ -141,29 +135,21 @@ function toggleEditor(%make) Editor.close("PlayGui"); } } - else + else { - if ( !$GuiEditorBtnPressed ) - { - canvas.pushDialog( EditorLoadingGui ); - canvas.repaint(); - } - else - { - $GuiEditorBtnPressed = false; - } + canvas.pushDialog( EditorLoadingGui ); + canvas.repaint(); Editor.open(); - // Cancel the scheduled event to prevent - // the level from cycling after it's duration - // has elapsed. + // Cancel the scheduled event to prevent + // the level from cycling after it's duration + // has elapsed. cancel($Game::Schedule); if (theLevelInfo.type $= "DemoScene") commandToServer('dropCameraAtPlayer', true); - canvas.popDialog(EditorLoadingGui); } diff --git a/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs index b6c4200d4..be068b9ed 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs @@ -42,47 +42,59 @@ function EditorGui::buildMenus(%this) } // Sub menus (temporary, until MenuBuilder gets updated) - // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState. - // The new min/max for the editor camera speed range can be set in each level's levelInfo object. - %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions) + // The speed increments located here are overwritten in EditorCameraSpeedMenu::setupDefaultState. + // The new min/max for the editor camera speed range can be set in each level's levelInfo object. + if(!isObject(EditorCameraSpeedOptions)) { - superClass = "MenuBuilder"; - class = "EditorCameraSpeedMenu"; - - item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5"; - item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35"; - item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70"; - item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100"; - item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130"; - item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165"; - item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200"; - }; - %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions) + %this.cameraSpeedMenu = new PopupMenu(EditorCameraSpeedOptions) + { + superClass = "MenuBuilder"; + class = "EditorCameraSpeedMenu"; + + item[0] = "Slowest" TAB %cmdCtrl @ "-Shift 1" TAB "5"; + item[1] = "Slow" TAB %cmdCtrl @ "-Shift 2" TAB "35"; + item[2] = "Slower" TAB %cmdCtrl @ "-Shift 3" TAB "70"; + item[3] = "Normal" TAB %cmdCtrl @ "-Shift 4" TAB "100"; + item[4] = "Faster" TAB %cmdCtrl @ "-Shift 5" TAB "130"; + item[5] = "Fast" TAB %cmdCtrl @ "-Shift 6" TAB "165"; + item[6] = "Fastest" TAB %cmdCtrl @ "-Shift 7" TAB "200"; + }; + } + if(!isObject(EditorFreeCameraTypeOptions)) { - superClass = "MenuBuilder"; - class = "EditorFreeCameraTypeMenu"; - - item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; - item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; - Item[2] = "-"; - item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; - item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; - }; - %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions) + %this.freeCameraTypeMenu = new PopupMenu(EditorFreeCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorFreeCameraTypeMenu"; + + item[0] = "Standard" TAB "Ctrl 1" TAB "EditorGuiStatusBar.setCamera(\"Standard Camera\");"; + item[1] = "Orbit Camera" TAB "Ctrl 2" TAB "EditorGuiStatusBar.setCamera(\"Orbit Camera\");"; + Item[2] = "-"; + item[3] = "Smoothed" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Camera\");"; + item[4] = "Smoothed Rotate" TAB "" TAB "EditorGuiStatusBar.setCamera(\"Smooth Rot Camera\");"; + }; + } + if(!isObject(EditorPlayerCameraTypeOptions)) { - superClass = "MenuBuilder"; - class = "EditorPlayerCameraTypeMenu"; - - Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; - Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; - }; - %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks) + %this.playerCameraTypeMenu = new PopupMenu(EditorPlayerCameraTypeOptions) + { + superClass = "MenuBuilder"; + class = "EditorPlayerCameraTypeMenu"; + + Item[0] = "First Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"1st Person Camera\");"; + Item[1] = "Third Person" TAB "" TAB "EditorGuiStatusBar.setCamera(\"3rd Person Camera\");"; + }; + } + if(!isObject(EditorCameraBookmarks)) { - superClass = "MenuBuilder"; - class = "EditorCameraBookmarksMenu"; - - //item[0] = "None"; - }; + %this.cameraBookmarksMenu = new PopupMenu(EditorCameraBookmarks) + { + superClass = "MenuBuilder"; + class = "EditorCameraBookmarksMenu"; + + //item[0] = "None"; + }; + } %this.viewTypeMenu = new PopupMenu() { superClass = "MenuBuilder"; @@ -98,7 +110,7 @@ function EditorGui::buildMenus(%this) }; // Menu bar - %this.menuBar = new MenuBar() + %this.menuBar = new MenuBar(WorldEditorMenubar) { dynamicItemInsertPos = 3; }; From 80a2a8c29abb25bb694972d4e090cf97db4f934c Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 23 Jan 2017 18:52:30 -0600 Subject: [PATCH 47/50] Fixed the fadeout coloration when using textures, as well as some cleanup for the code. --- Engine/source/T3D/fx/lightning.cpp | 55 ++++++++++++++++-------------- Engine/source/T3D/fx/lightning.h | 1 + 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/Engine/source/T3D/fx/lightning.cpp b/Engine/source/T3D/fx/lightning.cpp index ed941a82b..080bbed82 100644 --- a/Engine/source/T3D/fx/lightning.cpp +++ b/Engine/source/T3D/fx/lightning.cpp @@ -200,7 +200,7 @@ void LightningStrikeEvent::unpack(NetConnection* con, BitStream* stream) { if(!stream->readFlag()) return; - S32 mClientId = stream->readRangedU32(0, NetConnection::MaxGhostCount); + mClientId = stream->readRangedU32(0, NetConnection::MaxGhostCount); mLightning = NULL; NetObject* pObject = con->resolveGhost(mClientId); if (pObject) @@ -214,10 +214,10 @@ void LightningStrikeEvent::unpack(NetConnection* con, BitStream* stream) // target id S32 mTargetID = stream->readRangedU32(0, NetConnection::MaxGhostCount); - NetObject* pObject = con->resolveGhost(mTargetID); - if( pObject != NULL ) + NetObject* tObject = con->resolveGhost(mTargetID); + if(tObject != NULL ) { - mTarget = dynamic_cast(pObject); + mTarget = dynamic_cast(tObject); } if( bool(mTarget) == false ) { @@ -325,7 +325,8 @@ void LightningData::packData(BitStream* stream) stream->writeInt(mNumStrikeTextures, 4); - for (i = 0; i < MaxTextures; i++) { + for (i = 0; i < MaxTextures; i++) + { stream->writeString(strikeTextureNames[i]); } @@ -342,7 +343,8 @@ void LightningData::unpackData(BitStream* stream) mNumStrikeTextures = stream->readInt(4); - for (i = 0; i < MaxTextures; i++) { + for (i = 0; i < MaxTextures; i++) + { strikeTextureNames[i] = stream->readSTString(); } @@ -379,16 +381,16 @@ Lightning::~Lightning() { while( mThunderListHead ) { - Thunder* next = mThunderListHead->next; + Thunder* nextThunder = mThunderListHead->next; delete mThunderListHead; - mThunderListHead = next; + mThunderListHead = nextThunder; } while( mStrikeListHead ) { - Strike* next = mStrikeListHead->next; + Strike* nextStrike = mStrikeListHead->next; delete mStrikeListHead; - mStrikeListHead = next; + mStrikeListHead = nextStrike; } } @@ -489,6 +491,7 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base desc.setBlend( true, GFXBlendSrcAlpha, GFXBlendOne); desc.setCullMode(GFXCullNone); desc.zWriteEnable = false; + desc.vertexColorEnable = true; if (mDataBlock->mNumStrikeTextures != 0) { @@ -518,7 +521,7 @@ void Lightning::renderObject(ObjectRenderInst *ri, SceneRenderState *state, Base GFX->setTexture(0, mDataBlock->strikeTextures[0]); } - for( U32 i=0; i<3; i++ ) + for( U32 i=0; ibolt[i].isFading ) { @@ -611,7 +614,7 @@ void Lightning::advanceTime(F32 dt) while (*pWalker != NULL) { Strike* pStrike = *pWalker; - for( U32 i=0; i<3; i++ ) + for( U32 i=0; ibolt[i].update( dt ); } @@ -695,7 +698,7 @@ void Lightning::processEvent(LightningStrikeEvent* pEvent) pStrike->currentAge = 0.0f; pStrike->next = mStrikeListHead; - for( U32 i=0; i<3; i++ ) + for( U32 i=0; iwrite(color.red); stream->write(color.green); stream->write(color.blue); + stream->write(color.alpha); stream->write(fadeColor.red); stream->write(fadeColor.green); stream->write(fadeColor.blue); @@ -918,6 +922,7 @@ void Lightning::unpackUpdate(NetConnection* con, BitStream* stream) stream->read(&color.red); stream->read(&color.green); stream->read(&color.blue); + stream->read(&color.alpha); stream->read(&fadeColor.red); stream->read(&fadeColor.green); stream->read(&fadeColor.blue); @@ -953,7 +958,7 @@ DefineEngineMethod(Lightning, strikeRandomPoint, void, (),, object->strikeRandomPoint(); } -DefineEngineMethod(Lightning, strikeObject, void, (ShapeBase* pSB),, +DefineEngineMethod(Lightning, strikeObject, void, (ShapeBase* pSB), (nullAsType()), "Creates a LightningStrikeEvent which strikes a specific object.\n" "@note This method is currently unimplemented.\n" ) { @@ -1177,7 +1182,7 @@ void LightningBolt::generateMinorNodes() //---------------------------------------------------------------------------- // Recursive algo to create bolts that split off from main bolt //---------------------------------------------------------------------------- -void LightningBolt::createSplit( const Point3F &startPoint, const Point3F &endPoint, U32 depth, F32 width ) +void LightningBolt::createSplit( const Point3F &startingPoint, const Point3F &endingPoint, U32 depth, F32 splitWidth ) { if( depth == 0 ) return; @@ -1186,17 +1191,17 @@ void LightningBolt::createSplit( const Point3F &startPoint, const Point3F &endPo if( chanceToEnd > 0.70f ) return; - if( width < 0.75f ) - width = 0.75f; + if(splitWidth < 0.75f ) + splitWidth = 0.75f; - VectorF diff = endPoint - startPoint; + VectorF diff = endingPoint - startingPoint; F32 length = diff.len(); diff.normalizeSafe(); LightningBolt newBolt; - newBolt.startPoint = startPoint; - newBolt.endPoint = endPoint; - newBolt.width = width; + newBolt.startPoint = startingPoint; + newBolt.endPoint = endingPoint; + newBolt.width = splitWidth; newBolt.numMajorNodes = 3; newBolt.maxMajorAngle = 30.0f; newBolt.numMinorNodes = 3; @@ -1207,13 +1212,13 @@ void LightningBolt::createSplit( const Point3F &startPoint, const Point3F &endPo splitList.pushBack( newBolt ); VectorF newDir1 = MathUtils::randomDir( diff, 10.0f, 45.0f ); - Point3F newEndPoint1 = endPoint + newDir1 * gRandGen.randF( 0.5f, 1.5f ) * length; + Point3F newEndPoint1 = endingPoint + newDir1 * gRandGen.randF( 0.5f, 1.5f ) * length; VectorF newDir2 = MathUtils::randomDir( diff, 10.0f, 45.0f ); - Point3F newEndPoint2 = endPoint + newDir2 * gRandGen.randF( 0.5f, 1.5f ) * length; + Point3F newEndPoint2 = endingPoint + newDir2 * gRandGen.randF( 0.5f, 1.5f ) * length; - createSplit( endPoint, newEndPoint1, depth - 1, width * 0.30f ); - createSplit( endPoint, newEndPoint2, depth - 1, width * 0.30f ); + createSplit(endingPoint, newEndPoint1, depth - 1, splitWidth * 0.30f ); + createSplit(endingPoint, newEndPoint2, depth - 1, splitWidth * 0.30f ); } diff --git a/Engine/source/T3D/fx/lightning.h b/Engine/source/T3D/fx/lightning.h index 71ff493d1..340d4e067 100644 --- a/Engine/source/T3D/fx/lightning.h +++ b/Engine/source/T3D/fx/lightning.h @@ -47,6 +47,7 @@ class ShapeBase; class LightningStrikeEvent; class SFXTrack; +#define MAX_LIGHTNING 3 // ------------------------------------------------------------------------- class LightningData : public GameBaseData From a8f2fc567beeedb365712857745250a07c5038d6 Mon Sep 17 00:00:00 2001 From: Areloch Date: Sun, 29 Jan 2017 03:22:25 -0600 Subject: [PATCH 48/50] Fixes up the handling of accelerator keybinds for SDL - specifically compound ones with several modifier keys, ie ctrl-alt-shift-up. --- Engine/source/platform/input/event.h | 2 +- Engine/source/windowManager/sdl/sdlWindow.cpp | 42 +++++++++++++------ .../windowManager/windowInputGenerator.cpp | 12 +++--- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/Engine/source/platform/input/event.h b/Engine/source/platform/input/event.h index b77caa202..1c6d1f1dc 100644 --- a/Engine/source/platform/input/event.h +++ b/Engine/source/platform/input/event.h @@ -429,7 +429,7 @@ struct InputEventInfo U16 ascii; /// Modifiers to action: SI_LSHIFT, SI_LCTRL, etc. - InputModifiers modifier; + U32 modifier; inline void postToSignal(InputEvent &ie) { diff --git a/Engine/source/windowManager/sdl/sdlWindow.cpp b/Engine/source/windowManager/sdl/sdlWindow.cpp index 510834fca..3c819248b 100644 --- a/Engine/source/windowManager/sdl/sdlWindow.cpp +++ b/Engine/source/windowManager/sdl/sdlWindow.cpp @@ -51,23 +51,41 @@ namespace { U32 ret = 0; - if(mod & KMOD_LSHIFT) - ret |= IM_LSHIFT; + if (mod & KMOD_LSHIFT) + { + ret |= SI_LSHIFT; + ret |= SI_SHIFT; + } - if(mod & KMOD_RSHIFT) - ret |= IM_RSHIFT; + if (mod & KMOD_RSHIFT) + { + ret |= SI_RSHIFT; + ret |= SI_SHIFT; + } - if(mod & KMOD_LCTRL) - ret |= IM_LCTRL; + if (mod & KMOD_LCTRL) + { + ret |= SI_LCTRL; + ret |= SI_CTRL; + } - if(mod & KMOD_RCTRL) - ret |= IM_RCTRL; + if (mod & KMOD_RCTRL) + { + ret |= SI_RCTRL; + ret |= SI_CTRL; + } - if(mod & KMOD_LALT) - ret |= IM_LALT; + if (mod & KMOD_LALT) + { + ret |= SI_LALT; + ret |= SI_ALT; + } - if(mod & KMOD_RALT) - ret |= IM_RALT; + if (mod & KMOD_RALT) + { + ret |= SI_RALT; + ret |= SI_ALT; + } return ret; } diff --git a/Engine/source/windowManager/windowInputGenerator.cpp b/Engine/source/windowManager/windowInputGenerator.cpp index c31bad1ba..907f1be77 100644 --- a/Engine/source/windowManager/windowInputGenerator.cpp +++ b/Engine/source/windowManager/windowInputGenerator.cpp @@ -95,7 +95,7 @@ void WindowInputGenerator::generateInputEvent( InputEventInfo &inputEvent ) { const AccKeyMap &acc = mAcceleratorMap[i]; if (!mWindow->getKeyboardTranslation() && - (acc.modifier & inputEvent.modifier || (acc.modifier == 0 && inputEvent.modifier == 0)) + ((acc.modifier == inputEvent.modifier && acc.modifier != 0) || (acc.modifier == 0 && inputEvent.modifier == 0)) && acc.keyCode == inputEvent.objInst) { Con::evaluatef(acc.cmd); @@ -145,7 +145,7 @@ void WindowInputGenerator::handleMouseMove( WindowId did, U32 modifier, S32 x, S event.deviceType = MouseDeviceType; event.deviceInst = 0; event.objType = SI_AXIS; - event.modifier = convertModifierBits(modifier); + event.modifier = modifier; event.ascii = 0; // Generate delta movement along each axis @@ -231,7 +231,7 @@ void WindowInputGenerator::handleMouseButton( WindowId did, U32 modifiers, U32 a event.deviceInst = 0; event.objType = SI_BUTTON; event.objInst = (InputObjectInstances)(KEY_BUTTON0 + button); - event.modifier = convertModifierBits(modifiers); + event.modifier = modifiers; event.ascii = 0; event.action = (action==IA_MAKE) ? SI_MAKE : SI_BREAK; event.fValue = (action==IA_MAKE) ? 1.0 : 0.0; @@ -248,7 +248,7 @@ void WindowInputGenerator::handleMouseWheel( WindowId did, U32 modifiers, S32 wh event.deviceType = MouseDeviceType; event.deviceInst = 0; event.objType = SI_AXIS; - event.modifier = convertModifierBits(modifiers); + event.modifier = modifiers; event.ascii = 0; event.action = SI_MOVE; @@ -281,7 +281,7 @@ void WindowInputGenerator::handleCharInput( WindowId did, U32 modifier, U16 key event.deviceInst = 0; event.objType = SI_KEY; event.objInst = KEY_NULL; - event.modifier = convertModifierBits(modifier); + event.modifier = modifier; event.ascii = key; event.action = SI_MAKE; event.fValue = 1.0; @@ -303,7 +303,7 @@ void WindowInputGenerator::handleKeyboard( WindowId did, U32 modifier, U32 actio event.deviceInst = 0; event.objType = SI_KEY; event.objInst = (InputObjectInstances)key; - event.modifier = convertModifierBits(modifier); + event.modifier = modifier; event.ascii = 0; switch(action) From 48bd911dcbc94804286acd23c7ca2178a832a3f6 Mon Sep 17 00:00:00 2001 From: Areloch Date: Sun, 29 Jan 2017 04:12:32 -0600 Subject: [PATCH 49/50] Made sure the old code was still there for non-SDL usage. --- .../windowManager/windowInputGenerator.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Engine/source/windowManager/windowInputGenerator.cpp b/Engine/source/windowManager/windowInputGenerator.cpp index 907f1be77..6c9e45b71 100644 --- a/Engine/source/windowManager/windowInputGenerator.cpp +++ b/Engine/source/windowManager/windowInputGenerator.cpp @@ -145,7 +145,11 @@ void WindowInputGenerator::handleMouseMove( WindowId did, U32 modifier, S32 x, S event.deviceType = MouseDeviceType; event.deviceInst = 0; event.objType = SI_AXIS; - event.modifier = modifier; +#ifdef TORQUE_SDL + event.modifier = modifier; +#else + event.modifier = convertModifierBits(modifier); +#endif event.ascii = 0; // Generate delta movement along each axis @@ -231,7 +235,11 @@ void WindowInputGenerator::handleMouseButton( WindowId did, U32 modifiers, U32 a event.deviceInst = 0; event.objType = SI_BUTTON; event.objInst = (InputObjectInstances)(KEY_BUTTON0 + button); - event.modifier = modifiers; +#ifdef TORQUE_SDL + event.modifier = modifiers; +#else + event.modifier = convertModifierBits(modifiers); +#endif event.ascii = 0; event.action = (action==IA_MAKE) ? SI_MAKE : SI_BREAK; event.fValue = (action==IA_MAKE) ? 1.0 : 0.0; @@ -248,7 +256,11 @@ void WindowInputGenerator::handleMouseWheel( WindowId did, U32 modifiers, S32 wh event.deviceType = MouseDeviceType; event.deviceInst = 0; event.objType = SI_AXIS; - event.modifier = modifiers; +#ifdef TORQUE_SDL + event.modifier = modifiers; +#else + event.modifier = convertModifierBits(modifiers); +#endif event.ascii = 0; event.action = SI_MOVE; @@ -281,7 +293,11 @@ void WindowInputGenerator::handleCharInput( WindowId did, U32 modifier, U16 key event.deviceInst = 0; event.objType = SI_KEY; event.objInst = KEY_NULL; - event.modifier = modifier; +#ifdef TORQUE_SDL + event.modifier = modifier; +#else + event.modifier = convertModifierBits(modifier); +#endif event.ascii = key; event.action = SI_MAKE; event.fValue = 1.0; @@ -303,7 +319,11 @@ void WindowInputGenerator::handleKeyboard( WindowId did, U32 modifier, U32 actio event.deviceInst = 0; event.objType = SI_KEY; event.objInst = (InputObjectInstances)key; +#ifdef TORQUE_SDL event.modifier = modifier; +#else + event.modifier = convertModifierBits(modifier); +#endif event.ascii = 0; switch(action) From 501b55d9399e3a383a6dd486933be612720f923b Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 30 Jan 2017 20:36:48 -0600 Subject: [PATCH 50/50] Adds a check to the record movie call so that it only happens in Release mode, to avoid crash issues with theora and debug mode. --- Engine/source/gfx/video/videoCapture.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Engine/source/gfx/video/videoCapture.cpp b/Engine/source/gfx/video/videoCapture.cpp index 8f7b7e52e..a966bbe01 100644 --- a/Engine/source/gfx/video/videoCapture.cpp +++ b/Engine/source/gfx/video/videoCapture.cpp @@ -314,6 +314,9 @@ DefineEngineFunction( startVideoCapture, void, "@see stopVideoCapture\n" "@ingroup Rendering\n" ) { +#ifdef TORQUE_DEBUG + Con::errorf("Recording video is disabled in debug!"); +#else if ( !canvas ) { Con::errorf("startVideoCapture -Please specify a GuiCanvas object to record from!"); @@ -328,6 +331,7 @@ DefineEngineFunction( startVideoCapture, void, VIDCAP->setResolution(resolution); VIDCAP->begin(canvas); +#endif } DefineEngineFunction( stopVideoCapture, void, (),,